mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2024-11-10 23:02:01 +00:00
use memcpy for OP_BLOCK_COPY
This commit is contained in:
parent
b6228f1408
commit
58512aff09
1 changed files with 56 additions and 65 deletions
|
@ -59,8 +59,14 @@ long printsyscall(long* args)
|
||||||
args[4]);
|
args[4]);
|
||||||
|
|
||||||
switch( args[0] ) {
|
switch( args[0] ) {
|
||||||
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
fputs((VMA(1)?VMA(1):"(NULL)\n"), stderr);
|
{
|
||||||
|
char * s = VMA(1)?VMA(1):"(NULL)\n";
|
||||||
|
fputs(s, stderr);
|
||||||
|
if(s[strlen(s)-1] != '\n')
|
||||||
|
putc('\n', stderr);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
case 999:
|
case 999:
|
||||||
{
|
{
|
||||||
|
@ -166,7 +172,7 @@ static long callAsmCall(long callProgramStack, long callSyscallNum)
|
||||||
vm_t *savedVM;
|
vm_t *savedVM;
|
||||||
long ret = 0x77;
|
long ret = 0x77;
|
||||||
long args[11];
|
long args[11];
|
||||||
int iargs[11];
|
// int iargs[11];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// Dfprintf(stderr, "callAsmCall(%ld, %ld)\n", callProgramStack, callSyscallNum);
|
// Dfprintf(stderr, "callAsmCall(%ld, %ld)\n", callProgramStack, callSyscallNum);
|
||||||
|
@ -178,10 +184,10 @@ static long callAsmCall(long callProgramStack, long callSyscallNum)
|
||||||
currentVM->programStack = callProgramStack - 4;
|
currentVM->programStack = callProgramStack - 4;
|
||||||
|
|
||||||
args[0] = callSyscallNum;
|
args[0] = callSyscallNum;
|
||||||
iargs[0] = callSyscallNum;
|
// iargs[0] = callSyscallNum;
|
||||||
for(i = 0; i < 10; ++i)
|
for(i = 0; i < 10; ++i)
|
||||||
{
|
{
|
||||||
iargs[i+1] = *(int *)((byte *)currentVM->dataBase + callProgramStack + 8 + 4*i);
|
// iargs[i+1] = *(int *)((byte *)currentVM->dataBase + callProgramStack + 8 + 4*i);
|
||||||
args[i+1] = *(int *)((byte *)currentVM->dataBase + callProgramStack + 8 + 4*i);
|
args[i+1] = *(int *)((byte *)currentVM->dataBase + callProgramStack + 8 + 4*i);
|
||||||
}
|
}
|
||||||
ret = currentVM->systemCall(args);
|
ret = currentVM->systemCall(args);
|
||||||
|
@ -433,7 +439,7 @@ static int doas(const char* in, const char* out, unsigned char** compiledcode)
|
||||||
buf = FS_BuildOSPath(homedir->string, NULL, out);
|
buf = FS_BuildOSPath(homedir->string, NULL, out);
|
||||||
strcpy(rout, buf);
|
strcpy(rout, buf);
|
||||||
|
|
||||||
Com_Printf("running assembler\n");
|
Com_Printf("running assembler < %s > %s\n", rin, rout);
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if(pid == -1)
|
if(pid == -1)
|
||||||
Com_Error(ERR_FATAL, "can't fork\n");
|
Com_Error(ERR_FATAL, "can't fork\n");
|
||||||
|
@ -496,6 +502,24 @@ static int doas(const char* in, const char* out, unsigned char** compiledcode)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void block_copy_vm(unsigned dest, unsigned src, unsigned count)
|
||||||
|
{
|
||||||
|
unsigned dataMask = currentVM->dataMask;
|
||||||
|
|
||||||
|
if ((dest & dataMask) != dest
|
||||||
|
|| (src & dataMask) != src
|
||||||
|
|| ((dest+count) & dataMask) != dest + count
|
||||||
|
|| ((src+count) & dataMask) != src + count)
|
||||||
|
{
|
||||||
|
Com_Error(ERR_DROP, "OP_BLOCK_COPY out of range!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Com_Printf("OP_BLOCK_COPY %s %x %x %d\n", currentVM->name, dest, src, count);
|
||||||
|
// __asm__ __volatile__ ("int3");
|
||||||
|
|
||||||
|
memcpy(currentVM->dataBase+dest, currentVM->dataBase+src, count);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
VM_Compile
|
VM_Compile
|
||||||
|
@ -510,8 +534,8 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
||||||
unsigned char barg = 0;
|
unsigned char barg = 0;
|
||||||
void* entryPoint;
|
void* entryPoint;
|
||||||
|
|
||||||
char fn_s[MAX_QPATH]; // output file for assembler code
|
char fn_s[2*MAX_QPATH]; // output file for assembler code
|
||||||
char fn_o[MAX_QPATH]; // file written by as
|
char fn_o[2*MAX_QPATH]; // file written by as
|
||||||
#ifdef DEBUG_VM
|
#ifdef DEBUG_VM
|
||||||
char fn_d[MAX_QPATH]; // disassembled
|
char fn_d[MAX_QPATH]; // disassembled
|
||||||
#endif
|
#endif
|
||||||
|
@ -627,7 +651,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
||||||
emit("decl %%eax");
|
emit("decl %%eax");
|
||||||
// first argument already in rdi
|
// first argument already in rdi
|
||||||
emit("movq %%rax, %%rsi"); // second argument in rsi
|
emit("movq %%rax, %%rsi"); // second argument in rsi
|
||||||
emit("movq $%ld, %%rax", (unsigned long)callAsmCall);
|
emit("movq $%lu, %%rax", (unsigned long)callAsmCall);
|
||||||
emit("callq *%%rax");
|
emit("callq *%%rax");
|
||||||
emit("pop %%r10");
|
emit("pop %%r10");
|
||||||
emit("pop %%r9");
|
emit("pop %%r9");
|
||||||
|
@ -774,52 +798,23 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
||||||
emit("movl %%eax, 0(%%r8,%%rbx, 1)"); // store in args space
|
emit("movl %%eax, 0(%%r8,%%rbx, 1)"); // store in args space
|
||||||
break;
|
break;
|
||||||
case OP_BLOCK_COPY:
|
case OP_BLOCK_COPY:
|
||||||
if(iarg % 4) Com_Error(ERR_DROP,
|
|
||||||
"argument to OP_BLOCK_COPY not multiple of 4\n");
|
|
||||||
|
|
||||||
emit("subq $8, %%rsi");
|
emit("subq $8, %%rsi");
|
||||||
emit("movl 8(%%rsi), %%ebx"); // get pointer from stack
|
emit("push %%rsi");
|
||||||
|
emit("push %%rdi");
|
||||||
emit("movl %%ebx, %%ecx");
|
emit("push %%r8");
|
||||||
RANGECHECK(ecx);
|
emit("push %%r9");
|
||||||
emit("cmp %%ebx, %%ecx");
|
emit("push %%r10");
|
||||||
emit("jne broken%d", instruction);
|
emit("movl 4(%%rsi), %%edi"); // 1st argument dest
|
||||||
|
emit("movl 8(%%rsi), %%esi"); // 2nd argument src
|
||||||
emit("movl %%ecx, %%edx");
|
emit("movl $%d, %%edx", iarg); // 3rd argument count
|
||||||
emit("addl $%d, %%edx", iarg);
|
emit("movq $%lu, %%rax", (unsigned long)block_copy_vm);
|
||||||
emit("addl $%d, %%ecx", iarg);
|
emit("callq *%%rax");
|
||||||
RANGECHECK(edx);
|
emit("pop %%r10");
|
||||||
emit("cmp %%ecx, %%edx");
|
emit("pop %%r9");
|
||||||
emit("jne broken%d", instruction);
|
emit("pop %%r8");
|
||||||
|
emit("pop %%rdi");
|
||||||
emit("movl 4(%%rsi), %%eax"); // get pointer from stack
|
emit("pop %%rsi");
|
||||||
|
|
||||||
emit("movl %%eax, %%ecx");
|
|
||||||
RANGECHECK(ecx);
|
|
||||||
emit("cmp %%eax, %%ecx");
|
|
||||||
emit("jne broken%d", instruction);
|
|
||||||
|
|
||||||
emit("movl %%ecx, %%edx");
|
|
||||||
emit("addl $%d, %%edx", iarg);
|
|
||||||
emit("addl $%d, %%ecx", iarg);
|
|
||||||
RANGECHECK(edx);
|
|
||||||
emit("cmp %%ecx, %%edx");
|
|
||||||
emit("jne broken%d", instruction);
|
|
||||||
|
|
||||||
emit("addq %%r8, %%rax"); // calc real address
|
|
||||||
emit("addq %%r8, %%rbx"); // calc real address
|
|
||||||
emit("movl $%d, %%ecx", iarg);
|
|
||||||
emit("shrl $2, %%ecx");
|
|
||||||
emit("block_copy_loop_%d:", instruction);
|
|
||||||
emit("decl %%ecx");
|
|
||||||
emit("movl 0(%%rbx, %%rcx, 4), %%edx");
|
|
||||||
emit("movl %%edx, 0(%%rax, %%rcx, 4)");
|
|
||||||
emit("orl %%ecx, %%ecx");
|
|
||||||
emit("jnz block_copy_loop_%d", instruction);
|
|
||||||
emit("jmp i_%08x", instruction+1);
|
|
||||||
|
|
||||||
emit("broken%d:", instruction);
|
|
||||||
emit("int3");
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case OP_SEX8:
|
case OP_SEX8:
|
||||||
|
@ -1010,6 +1005,14 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Com_Printf( "VM file %s compiled to %i bytes of code (0x%lx - 0x%lx)\n", vm->name, vm->codeLength, vm->codeBase, vm->codeBase+vm->codeLength );
|
Com_Printf( "VM file %s compiled to %i bytes of code (0x%lx - 0x%lx)\n", vm->name, vm->codeLength, vm->codeBase, vm->codeBase+vm->codeLength );
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if(!com_developer->integer)
|
||||||
|
{
|
||||||
|
unlink(fn_o);
|
||||||
|
unlink(fn_s);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1112,7 +1115,7 @@ int testops(vm_t* vm)
|
||||||
int i1, i2, vmres;
|
int i1, i2, vmres;
|
||||||
int i;
|
int i;
|
||||||
float f1, f2, fres, fvmres;
|
float f1, f2, fres, fvmres;
|
||||||
int numitests = 26;
|
int numitests = 32;
|
||||||
int numftests = 11;
|
int numftests = 11;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int testno;
|
int testno;
|
||||||
|
@ -1209,14 +1212,10 @@ void VM_VmInfo_f( void );
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
size_t size;
|
|
||||||
vmHeader_t *header;
|
|
||||||
vm_t* vm[3];
|
vm_t* vm[3];
|
||||||
unsigned dataLength;
|
|
||||||
int i;
|
int i;
|
||||||
long args[11] = {0};
|
long args[11] = {0};
|
||||||
int ret = 0xDEADBEEF;
|
int ret = 0xDEADBEEF;
|
||||||
char* mem;
|
|
||||||
|
|
||||||
char* file = argv[1];
|
char* file = argv[1];
|
||||||
|
|
||||||
|
@ -1229,8 +1228,6 @@ int main(int argc, char* argv[])
|
||||||
*strchr(module, '.') = '\0';
|
*strchr(module, '.') = '\0';
|
||||||
|
|
||||||
vm[0] = VM_Create( module, printsyscall, interpret );
|
vm[0] = VM_Create( module, printsyscall, interpret );
|
||||||
vm[1] = VM_Create( module, printsyscall, interpret );
|
|
||||||
vm[2] = VM_Create( module, printsyscall, interpret );
|
|
||||||
|
|
||||||
VM_VmInfo_f();
|
VM_VmInfo_f();
|
||||||
|
|
||||||
|
@ -1242,16 +1239,10 @@ int main(int argc, char* argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = VM_Call(vm[0], args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
|
ret = VM_Call(vm[0], args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
|
||||||
ret += VM_Call(vm[1], args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
|
|
||||||
ret += VM_Call(vm[2], args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ret = testops(vm[0]);
|
ret = testops(vm[0]);
|
||||||
ret += testops(vm[1]);
|
|
||||||
ret += testops(vm[2]);
|
|
||||||
ret += testops(vm[1]);
|
|
||||||
ret += testops(vm[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue