[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