mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2024-11-11 07:11:36 +00:00
- Use edx for CALLs instead of ecx, as the latter does not require any push to stack
- Make Linux AT&T asm code consistent with the MASM codeblock
This commit is contained in:
parent
c7a68bf283
commit
3f9ec83ce0
1 changed files with 19 additions and 24 deletions
|
@ -329,7 +329,7 @@ qboolean EmitMovEBXEDI(vm_t *vm, int andit) {
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
DoSyscall
|
DoSyscall
|
||||||
Uses asm to get arguments from stack to work around different calling conventions
|
Uses asm to retrieve arguments from registers to work around different calling conventions
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -342,7 +342,6 @@ static void DoSyscall(void)
|
||||||
int programStack;
|
int programStack;
|
||||||
int *opStack;
|
int *opStack;
|
||||||
|
|
||||||
// Get arguments directly from registers to work around different calling conventions
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
__asm
|
__asm
|
||||||
{
|
{
|
||||||
|
@ -417,8 +416,8 @@ int EmitCallProcedure(vm_t *vm)
|
||||||
retval = compiledOfs;
|
retval = compiledOfs;
|
||||||
|
|
||||||
EmitString("F7 D0"); // not eax
|
EmitString("F7 D0"); // not eax
|
||||||
// use ecx register to store DoSyscall address
|
// use edx register to store DoSyscall address
|
||||||
EmitString("B9"); // mov ecx, DoSyscall
|
EmitString("BA"); // mov edx, DoSyscall
|
||||||
Emit4((intptr_t) DoSyscall);
|
Emit4((intptr_t) DoSyscall);
|
||||||
|
|
||||||
// align the stack pointer to a 16-byte-boundary
|
// align the stack pointer to a 16-byte-boundary
|
||||||
|
@ -427,7 +426,7 @@ int EmitCallProcedure(vm_t *vm)
|
||||||
EmitString("83 E4 F0"); // and esp, 0xFFFFFFF0
|
EmitString("83 E4 F0"); // and esp, 0xFFFFFFF0
|
||||||
|
|
||||||
// call the syscall wrapper function
|
// call the syscall wrapper function
|
||||||
EmitString("FF D1"); // call ecx
|
EmitString("FF D2"); // call edx
|
||||||
|
|
||||||
// reset the stack pointer to its previous value
|
// reset the stack pointer to its previous value
|
||||||
EmitString("89 EC"); // mov esp, ebp
|
EmitString("89 EC"); // mov esp, ebp
|
||||||
|
@ -442,26 +441,24 @@ int EmitCallProcedure(vm_t *vm)
|
||||||
|
|
||||||
void EmitCall(vm_t *vm, int sysCallOfs)
|
void EmitCall(vm_t *vm, int sysCallOfs)
|
||||||
{
|
{
|
||||||
EmitString("51"); // push ecx
|
EmitString("8B 15"); // mov edx, [dword ptr vm->codeBase]
|
||||||
EmitString("8B 0D"); // mov ecx, dword ptr [&vm->codeBase]
|
|
||||||
Emit4((intptr_t) &vm->codeBase);
|
Emit4((intptr_t) &vm->codeBase);
|
||||||
|
|
||||||
if(sysCallOfs)
|
if(sysCallOfs)
|
||||||
{
|
{
|
||||||
if(sysCallOfs < 0x80 || sysCallOfs > 0x7f)
|
if(sysCallOfs < 0x80 || sysCallOfs > 0x7f)
|
||||||
{
|
{
|
||||||
EmitString("83 C1"); // add ecx, sysCallOfs
|
EmitString("83 C2"); // add edx, sysCallOfs
|
||||||
Emit1(sysCallOfs);
|
Emit1(sysCallOfs);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EmitString("81 C1"); // add ecx, sysCallOfs
|
EmitString("81 C2"); // add edx, sysCallOfs
|
||||||
Emit4(sysCallOfs);
|
Emit4(sysCallOfs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitString("FF D1"); // call ecx
|
EmitString("FF D2"); // call edx
|
||||||
EmitString("59"); // pop ecx
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1258,7 +1255,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
||||||
break;
|
break;
|
||||||
case OP_DIVI:
|
case OP_DIVI:
|
||||||
EmitString( "8B 47 FC" ); // mov eax,dword ptr [edi-4]
|
EmitString( "8B 47 FC" ); // mov eax,dword ptr [edi-4]
|
||||||
EmitString( "99" ); // cdq
|
EmitString( "99" ); // cdq
|
||||||
EmitString( "F7 3F" ); // idiv dword ptr [edi]
|
EmitString( "F7 3F" ); // idiv dword ptr [edi]
|
||||||
EmitString( "89 47 FC" ); // mov dword ptr [edi-4],eax
|
EmitString( "89 47 FC" ); // mov dword ptr [edi-4],eax
|
||||||
EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
|
EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
|
||||||
|
@ -1272,7 +1269,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
||||||
break;
|
break;
|
||||||
case OP_MODI:
|
case OP_MODI:
|
||||||
EmitString( "8B 47 FC" ); // mov eax,dword ptr [edi-4]
|
EmitString( "8B 47 FC" ); // mov eax,dword ptr [edi-4]
|
||||||
EmitString( "99" ); // cdq
|
EmitString( "99" ); // cdq
|
||||||
EmitString( "F7 3F" ); // idiv dword ptr [edi]
|
EmitString( "F7 3F" ); // idiv dword ptr [edi]
|
||||||
EmitString( "89 57 FC" ); // mov dword ptr [edi-4],edx
|
EmitString( "89 57 FC" ); // mov dword ptr [edi-4],edx
|
||||||
EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
|
EmitCommand(LAST_COMMAND_SUB_DI_4); // sub edi, 4
|
||||||
|
@ -1546,18 +1543,16 @@ int VM_CallCompiled( vm_t *vm, int *args ) {
|
||||||
popad
|
popad
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* These registers are used as scratch registers and are destroyed after the
|
|
||||||
* call. Do not use clobber, so they can be used as input for the asm. */
|
|
||||||
unsigned eax;
|
|
||||||
unsigned ebx;
|
|
||||||
unsigned ecx;
|
|
||||||
unsigned edx;
|
|
||||||
|
|
||||||
__asm__ volatile(
|
__asm__ volatile(
|
||||||
"call *%6"
|
"pushal\r\n"
|
||||||
: "+S" (programStack), "+D" (opStack),
|
"movl %0, %%esi\r\n"
|
||||||
"=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
|
"movl %1, %%edi\r\n"
|
||||||
: "mr" (vm->codeBase + vm->entryOfs)
|
"call *%2\r\n"
|
||||||
|
"movl %%edi, %1\r\n"
|
||||||
|
"movl %%esi, %0\r\n"
|
||||||
|
"popal\r\n"
|
||||||
|
: "+g" (programStack), "+g" (opStack)
|
||||||
|
: "g" (vm->codeBase + vm->entryOfs)
|
||||||
: "cc", "memory"
|
: "cc", "memory"
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue