[quake3-commits] r1992 - trunk/code/qcommon

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Mon May 16 13:55:07 EDT 2011


Author: thilo
Date: 2011-05-16 13:55:07 -0400 (Mon, 16 May 2011)
New Revision: 1992

Modified:
   trunk/code/qcommon/vm_x86_64.c
   trunk/code/qcommon/vm_x86_64_assembler.c
Log:
- Fix SEGV in while loop getop() after t = b = 0
- Fix iss8, iss16 and iss32 which would not correctly detect 32-bit signed integer range
- Add support for "addb", "subb" etc. assembler mnemonic
- Change opStack protection for x86_64 VM: No overflow checks necessary anymore as offset register is 1 byte long only


Modified: trunk/code/qcommon/vm_x86_64.c
===================================================================
--- trunk/code/qcommon/vm_x86_64.c	2011-05-15 14:58:56 UTC (rev 1991)
+++ trunk/code/qcommon/vm_x86_64.c	2011-05-16 17:55:07 UTC (rev 1992)
@@ -71,13 +71,13 @@
   +- r8
 
   eax	scratch
-  ebx	scratch
+  bl	opStack offset
   ecx	scratch (required for shifts)
   edx	scratch (required for divisions)
-  rsi	opStack offset
+  rsi	scratch
   rdi	program frame pointer (programStack)
   r8    pointer data (vm->dataBase)
-  r9    opStack data base (opStack)
+  r9    opStack data base (vm->opStack + OPSTACK_SIZE / 2)
   r10   start of generated code
 */
 
@@ -248,33 +248,19 @@
 	emit("movq $%"PRIu64", %%rax", (intptr_t) memviolation); \
 	emit("callq *%%rax"); \
 	emit("rc_ok_i_%08x:", instruction)
