mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2024-11-23 12:32:09 +00:00
optimize const before jump
This commit is contained in:
parent
a7dee44def
commit
ed98f65d10
1 changed files with 97 additions and 10 deletions
|
@ -239,8 +239,23 @@ void emit(const char* fmt, ...)
|
|||
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 @@ void emit(const char* fmt, ...)
|
|||
|
||||
#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 @@ void emit(const char* fmt, ...)
|
|||
#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 @@ void emit(const char* fmt, ...)
|
|||
#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 @@ void emit(const char* fmt, ...)
|
|||
#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 @@ void emit(const char* fmt, ...)
|
|||
#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 @@ static void block_copy_vm(unsigned dest, unsigned src, unsigned count)
|
|||
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 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
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 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
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 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
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 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
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 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
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 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
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 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
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 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
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 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
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 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
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 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
break;
|
||||
case OP_BLOCK_COPY:
|
||||
|
||||
MAYBE_EMIT_CONST();
|
||||
emit("subq $8, %%rsi");
|
||||
emit("push %%rsi");
|
||||
emit("push %%rdi");
|
||||
|
@ -648,6 +704,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
|
||||
break;
|
||||
case OP_SEX8:
|
||||
MAYBE_EMIT_CONST();
|
||||
emit("movw 0(%%rsi), %%ax");
|
||||
emit("andq $255, %%rax");
|
||||
emit("cbw");
|
||||
|
@ -655,11 +712,13 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
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 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
SIMPLE("subl");
|
||||
break;
|
||||
case OP_DIVI:
|
||||
MAYBE_EMIT_CONST();
|
||||
emit("subq $4, %%rsi");
|
||||
emit("movl 0(%%rsi), %%eax");
|
||||
emit("cdq");
|
||||
|
@ -676,6 +736,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
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 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
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 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
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 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
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 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
SIMPLE("xorl");
|
||||
break;
|
||||
case OP_BCOM:
|
||||
MAYBE_EMIT_CONST();
|
||||
emit("notl 0(%%rsi)");
|
||||
break;
|
||||
case OP_LSH:
|
||||
|
@ -731,6 +797,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
SHIFT("shrl");
|
||||
break;
|
||||
case OP_NEGF:
|
||||
MAYBE_EMIT_CONST();
|
||||
#ifdef USE_X87
|
||||
emit("flds 0(%%rsi)");
|
||||
emit("fchs");
|
||||
|
@ -757,6 +824,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
XSIMPLE("mulss");
|
||||
break;
|
||||
case OP_CVIF:
|
||||
MAYBE_EMIT_CONST();
|
||||
#ifdef USE_X87
|
||||
emit("filds 0(%%rsi)");
|
||||
emit("fstps 0(%%rsi)");
|
||||
|
@ -767,6 +835,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
#endif
|
||||
break;
|
||||
case OP_CVFI:
|
||||
MAYBE_EMIT_CONST();
|
||||
#ifdef USE_X87
|
||||
emit("flds 0(%%rsi)");
|
||||
emit("fnstcw 4(%%rsi)");
|
||||
|
@ -784,8 +853,17 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
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,6 +876,15 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
#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)
|
||||
|
|
Loading…
Reference in a new issue