mirror of
https://github.com/ReactionQuake3/reaction.git
synced 2025-01-23 01:50:41 +00:00
IOQ3 commit 2230 - 2237
This commit is contained in:
parent
66e8592580
commit
dcde1e2712
7 changed files with 63 additions and 77 deletions
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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( );
|
||||||
|
|
|
@ -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 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue