IOQ3 commit 2230 - 2237

This commit is contained in:
Richard Allen 2012-10-04 15:56:18 +00:00
parent 66e8592580
commit dcde1e2712
7 changed files with 63 additions and 77 deletions

View file

@ -405,7 +405,7 @@ else # ifeq Linux
ifeq ($(PLATFORM),darwin) ifeq ($(PLATFORM),darwin)
HAVE_VM_COMPILED=true HAVE_VM_COMPILED=true
LIBS = -framework Cocoa LIBS = -framework Cocoa -framework SDL
CLIENT_LIBS= CLIENT_LIBS=
RENDERER_LIBS= RENDERER_LIBS=
OPTIMIZEVM= OPTIMIZEVM=
@ -462,8 +462,8 @@ ifeq ($(PLATFORM),darwin)
LIBSDLMAIN=$(B)/libSDLmain.a LIBSDLMAIN=$(B)/libSDLmain.a
LIBSDLMAINSRC=$(LIBSDIR)/macosx/libSDLmain.a LIBSDLMAINSRC=$(LIBSDIR)/macosx/libSDLmain.a
CLIENT_LIBS += -framework IOKit \ CLIENT_LIBS += -framework IOKit \
$(LIBSDIR)/macosx/libSDL-1.2.0.dylib -framework SDL
RENDERER_LIBS += -framework OpenGL $(LIBSDIR)/macosx/libSDL-1.2.0.dylib RENDERER_LIBS += -framework OpenGL -framework SDL
OPTIMIZEVM += -falign-loops=16 OPTIMIZEVM += -falign-loops=16
OPTIMIZE = $(OPTIMIZEVM) -ffast-math OPTIMIZE = $(OPTIMIZEVM) -ffast-math

View file

@ -23,26 +23,8 @@
; ;
; assumes __fastcall calling convention ; assumes __fastcall calling convention
DoSyscall PROTO
.code .code
; Call to static void DoSyscall(int syscallNum, int programStack, int *opStackBase, uint8_t opStackOfs, intptr_t arg)
qsyscall64 PROC
sub rsp, 28h ; after this esp will be aligned to 16 byte boundary
mov qword ptr [rsp + 20h], rcx ; 5th parameter "arg" is passed on stack
mov r9b, bl ; opStackOfs
mov r8, rdi ; opStackBase
mov edx, esi ; programStack
mov ecx, eax ; syscallNum
mov rax, DoSyscall ; store call address of DoSyscall in rax
call rax
add rsp, 28h
ret
qsyscall64 ENDP
; Call to compiled code after setting up the register environment for the VM ; Call to compiled code after setting up the register environment for the VM
; prototype: ; prototype:
; uint8_t qvmcall64(int *programStack, int *opStack, intptr_t *instructionPointers, byte *dataBase); ; uint8_t qvmcall64(int *programStack, int *opStack, intptr_t *instructionPointers, byte *dataBase);

View file

