[quake3-commits] r1778 - in trunk: . code/jpeg-6b code/qcommon code/sys

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Sun Feb 28 04:00:09 EST 2010


Author: ludwig
Date: 2010-02-28 04:00:02 -0500 (Sun, 28 Feb 2010)
New Revision: 1778

Modified:
   trunk/Makefile
   trunk/code/jpeg-6b/jinclude.h
   trunk/code/jpeg-6b/jmorecfg.h
   trunk/code/qcommon/q_platform.h
   trunk/code/qcommon/vm_x86_64.c
   trunk/code/qcommon/vm_x86_64_assembler.c
   trunk/code/sys/sys_win32.c
Log:
64bit Windows support (patch by Michael Menegakis)

Modified: trunk/Makefile
===================================================================
--- trunk/Makefile	2010-02-28 08:58:03 UTC (rev 1777)
+++ trunk/Makefile	2010-02-28 09:00:02 UTC (rev 1778)
@@ -460,8 +460,6 @@
     WINDRES=windres
   endif
 
-  ARCH=x86
-
   BASE_CFLAGS = -Wall -fno-strict-aliasing -Wimplicit -Wstrict-prototypes \
     -DUSE_ICON
   CLIENT_CFLAGS =
@@ -486,13 +484,21 @@
     CLIENT_CFLAGS += -DUSE_CODEC_VORBIS
   endif
 
-  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
+  ifeq ($(ARCH),x86_64)
+    OPTIMIZEVM = -O3 -fno-omit-frame-pointer \
+      -falign-loops=2 -funroll-loops -falign-jumps=2 -falign-functions=2 \
+      -fstrength-reduce
+    OPTIMIZE = $(OPTIMIZEVM) --fast-math
+    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
 
-  HAVE_VM_COMPILED = true
-
   SHLIBEXT=dll
   SHLIBCFLAGS=
   SHLIBLDFLAGS=-shared $(LDFLAGS)
@@ -509,7 +515,11 @@
     ifneq ($(USE_CURL_DLOPEN),1)
       ifeq ($(USE_LOCAL_HEADERS),1)
         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
         CLIENT_LIBS += $(CURL_LIBS)
       endif
@@ -523,14 +533,22 @@
   ifeq ($(ARCH),x86)
     # build 32bit
     BASE_CFLAGS += -m32
+  else
+    BASE_CFLAGS += -m64
   endif
 
   # libmingw32 must be linked before libSDLmain
   CLIENT_LIBS += -lmingw32
   ifeq ($(USE_LOCAL_HEADERS),1)
     CLIENT_CFLAGS += -I$(SDLHDIR)/include
+    ifeq ($(ARCH), x86)
     CLIENT_LIBS += $(LIBSDIR)/win32/libSDLmain.a \
                       $(LIBSDIR)/win32/libSDL.dll.a
+    else
+    CLIENT_LIBS += $(LIBSDIR)/win64/libSDLmain.a \
+                      $(LIBSDIR)/win64/libSDL.dll.a \
+                      $(LIBSDIR)/win64/libSDL.a
+    endif
   else
     CLIENT_CFLAGS += $(SDL_CFLAGS)
     CLIENT_LIBS += $(SDL_LIBS)

Modified: trunk/code/jpeg-6b/jinclude.h
===================================================================
--- trunk/code/jpeg-6b/jinclude.h	2010-02-28 08:58:03 UTC (rev 1777)
+++ trunk/code/jpeg-6b/jinclude.h	2010-02-28 09:00:02 UTC (rev 1778)
@@ -14,6 +14,9 @@
  * JPEG library.  Most applications need only include jpeglib.h.
  */
 
+#ifdef __WIN64__
+#include "basetsd.h"
+#endif
 
 #ifdef _MSC_VER
 

Modified: trunk/code/jpeg-6b/jmorecfg.h
===================================================================
--- trunk/code/jpeg-6b/jmorecfg.h	2010-02-28 08:58:03 UTC (rev 1777)
+++ trunk/code/jpeg-6b/jmorecfg.h	2010-02-28 09:00:02 UTC (rev 1778)
@@ -158,9 +158,11 @@
 /* INT32 must hold at least signed 32-bit values. */
 
 /* MinGW basetsd.h defines INT32 - don't redefine it */
+#ifndef __WIN64
 #if !(defined __MINGW32__ && defined _BASETSD_H)
 typedef long INT32;
 #endif
