mirror of
https://github.com/UberGames/ioef.git
synced 2025-02-17 17:31:08 +00:00
use native stack for vm stack as well, frees one register
This commit is contained in:
parent
6a5908d444
commit
da2f4341c2
1 changed files with 36 additions and 26 deletions
|
@ -42,15 +42,19 @@ static FILE* qdasmout;
|
||||||
static void VM_Destroy_Compiled(vm_t* self);
|
static void VM_Destroy_Compiled(vm_t* self);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
|=====================|
|
||||||
|
^ dataMask ^- programStack rdi
|
||||||
|
|
|
||||||
|
+- r8
|
||||||
|
|
||||||
eax scratch
|
eax scratch
|
||||||
ebx scratch
|
ebx scratch
|
||||||
ecx scratch (required for shifts)
|
ecx scratch (required for shifts)
|
||||||
edx scratch (required for divisions)
|
edx scratch (required for divisions)
|
||||||
rsi stack pointer
|
rsi stack pointer (opStack)
|
||||||
rdi program frame pointer
|
rdi program frame pointer (programStack)
|
||||||
r8 pointer to begin of real stack memory
|
r8 pointer data (vm->dataBase)
|
||||||
r9 return address to real program
|
|
||||||
r10 start of generated code
|
r10 start of generated code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -265,6 +269,15 @@ static unsigned char op_argsize[256] =
|
||||||
#if 1
|
#if 1
|
||||||
#define RANGECHECK(reg) \
|
#define RANGECHECK(reg) \
|
||||||
emit("andl $0x%x, %%" #reg, vm->dataMask);
|
emit("andl $0x%x, %%" #reg, vm->dataMask);
|
||||||
|
#elif 0
|
||||||
|
#define RANGECHECK(reg) \
|
||||||
|
emit("pushl %%" #reg); \
|
||||||
|
emit("andl $0x%x, %%" #reg, ~vm->dataMask); \
|
||||||
|
emit("jz rangecheck_ok_i_%08x", instruction); \
|
||||||
|
emit("int3"); \
|
||||||
|
emit("rangecheck_ok_i_%08x:", instruction); \
|
||||||
|
emit("popl %%" #reg); \
|
||||||
|
emit("andl $0x%x, %%" #reg, vm->dataMask);
|
||||||
#else
|
#else
|
||||||
#define RANGECHECK(reg)
|
#define RANGECHECK(reg)
|
||||||
#endif
|
#endif
|
||||||
|
@ -411,10 +424,17 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
||||||
|
|
||||||
Com_Printf("compiling %s\n", vm->name);
|
Com_Printf("compiling %s\n", vm->name);
|
||||||
|
|
||||||
|
#ifdef DEBUG_VM
|
||||||
|
snprintf(fn_s, sizeof(fn_s), "%.63s.s", vm->name);
|
||||||
|
snprintf(fn_o, sizeof(fn_o), "%.63s.o", vm->name);
|
||||||
|
fd_s = open(fn_s, O_CREAT|O_WRONLY, 0644);
|
||||||
|
fd_o = open(fn_o, O_CREAT|O_WRONLY, 0644);
|
||||||
|
#else
|
||||||
snprintf(fn_s, sizeof(fn_s), "/tmp/%.63s.s_XXXXXX", vm->name);
|
snprintf(fn_s, sizeof(fn_s), "/tmp/%.63s.s_XXXXXX", vm->name);
|
||||||
snprintf(fn_o, sizeof(fn_o), "/tmp/%.63s.o_XXXXXX", vm->name);
|
snprintf(fn_o, sizeof(fn_o), "/tmp/%.63s.o_XXXXXX", vm->name);
|
||||||
fd_s = mkstemp(fn_s);
|
fd_s = mkstemp(fn_s);
|
||||||
fd_o = mkstemp(fn_o);
|
fd_o = mkstemp(fn_o);
|
||||||
|
#endif
|
||||||
if(fd_s == -1 || fd_o == -1)
|
if(fd_s == -1 || fd_o == -1)
|
||||||
{
|
{
|
||||||
if(fd_s != -1) close(fd_s);
|
if(fd_s != -1) close(fd_s);
|
||||||
|
@ -450,8 +470,6 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
||||||
emit("or %%r8, %%r8"); // check whether to set up instruction pointers
|
emit("or %%r8, %%r8"); // check whether to set up instruction pointers
|
||||||
emit("jnz main");
|
emit("jnz main");
|
||||||
emit("jmp setupinstructionpointers");
|
emit("jmp setupinstructionpointers");
|
||||||
emit("exit:");
|
|
||||||
emit("jmp *%%r9");
|
|
||||||
|
|
||||||
emit("main:");
|
emit("main:");
|
||||||
|
|
||||||
|
@ -501,16 +519,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
||||||
break;
|
break;
|
||||||
case OP_LEAVE:
|
case OP_LEAVE:
|
||||||
emit("addl $%d, %%edi", iarg); // get rid of stack frame
|
emit("addl $%d, %%edi", iarg); // get rid of stack frame
|
||||||
RANGECHECK(edi);
|
emit("ret");
|
||||||
emit("movl 0(%%r8, %%rdi, 1), %%eax"); // get return address
|
|
||||||
emit("movq $%lu, %%rbx", (unsigned long)vm->instructionPointers);
|
|
||||||
emit("cmp $-1, %%eax");
|
|
||||||
emit("je jumptoexit%d", instruction);
|
|
||||||
emit("movl (%%rbx, %%rax, 4), %%eax"); // load new relative jump address
|
|
||||||
emit("addq %%r10, %%rax");
|
|
||||||
emit("jmp *%%rax");
|
|
||||||
emit("jumptoexit%d:", instruction);
|
|
||||||
emit("jmp exit");
|
|
||||||
break;
|
break;
|
||||||
case OP_CALL:
|
case OP_CALL:
|
||||||
emit("movl 0(%%rsi), %%eax"); // get instr from stack
|
emit("movl 0(%%rsi), %%eax"); // get instr from stack
|
||||||
|
@ -521,7 +530,8 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
||||||
emit("movq $%lu, %%rbx", (unsigned long)vm->instructionPointers);
|
emit("movq $%lu, %%rbx", (unsigned long)vm->instructionPointers);
|
||||||
emit("movl (%%rbx, %%rax, 4), %%eax"); // load new relative jump address
|
emit("movl (%%rbx, %%rax, 4), %%eax"); // load new relative jump address
|
||||||
emit("addq %%r10, %%rax");
|
emit("addq %%r10, %%rax");
|
||||||
emit("jmp *%%rax");
|
emit("callq *%%rax");
|
||||||
|
emit("jmp i_%08x", instruction+1);
|
||||||
emit("callSyscall%d:", instruction);
|
emit("callSyscall%d:", instruction);
|
||||||
// emit("fnsave 4(%%rsi)");
|
// emit("fnsave 4(%%rsi)");
|
||||||
emit("push %%rsi");
|
emit("push %%rsi");
|
||||||
|
@ -846,7 +856,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
||||||
{
|
{
|
||||||
emit("movl $i_%08x-start, %d(%%rax)", instruction, instruction*4);
|
emit("movl $i_%08x-start, %d(%%rax)", instruction, instruction*4);
|
||||||
}
|
}
|
||||||
emit("jmp exit");
|
emit("ret");
|
||||||
|
|
||||||
emit("debugger:");
|
emit("debugger:");
|
||||||
if(1);
|
if(1);
|
||||||
|
@ -882,28 +892,30 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
||||||
// call code with r8 set to zero to set up instruction pointers
|
// call code with r8 set to zero to set up instruction pointers
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
" xorq %%r8,%%r8 \r\n" \
|
" xorq %%r8,%%r8 \r\n" \
|
||||||
" movq $doneinit,%%r9 \r\n" \
|
|
||||||
" movq %0,%%r10 \r\n" \
|
" movq %0,%%r10 \r\n" \
|
||||||
" jmp *%%r10 \r\n" \
|
" callq *%%r10 \r\n" \
|
||||||
"doneinit: \r\n" \
|
|
||||||
:
|
:
|
||||||
: "m" (entryPoint)
|
: "m" (entryPoint)
|
||||||
: "%r8", "%r9", "%r10", "%rax"
|
: "%r8", "%r10", "%rax"
|
||||||
);
|
);
|
||||||
|
|
||||||
#ifdef DEBUG_VM
|
#ifdef DEBUG_VM
|
||||||
fflush(qdasmout);
|
fflush(qdasmout);
|
||||||
|
fclose(qdasmout);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Com_Printf( "VM file %s compiled to %i bytes of code (%p - %p)\n", vm->name, vm->codeLength, vm->codeBase, vm->codeBase+vm->codeLength );
|
Com_Printf( "VM file %s compiled to %i bytes of code (%p - %p)\n", vm->name, vm->codeLength, vm->codeBase, vm->codeBase+vm->codeLength );
|
||||||
|
|
||||||
out:
|
out:
|
||||||
close(fd_o);
|
close(fd_o);
|
||||||
|
|
||||||
|
#ifndef DEBUG_VM
|
||||||
if(!com_developer->integer)
|
if(!com_developer->integer)
|
||||||
{
|
{
|
||||||
unlink(fn_o);
|
unlink(fn_o);
|
||||||
unlink(fn_s);
|
unlink(fn_s);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -977,16 +989,14 @@ int VM_CallCompiled( vm_t *vm, int *args ) {
|
||||||
__asm__ __volatile__ (
|
__asm__ __volatile__ (
|
||||||
" movq %5,%%rsi \r\n" \
|
" movq %5,%%rsi \r\n" \
|
||||||
" movl %4,%%edi \r\n" \
|
" movl %4,%%edi \r\n" \
|
||||||
" movq $done,%%r9 \r\n" \
|
|
||||||
" movq %2,%%r10 \r\n" \
|
" movq %2,%%r10 \r\n" \
|
||||||
" movq %3,%%r8 \r\n" \
|
" movq %3,%%r8 \r\n" \
|
||||||
" jmp *%%r10 \r\n" \
|
" callq *%%r10 \r\n" \
|
||||||
"done: \r\n" \
|
|
||||||
" movl %%edi, %0 \r\n" \
|
" movl %%edi, %0 \r\n" \
|
||||||
" movq %%rsi, %1 \r\n" \
|
" movq %%rsi, %1 \r\n" \
|
||||||
: "=m" (programStack), "=m" (opStack)
|
: "=m" (programStack), "=m" (opStack)
|
||||||
: "m" (entryPoint), "m" (vm->dataBase), "m" (programStack), "m" (opStack)
|
: "m" (entryPoint), "m" (vm->dataBase), "m" (programStack), "m" (opStack)
|
||||||
: "%rsi", "%rdi", "%rax", "%rbx", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r15", "%xmm0"
|
: "%rsi", "%rdi", "%rax", "%rbx", "%rcx", "%rdx", "%r8", "%r10", "%r15", "%xmm0"
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( opStack != &stack[1] ) {
|
if ( opStack != &stack[1] ) {
|
||||||
|
|
Loading…
Reference in a new issue