mirror of
https://github.com/UberGames/ioef.git
synced 2024-11-24 05:01:40 +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);
|
||||
|
||||
/*
|
||||
|
||||
|=====================|
|
||||
^ dataMask ^- programStack rdi
|
||||
|
|
||||
+- r8
|
||||
|
||||
eax scratch
|
||||
ebx scratch
|
||||
ecx scratch (required for shifts)
|
||||
edx scratch (required for divisions)
|
||||
rsi stack pointer
|
||||
rdi program frame pointer
|
||||
r8 pointer to begin of real stack memory
|
||||
r9 return address to real program
|
||||
rsi stack pointer (opStack)
|
||||
rdi program frame pointer (programStack)
|
||||
r8 pointer data (vm->dataBase)
|
||||
r10 start of generated code
|
||||
*/
|
||||
|
||||
|
@ -265,6 +269,15 @@ static unsigned char op_argsize[256] =
|
|||
#if 1
|
||||
#define RANGECHECK(reg) \
|
||||
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
|
||||
#define RANGECHECK(reg)
|
||||
#endif
|
||||
|
@ -411,10 +424,17 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
|
||||
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_o, sizeof(fn_o), "/tmp/%.63s.o_XXXXXX", vm->name);
|
||||
fd_s = mkstemp(fn_s);
|
||||
fd_o = mkstemp(fn_o);
|
||||
#endif
|
||||
if(fd_s == -1 || fd_o == -1)
|
||||
{
|
||||
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("jnz main");
|
||||
emit("jmp setupinstructionpointers");
|
||||
emit("exit:");
|
||||
emit("jmp *%%r9");
|
||||
|
||||
emit("main:");
|
||||
|
||||
|
@ -501,16 +519,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
|||
break;
|
||||
case OP_LEAVE:
|
||||
emit("addl $%d, %%edi", iarg); // get rid of stack frame
|
||||
RANGECHECK(edi);
|
||||
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");
|
||||
emit("ret");
|
||||
break;
|
||||
case OP_CALL:
|
||||
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("movl (%%rbx, %%rax, 4), %%eax"); // load new relative jump address
|
||||
emit("addq %%r10, %%rax");
|
||||
emit("jmp *%%rax");
|
||||
emit("callq *%%rax");
|
||||
emit("jmp i_%08x", instruction+1);
|
||||
emit("callSyscall%d:", instruction);
|
||||
// emit("fnsave 4(%%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("jmp exit");
|
||||
emit("ret");
|
||||
|
||||
emit("debugger:");
|
||||
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
|
||||
__asm__ __volatile__ (
|
||||
" xorq %%r8,%%r8 \r\n" \
|
||||
" movq $doneinit,%%r9 \r\n" \
|
||||
" movq %0,%%r10 \r\n" \
|
||||
" jmp *%%r10 \r\n" \
|
||||
"doneinit: \r\n" \
|
||||
" callq *%%r10 \r\n" \
|
||||
:
|
||||
: "m" (entryPoint)
|
||||
: "%r8", "%r9", "%r10", "%rax"
|
||||
: "%r8", "%r10", "%rax"
|
||||
);
|
||||
|
||||
#ifdef DEBUG_VM
|
||||
fflush(qdasmout);
|
||||
fclose(qdasmout);
|
||||
#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 );
|
||||
|
||||
out:
|
||||
close(fd_o);
|
||||
|
||||
#ifndef DEBUG_VM
|
||||
if(!com_developer->integer)
|
||||
{
|
||||
unlink(fn_o);
|
||||
unlink(fn_s);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -977,16 +989,14 @@ int VM_CallCompiled( vm_t *vm, int *args ) {
|
|||
__asm__ __volatile__ (
|
||||
" movq %5,%%rsi \r\n" \
|
||||
" movl %4,%%edi \r\n" \
|
||||
" movq $done,%%r9 \r\n" \
|
||||
" movq %2,%%r10 \r\n" \
|
||||
" movq %3,%%r8 \r\n" \
|
||||
" jmp *%%r10 \r\n" \
|
||||
"done: \r\n" \
|
||||
" callq *%%r10 \r\n" \
|
||||
" movl %%edi, %0 \r\n" \
|
||||
" movq %%rsi, %1 \r\n" \
|
||||
: "=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] ) {
|
||||
|
|
Loading…
Reference in a new issue