+#endif
 
 /* Datatype used for image dimensions.  The JPEG standard only supports
  * images up to 64K*64K due to 16-bit fields in SOF markers.  Therefore

Modified: trunk/code/qcommon/q_platform.h
===================================================================
--- trunk/code/qcommon/q_platform.h	2010-02-28 08:58:03 UTC (rev 1777)
+++ trunk/code/qcommon/q_platform.h	2010-02-28 09:00:02 UTC (rev 1778)
@@ -72,14 +72,38 @@
 // for windows fastcall option
 #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
+#define QDECL __cdecl
+
+#if defined( _MSC_VER )
 #define OS_STRING "win_msvc"
 #elif defined __MINGW32__
 #define OS_STRING "win_mingw"

Modified: trunk/code/qcommon/vm_x86_64.c
===================================================================
--- trunk/code/qcommon/vm_x86_64.c	2010-02-28 08:58:03 UTC (rev 1777)
+++ trunk/code/qcommon/vm_x86_64.c	2010-02-28 09:00:02 UTC (rev 1778)
@@ -23,11 +23,8 @@
 // vm_x86_64.c -- load time compiler and execution environment for x86-64
 
 #include "vm_local.h"
-
-#include <sys/mman.h>
 #include <sys/stat.h>
 #include <sys/types.h>
-#include <sys/wait.h>
 #include <sys/time.h>
 #include <time.h>
 #include <fcntl.h>
@@ -35,6 +32,19 @@
 #include <unistd.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
 
 #ifdef DEBUG_VM
@@ -44,8 +54,6 @@
 #define Dfprintf(args...)
 #endif
 
-#define VM_X86_64_MMAP
-
 void assembler_set_output(char* buf);
 size_t assembler_get_code_size(void);
 void assembler_init(int pass);
@@ -71,11 +79,11 @@
 */
 
 
-static long callAsmCall(long callProgramStack, long callSyscallNum)
+static int64_t CROSSCALL callAsmCall(int64_t callProgramStack, int64_t callSyscallNum)
 {
 	vm_t *savedVM;
-	long ret = 0x77;
-	long args[11];
+	int64_t ret = 0x77;
+	int64_t args[11];
 //	int iargs[11];
 	int i;
 
@@ -231,13 +239,13 @@
 #define CHECK_INSTR_REG(reg) \
 	emit("cmpl $%u, %%"#reg, header->instructionCount); \
 	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("jmp_ok_i_%08x:", instruction);
 
 #define PREPARE_JMP(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("addq %%r10, %%rax");
 
@@ -249,7 +257,7 @@
 
 #define JMPIARG \
 	CHECK_INSTR(iarg); \
-	emit("movq $%lu, %%rax", vm->codeBase+vm->instructionPointers[iarg]); \
+	emit("movq $%"PRIu64", %%rax", vm->codeBase+vm->instructionPointers[iarg]); \
 	emit("jmpq *%%rax");
  
 #define CONST_OPTIMIZE
@@ -339,7 +347,7 @@
 	emit("andl $0x%x, %%ecx", vm->dataMask &~(bytes-1)); \
 	emit("cmpl %%" #reg ", %%ecx"); \
 	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("rc_ok_i_%08x:", instruction);
 #elif 1
@@ -363,7 +371,7 @@
        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;
 
@@ -378,20 +386,20 @@
 	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");
 	exit(1);
 }
 
-static void jmpviolation(void)
+static void CROSSCALL jmpviolation(void)
 {
 	Com_Error(ERR_DROP, "program tried to execute code outside VM\n");
 	exit(1);
 }
 
 #ifdef DEBUG_VM
-static void memviolation(void)
+static void CROSSCALL memviolation(void)
 {
 	Com_Error(ERR_DROP, "program tried to access memory outside VM\n");
 	exit(1);
@@ -430,10 +438,20 @@
 	{
 		compiledOfs = assembler_get_code_size();
 		vm->codeLength = compiledOfs;
-		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");
 
+		#ifdef VM_X86_64_MMAP
+			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);
 	}
 
@@ -473,7 +491,7 @@
 		else if(op_argsize[op] == 1)
 		{
 			barg = code[pc++];
-			Dfprintf(qdasmout, "%s %8hhu\n", opnames[op], barg);
+			Dfprintf(qdasmout, "%s %8hu\n", opnames[op], barg);
 		}
 		else
 		{
@@ -517,7 +535,7 @@
 						goto emit_do_syscall;
 
 					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");
 					got_const = 0;
 					break;
@@ -558,7 +576,7 @@
 					// first argument already in rdi
 					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("pop %%rbx");
 				emit("addq %%rbx, %%rsp");
@@ -725,7 +743,7 @@
 				MAYBE_EMIT_CONST();
 				emit("subq $4, %%rsi");
 				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");
 				RANGECHECK(ebx, 4);
 				emit("movl %%eax, 0(%%r8,%%rbx, 1)"); // store in args space
@@ -742,7 +760,7 @@
 				emit("movl 4(%%rsi), %%edi");  // 1st argument dest
 				emit("movl 8(%%rsi), %%esi");  // 2nd argument src
 				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("pop %%r10");
 				emit("pop %%r9");
@@ -909,15 +927,25 @@
 		Com_Error(ERR_DROP, "leftover const\n");
 	}
 
-	emit("movq $%lu, %%rax", (unsigned long)eop);
+	emit("movq $%"PRIu64", %%rax", (uint64_t)eop);
 	emit("callq *%%rax");
 
 	} // pass loop
 
 	assembler_init(0);
 
-	if(mprotect(vm->codeBase, compiledOfs, PROT_READ|PROT_EXEC))
-		Com_Error(ERR_DROP, "VM_CompileX86: mprotect failed");
+	#ifdef VM_X86_64_MMAP
+		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;
 
@@ -934,17 +962,19 @@
 	fclose(qdasmout);
 #endif
 #endif
-	
-	if(vm->compiled)
-	{
-		struct timeval tvdone =  {0, 0};
-		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);
-		timersub(&tvdone, &tvstart, &dur);
-		Com_Printf( "compilation took %lu.%06lu seconds\n", dur.tv_sec, dur.tv_usec );
-	}
+	#ifndef __WIN64__ //timersub and gettimeofday
+		if(vm->compiled)
+		{
+			struct timeval tvdone =  {0, 0};
+			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);
+			timersub(&tvdone, &tvstart, &dur);
+			Com_Printf( "compilation took %"PRIu64".%06"PRIu64" seconds\n", dur.tv_sec, dur.tv_usec );
+		}
+	#endif
 }
 
 
