mirror of
https://github.com/DrBeef/ioq3quest.git
synced 2024-11-26 22:11:18 +00:00
64bit Windows support (patch by Michael Menegakis)
This commit is contained in:
parent
34d616dbef
commit
760f4a1949
7 changed files with 151 additions and 63 deletions
36
Makefile
36
Makefile
|
@ -460,8 +460,6 @@ ifeq ($(PLATFORM),mingw32)
|
||||||
WINDRES=windres
|
WINDRES=windres
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ARCH=x86
|
|
||||||
|
|
||||||
BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes \
|
BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes \
|
||||||
-DUSE_ICON
|
-DUSE_ICON
|
||||||
CLIENT_CFLAGS =
|
CLIENT_CFLAGS =
|
||||||
|
@ -486,12 +484,20 @@ ifeq ($(PLATFORM),mingw32)
|
||||||
CLIENT_CFLAGS += -DUSE_CODEC_VORBIS
|
CLIENT_CFLAGS += -DUSE_CODEC_VORBIS
|
||||||
endif
|
endif
|
||||||
|
|
||||||
OPTIMIZEVM = -O3 -march=i586 -fno-omit-frame-pointer \
|
ifeq ($(ARCH),x86_64)
|
||||||
-falign-loops=2 -funroll-loops -falign-jumps=2 -falign-functions=2 \
|
OPTIMIZEVM = -O3 -fno-omit-frame-pointer \
|
||||||
-fstrength-reduce
|
-falign-loops=2 -funroll-loops -falign-jumps=2 -falign-functions=2 \
|
||||||
OPTIMIZE = $(OPTIMIZEVM) -ffast-math
|
-fstrength-reduce
|
||||||
|
OPTIMIZE = $(OPTIMIZEVM) --fast-math
|
||||||
HAVE_VM_COMPILED = true
|
HAVE_VM_COMPILED = true
|
||||||
|
endif
|
||||||
|
ifeq ($(ARCH),x86)
|
||||||
|
OPTIMIZEVM = -O3 -march=i586 -fno-omit-frame-pointer \
|
||||||
|
-falign-loops=2 -funroll-loops -falign-jumps=2 -falign-functions=2 \
|
||||||
|
-fstrength-reduce
|
||||||
|
OPTIMIZE = $(OPTIMIZEVM) -ffast-math
|
||||||
|
HAVE_VM_COMPILED = true
|
||||||
|
endif
|
||||||
|
|
||||||
SHLIBEXT=dll
|
SHLIBEXT=dll
|
||||||
SHLIBCFLAGS=
|
SHLIBCFLAGS=
|
||||||
|
@ -509,7 +515,11 @@ ifeq ($(PLATFORM),mingw32)
|
||||||
ifneq ($(USE_CURL_DLOPEN),1)
|
ifneq ($(USE_CURL_DLOPEN),1)
|
||||||
ifeq ($(USE_LOCAL_HEADERS),1)
|
ifeq ($(USE_LOCAL_HEADERS),1)
|
||||||
CLIENT_CFLAGS += -DCURL_STATICLIB
|
CLIENT_CFLAGS += -DCURL_STATICLIB
|
||||||
CLIENT_LIBS += $(LIBSDIR)/win32/libcurl.a
|
ifeq ($(ARCH),x86_64)
|
||||||
|
CLIENT_LIBS += $(LIBSDIR)/win64/libcurl.a
|
||||||
|
else
|
||||||
|
CLIENT_LIBS += $(LIBSDIR)/win32/libcurl.a
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
CLIENT_LIBS += $(CURL_LIBS)
|
CLIENT_LIBS += $(CURL_LIBS)
|
||||||
endif
|
endif
|
||||||
|
@ -523,14 +533,22 @@ ifeq ($(PLATFORM),mingw32)
|
||||||
ifeq ($(ARCH),x86)
|
ifeq ($(ARCH),x86)
|
||||||
# build 32bit
|
# build 32bit
|
||||||
BASE_CFLAGS += -m32
|
BASE_CFLAGS += -m32
|
||||||
|
else
|
||||||
|
BASE_CFLAGS += -m64
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# libmingw32 must be linked before libSDLmain
|
# libmingw32 must be linked before libSDLmain
|
||||||
CLIENT_LIBS += -lmingw32
|
CLIENT_LIBS += -lmingw32
|
||||||
ifeq ($(USE_LOCAL_HEADERS),1)
|
ifeq ($(USE_LOCAL_HEADERS),1)
|
||||||
CLIENT_CFLAGS += -I$(SDLHDIR)/include
|
CLIENT_CFLAGS += -I$(SDLHDIR)/include
|
||||||
|
ifeq ($(ARCH), x86)
|
||||||
CLIENT_LIBS += $(LIBSDIR)/win32/libSDLmain.a \
|
CLIENT_LIBS += $(LIBSDIR)/win32/libSDLmain.a \
|
||||||
$(LIBSDIR)/win32/libSDL.dll.a
|
$(LIBSDIR)/win32/libSDL.dll.a
|
||||||
|
else
|
||||||
|
CLIENT_LIBS += $(LIBSDIR)/win64/libSDLmain.a \
|
||||||
|
$(LIBSDIR)/win64/libSDL.dll.a \
|
||||||
|
$(LIBSDIR)/win64/libSDL.a
|
||||||
|
endif
|
||||||
else
|
else
|
||||||
CLIENT_CFLAGS += $(SDL_CFLAGS)
|
CLIENT_CFLAGS += $(SDL_CFLAGS)
|
||||||
CLIENT_LIBS += $(SDL_LIBS)
|
CLIENT_LIBS += $(SDL_LIBS)
|
||||||
|
|
|
@ -14,6 +14,9 @@
|
||||||
* JPEG library. Most applications need only include jpeglib.h.
|
* JPEG library. Most applications need only include jpeglib.h.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifdef __WIN64__
|
||||||
|
#include "basetsd.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
|
|
@ -158,9 +158,11 @@ typedef short INT16;
|
||||||
/* INT32 must hold at least signed 32-bit values. */
|
/* INT32 must hold at least signed 32-bit values. */
|
||||||
|
|
||||||
/* MinGW basetsd.h defines INT32 - don't redefine it */
|
/* MinGW basetsd.h defines INT32 - don't redefine it */
|
||||||
|
#ifndef __WIN64
|
||||||
#if !(defined __MINGW32__ && defined _BASETSD_H)
|
#if !(defined __MINGW32__ && defined _BASETSD_H)
|
||||||
typedef long INT32;
|
typedef long INT32;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Datatype used for image dimensions. The JPEG standard only supports
|
/* Datatype used for image dimensions. The JPEG standard only supports
|
||||||
* images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
|
* images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
|
||||||
|
|
|
@ -72,9 +72,33 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
// for windows fastcall option
|
// for windows fastcall option
|
||||||
#define QDECL
|
#define QDECL
|
||||||
|
|
||||||
//================================================================= WIN32 ===
|
//================================================================= WIN64/32 ===
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef __WIN64__
|
||||||
|
|
||||||
|
#undef QDECL
|
||||||
|
#define QDECL __cdecl
|
||||||
|
|
||||||
|
#if defined( _MSC_VER )
|
||||||
|
#define OS_STRING "win_msvc64"
|
||||||
|
#elif defined __MINGW64__
|
||||||
|
#define OS_STRING "win_mingw64"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ID_INLINE inline
|
||||||
|
#define PATH_SEP '\\'
|
||||||
|
|
||||||
|
#if defined( __WIN64__ )
|
||||||
|
#define ARCH_STRING "x86_64"
|
||||||
|
#elif defined _M_ALPHA
|
||||||
|
#define ARCH_STRING "AXP"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define Q3_LITTLE_ENDIAN
|
||||||
|
|
||||||
|
#define DLL_EXT ".dll"
|
||||||
|
|
||||||
|
#elif __WIN32__
|
||||||
|
|
||||||
#undef QDECL
|
#undef QDECL
|
||||||
#define QDECL __cdecl
|
#define QDECL __cdecl
|
||||||
|
|
|
@ -23,11 +23,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
// vm_x86_64.c -- load time compiler and execution environment for x86-64
|
// vm_x86_64.c -- load time compiler and execution environment for x86-64
|
||||||
|
|
||||||
#include "vm_local.h"
|
#include "vm_local.h"
|
||||||
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
@ -35,6 +32,19 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#ifdef __WIN64__
|
||||||
|
#include <windows.h>
|
||||||
|
#define CROSSCALL __attribute__ ((sysv_abi))//fool the vm we're SYSV ABI
|
||||||
|
//#define __USE_MINGW_ANSI_STDIO 1 //very slow - avoid if possible
|
||||||
|
#else
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#define VM_X86_64_MMAP
|
||||||
|
#define CROSSCALL
|
||||||
|
#endif
|
||||||
|
|
||||||
//#define DEBUG_VM
|
//#define DEBUG_VM
|
||||||
|
|
||||||
#ifdef DEBUG_VM
|
#ifdef DEBUG_VM
|
||||||
|
@ -44,8 +54,6 @@ static FILE* qdasmout;
|
||||||
#define Dfprintf(args...)
|
#define Dfprintf(args...)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define VM_X86_64_MMAP
|
|
||||||
|
|
||||||
void assembler_set_output(char* buf);
|
void assembler_set_output(char* buf);
|
||||||
size_t assembler_get_code_size(void);
|
size_t assembler_get_code_size(void);
|
||||||
void assembler_init(int pass);
|
void assembler_init(int pass);
|
||||||
|
@ -71,11 +79,11 @@ static void VM_Destroy_Compiled(vm_t* self);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
static long callAsmCall(long callProgramStack, long callSyscallNum)
|
static int64_t CROSSCALL callAsmCall(int64_t callProgramStack, int64_t callSyscallNum)
|
||||||
{
|
{
|
||||||
vm_t *savedVM;
|
vm_t *savedVM;
|
||||||
long ret = 0x77;
|
int64_t ret = 0x77;
|
||||||
long args[11];
|
int64_t args[11];
|
||||||
// int iargs[11];
|
// int iargs[11];
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -231,13 +239,13 @@ void emit(const char* fmt, ...)
|
||||||
#define CHECK_INSTR_REG(reg) \
|
#define CHECK_INSTR_REG(reg) \
|
||||||
emit("cmpl $%u, %%"#reg, header->instructionCount); \
|
emit("cmpl $%u, %%"#reg, header->instructionCount); \
|
||||||
emit("jb jmp_ok_i_%08x", instruction); \
|
emit("jb jmp_ok_i_%08x", instruction); \
|
||||||
emit("movq $%lu, %%rax", (unsigned long)jmpviolation); \
|
emit("movq $%"PRIu64", %%rax", (uint64_t)jmpviolation); \
|
||||||
emit("callq *%%rax"); \
|
emit("callq *%%rax"); \
|
||||||
emit("jmp_ok_i_%08x:", instruction);
|
emit("jmp_ok_i_%08x:", instruction);
|
||||||
|
|
||||||
#define PREPARE_JMP(reg) \
|
#define PREPARE_JMP(reg) \
|
||||||
CHECK_INSTR_REG(reg) \
|
CHECK_INSTR_REG(reg) \
|
||||||
emit("movq $%lu, %%rbx", (unsigned long)vm->instructionPointers); \
|
emit("movq $%"PRIu64", %%rbx", (uint64_t)vm->instructionPointers); \
|
||||||
emit("movl (%%rbx, %%rax, 4), %%eax"); \
|
emit("movl (%%rbx, %%rax, 4), %%eax"); \
|
||||||
emit("addq %%r10, %%rax");
|
emit("addq %%r10, %%rax");
|
||||||
|
|
||||||
|
@ -249,7 +257,7 @@ void emit(const char* fmt, ...)
|
||||||
|
|
||||||
#define JMPIARG \
|
#define JMPIARG \
|
||||||
CHECK_INSTR(iarg); \
|
CHECK_INSTR(iarg); \
|
||||||
emit("movq $%lu, %%rax", vm->codeBase+vm->instructionPointers[iarg]); \
|
emit("movq $%"PRIu64", %%rax", vm->codeBase+vm->instructionPointers[iarg]); \
|
||||||
emit("jmpq *%%rax");
|
emit("jmpq *%%rax");
|
||||||
|
|
||||||
#define CONST_OPTIMIZE
|
#define CONST_OPTIMIZE
|
||||||
|
@ -339,7 +347,7 @@ void emit(const char* fmt, ...)
|
||||||
emit("andl $0x%x, %%ecx", vm->dataMask &~(bytes-1)); \
|
emit("andl $0x%x, %%ecx", vm->dataMask &~(bytes-1)); \
|
||||||
emit("cmpl %%" #reg ", %%ecx"); \
|
emit("cmpl %%" #reg ", %%ecx"); \
|
||||||
emit("jz rc_ok_i_%08x", instruction); \
|
emit("jz rc_ok_i_%08x", instruction); \
|
||||||
emit("movq $%lu, %%rax", (unsigned long)memviolation); \
|
emit("movq $%"PRIu64", %%rax", (uint64_t)memviolation); \
|
||||||
emit("callq *%%rax"); \
|
emit("callq *%%rax"); \
|
||||||
emit("rc_ok_i_%08x:", instruction);
|
emit("rc_ok_i_%08x:", instruction);
|
||||||
#elif 1
|
#elif 1
|
||||||
|
@ -363,7 +371,7 @@ static void* getentrypoint(vm_t* vm)
|
||||||
return vm->codeBase;
|
return vm->codeBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void block_copy_vm(unsigned dest, unsigned src, unsigned count)
|
static void CROSSCALL block_copy_vm(unsigned dest, unsigned src, unsigned count)
|
||||||
{
|
{
|
||||||
unsigned dataMask = currentVM->dataMask;
|
unsigned dataMask = currentVM->dataMask;
|
||||||
|
|
||||||
|
@ -378,20 +386,20 @@ static void block_copy_vm(unsigned dest, unsigned src, unsigned count)
|
||||||
memcpy(currentVM->dataBase+dest, currentVM->dataBase+src, count);
|
memcpy(currentVM->dataBase+dest, currentVM->dataBase+src, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void eop(void)
|
static void CROSSCALL eop(void)
|
||||||
{
|
{
|
||||||
Com_Error(ERR_DROP, "end of program reached without return!\n");
|
Com_Error(ERR_DROP, "end of program reached without return!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void jmpviolation(void)
|
static void CROSSCALL jmpviolation(void)
|
||||||
{
|
{
|
||||||
Com_Error(ERR_DROP, "program tried to execute code outside VM\n");
|
Com_Error(ERR_DROP, "program tried to execute code outside VM\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_VM
|
#ifdef DEBUG_VM
|
||||||
static void memviolation(void)
|
static void CROSSCALL memviolation(void)
|
||||||
{
|
{
|
||||||
Com_Error(ERR_DROP, "program tried to access memory outside VM\n");
|
Com_Error(ERR_DROP, "program tried to access memory outside VM\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -430,9 +438,19 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
||||||
{
|
{
|
||||||
compiledOfs = assembler_get_code_size();
|
compiledOfs = assembler_get_code_size();
|
||||||
vm->codeLength = compiledOfs;
|
vm->codeLength = compiledOfs;
|
||||||
vm->codeBase = mmap(NULL, compiledOfs, PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
|
|
||||||
if(vm->codeBase == (void*)-1)
|
#ifdef VM_X86_64_MMAP
|
||||||
Com_Error(ERR_DROP, "VM_CompileX86: can't mmap memory");
|
vm->codeBase = mmap(NULL, compiledOfs, PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
|
||||||
|
if(vm->codeBase == (void*)-1)
|
||||||
|
Com_Error(ERR_DROP, "VM_CompileX86: can't mmap memory");
|
||||||
|
#elif __WIN64__
|
||||||
|
// allocate memory with write permissions under windows.
|
||||||
|
vm->codeBase = VirtualAlloc(NULL, compiledOfs, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
||||||
|
if(!vm->codeBase)
|
||||||
|
Com_Error(ERR_DROP, "VM_CompileX86: VirtualAlloc failed");
|
||||||
|
#else
|
||||||
|
vm->codeBase = malloc(compiledOfs);
|
||||||
|
#endif
|
||||||
|
|
||||||
assembler_set_output((char*)vm->codeBase);
|
assembler_set_output((char*)vm->codeBase);
|
||||||
}
|
}
|
||||||
|
@ -473,7 +491,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
||||||
else if(op_argsize[op] == 1)
|
else if(op_argsize[op] == 1)
|
||||||
{
|
{
|
||||||
barg = code[pc++];
|
barg = code[pc++];
|
||||||
Dfprintf(qdasmout, "%s %8hhu\n", opnames[op], barg);
|
Dfprintf(qdasmout, "%s %8hu\n", opnames[op], barg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -517,7 +535,7 @@ void VM_Compile( vm_t *vm, vmHeader_t *header ) {
|
||||||
goto emit_do_syscall;
|
goto emit_do_syscall;
|
||||||
|
|
||||||
CHECK_INSTR(const_value);
|
CHECK_INSTR(const_value);
|
||||||
emit("movq $%lu, %%rax", vm->codeBase+vm->instructionPointers[const_value]);
|
emit("movq $%"PRIu64", %%rax", vm->codeBase+vm->instructionPointers[const_value]);
|
||||||
emit("callq *%%rax");
|
emit("callq *%%rax");
|
||||||
got_const = 0;
|
got_const = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -558,7 +576,7 @@ emit_do_syscall:
|
||||||
// first argument already in rdi
|
// first argument already in rdi
|
||||||
emit("movq %%rax, %%rsi"); // second argument in rsi
|
emit("movq %%rax, %%rsi"); // second argument in rsi
|
||||||
}
|
}
|
||||||
emit("movq $%lu, %%rax", (unsigned long)callAsmCall);
|
emit("movq $%"PRIu64", %%rax", (uint64_t)callAsmCall);
|
||||||
emit("callq *%%rax");
|
emit("callq *%%rax");
|
||||||
emit("pop %%rbx");
|
emit("pop %%rbx");
|
||||||
emit("addq %%rbx, %%rsp");
|
emit("addq %%rbx, %%rsp");
|
||||||
|
@ -725,7 +743,7 @@ emit_do_syscall:
|
||||||
MAYBE_EMIT_CONST();
|
MAYBE_EMIT_CONST();
|
||||||
emit("subq $4, %%rsi");
|
emit("subq $4, %%rsi");
|
||||||
emit("movl 4(%%rsi), %%eax"); // get value from stack
|
emit("movl 4(%%rsi), %%eax"); // get value from stack
|
||||||
emit("movl $0x%hhx, %%ebx", barg);
|
emit("movl $0x%hx, %%ebx", barg);
|
||||||
emit("addl %%edi, %%ebx");
|
emit("addl %%edi, %%ebx");
|
||||||
RANGECHECK(ebx, 4);
|
RANGECHECK(ebx, 4);
|
||||||
emit("movl %%eax, 0(%%r8,%%rbx, 1)"); // store in args space
|
emit("movl %%eax, 0(%%r8,%%rbx, 1)"); // store in args space
|
||||||
|
@ -742,7 +760,7 @@ emit_do_syscall:
|
||||||
emit("movl 4(%%rsi), %%edi"); // 1st argument dest
|
emit("movl 4(%%rsi), %%edi"); // 1st argument dest
|
||||||
emit("movl 8(%%rsi), %%esi"); // 2nd argument src
|
emit("movl 8(%%rsi), %%esi"); // 2nd argument src
|
||||||
emit("movl $%d, %%edx", iarg); // 3rd argument count
|
emit("movl $%d, %%edx", iarg); // 3rd argument count
|
||||||
emit("movq $%lu, %%rax", (unsigned long)block_copy_vm);
|
emit("movq $%"PRIu64", %%rax", (uint64_t)block_copy_vm);
|
||||||
emit("callq *%%rax");
|
emit("callq *%%rax");
|
||||||
emit("pop %%r10");
|
emit("pop %%r10");
|
||||||
emit("pop %%r9");
|
emit("pop %%r9");
|
||||||
|
@ -909,15 +927,25 @@ emit_do_syscall:
|
||||||
Com_Error(ERR_DROP, "leftover const\n");
|
Com_Error(ERR_DROP, "leftover const\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
emit("movq $%lu, %%rax", (unsigned long)eop);
|
emit("movq $%"PRIu64", %%rax", (uint64_t)eop);
|
||||||
emit("callq *%%rax");
|
emit("callq *%%rax");
|
||||||
|
|
||||||
} // pass loop
|
} // pass loop
|
||||||
|
|
||||||
assembler_init(0);
|
assembler_init(0);
|
||||||
|
|
||||||
if(mprotect(vm->codeBase, compiledOfs, PROT_READ|PROT_EXEC))
|
#ifdef VM_X86_64_MMAP
|
||||||
Com_Error(ERR_DROP, "VM_CompileX86: mprotect failed");
|
if(mprotect(vm->codeBase, compiledOfs, PROT_READ|PROT_EXEC))
|
||||||
|
Com_Error(ERR_DROP, "VM_CompileX86: mprotect failed");
|
||||||
|
#elif __WIN64__
|
||||||
|
{
|
||||||
|
DWORD oldProtect = 0;
|
||||||
|
|
||||||
|
// remove write permissions; give exec permision
|
||||||
|
if(!VirtualProtect(vm->codeBase, compiledOfs, PAGE_EXECUTE_READ, &oldProtect))
|
||||||
|
Com_Error(ERR_DROP, "VM_CompileX86: VirtualProtect failed");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
vm->destroy = VM_Destroy_Compiled;
|
vm->destroy = VM_Destroy_Compiled;
|
||||||
|
|
||||||
|
@ -935,16 +963,18 @@ emit_do_syscall:
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(vm->compiled)
|
#ifndef __WIN64__ //timersub and gettimeofday
|
||||||
{
|
if(vm->compiled)
|
||||||
struct timeval tvdone = {0, 0};
|
{
|
||||||
struct timeval dur = {0, 0};
|
struct timeval tvdone = {0, 0};
|
||||||
Com_Printf( "VM file %s compiled to %i bytes of code (%p - %p)\n", vm->name, vm->codeLength, vm->codeBase, vm->codeBase+vm->codeLength );
|
struct timeval dur = {0, 0};
|
||||||
|
Com_Printf( "VM file %s compiled to %i bytes of code (%p - %p)\n", vm->name, vm->codeLength, vm->codeBase, vm->codeBase+vm->codeLength );
|
||||||
|
|
||||||
gettimeofday(&tvdone, NULL);
|
gettimeofday(&tvdone, NULL);
|
||||||
timersub(&tvdone, &tvstart, &dur);
|
timersub(&tvdone, &tvstart, &dur);
|
||||||
Com_Printf( "compilation took %lu.%06lu seconds\n", dur.tv_sec, dur.tv_usec );
|
Com_Printf( "compilation took %"PRIu64".%06"PRIu64" seconds\n", dur.tv_sec, dur.tv_usec );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1034,7 +1064,7 @@ int VM_CallCompiled( vm_t *vm, int *args ) {
|
||||||
);
|
);
|
||||||
|
|
||||||
if ( opStack != &stack[1] ) {
|
if ( opStack != &stack[1] ) {
|
||||||
Com_Error( ERR_DROP, "opStack corrupted in compiled code (offset %ld)\n", (long int) ((void *) &stack[1] - opStack));
|
Com_Error( ERR_DROP, "opStack corrupted in compiled code (offset %"PRId64")\n", (int64_t) ((void *) &stack[1] - opStack));
|
||||||
}
|
}
|
||||||
if ( programStack != stackOnEntry - 48 ) {
|
if ( programStack != stackOnEntry - 48 ) {
|
||||||
Com_Error( ERR_DROP, "programStack corrupted in compiled code\n" );
|
Com_Error( ERR_DROP, "programStack corrupted in compiled code\n" );
|
||||||
|
|
|
@ -25,10 +25,12 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
typedef unsigned char u8;
|
#include <inttypes.h>
|
||||||
typedef unsigned short u16;
|
|
||||||
typedef unsigned int u32;
|
typedef uint8_t u8;
|
||||||
typedef unsigned long u64;
|
typedef uint16_t u16;
|
||||||
|
typedef uint32_t u32;
|
||||||
|
typedef uint64_t u64;
|
||||||
|
|
||||||
static char* out;
|
static char* out;
|
||||||
static unsigned compiledOfs;
|
static unsigned compiledOfs;
|
||||||
|
@ -77,7 +79,7 @@ static void emit1(unsigned char v)
|
||||||
if(fout)
|
if(fout)
|
||||||
writecnt = fwrite(&v, 1, 1, fout);
|
writecnt = fwrite(&v, 1, 1, fout);
|
||||||
|
|
||||||
debug("%02hhx ", v);
|
debug("%02hx ", v);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -282,7 +284,7 @@ static void labelhash_free(void)
|
||||||
min = MIN(min, n);
|
min = MIN(min, n);
|
||||||
max = MAX(max, n);
|
max = MAX(max, n);
|
||||||
}
|
}
|
||||||
printf("total %u, hsize %lu, zero %u, min %u, max %u\n", t, sizeof(labelhash)/sizeof(labelhash[0]), z, min, max);
|
printf("total %u, hsize %"PRIu64", zero %u, min %u, max %u\n", t, sizeof(labelhash)/sizeof(labelhash[0]), z, min, max);
|
||||||
memset(labelhash, 0, sizeof(labelhash));
|
memset(labelhash, 0, sizeof(labelhash));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,7 +310,7 @@ static const char* argtype2str(argtype_t t)
|
||||||
|
|
||||||
static inline int iss8(u64 v)
|
static inline int iss8(u64 v)
|
||||||
{
|
{
|
||||||
return (labs(v) <= 0x80);
|
return (llabs(v) <= 0x80); //llabs instead of labs required for __WIN64
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int isu8(u64 v)
|
static inline int isu8(u64 v)
|
||||||
|
@ -318,7 +320,7 @@ static inline int isu8(u64 v)
|
||||||
|
|
||||||
static inline int iss16(u64 v)
|
static inline int iss16(u64 v)
|
||||||
{
|
{
|
||||||
return (labs(v) <= 0x8000);
|
return (llabs(v) <= 0x8000);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int isu16(u64 v)
|
static inline int isu16(u64 v)
|
||||||
|
@ -328,7 +330,7 @@ static inline int isu16(u64 v)
|
||||||
|
|
||||||
static inline int iss32(u64 v)
|
static inline int iss32(u64 v)
|
||||||
{
|
{
|
||||||
return (labs(v) <= 0x80000000);
|
return (llabs(v) <= 0x80000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int isu32(u64 v)
|
static inline int isu32(u64 v)
|
||||||
|
@ -338,7 +340,7 @@ static inline int isu32(u64 v)
|
||||||
|
|
||||||
static void emit_opsingle(const char* mnemonic, arg_t arg1, arg_t arg2, void* data)
|
static void emit_opsingle(const char* mnemonic, arg_t arg1, arg_t arg2, void* data)
|
||||||
{
|
{
|
||||||
u8 op = (u8)((unsigned long) data);
|
u8 op = (u8)((uint64_t) data);
|
||||||
|
|
||||||
if(arg1.type != T_NONE || arg2.type != T_NONE)
|
if(arg1.type != T_NONE || arg2.type != T_NONE)
|
||||||
CRAP_INVALID_ARGS;
|
CRAP_INVALID_ARGS;
|
||||||
|
@ -501,7 +503,7 @@ static void maybe_emit_displacement(arg_t* arg)
|
||||||
/* one byte operator with register added to operator */
|
/* one byte operator with register added to operator */
|
||||||
static void emit_opreg(const char* mnemonic, arg_t arg1, arg_t arg2, void* data)
|
static void emit_opreg(const char* mnemonic, arg_t arg1, arg_t arg2, void* data)
|
||||||
{
|
{
|
||||||
u8 op = (u8)((unsigned long) data);
|
u8 op = (u8)((uint64_t) data);
|
||||||
|
|
||||||
if(arg1.type != T_REGISTER || arg2.type != T_NONE)
|
if(arg1.type != T_REGISTER || arg2.type != T_NONE)
|
||||||
CRAP_INVALID_ARGS;
|
CRAP_INVALID_ARGS;
|
||||||
|
@ -754,7 +756,7 @@ static void emit_condjump(const char* mnemonic, arg_t arg1, arg_t arg2, void* da
|
||||||
{
|
{
|
||||||
unsigned off;
|
unsigned off;
|
||||||
int disp;
|
int disp;
|
||||||
unsigned char opcode = (unsigned char)(((unsigned long)data)&0xFF);
|
unsigned char opcode = (unsigned char)(((uint64_t)data)&0xFF);
|
||||||
|
|
||||||
if(arg1.type != T_LABEL || arg2.type != T_NONE)
|
if(arg1.type != T_LABEL || arg2.type != T_NONE)
|
||||||
crap("%s: argument must be label", mnemonic);
|
crap("%s: argument must be label", mnemonic);
|
||||||
|
@ -1151,7 +1153,7 @@ static unsigned char nexttok(const char** str, char* label, u64* val)
|
||||||
else if(*s >= '0' && *s <= '9')
|
else if(*s >= '0' && *s <= '9')
|
||||||
{
|
{
|
||||||
char* endptr = NULL;
|
char* endptr = NULL;
|
||||||
u64 v = strtol(s, &endptr, 0);
|
u64 v = strtoull(s, &endptr, 0);
|
||||||
if(endptr && (endptr-s == 0))
|
if(endptr && (endptr-s == 0))
|
||||||
crap("invalid integer %s", s);
|
crap("invalid integer %s", s);
|
||||||
if(val) *val = v;
|
if(val) *val = v;
|
||||||
|
@ -1272,7 +1274,7 @@ tok_memory:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
crap("invalid token %hhu in %s", *(unsigned char*)s, *str);
|
crap("invalid token %hu in %s", *(unsigned char*)s, *str);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,15 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
// Used to determine where to store user-specific files
|
// Used to determine where to store user-specific files
|
||||||
static char homePath[ MAX_OSPATH ] = { 0 };
|
static char homePath[ MAX_OSPATH ] = { 0 };
|
||||||
|
|
||||||
|
#ifdef __WIN64__
|
||||||
|
void Sys_SnapVector( float *v )
|
||||||
|
{
|
||||||
|
v[0] = rint(v[0]);
|
||||||
|
v[1] = rint(v[1]);
|
||||||
|
v[2] = rint(v[2]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
================
|
================
|
||||||
Sys_DefaultHomePath
|
Sys_DefaultHomePath
|
||||||
|
|
Loading…
Reference in a new issue