[quake3-commits] r1719 - trunk/code/qcommon

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Sun Nov 1 14:58:12 EST 2009


Author: ludwig
Date: 2009-11-01 14:58:12 -0500 (Sun, 01 Nov 2009)
New Revision: 1719

Modified:
   trunk/code/qcommon/vm_x86_64.c
Log:
optimize const before jump

Modified: trunk/code/qcommon/vm_x86_64.c
===================================================================
--- trunk/code/qcommon/vm_x86_64.c	2009-11-01 19:58:09 UTC (rev 1718)
+++ trunk/code/qcommon/vm_x86_64.c	2009-11-01 19:58:12 UTC (rev 1719)
@@ -239,8 +239,23 @@
 	emit("movq $%lu, %%rax", vm->codeBase+vm->instructionPointers[iarg]); \
 	emit("jmpq *%%rax");
  
+#define CONST_OPTIMIZE
+#ifdef CONST_OPTIMIZE
+#define MAYBE_EMIT_CONST() \
+	if (got_const) \
+	{ \
+		got_const = 0; \
+		vm->instructionPointers[instruction-1] = assembler_get_code_size(); \
+		emit("addq $4, %%rsi"); \
+		emit("movl $%d, 0(%%rsi)", const_value); \
+	}
+#else
+#define MAYBE_EMIT_CONST()
+#endif
+
 // integer compare and jump
 #define IJ(op) \
+	MAYBE_EMIT_CONST(); \
 	emit("subq $8, %%rsi"); \
 	emit("movl 4(%%rsi), %%eax"); \
 	emit("cmpl 8(%%rsi), %%eax"); \
@@ -250,6 +265,7 @@
 
 #ifdef USE_X87
 #define FJ(bits, op) \
+	MAYBE_EMIT_CONST(); \
 	emit("subq $8, %%rsi");\
 	emit("flds 4(%%rsi)");\
 	emit("fcomps 8(%%rsi)");\
@@ -262,6 +278,7 @@
 #else
 #define FJ(x, y)
 #define XJ(op) \
+	MAYBE_EMIT_CONST(); \
 	emit("subq $8, %%rsi");\
 	emit("movss 4(%%rsi), %%xmm0");\
 	emit("ucomiss 8(%%rsi), %%xmm0");\
@@ -272,12 +289,14 @@
 #endif
 
 #define SIMPLE(op) \
+	MAYBE_EMIT_CONST(); \
 	emit("subq $4, %%rsi"); \
 	emit("movl 4(%%rsi), %%eax"); \
 	emit(op " %%eax, 0(%%rsi)");
 
 #ifdef USE_X87
 #define FSIMPLE(op) \
+	MAYBE_EMIT_CONST(); \
 	emit("subq $4, %%rsi"); \
 	emit("flds 0(%%rsi)"); \
 	emit(op " 4(%%rsi)"); \
@@ -286,6 +305,7 @@
 #else
 #define FSIMPLE(op)
 #define XSIMPLE(op) \
+	MAYBE_EMIT_CONST(); \
 	emit("subq $4, %%rsi"); \
 	emit("movss 0(%%rsi), %%xmm0"); \
 	emit(op " 4(%%rsi), %%xmm0"); \
@@ -293,6 +313,7 @@
 #endif
 
 #define SHIFT(op) \
+	MAYBE_EMIT_CONST(); \
 	emit("subq $4, %%rsi"); \
 	emit("movl 4(%%rsi), %%ecx"); \
 	emit("movl 0(%%rsi), %%eax"); \
@@ -343,6 +364,12 @@
 	memcpy(currentVM->dataBase+dest, currentVM->dataBase+src, count);
 }
 
+static void eop(void)
+{
+	Com_Error(ERR_DROP, "end of program reached without return!\n");
+	exit(1);
+}
+
 /*
 =================
 VM_Compile
@@ -364,6 +391,9 @@
 	int pass;
 	size_t compiledOfs = 0;
 
+	// const optimization
+	unsigned got_const = 0, const_value = 0;
+
 	gettimeofday(&tvstart, NULL);
 
 	for (pass = 0; pass < 2; ++pass) {
@@ -400,7 +430,7 @@
 		vm->instructionPointers[instruction] = assembler_get_code_size();
 
 		/* store current instruction number in r15 for debugging */
-#if DEBUG_VM
+#if DEBUG_VM0
 		emit("nop");
 		emit("movq $%d, %%r15", instruction);
 		emit("nop");
@@ -434,20 +464,25 @@
 				NOTIMPL(op);
 				break;
 			case OP_IGNORE:
+				MAYBE_EMIT_CONST();
 				emit("nop");
 				break;
 			case OP_BREAK:
+				MAYBE_EMIT_CONST();
 				emit("int3");
 				break;
 			case OP_ENTER:
+				MAYBE_EMIT_CONST();
 				emit("subl $%d, %%edi", iarg);
 				RANGECHECK(edi);
 				break;
 			case OP_LEAVE:
+				MAYBE_EMIT_CONST();
 				emit("addl $%d, %%edi", iarg);          // get rid of stack frame
 				emit("ret");
 				break;
 			case OP_CALL:
