mirror of
https://github.com/ReactionQuake3/reaction.git
synced 2024-11-10 07:11:36 +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)
|
||||
HAVE_VM_COMPILED=true
|
||||
LIBS = -framework Cocoa
|
||||
LIBS = -framework Cocoa -framework SDL
|
||||
CLIENT_LIBS=
|
||||
RENDERER_LIBS=
|
||||
OPTIMIZEVM=
|
||||
|
@ -462,8 +462,8 @@ ifeq ($(PLATFORM),darwin)
|
|||
LIBSDLMAIN=$(B)/libSDLmain.a
|
||||
LIBSDLMAINSRC=$(LIBSDIR)/macosx/libSDLmain.a
|
||||
CLIENT_LIBS += -framework IOKit \
|
||||
$(LIBSDIR)/macosx/libSDL-1.2.0.dylib
|
||||
RENDERER_LIBS += -framework OpenGL $(LIBSDIR)/macosx/libSDL-1.2.0.dylib
|
||||
-framework SDL
|
||||
RENDERER_LIBS += -framework OpenGL -framework SDL
|
||||
|
||||
OPTIMIZEVM += -falign-loops=16
|
||||
OPTIMIZE = $(OPTIMIZEVM) -ffast-math
|
||||
|
|
|
@ -23,26 +23,8 @@
|
|||
;
|
||||
; assumes __fastcall calling convention
|
||||
|
||||
DoSyscall PROTO
|
||||
|
||||
.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
|
||||
; prototype:
|
||||
; uint8_t qvmcall64(int *programStack, int *opStack, intptr_t *instructionPointers, byte *dataBase);
|
||||
|
|
|
@ -390,55 +390,28 @@ static void ErrJump(void)
|
|||
/*
|
||||
=================
|
||||
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)
|
||||
{
|
||||
int syscallNum;
|
||||
int programStack;
|
||||
int *opStackBase;
|
||||
uint8_t opStackOfs;
|
||||
intptr_t arg;
|
||||
#endif
|
||||
|
||||
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
|
||||
savedVM = currentVM;
|
||||
// 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;
|
||||
#if idx64
|
||||
|
@ -446,34 +419,34 @@ static void DoSyscall(void)
|
|||
intptr_t args[16];
|
||||
#endif
|
||||
|
||||
data = (int *) (savedVM->dataBase + programStack + 4);
|
||||
data = (int *) (savedVM->dataBase + vm_programStack + 4);
|
||||
|
||||
#if idx64
|
||||
args[0] = ~syscallNum;
|
||||
args[0] = ~vm_syscallNum;
|
||||
for(index = 1; index < ARRAY_LEN(args); index++)
|
||||
args[index] = data[index];
|
||||
|
||||
opStackBase[opStackOfs + 1] = savedVM->systemCall(args);
|
||||
vm_opStackBase[vm_opStackOfs + 1] = savedVM->systemCall(args);
|
||||
#else
|
||||
data[0] = ~syscallNum;
|
||||
opStackBase[opStackOfs + 1] = savedVM->systemCall((intptr_t *) data);
|
||||
data[0] = ~vm_syscallNum;
|
||||
vm_opStackBase[vm_opStackOfs + 1] = savedVM->systemCall((intptr_t *) data);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(syscallNum)
|
||||
switch(vm_syscallNum)
|
||||
{
|
||||
case VM_JMP_VIOLATION:
|
||||
ErrJump();
|
||||
break;
|
||||
case VM_BLOCK_COPY:
|
||||
if(opStackOfs < 1)
|
||||
if(vm_opStackOfs < 1)
|
||||
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;
|
||||
default:
|
||||
Com_Error(ERR_DROP, "Unknown VM operation %d", syscallNum);
|
||||
Com_Error(ERR_DROP, "Unknown VM operation %d", vm_syscallNum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -504,13 +477,8 @@ Call to DoSyscall()
|
|||
int EmitCallDoSyscall(vm_t *vm)
|
||||
{
|
||||
// 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
|
||||
EmitPtr(DoSyscall);
|
||||
#endif
|
||||
|
||||
// Push important registers to stack as we can't really make
|
||||
// any assumptions about calling conventions.
|
||||
|
@ -522,6 +490,27 @@ int EmitCallDoSyscall(vm_t *vm)
|
|||
EmitRexString(0x41, "51"); // push r9
|
||||
#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
|
||||
EmitString("55"); // push ebp
|
||||
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)
|
||||
{
|
||||
byte stack[OPSTACK_SIZE + 15];
|
||||
|
|
|
@ -552,7 +552,7 @@ static void SVC_Status( netadr_t from ) {
|
|||
char infostring[MAX_INFO_STRING];
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -140,7 +140,12 @@ Sys_PIDFileName
|
|||
*/
|
||||
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;
|
||||
qboolean stale = qfalse;
|
||||
|
||||
if( pidFile == NULL )
|
||||
return qfalse;
|
||||
|
||||
// First, check if the pid file is already there
|
||||
if( ( f = fopen( pidFile, "r" ) ) != NULL )
|
||||
{
|
||||
|
@ -204,7 +212,10 @@ static __attribute__ ((noreturn)) void Sys_Exit( int exitCode )
|
|||
if( exitCode < 2 )
|
||||
{
|
||||
// Normal exit
|
||||
remove( Sys_PIDFileName( ) );
|
||||
char *pidFile = Sys_PIDFileName( );
|
||||
|
||||
if( pidFile != NULL )
|
||||
remove( pidFile );
|
||||
}
|
||||
|
||||
Sys_PlatformExit( );
|
||||
|
|
|
@ -53,7 +53,7 @@ char *Sys_DefaultHomePath(void)
|
|||
{
|
||||
char *p;
|
||||
|
||||
if( !*homePath )
|
||||
if( !*homePath && com_homepath != NULL )
|
||||
{
|
||||
if( ( p = getenv( "HOME" ) ) != NULL )
|
||||
{
|
||||
|
|
|
@ -90,7 +90,7 @@ char *Sys_DefaultHomePath( void )
|
|||
FARPROC qSHGetFolderPath;
|
||||
HMODULE shfolder = LoadLibrary("shfolder.dll");
|
||||
|
||||
if( !*homePath )
|
||||
if(!*homePath && com_homepath)
|
||||
{
|
||||
if(shfolder == NULL)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue