- 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:
Thilo Schulz 2011-05-17 12:07:56 +00:00
parent c7a68bf283
commit 3f9ec83ce0

View file

@ -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
} }
/* /*
@ -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