@@ -1034,7 +1064,7 @@
 	);
 
 	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 ) {
 		Com_Error( ERR_DROP, "programStack corrupted in compiled code\n" );

Modified: trunk/code/qcommon/vm_x86_64_assembler.c
===================================================================
--- trunk/code/qcommon/vm_x86_64_assembler.c	2010-02-28 08:58:03 UTC (rev 1777)
+++ trunk/code/qcommon/vm_x86_64_assembler.c	2010-02-28 09:00:02 UTC (rev 1778)
@@ -25,11 +25,13 @@
 #include <string.h>
 #include <stdarg.h>
 
-typedef unsigned char u8;
-typedef unsigned short u16;
-typedef unsigned int u32;
-typedef unsigned long u64;
+#include <inttypes.h>
 
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
 static char* out;
 static unsigned compiledOfs;
 static unsigned assembler_pass;
@@ -77,7 +79,7 @@
 		if(fout)
 			writecnt = fwrite(&v, 1, 1, fout);
 			
-		debug("%02hhx ", v);
+		debug("%02hx ", v);
 	}
 	else
 	{
@@ -282,7 +284,7 @@
 		min = MIN(min, 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));
 }
 
@@ -308,7 +310,7 @@
 
 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)
@@ -318,7 +320,7 @@
 
 static inline int iss16(u64 v)
 {
-	return (labs(v) <= 0x8000);
+	return (llabs(v) <= 0x8000);
 }
 
 static inline int isu16(u64 v)
@@ -328,7 +330,7 @@
 
 static inline int iss32(u64 v)
 {
-	return (labs(v) <= 0x80000000);
+	return (llabs(v) <= 0x80000000);
 }
 
 static inline int isu32(u64 v)
@@ -338,7 +340,7 @@
 
 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)
 		CRAP_INVALID_ARGS;
@@ -501,7 +503,7 @@
 /* one byte operator with register added to operator */
 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)
 		CRAP_INVALID_ARGS;
@@ -754,7 +756,7 @@
 {
 	unsigned off;
 	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)
 		crap("%s: argument must be label", mnemonic);
@@ -1151,7 +1153,7 @@
 	else if(*s >= '0' && *s <= '9')
 	{
 		char* endptr = NULL;
-		u64 v = strtol(s, &endptr, 0);
+		u64 v = strtoull(s, &endptr, 0);
 		if(endptr && (endptr-s == 0))
 			crap("invalid integer %s", s);
 		if(val) *val = v;
@@ -1272,7 +1274,7 @@
 			}
 			break;
 		default:
-			crap("invalid token %hhu in %s", *(unsigned char*)s, *str);
+			crap("invalid token %hu in %s", *(unsigned char*)s, *str);
 			break;
 	}
 

Modified: trunk/code/sys/sys_win32.c
===================================================================
--- trunk/code/sys/sys_win32.c	2010-02-28 08:58:03 UTC (rev 1777)
+++ trunk/code/sys/sys_win32.c	2010-02-28 09:00:02 UTC (rev 1778)
@@ -41,6 +41,15 @@
 // Used to determine where to store user-specific files
 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



More information about the quake3-commits mailing list