+				MAYBE_EMIT_CONST();
 				emit("movl 0(%%rsi), %%eax");  // get instr from stack
 				emit("subq $4, %%rsi");
 				emit("movl $%d, 0(%%r8, %%rdi, 1)", instruction+1);  // save next instruction
@@ -489,31 +524,43 @@
 				neednilabel = 1;
 				break;
 			case OP_PUSH:
+				MAYBE_EMIT_CONST();
 				emit("addq $4, %%rsi");
 				break;
 			case OP_POP:
+				MAYBE_EMIT_CONST();
 				emit("subq $4, %%rsi");
 				break;
 			case OP_CONST:
-				if(code[pc] == OP_JUMP) {
-					CHECK_IARG;
-				}
+				MAYBE_EMIT_CONST();
+#ifdef CONST_OPTIMIZE
+				got_const = 1;
+				const_value = iarg;
+#else
 				emit("addq $4, %%rsi");
 				emit("movl $%d, 0(%%rsi)", iarg);
+#endif
 				break;
 			case OP_LOCAL:
+				MAYBE_EMIT_CONST();
 				emit("movl %%edi, %%ebx");
 				emit("addl $%d,%%ebx", iarg);
 				emit("addq $4, %%rsi");
 				emit("movl %%ebx, 0(%%rsi)");
 				break;
 			case OP_JUMP:
-				emit("movl 0(%%rsi), %%eax"); // get instr from stack
-				emit("subq $4, %%rsi");
-				emit("movq $%lu, %%rbx", (unsigned long)vm->instructionPointers);
-				emit("movl (%%rbx, %%rax, 4), %%eax"); // load new relative jump address
-				emit("addq %%r10, %%rax");
-				emit("jmp *%%rax");
+				if(got_const) {
+					iarg = const_value;
+					got_const = 0;
+					JMPIARG;
+				} else {
+					emit("movl 0(%%rsi), %%eax"); // get instr from stack
+					emit("subq $4, %%rsi");
+					emit("movq $%lu, %%rbx", (unsigned long)vm->instructionPointers);
+					emit("movl (%%rbx, %%rax, 4), %%eax"); // load new relative jump address
+					emit("addq %%r10, %%rax");
+					emit("jmp *%%rax");
+				}
 				break;
 			case OP_EQ:
 				IJ("jne");
@@ -552,6 +599,7 @@
 			case OP_NEF:
 				FJ(0x40, "jnz");
 #ifndef USE_X87
+				MAYBE_EMIT_CONST();
 				emit("subq $8, %%rsi");
 				emit("movss 4(%%rsi), %%xmm0");
 				emit("ucomiss 8(%%rsi), %%xmm0");
@@ -579,6 +627,7 @@
 				XJ("jb");
 				break;
 			case OP_LOAD1:
+				MAYBE_EMIT_CONST();
 				emit("movl 0(%%rsi), %%eax"); // get value from stack
 				RANGECHECK(eax);
 				emit("movb 0(%%r8, %%rax, 1), %%al"); // deref into eax
@@ -586,18 +635,21 @@
 				emit("movl %%eax, 0(%%rsi)"); // store on stack
 				break;
 			case OP_LOAD2:
+				MAYBE_EMIT_CONST();
 				emit("movl 0(%%rsi), %%eax"); // get value from stack
 				RANGECHECK(eax);
 				emit("movw 0(%%r8, %%rax, 1), %%ax"); // deref into eax
 				emit("movl %%eax, 0(%%rsi)"); // store on stack
 				break;
 			case OP_LOAD4:
+				MAYBE_EMIT_CONST();
 				emit("movl 0(%%rsi), %%eax"); // get value from stack
 				RANGECHECK(eax); // not a pointer!?
 				emit("movl 0(%%r8, %%rax, 1), %%eax"); // deref into eax
 				emit("movl %%eax, 0(%%rsi)"); // store on stack
 				break;
 			case OP_STORE1:
+				MAYBE_EMIT_CONST();
 				emit("movl 0(%%rsi), %%eax"); // get value from stack
 				emit("andq $255, %%rax");
 				emit("movl -4(%%rsi), %%ebx"); // get pointer from stack
@@ -606,6 +658,7 @@
 				emit("subq $8, %%rsi");
 				break;
 			case OP_STORE2:
+				MAYBE_EMIT_CONST();
 				emit("movl 0(%%rsi), %%eax"); // get value from stack
 				emit("movl -4(%%rsi), %%ebx"); // get pointer from stack
 				RANGECHECK(ebx);
@@ -613,6 +666,7 @@
 				emit("subq $8, %%rsi");
 				break;
 			case OP_STORE4:
+				MAYBE_EMIT_CONST();
 				emit("movl -4(%%rsi), %%ebx"); // get pointer from stack
 				RANGECHECK(ebx);
 				emit("movl 0(%%rsi), %%ecx"); // get value from stack
@@ -620,6 +674,7 @@
 				emit("subq $8, %%rsi");
 				break;
 			case OP_ARG:
+				MAYBE_EMIT_CONST();
 				emit("subq $4, %%rsi");
 				emit("movl 4(%%rsi), %%eax"); // get value from stack
 				emit("movl $0x%hhx, %%ebx", barg);
@@ -629,6 +684,7 @@
 				break;
 			case OP_BLOCK_COPY:
 
+				MAYBE_EMIT_CONST();
 				emit("subq $8, %%rsi");
 				emit("push %%rsi");
 				emit("push %%rdi");
@@ -648,6 +704,7 @@
 
 				break;
 			case OP_SEX8:
+				MAYBE_EMIT_CONST();
 				emit("movw 0(%%rsi), %%ax");
 				emit("andq $255, %%rax");
 				emit("cbw");
@@ -655,11 +712,13 @@
 				emit("movl %%eax, 0(%%rsi)");
 				break;
 			case OP_SEX16:
+				MAYBE_EMIT_CONST();
 				emit("movw 0(%%rsi), %%ax");
 				emit("cwde");
 				emit("movl %%eax, 0(%%rsi)");
 				break;
 			case OP_NEGI:
+				MAYBE_EMIT_CONST();
 				emit("negl 0(%%rsi)");
 				break;
 			case OP_ADD:
@@ -669,6 +728,7 @@
 				SIMPLE("subl");
 				break;
 			case OP_DIVI:
+				MAYBE_EMIT_CONST();
 				emit("subq $4, %%rsi");
 				emit("movl 0(%%rsi), %%eax");
 				emit("cdq");
@@ -676,6 +736,7 @@
 				emit("movl %%eax, 0(%%rsi)");
 				break;
 			case OP_DIVU:
+				MAYBE_EMIT_CONST();
 				emit("subq $4, %%rsi");
 				emit("movl 0(%%rsi), %%eax");
 				emit("xorq %%rdx, %%rdx");
@@ -683,6 +744,7 @@
 				emit("movl %%eax, 0(%%rsi)");
 				break;
 			case OP_MODI:
+				MAYBE_EMIT_CONST();
 				emit("subq $4, %%rsi");
 				emit("movl 0(%%rsi), %%eax");
 				emit("xorl %%edx, %%edx");
@@ -691,6 +753,7 @@
 				emit("movl %%edx, 0(%%rsi)");
 				break;
 			case OP_MODU:
+				MAYBE_EMIT_CONST();
 				emit("subq $4, %%rsi");
 				emit("movl 0(%%rsi), %%eax");
 				emit("xorl %%edx, %%edx");
@@ -698,12 +761,14 @@
 				emit("movl %%edx, 0(%%rsi)");
 				break;
 			case OP_MULI:
+				MAYBE_EMIT_CONST();
 				emit("subq $4, %%rsi");
 				emit("movl 0(%%rsi), %%eax");
 				emit("imull 4(%%rsi)");
 				emit("movl %%eax, 0(%%rsi)");
 				break;
 			case OP_MULU:
+				MAYBE_EMIT_CONST();
 				emit("subq $4, %%rsi");
 				emit("movl 0(%%rsi), %%eax");
 				emit("mull 4(%%rsi)");
@@ -719,6 +784,7 @@
 				SIMPLE("xorl");
 				break;
 			case OP_BCOM:
+				MAYBE_EMIT_CONST();
 				emit("notl 0(%%rsi)");
 				break;
 			case OP_LSH:
@@ -731,6 +797,7 @@
 				SHIFT("shrl");
 				break;
 			case OP_NEGF:
+				MAYBE_EMIT_CONST();
 #ifdef USE_X87
 				emit("flds 0(%%rsi)");
 				emit("fchs");
@@ -757,6 +824,7 @@
 				XSIMPLE("mulss");
 				break;
 			case OP_CVIF:
+				MAYBE_EMIT_CONST();
 #ifdef USE_X87
 				emit("filds 0(%%rsi)");
 				emit("fstps 0(%%rsi)");
@@ -767,6 +835,7 @@
 #endif
 				break;
 			case OP_CVFI:
+				MAYBE_EMIT_CONST();
 #ifdef USE_X87
 				emit("flds 0(%%rsi)");
 				emit("fnstcw 4(%%rsi)");
@@ -784,8 +853,17 @@
 				NOTIMPL(op);
 				break;
 		}
+
+
 	}
 
+	if(got_const) {
+		Com_Error(ERR_DROP, "leftover const\n");
+	}
+
+	emit("movq $%lu, %%rax", (unsigned long)eop);
+	emit("callq *%%rax");
+
 	} // pass loop
 
 	assembler_init(0);
@@ -798,7 +876,16 @@
 #ifdef DEBUG_VM
 	fflush(qdasmout);
 	fclose(qdasmout);
+
+#if 0
+	strcpy(fn_d,vm->name);
+	strcat(fn_d, ".bin");
+	qdasmout = fopen(fn_d, "w");
+	fwrite(vm->codeBase, compiledOfs, 1, qdasmout);
+	fflush(qdasmout);
+	fclose(qdasmout);
 #endif
+#endif
 	
 	if(vm->compiled)
 	{



More information about the quake3-commits mailing list