@ -390,55 +390,28 @@ static void ErrJump(void)
/* /*
================= =================
DoSyscall DoSyscall
Uses asm to retrieve arguments from registers to work around different calling conventions
Assembler helper routines will write its arguments directly to global variables so as to
work around different calling conventions
================= =================
*/ */
#if defined(_MSC_VER) && idx64 int vm_syscallNum;
int vm_programStack;
int *vm_opStackBase;
uint8_t vm_opStackOfs;
intptr_t vm_arg;
extern void qsyscall64(void);
extern uint8_t qvmcall64(int *programStack, int *opStack, intptr_t *instructionPointers, byte *dataBase);
// Microsoft does not support inline assembler on x64 platforms. Meh.
void DoSyscall(int syscallNum, int programStack, int *opStackBase, uint8_t opStackOfs, intptr_t arg)
{
#else
static void DoSyscall(void) static void DoSyscall(void)
{ {
int syscallNum;
int programStack;
int *opStackBase;
uint8_t opStackOfs;
intptr_t arg;
#endif
vm_t *savedVM; vm_t *savedVM;
#if defined(_MSC_VER)
#if !idx64
__asm
{
mov dword ptr syscallNum, eax
mov dword ptr programStack, esi
mov byte ptr opStackOfs, bl
mov dword ptr opStackBase, edi
mov dword ptr arg, ecx
}
#endif
#else
__asm__ volatile(
""
: "=a" (syscallNum), "=S" (programStack), "=D" (opStackBase), "=b" (opStackOfs),
"=c" (arg)
);
#endif
// save currentVM so as to allow for recursive VM entry // save currentVM so as to allow for recursive VM entry
savedVM = currentVM; savedVM = currentVM;
// modify VM stack pointer for recursive VM entry // modify VM stack pointer for recursive VM entry
currentVM->programStack = programStack - 4; currentVM->programStack = vm_programStack - 4;
if(syscallNum < 0) if(vm_syscallNum < 0)
{ {
int *data; int *data;
#if idx64 #if idx64
@ -446,34 +419,34 @@ static void DoSyscall(void)
intptr_t args[16]; intptr_t args[16];
#endif #endif
data = (int *) (savedVM->dataBase + programStack + 4); data = (int *) (savedVM->dataBase + vm_programStack + 4);
#if idx64 #if idx64
args[0] = ~syscallNum; args[0] = ~vm_syscallNum;
for(index = 1; index < ARRAY_LEN(args); index++) for(index = 1; index < ARRAY_LEN(args); index++)
args[index] = data[index]; args[index] = data[index];
opStackBase[opStackOfs + 1] = savedVM->systemCall(args); vm_opStackBase[vm_opStackOfs + 1] = savedVM->systemCall(args);
#else #else
data[0] = ~syscallNum; data[0] = ~vm_syscallNum;
opStackBase[opStackOfs + 1] = savedVM->systemCall((intptr_t *) data); vm_opStackBase[vm_opStackOfs + 1] = savedVM->systemCall((intptr_t *) data);
#endif #endif
} }
else else
{ {
switch(syscallNum) switch(vm_syscallNum)
{ {
case VM_JMP_VIOLATION: case VM_JMP_VIOLATION:
ErrJump(); ErrJump();
break; break;
case VM_BLOCK_COPY: case VM_BLOCK_COPY:
if(opStackOfs < 1) if(vm_opStackOfs < 1)
Com_Error(ERR_DROP, "VM_BLOCK_COPY failed due to corrupted opStack"); Com_Error(ERR_DROP, "VM_BLOCK_COPY failed due to corrupted opStack");
VM_BlockCopy(opStackBase[(opStackOfs - 1)], opStackBase[opStackOfs], arg); VM_BlockCopy(vm_opStackBase[(vm_opStackOfs - 1)], vm_opStackBase[vm_opStackOfs], vm_arg);
break; break;
default: default:
Com_Error(ERR_DROP, "Unknown VM operation %d", syscallNum); Com_Error(ERR_DROP, "Unknown VM operation %d", vm_syscallNum);
break; break;
} }
} }
@ -504,13 +477,8 @@ Call to DoSyscall()
int EmitCallDoSyscall(vm_t *vm) int EmitCallDoSyscall(vm_t *vm)
{ {
// use edx register to store DoSyscall address // use edx register to store DoSyscall address
#if defined(_MSC_VER) && idx64
EmitRexString(0x48, "BA"); // mov edx, qsyscall64
EmitPtr(qsyscall64);
#else
EmitRexString(0x48, "BA"); // mov edx, DoSyscall EmitRexString(0x48, "BA"); // mov edx, DoSyscall
EmitPtr(DoSyscall); EmitPtr(DoSyscall);
#endif
// Push important registers to stack as we can't really make // Push important registers to stack as we can't really make
// any assumptions about calling conventions. // any assumptions about calling conventions.
@ -522,6 +490,27 @@ int EmitCallDoSyscall(vm_t *vm)
EmitRexString(0x41, "51"); // push r9 EmitRexString(0x41, "51"); // push r9
#endif #endif
// write arguments to global vars
// syscall number
EmitString("A3"); // mov [0x12345678], eax
EmitPtr(&vm_syscallNum);
// vm_programStack value
EmitString("89 F0"); // mov eax, esi
EmitString("A3"); // mov [0x12345678], eax
EmitPtr(&vm_programStack);
// vm_opStackOfs
EmitString("88 D8"); // mov al, bl
EmitString("A2"); // mov [0x12345678], al
EmitPtr(&vm_opStackOfs);
// vm_opStackBase
EmitRexString(0x48, "89 F8"); // mov eax, edi
EmitRexString(0x48, "A3"); // mov [0x12345678], eax
EmitPtr(&vm_opStackBase);
// vm_arg
EmitString("89 C8"); // mov eax, ecx
EmitString("A3"); // mov [0x12345678], eax
EmitPtr(&vm_arg);
// align the stack pointer to a 16-byte-boundary // align the stack pointer to a 16-byte-boundary
EmitString("55"); // push ebp EmitString("55"); // push ebp
EmitRexString(0x48, "89 E5"); // mov ebp, esp EmitRexString(0x48, "89 E5"); // mov ebp, esp
@ -1713,6 +1702,10 @@ This function is called directly by the generated code
============== ==============
*/ */
#if defined(_MSC_VER) && defined(idx64)
extern uint8_t qvmcall64(int *programStack, int *opStack, intptr_t *instructionPointers, byte *dataBase);
#endif
int VM_CallCompiled(vm_t *vm, int *args) int VM_CallCompiled(vm_t *vm, int *args)
{ {
byte stack[OPSTACK_SIZE + 15]; byte stack[OPSTACK_SIZE + 15];

View file

@ -552,7 +552,7 @@ static void SVC_Status( netadr_t from ) {
char infostring[MAX_INFO_STRING]; char infostring[MAX_INFO_STRING];
// ignore if we are in single player // ignore if we are in single player
if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER ) { if ( Cvar_VariableValue( "g_gametype" ) == GT_SINGLE_PLAYER || Cvar_VariableValue("ui_singlePlayerActive")) {
return; return;
} }

View file

@ -140,7 +140,12 @@ Sys_PIDFileName
*/ */
static char *Sys_PIDFileName( void ) static char *Sys_PIDFileName( void )
{ {
return va( "%s/%s", Sys_DefaultHomePath( ), PID_FILENAME ); const char *homePath = Sys_DefaultHomePath( );
if( *homePath != '\0' )
return va( "%s/%s", homePath, PID_FILENAME );
return NULL;
} }
/* /*
@ -156,6 +161,9 @@ qboolean Sys_WritePIDFile( void )
FILE *f; FILE *f;
qboolean stale = qfalse; qboolean stale = qfalse;
if( pidFile == NULL )
return qfalse;
// First, check if the pid file is already there // First, check if the pid file is already there
if( ( f = fopen( pidFile, "r" ) ) != NULL ) if( ( f = fopen( pidFile, "r" ) ) != NULL )
{ {
@ -204,7 +212,10 @@ static __attribute__ ((noreturn)) void Sys_Exit( int exitCode )
if( exitCode < 2 ) if( exitCode < 2 )
{ {
// Normal exit // Normal exit
remove( Sys_PIDFileName( ) ); char *pidFile = Sys_PIDFileName( );
if( pidFile != NULL )
remove( pidFile );
} }
Sys_PlatformExit( ); Sys_PlatformExit( );

View file

@ -53,7 +53,7 @@ char *Sys_DefaultHomePath(void)
{ {
char *p; char *p;
if( !*homePath ) if( !*homePath && com_homepath != NULL )
{ {
if( ( p = getenv( "HOME" ) ) != NULL ) if( ( p = getenv( "HOME" ) ) != NULL )
{ {

View file

@ -90,7 +90,7 @@ char *Sys_DefaultHomePath( void )
FARPROC qSHGetFolderPath; FARPROC qSHGetFolderPath;
HMODULE shfolder = LoadLibrary("shfolder.dll"); HMODULE shfolder = LoadLibrary("shfolder.dll");
if( !*homePath ) if(!*homePath && com_homepath)
{ {
if(shfolder == NULL) if(shfolder == NULL)
{ {