-
-#define OPSTACKCHECK() \
-	emit("movl %%esi, %%ecx"); \
-	emit("andl $0x%x, %%ecx", OPSTACK_MASK & ~0x03); \
-	emit("cmpl %%esi, %%ecx"); \
-	emit("jz oc_ok_i_%08x", instruction); \
-	emit("movq $%"PRIu64", %%rax", (intptr_t) opstackviolation); \
-	emit("callq *%%rax"); \
-	emit("oc_ok_i_%08x:", instruction)
 #elif 1
 // check is too expensive, so just confine memory access
 #define RANGECHECK(reg, bytes) \
 	emit("andl $0x%x, %%" #reg, vm->dataMask &~(bytes-1))
-
-#define OPSTACKCHECK() \
-	emit("andl $0x%x, %%esi", OPSTACK_MASK & ~0x03)
 #else
 #define RANGECHECK(reg, bytes)
 #endif
 
 #define STACK_PUSH(bytes) \
-	emit("addl $0x%x, %%esi", bytes); \
-	OPSTACKCHECK()
+	emit("addb $0x%x, %%bl", bytes); \
 
 #define STACK_POP(bytes) \
-	emit("subl $0x%x, %%esi", bytes); \
-	OPSTACKCHECK()
+	emit("subb $0x%x, %%bl", bytes); \
 
 #define CHECK_INSTR_REG(reg) \
 	emit("cmpl $%u, %%"#reg, header->instructionCount); \
@@ -285,8 +271,8 @@
 
 #define PREPARE_JMP(reg) \
 	CHECK_INSTR_REG(reg); \
-	emit("movq $%"PRIu64", %%rbx", (intptr_t)vm->instructionPointers); \
-	emit("movl (%%rbx, %%rax, 4), %%eax"); \
+	emit("movq $%"PRIu64", %%rsi", (intptr_t)vm->instructionPointers); \
+	emit("movl (%%rsi, %%rax, 4), %%eax"); \
 	emit("addq %%r10, %%rax")
 
 #define CHECK_INSTR(nr) \
@@ -309,7 +295,7 @@
 		got_const = 0; \
 		vm->instructionPointers[instruction-1] = assembler_get_code_size(); \
 		STACK_PUSH(4); \
-		emit("movl $%d, 0(%%r9, %%rsi, 1)", const_value); \
+		emit("movl $%d, (%%r9, %%rbx, 1)", const_value); \
 	}
 #else
 #define MAYBE_EMIT_CONST()
@@ -319,8 +305,8 @@
 #define IJ(op) \
 	MAYBE_EMIT_CONST(); \
 	STACK_POP(8); \
-	emit("movl 4(%%r9, %%rsi, 1), %%eax"); \
-	emit("cmpl 8(%%r9, %%rsi, 1), %%eax"); \
+	emit("movl 4(%%r9, %%rbx, 1), %%eax"); \
+	emit("cmpl 8(%%r9, %%rbx, 1), %%eax"); \
 	emit(op " i_%08x", instruction+1); \
 	JMPIARG(); \
 	neednilabel = 1
@@ -329,8 +315,8 @@
 #define FJ(bits, op) \
 	MAYBE_EMIT_CONST(); \
 	STACK_POP(8); \
-	emit("flds 4(%%r9, %%rsi, 1)");\
-	emit("fcomps 8(%%r9, %%rsi, 1)");\
+	emit("flds 4(%%r9, %%rbx, 1)");\
+	emit("fcomps 8(%%r9, %%rbx, 1)");\
 	emit("fnstsw %%ax");\
 	emit("testb $" #bits ", %%ah");\
 	emit(op " i_%08x", instruction+1);\
@@ -342,8 +328,8 @@
 #define XJ(op) \
 	MAYBE_EMIT_CONST(); \
 	STACK_POP(8); \
-	emit("movss 4(%%r9, %%rsi, 1), %%xmm0");\
-	emit("ucomiss 8(%%r9, %%rsi, 1), %%xmm0");\
+	emit("movss 4(%%r9, %%rbx, 1), %%xmm0");\
+	emit("ucomiss 8(%%r9, %%rbx, 1), %%xmm0");\
 	emit("jp i_%08x", instruction+1);\
 	emit(op " i_%08x", instruction+1);\
 	JMPIARG(); \
@@ -352,35 +338,35 @@
 
 #define SIMPLE(op) \
 	MAYBE_EMIT_CONST(); \
-	emit("movl 0(%%r9, %%rsi, 1), %%eax"); \
+	emit("movl (%%r9, %%rbx, 1), %%eax"); \
 	STACK_POP(4); \
-	emit(op " %%eax, 0(%%r9, %%rsi, 1)")
+	emit(op " %%eax, (%%r9, %%rbx, 1)")
 
 #ifdef USE_X87
 #define FSIMPLE(op) \
 	MAYBE_EMIT_CONST(); \
 	STACK_POP(4); \
-	emit("flds 0(%%r9, %%rsi, 1)"); \
-	emit(op " 4(%%r9, %%rsi, 1)"); \
-	emit("fstps 0(%%r9, %%rsi, 1)")
+	emit("flds (%%r9, %%rbx, 1)"); \
+	emit(op " 4(%%r9, %%rbx, 1)"); \
+	emit("fstps (%%r9, %%rbx, 1)")
 #define XSIMPLE(op)
 #else
 #define FSIMPLE(op)
 #define XSIMPLE(op) \
 	MAYBE_EMIT_CONST(); \
 	STACK_POP(4); \
-	emit("movss 0(%%r9, %%rsi, 1), %%xmm0"); \
-	emit(op " 4(%%r9, %%rsi, 1), %%xmm0"); \
-	emit("movss %%xmm0, 0(%%r9, %%rsi, 1)")
+	emit("movss (%%r9, %%rbx, 1), %%xmm0"); \
+	emit(op " 4(%%r9, %%rbx, 1), %%xmm0"); \
+	emit("movss %%xmm0, (%%r9, %%rbx, 1)")
 #endif
 
 #define SHIFT(op) \
 	MAYBE_EMIT_CONST(); \
 	STACK_POP(4); \
-	emit("movl 4(%%r9, %%rsi, 1), %%ecx"); \
-	emit("movl 0(%%r9, %%rsi, 1), %%eax"); \
+	emit("movl 4(%%r9, %%rbx, 1), %%ecx"); \
+	emit("movl (%%r9, %%rbx, 1), %%eax"); \
 	emit(op " %%cl, %%eax"); \
-	emit("movl %%eax, 0(%%r9, %%rsi, 1)")
+	emit("movl %%eax, (%%r9, %%rbx, 1)")
 
 #ifdef DEBUG_VM
 #define NOTIMPL(x) \
@@ -562,7 +548,7 @@
 				break;
 			case OP_CALL:
 				RANGECHECK(edi, 4);
-				emit("movl $%d, 0(%%r8, %%rdi, 1)", instruction+1);  // save next instruction
+				emit("movl $%d, (%%r8, %%rdi, 1)", instruction+1);  // save next instruction
 
 				if(got_const)
 				{
@@ -578,7 +564,7 @@
 				else
 				{
 					MAYBE_EMIT_CONST();
-					emit("movl 0(%%r9, %%rsi, 1), %%eax");  // get instr from stack
+					emit("movl (%%r9, %%rbx, 1), %%eax");  // get instr from stack
 					STACK_POP(4);
 
 					emit("orl %%eax, %%eax");
@@ -592,16 +578,15 @@
 				}
 
 //				emit("fnsave 4(%%r9, %%rsi, 1)");
-				emit("push %%rsi");
 				emit("push %%rdi");
 				emit("push %%r8");
 				emit("push %%r9");
 				emit("push %%r10");
-				emit("movq %%rsp, %%rbx"); // we need to align the stack pointer
-				emit("subq $8, %%rbx");    //   |
-				emit("andq $127, %%rbx");  //   |
-				emit("subq %%rbx, %%rsp"); // <-+
-				emit("push %%rbx");
+				emit("movq %%rsp, %%rsi"); // we need to align the stack pointer
+				emit("subq $8, %%rsi");    //   |
+				emit("andq $127, %%rsi");  //   |
+				emit("subq %%rsi, %%rsp"); // <-+
+				emit("push %%rsi");
 				if(got_const) {
 					got_const = 0;
 					emit("movq $%u, %%rsi", -1-const_value); // second argument in rsi
@@ -612,16 +597,15 @@
 				}
 				emit("movq $%"PRIu64", %%rax", (intptr_t) callAsmCall);
 				emit("callq *%%rax");
-				emit("pop %%rbx");
-				emit("addq %%rbx, %%rsp");
+				emit("pop %%rsi");
+				emit("addq %%rsi, %%rsp");
 				emit("pop %%r10");
 				emit("pop %%r9");
 				emit("pop %%r8");
 				emit("pop %%rdi");
-				emit("pop %%rsi");
 //				emit("frstor 4(%%r9, %%rsi, 1)");
 				STACK_PUSH(4);
-				emit("movl %%eax, (%%r9, %%rsi, 1)"); // store return value
+				emit("movl %%eax, (%%r9, %%rbx, 1)"); // store return value
 				neednilabel = 1;
 				break;
 			case OP_PUSH:
@@ -639,15 +623,15 @@
 				const_value = iarg;
 #else
 				STACK_PUSH(4);
-				emit("movl $%d, 0(%%r9, %%rsi, 1)", iarg);
+				emit("movl $%d, (%%r9, %%rbx, 1)", iarg);
 #endif
 				break;
 			case OP_LOCAL:
 				MAYBE_EMIT_CONST();
-				emit("movl %%edi, %%ebx");
-				emit("addl $%d,%%ebx", iarg);
+				emit("movl %%edi, %%esi");
+				emit("addl $%d,%%esi", iarg);
 				STACK_PUSH(4);
-				emit("movl %%ebx, 0(%%r9, %%rsi, 1)");
+				emit("movl %%esi, (%%r9, %%rbx, 1)");
 				break;
 			case OP_JUMP:
 				if(got_const) {
@@ -655,7 +639,7 @@
 					got_const = 0;
 					JMPIARG();
 				} else {
-					emit("movl 0(%%r9, %%rsi, 1), %%eax"); // get instr from stack
+					emit("movl (%%r9, %%rbx, 1), %%eax"); // get instr from stack
 					STACK_POP(4);
 
 					PREPARE_JMP(eax);
@@ -701,8 +685,8 @@
 #ifndef USE_X87
 				MAYBE_EMIT_CONST();
 				STACK_POP(8);
-				emit("movss 4(%%r9, %%rsi, 1), %%xmm0");
-				emit("ucomiss 8(%%r9, %%rsi, 1), %%xmm0");
+				emit("movss 4(%%r9, %%rbx, 1), %%xmm0");
+				emit("ucomiss 8(%%r9, %%rbx, 1), %%xmm0");
 				emit("jp dojump_i_%08x", instruction);
 				emit("jz i_%08x", instruction+1);
 				emit("dojump_i_%08x:", instruction);
@@ -728,105 +712,103 @@
 				break;
 			case OP_LOAD1:
 				MAYBE_EMIT_CONST();
-				emit("movl 0(%%r9, %%rsi, 1), %%eax"); // get value from stack
+				emit("movl (%%r9, %%rbx, 1), %%eax"); // get value from stack
 				RANGECHECK(eax, 1);
-				emit("movb 0(%%r8, %%rax, 1), %%al"); // deref into eax
+				emit("movb (%%r8, %%rax, 1), %%al"); // deref into eax
 				emit("andq $255, %%rax");
-				emit("movl %%eax, 0(%%r9, %%rsi, 1)"); // store on stack
+				emit("movl %%eax, (%%r9, %%rbx, 1)"); // store on stack
 				break;
 			case OP_LOAD2:
 				MAYBE_EMIT_CONST();
-				emit("movl 0(%%r9, %%rsi, 1), %%eax"); // get value from stack
+				emit("movl (%%r9, %%rbx, 1), %%eax"); // get value from stack
 				RANGECHECK(eax, 2);
-				emit("movw 0(%%r8, %%rax, 1), %%ax"); // deref into eax
-				emit("movl %%eax, 0(%%r9, %%rsi, 1)"); // store on stack
+				emit("movw (%%r8, %%rax, 1), %%ax"); // deref into eax
+				emit("movl %%eax, (%%r9, %%rbx, 1)"); // store on stack
 				break;
 			case OP_LOAD4:
 				MAYBE_EMIT_CONST();
-				emit("movl 0(%%r9, %%rsi, 1), %%eax"); // get value from stack
+				emit("movl (%%r9, %%rbx, 1), %%eax"); // get value from stack
 				RANGECHECK(eax, 4); // not a pointer!?
-				emit("movl 0(%%r8, %%rax, 1), %%eax"); // deref into eax
-				emit("movl %%eax, 0(%%r9, %%rsi, 1)"); // store on stack
+				emit("movl (%%r8, %%rax, 1), %%eax"); // deref into eax
+				emit("movl %%eax, (%%r9, %%rbx, 1)"); // store on stack
 				break;
 			case OP_STORE1:
 				MAYBE_EMIT_CONST();
-				emit("movl 0(%%r9, %%rsi, 1), %%eax"); // get value from stack
+				emit("movl (%%r9, %%rbx, 1), %%eax"); // get value from stack
 				STACK_POP(8);
 				emit("andq $255, %%rax");
-				emit("movl 4(%%r9, %%rsi, 1), %%ebx"); // get pointer from stack
-				RANGECHECK(ebx, 1);
-				emit("movb %%al, 0(%%r8, %%rbx, 1)"); // store in memory
+				emit("movl 4(%%r9, %%rbx, 1), %%esi"); // get pointer from stack
+				RANGECHECK(esi, 1);
+				emit("movb %%al, (%%r8, %%rsi, 1)"); // store in memory
 				break;
 			case OP_STORE2:
 				MAYBE_EMIT_CONST();
-				emit("movl 0(%%r9, %%rsi, 1), %%eax"); // get value from stack
+				emit("movl (%%r9, %%rbx, 1), %%eax"); // get value from stack
 				STACK_POP(8);
-				emit("movl 4(%%r9, %%rsi, 1), %%ebx"); // get pointer from stack
-				RANGECHECK(ebx, 2);
-				emit("movw %%ax, 0(%%r8, %%rbx, 1)"); // store in memory
+				emit("movl 4(%%r9, %%rbx, 1), %%esi"); // get pointer from stack
+				RANGECHECK(esi, 2);
+				emit("movw %%ax, (%%r8, %%rsi, 1)"); // store in memory
 				break;
 			case OP_STORE4:
 				MAYBE_EMIT_CONST();
-				emit("movl 0(%%r9, %%rsi, 1), %%eax"); // get value from stack
+				emit("movl (%%r9, %%rbx, 1), %%eax"); // get value from stack
 				STACK_POP(8);
-				emit("movl 4(%%r9, %%rsi, 1), %%ebx"); // get pointer from stack
-				RANGECHECK(ebx, 4);
-				emit("movl %%eax, 0(%%r8, %%rbx, 1)"); // store in memory
+				emit("movl 4(%%r9, %%rbx, 1), %%esi"); // get pointer from stack
+				RANGECHECK(esi, 4);
+				emit("movl %%eax, (%%r8, %%rsi, 1)"); // store in memory
 				break;
 			case OP_ARG:
 				MAYBE_EMIT_CONST();
-				emit("movl 0(%%r9, %%rsi, 1), %%eax"); // get value from stack
+				emit("movl (%%r9, %%rbx, 1), %%eax"); // get value from stack
 				STACK_POP(4);
-				emit("movl $0x%hx, %%ebx", barg);
-				emit("addl %%edi, %%ebx");
-				RANGECHECK(ebx, 4);
-				emit("movl %%eax, 0(%%r8,%%rbx, 1)"); // store in args space
+				emit("movl $0x%hx, %%esi", barg);
+				emit("addl %%edi, %%esi");
+				RANGECHECK(esi, 4);
+				emit("movl %%eax, (%%r8,%%rsi, 1)"); // store in args space
 				break;
 			case OP_BLOCK_COPY:
 
 				MAYBE_EMIT_CONST();
 				STACK_POP(8);
-				emit("push %%rsi");
 				emit("push %%rdi");
 				emit("push %%r8");
 				emit("push %%r9");
 				emit("push %%r10");
-				emit("movq %%rsp, %%rbx"); // we need to align the stack pointer
-				emit("subq $8, %%rbx");    //   |
-				emit("andq $127, %%rbx");  //   |
-				emit("subq %%rbx, %%rsp"); // <-+
-				emit("push %%rbx");
-				emit("movl 4(%%r9, %%rsi, 1), %%edi");  // 1st argument dest
-				emit("movl 8(%%r9, %%rsi, 1), %%esi");  // 2nd argument src
+				emit("movq %%rsp, %%rsi"); // we need to align the stack pointer
+				emit("subq $8, %%rsi");    //   |
+				emit("andq $127, %%rsi");  //   |
+				emit("subq %%rsi, %%rsp"); // <-+
+				emit("push %%rsi");
+				emit("movl 4(%%r9, %%rbx, 1), %%edi");  // 1st argument dest
+				emit("movl 8(%%r9, %%rbx, 1), %%rsi");  // 2nd argument src
 				emit("movl $%d, %%edx", iarg); // 3rd argument count
 				emit("movq $%"PRIu64", %%rax", (intptr_t) block_copy_vm);
 				emit("callq *%%rax");
-				emit("pop %%rbx");
-				emit("addq %%rbx, %%rsp");
+				emit("pop %%rsi");
+				emit("addq %%rsi, %%rsp");
 				emit("pop %%r10");
 				emit("pop %%r9");
 				emit("pop %%r8");
 				emit("pop %%rdi");
-				emit("pop %%rsi");
 
 				break;
 			case OP_SEX8:
 				MAYBE_EMIT_CONST();
-				emit("movw 0(%%r9, %%rsi, 1), %%ax");
+				emit("movw (%%r9, %%rbx, 1), %%ax");
 				emit("andq $255, %%rax");
 				emit("cbw");
 				emit("cwde");
-				emit("movl %%eax, 0(%%r9, %%rsi, 1)");
+				emit("movl %%eax, (%%r9, %%rbx, 1)");
 				break;
 			case OP_SEX16:
 				MAYBE_EMIT_CONST();
-				emit("movw 0(%%r9, %%rsi, 1), %%ax");
+				emit("movw (%%r9, %%rbx, 1), %%ax");
 				emit("cwde");
-				emit("movl %%eax, 0(%%r9, %%rsi, 1)");
+				emit("movl %%eax, (%%r9, %%rbx, 1)");
 				break;
 			case OP_NEGI:
 				MAYBE_EMIT_CONST();
-				emit("negl 0(%%r9, %%rsi, 1)");
+				emit("negl (%%r9, %%rbx, 1)");
 				break;
 			case OP_ADD:
 				SIMPLE("addl");
@@ -837,49 +819,49 @@
 			case OP_DIVI:
 				MAYBE_EMIT_CONST();
 				STACK_POP(4);
-				emit("movl 0(%%r9, %%rsi, 1), %%eax");
+				emit("movl (%%r9, %%rbx, 1), %%eax");
 				emit("cdq");
-				emit("idivl 4(%%r9, %%rsi, 1)");
-				emit("movl %%eax, 0(%%r9, %%rsi, 1)");
+				emit("idivl 4(%%r9, %%rbx, 1)");
+				emit("movl %%eax, (%%r9, %%rbx, 1)");
 				break;
 			case OP_DIVU:
 				MAYBE_EMIT_CONST();
 				STACK_POP(4);
-				emit("movl 0(%%r9, %%rsi, 1), %%eax");
+				emit("movl (%%r9, %%rbx, 1), %%eax");
 				emit("xorq %%rdx, %%rdx");
-				emit("divl 4(%%r9, %%rsi, 1)");
-				emit("movl %%eax, 0(%%r9, %%rsi, 1)");
+				emit("divl 4(%%r9, %%rbx, 1)");
+				emit("movl %%eax, (%%r9, %%rbx, 1)");
 				break;
 			case OP_MODI:
 				MAYBE_EMIT_CONST();
 				STACK_POP(4);
-				emit("movl 0(%%r9, %%rsi, 1), %%eax");
+				emit("movl (%%r9, %%rbx, 1), %%eax");
 				emit("xorl %%edx, %%edx");
 				emit("cdq");
-				emit("idivl 4(%%r9, %%rsi, 1)");
-				emit("movl %%edx, 0(%%r9, %%rsi, 1)");
+				emit("idivl 4(%%r9, %%rbx, 1)");
+				emit("movl %%edx, (%%r9, %%rbx, 1)");
 				break;
 			case OP_MODU:
 				MAYBE_EMIT_CONST();
 				STACK_POP(4);
-				emit("movl 0(%%r9, %%rsi, 1), %%eax");
+				emit("movl (%%r9, %%rbx, 1), %%eax");
 				emit("xorl %%edx, %%edx");
-				emit("divl 4(%%r9, %%rsi, 1)");
-				emit("movl %%edx, 0(%%r9, %%rsi, 1)");
+				emit("divl 4(%%r9, %%rbx, 1)");
+				emit("movl %%edx, (%%r9, %%rbx, 1)");
 				break;
 			case OP_MULI:
 				MAYBE_EMIT_CONST();
 				STACK_POP(4);
-				emit("movl 0(%%r9, %%rsi, 1), %%eax");
-				emit("imull 4(%%r9, %%rsi, 1)");
-				emit("movl %%eax, 0(%%r9, %%rsi, 1)");
+				emit("movl (%%r9, %%rbx, 1), %%eax");
+				emit("imull 4(%%r9, %%rbx, 1)");
+				emit("movl %%eax, (%%r9, %%rbx, 1)");
 				break;
 			case OP_MULU:
 				MAYBE_EMIT_CONST();
 				STACK_POP(4);
-				emit("movl 0(%%r9, %%rsi, 1), %%eax");
-				emit("mull 4(%%r9, %%rsi, 1)");
-				emit("movl %%eax, 0(%%r9, %%rsi, 1)");
+				emit("movl (%%r9, %%rbx, 1), %%eax");
+				emit("mull 4(%%r9, %%rbx, 1)");
+				emit("movl %%eax, (%%r9, %%rbx, 1)");
 				break;
 			case OP_BAND:
 				SIMPLE("andl");
@@ -892,7 +874,7 @@
 				break;
 			case OP_BCOM:
 				MAYBE_EMIT_CONST();
-				emit("notl 0(%%r9, %%rsi, 1)");
+				emit("notl (%%r9, %%rbx, 1)");
 				break;
 			case OP_LSH:
 				SHIFT("shl");
@@ -906,12 +888,12 @@
 			case OP_NEGF:
 				MAYBE_EMIT_CONST();
 #ifdef USE_X87
-				emit("flds 0(%%r9, %%rsi, 1)");
+				emit("flds (%%r9, %%rbx, 1)");
 				emit("fchs");
-				emit("fstps 0(%%r9, %%rsi, 1)");
+				emit("fstps (%%r9, %%rbx, 1)");
 #else
 				emit("movl $0x80000000, %%eax");
-				emit("xorl %%eax, 0(%%r9, %%rsi, 1)");
+				emit("xorl %%eax, (%%r9, %%rbx, 1)");
 #endif
 				break;
 			case OP_ADDF:
@@ -933,27 +915,27 @@
 			case OP_CVIF:
 				MAYBE_EMIT_CONST();
 #ifdef USE_X87
-				emit("filds 0(%%r9, %%rsi, 1)");
-				emit("fstps 0(%%r9, %%rsi, 1)");
+				emit("filds (%%r9, %%rbx, 1)");
+				emit("fstps (%%r9, %%rbx, 1)");
 #else
-				emit("movl 0(%%r9, %%rsi, 1), %%eax");
+				emit("movl (%%r9, %%rbx, 1), %%eax");
 				emit("cvtsi2ss %%eax, %%xmm0");
-				emit("movss %%xmm0, 0(%%r9, %%rsi, 1)");
+				emit("movss %%xmm0, (%%r9, %%rbx, 1)");
 #endif
 				break;
 			case OP_CVFI:
 				MAYBE_EMIT_CONST();
 #ifdef USE_X87
-				emit("flds 0(%%r9, %%rsi, 1)");
-				emit("fnstcw 4(%%r9, %%rsi, 1)");
-				emit("movw $0x0F7F, 8(%%r9, %%rsi, 1)"); // round toward zero
-				emit("fldcw 8(%%r9, %%rsi, 1)");
-				emit("fistpl 0(%%r9, %%rsi, 1)");
-				emit("fldcw 4(%%r9, %%rsi, 1)");
+				emit("flds (%%r9, %%rbx, 1)");
+				emit("fnstcw 4(%%r9, %%rbx, 1)");
+				emit("movw $0x0F7F, 8(%%r9, %%rbx, 1)"); // round toward zero
+				emit("fldcw 8(%%r9, %%rbx, 1)");
+				emit("fistpl (%%r9, %%rbx, 1)");
+				emit("fldcw 4(%%r9, %%rbx, 1)");
 #else
-				emit("movss 0(%%r9, %%rsi, 1), %%xmm0");
+				emit("movss (%%r9, %%rbx, 1), %%xmm0");
 				emit("cvttss2si %%xmm0, %%eax");
-				emit("movl %%eax, 0(%%r9, %%rsi, 1)");
+				emit("movl %%eax, (%%r9, %%rbx, 1)");
 #endif
 				break;
 			default:
@@ -1051,10 +1033,10 @@
 	int		programCounter;
 	int		programStack;
 	int		stackOnEntry;
-	int		opStackRet;
+	long		opStackRet;
 	byte	*image;
 	void	*entryPoint;
-	void	*opStack;
+	int	*opStack;
 	int stack[OPSTACK_SIZE + 3] = { 0xDEADBEEF };
 
 	currentVM = vm;
@@ -1098,7 +1080,7 @@
 	opStack = PADP(stack, 4);
 
 	__asm__ __volatile__ (
-		"	movl $0,%%esi		\r\n" \
+		"	movq $-0x80,%%rbx	\r\n" \
 		"	movl %5,%%edi		\r\n" \
 		"	movq %4,%%r8		\r\n" \
 		"	movq %3,%%r9		\r\n" \
@@ -1107,15 +1089,14 @@
 		"	callq *%%r10		\r\n" \
 		"       addq $24, %%rsp         \r\n" \
 		"	movl %%edi, %0		\r\n" \
-		"	movl %%esi, %1		\r\n" \
-		: "=m" (programStack), "=m" (opStackRet)
-		: "m" (entryPoint), "m" (opStack), "m" (vm->dataBase), "m" (programStack)
+		"	movq %%rbx, %1		\r\n" \
+		: "=g" (programStack), "=g" (opStackRet)
+		: "g" (entryPoint), "g" (((intptr_t ) opStack) + OPSTACK_SIZE / 2), "g" (vm->dataBase), "g" (programStack)
 		: "%rsi", "%rdi", "%rax", "%rbx", "%rcx", "%rdx", "%r8", "%r9", "%r10", "%r15", "%xmm0"
 	);
+	if(opStackRet != -(OPSTACK_SIZE / 2) + 4 || *opStack != 0xDEADBEEF)
+		Com_Error(ERR_DROP, "opStack corrupted in compiled code (offset %ld)", opStackRet);
 
-	if(opStackRet != 4)
-		Com_Error(ERR_DROP, "opStack corrupted in compiled code (offset %d)", opStackRet);
-
 	if ( programStack != stackOnEntry - 48 ) {
 		Com_Error( ERR_DROP, "programStack corrupted in compiled code" );
 	}

Modified: trunk/code/qcommon/vm_x86_64_assembler.c
===================================================================
--- trunk/code/qcommon/vm_x86_64_assembler.c	2011-05-15 14:58:56 UTC (rev 1991)
+++ trunk/code/qcommon/vm_x86_64_assembler.c	2011-05-16 17:55:07 UTC (rev 1992)
@@ -158,6 +158,7 @@
 	R_R15 =  0x0F  | R_64,
 	R_AL  =  R_EAX | R_8,
 	R_AX  =  R_EAX | R_16,
+	R_BL  =  R_EBX | R_8,
 	R_CL  =  R_ECX | R_8,
 	R_XMM0 = 0x00  | R_XMM,
 	R_MGP =  0x0F, // mask for general purpose registers
@@ -213,6 +214,32 @@
 	u8 rcode;  // opcode for reg/mem
 } opparam_t;
 
+static opparam_t params_add = { subcode: 0, rmcode: 0x01, };
+static opparam_t params_or = { subcode: 1, rmcode: 0x09, };
+static opparam_t params_and = { subcode: 4, rmcode: 0x21, };
+static opparam_t params_sub = { subcode: 5, rmcode: 0x29, };
+static opparam_t params_xor = { subcode: 6, rmcode: 0x31, };
+static opparam_t params_cmp = { subcode: 7, rmcode: 0x39, mrcode: 0x3b, };
+static opparam_t params_dec = { subcode: 1, rcode: 0xff, rcode8: 0xfe, };
+static opparam_t params_sar = { subcode: 7, rcode: 0xd3, rcode8: 0xd2, };
+static opparam_t params_shl = { subcode: 4, rcode: 0xd3, rcode8: 0xd2, };
+static opparam_t params_shr = { subcode: 5, rcode: 0xd3, rcode8: 0xd2, };
+static opparam_t params_idiv = { subcode: 7, rcode: 0xf7, rcode8: 0xf6, };
+static opparam_t params_div = { subcode: 6, rcode: 0xf7, rcode8: 0xf6, };
+static opparam_t params_imul = { subcode: 5, rcode: 0xf7, rcode8: 0xf6, };
+static opparam_t params_mul = { subcode: 4, rcode: 0xf7, rcode8: 0xf6, };
+static opparam_t params_neg = { subcode: 3, rcode: 0xf7, rcode8: 0xf6, };
+static opparam_t params_not = { subcode: 2, rcode: 0xf7, rcode8: 0xf6, };
+
+static opparam_t params_cvtsi2ss = { xmmprefix: 0xf3, rmcode: 0x2a };
+static opparam_t params_cvttss2si = { xmmprefix: 0xf3, rmcode: 0x2c };
+static opparam_t params_addss = { xmmprefix: 0xf3, mrcode: 0x58 };
+static opparam_t params_divss = { xmmprefix: 0xf3, mrcode: 0x5e };
+static opparam_t params_movss = { xmmprefix: 0xf3, mrcode: 0x10, rmcode: 0x11 };
+static opparam_t params_mulss = { xmmprefix: 0xf3, mrcode: 0x59 };
+static opparam_t params_subss = { xmmprefix: 0xf3, mrcode: 0x5c };
+static opparam_t params_ucomiss = { mrcode: 0x2e };
+
 /* ************************* */
 
 static unsigned hashkey(const char *string, unsigned len) {
@@ -314,9 +341,9 @@
 
 /* ************************* */
 
-static inline int iss8(u64 v)
+static inline int iss8(int64_t v)
 {
-	return (llabs(v) <= 0x80); //llabs instead of labs required for __WIN64
+	return (v >= -0x80 && v <= 0x7f);
 }
 
 static inline int isu8(u64 v)
@@ -324,9 +351,9 @@
 	return (v <= 0xff);
 }
 
-static inline int iss16(u64 v)
+static inline int iss16(int64_t v)
 {
-	return (llabs(v) <= 0x8000);
+	return (v >= -0x8000 && v <= 0x7fff);
 }
 
 static inline int isu16(u64 v)
@@ -334,9 +361,9 @@
 	return (v <= 0xffff);
 }
 
-static inline int iss32(u64 v)
+static inline int iss32(int64_t v)
 {
-	return (llabs(v) <= 0x80000000);
+	return (v >= -0x80000000L && v <= 0x7fffffff);
 }
 
 static inline int isu32(u64 v)
@@ -595,7 +622,7 @@
 		
 		if(arg2.v.reg & R_8)
 		{
-			if(!isu8(arg1.v.imm))
+			if(!iss8(arg1.v.imm))
 				crap("value too large for 8bit register");
 
 			op = 0xb0;
@@ -711,19 +738,23 @@
 		}
 
 		compute_rexmodrmsib(&rex, &modrm, &sib, &arg1, &arg2);
-
 		modrm |= params->subcode << 3;
 
 		if(rex) emit1(rex);
-#if 0
-		if(isu8(arg1.v.imm))
+
+		if(arg2.v.reg & R_8)
 		{
+			emit1(0x80); // sub reg8/mem8, imm8
+			emit1(modrm);
+			emit1(arg1.v.imm & 0xFF);
+		}
+		else if(iss8(arg1.v.imm))
+		{
 			emit1(0x83); // sub reg/mem, imm8
 			emit1(modrm);
-			emit1(arg1.v.imm&0xFF);
+			emit1(arg1.v.imm & 0xFF);
 		}
 		else
-#endif
 		{
 			emit1(0x81); // sub reg/mem, imm32
 			emit1(modrm);
@@ -893,42 +924,19 @@
 		CRAP_INVALID_ARGS;
 }
 
-static opparam_t params_add = { subcode: 0, rmcode: 0x01, };
-static opparam_t params_or = { subcode: 1, rmcode: 0x09, };
-static opparam_t params_and = { subcode: 4, rmcode: 0x21, };
-static opparam_t params_sub = { subcode: 5, rmcode: 0x29, };
-static opparam_t params_xor = { subcode: 6, rmcode: 0x31, };
-static opparam_t params_cmp = { subcode: 7, rmcode: 0x39, mrcode: 0x3b, };
-static opparam_t params_dec = { subcode: 1, rcode: 0xff, rcode8: 0xfe, };
-static opparam_t params_sar = { subcode: 7, rcode: 0xd3, rcode8: 0xd2, };
-static opparam_t params_shl = { subcode: 4, rcode: 0xd3, rcode8: 0xd2, };
-static opparam_t params_shr = { subcode: 5, rcode: 0xd3, rcode8: 0xd2, };
-static opparam_t params_idiv = { subcode: 7, rcode: 0xf7, rcode8: 0xf6, };
-static opparam_t params_div = { subcode: 6, rcode: 0xf7, rcode8: 0xf6, };
-static opparam_t params_imul = { subcode: 5, rcode: 0xf7, rcode8: 0xf6, };
-static opparam_t params_mul = { subcode: 4, rcode: 0xf7, rcode8: 0xf6, };
-static opparam_t params_neg = { subcode: 3, rcode: 0xf7, rcode8: 0xf6, };
-static opparam_t params_not = { subcode: 2, rcode: 0xf7, rcode8: 0xf6, };
-
-static opparam_t params_cvtsi2ss = { xmmprefix: 0xf3, rmcode: 0x2a };
-static opparam_t params_cvttss2si = { xmmprefix: 0xf3, rmcode: 0x2c };
-static opparam_t params_addss = { xmmprefix: 0xf3, mrcode: 0x58 };
-static opparam_t params_divss = { xmmprefix: 0xf3, mrcode: 0x5e };
-static opparam_t params_movss = { xmmprefix: 0xf3, mrcode: 0x10, rmcode: 0x11 };
-static opparam_t params_mulss = { xmmprefix: 0xf3, mrcode: 0x59 };
-static opparam_t params_subss = { xmmprefix: 0xf3, mrcode: 0x5c };
-static opparam_t params_ucomiss = { mrcode: 0x2e };
-
 static int ops_sorted = 0;
 static op_t ops[] = {
+	{ "addb", emit_subaddand, &params_add },
 	{ "addl", emit_subaddand, &params_add },
 	{ "addq", emit_subaddand, &params_add },
 	{ "addss", emit_twobyte, &params_addss },
+	{ "andb", emit_subaddand, &params_and },
 	{ "andl", emit_subaddand, &params_and },
 	{ "andq", emit_subaddand, &params_and },
 	{ "callq", emit_call, NULL },
 	{ "cbw", emit_opsingle16, (void*)0x98 },
 	{ "cdq", emit_opsingle, (void*)0x99 },
+	{ "cmpb", emit_subaddand, &params_cmp },
 	{ "cmpl", emit_subaddand, &params_cmp },
 	{ "cmpq", emit_subaddand, &params_cmp },
 	{ "cvtsi2ss", emit_twobyte, &params_cvtsi2ss },
@@ -974,18 +982,21 @@
 	{ "nop", emit_opsingle, (void*)0x90 },
 	{ "notl", emit_op_rm, &params_not },
 	{ "notq", emit_op_rm, &params_not },
-	{ "or",   emit_subaddand, &params_or },
+	{ "orb",   emit_subaddand, &params_or },
 	{ "orl",  emit_subaddand, &params_or },
+	{ "orq",  emit_subaddand, &params_or },
 	{ "pop", emit_opreg, (void*)0x58 },
 	{ "push", emit_opreg, (void*)0x50 },
 	{ "ret", emit_opsingle, (void*)0xc3 },
 	{ "sarl", emit_op_rm_cl, &params_sar },
 	{ "shl", emit_op_rm_cl, &params_shl },
 	{ "shrl", emit_op_rm_cl, &params_shr },
+	{ "subb", emit_subaddand, &params_sub },
 	{ "subl", emit_subaddand, &params_sub },
 	{ "subq", emit_subaddand, &params_sub },
 	{ "subss", emit_twobyte, &params_subss },
 	{ "ucomiss", emit_twobyte, &params_ucomiss },
+	{ "xorb",  emit_subaddand, &params_xor },
 	{ "xorl",  emit_subaddand, &params_xor },
 	{ "xorq",  emit_subaddand, &params_xor },
 	{ NULL, NULL, NULL }
@@ -1010,27 +1021,24 @@
 	}
 
 #else
-	unsigned m, t, b;
+	unsigned int m, t, b;
 	int r;
 	t = ARRAY_LEN(ops)-1;
-	b = 0;
 
-	while(b <= t)
+	r = m = -1;
+
+	do
 	{
-		m = ((t-b)>>1) + b;
-		if((r = strcmp(ops[m].mnemonic, n)) == 0)
-		{
-			return &ops[m];
-		}
-		else if(r < 0)
-		{
+		if(r < 0)
 			b = m + 1;
-		}
 		else
-		{
 			t = m - 1;
-		}
-	}
+
+		m = ((t - b) >> 1) + b;
+
+		if((r = strcmp(ops[m].mnemonic, n)) == 0)
+			return &ops[m];
+	} while(b <= t && t);
 #endif
 
 	return NULL;
@@ -1047,6 +1055,10 @@
 	{
 		return R_AX;
 	}
+	if(*s == 'b' && s[1] == 'l' && !s[2])
+	{
+		return R_BL;
+	}
 	if(*s == 'c' && s[1] == 'l' && !s[2])
 	{
 		return R_CL;



More information about the quake3-commits mailing list