[iortcw] 28/89: All: Allow unaligned load/store in QVM interpreter/x86 compiler

Simon McVittie smcv at debian.org
Fri Sep 8 10:44:20 UTC 2017


This is an automated email from the git hooks/post-receive script.

smcv pushed a commit to tag 1.51b
in repository iortcw.

commit d1144d2200e8f73ba7c89bd5dbd8d347b532479f
Author: ec- <tweels at gmail.com>
Date:   Wed Mar 15 11:42:58 2017 +0200

    All: Allow unaligned load/store in QVM interpreter/x86 compiler
---
 MP/code/qcommon/vm.c             |  8 +++++---
 MP/code/qcommon/vm_interpreted.c | 14 +++++++-------
 MP/code/qcommon/vm_local.h       |  1 +
 MP/code/qcommon/vm_x86.c         |  8 ++++----
 SP/code/qcommon/vm.c             |  8 +++++---
 SP/code/qcommon/vm_interpreted.c | 14 +++++++-------
 SP/code/qcommon/vm_local.h       |  1 +
 SP/code/qcommon/vm_x86.c         |  8 ++++----
 8 files changed, 34 insertions(+), 28 deletions(-)

diff --git a/MP/code/qcommon/vm.c b/MP/code/qcommon/vm.c
index f3b04a0..e37cce9 100644
--- a/MP/code/qcommon/vm.c
+++ b/MP/code/qcommon/vm.c
@@ -457,13 +457,15 @@ vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc, qboolean unpure)
 	if(alloc)
 	{
 		// allocate zero filled space for initialized and uninitialized data
-		vm->dataBase = Hunk_Alloc(dataLength, h_high);
+		// leave some space beyond data mask so we can secure all mask operations
+		vm->dataAlloc = dataLength + 4;
+		vm->dataBase = Hunk_Alloc(vm->dataAlloc, h_high);
 		vm->dataMask = dataLength - 1;
 	}
 	else
 	{
 		// clear the data, but make sure we're not clearing more than allocated
-		if(vm->dataMask + 1 != dataLength)
+		if(vm->dataAlloc != dataLength + 4)
 		{
 			VM_Free(vm);
 			FS_FreeFile(header.v);
@@ -473,7 +475,7 @@ vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc, qboolean unpure)
 			return NULL;
 		}
 		
-		Com_Memset(vm->dataBase, 0, dataLength);
+		Com_Memset(vm->dataBase, 0, vm->dataAlloc);
 	}
 
 	// copy the intialized data
diff --git a/MP/code/qcommon/vm_interpreted.c b/MP/code/qcommon/vm_interpreted.c
index f630d05..cb86a08 100644
--- a/MP/code/qcommon/vm_interpreted.c
+++ b/MP/code/qcommon/vm_interpreted.c
@@ -436,31 +436,31 @@ nextInstruction2:
 				return 0;
 			}
 #endif
-			r0 = opStack[opStackOfs] = *(int *) &image[r0 & dataMask & ~3 ];
+			r0 = opStack[opStackOfs] = *(int *) &image[ r0 & dataMask ];
 			goto nextInstruction2;
 		case OP_LOAD2:
-			r0 = opStack[opStackOfs] = *(unsigned short *)&image[ r0&dataMask&~1 ];
+			r0 = opStack[opStackOfs] = *(unsigned short *)&image[ r0 & dataMask ];
 			goto nextInstruction2;
 		case OP_LOAD1:
-			r0 = opStack[opStackOfs] = image[ r0&dataMask ];
+			r0 = opStack[opStackOfs] = image[ r0 & dataMask ];
 			goto nextInstruction2;
 
 		case OP_STORE4:
-			*(int *)&image[ r1&(dataMask & ~3) ] = r0;
+			*(int *)&image[ r1 & dataMask ] = r0;
 			opStackOfs -= 2;
 			goto nextInstruction;
 		case OP_STORE2:
-			*(short *)&image[ r1&(dataMask & ~1) ] = r0;
+			*(short *)&image[ r1 & dataMask ] = r0;
 			opStackOfs -= 2;
 			goto nextInstruction;
 		case OP_STORE1:
-			image[ r1&dataMask ] = r0;
+			image[ r1 & dataMask ] = r0;
 			opStackOfs -= 2;
 			goto nextInstruction;
 
 		case OP_ARG:
 			// single byte offset from programStack
-			*(int *)&image[ (codeImage[programCounter] + programStack)&dataMask&~3 ] = r0;
+			*(int *)&image[ (codeImage[programCounter] + programStack) & dataMask ] = r0;
 			opStackOfs--;
 			programCounter += 1;
 			goto nextInstruction;
diff --git a/MP/code/qcommon/vm_local.h b/MP/code/qcommon/vm_local.h
index d1b60c5..4e9dab9 100644
--- a/MP/code/qcommon/vm_local.h
+++ b/MP/code/qcommon/vm_local.h
@@ -170,6 +170,7 @@ struct vm_s {
 
 	byte		*dataBase;
 	int			dataMask;
+	int			dataAlloc;			// actually allocated
 
 	int			heapLength;			// length of QVMs data
 	int			heapAlloc;			// QVM's current allocate point
diff --git a/MP/code/qcommon/vm_x86.c b/MP/code/qcommon/vm_x86.c
index 9ee2679..2435a6e 100644
--- a/MP/code/qcommon/vm_x86.c
+++ b/MP/code/qcommon/vm_x86.c
@@ -790,7 +790,7 @@ qboolean ConstOptimize(vm_t *vm, int callProcOfsSyscall)
 		return qtrue;
 
 	case OP_STORE4:
-		EmitMovEAXStack(vm, (vm->dataMask & ~3));
+		EmitMovEAXStack(vm, vm->dataMask);
 #if idx64
 		EmitRexString(0x41, "C7 04 01");		// mov dword ptr [r9 + eax], 0x12345678
 		Emit4(Constant4());
@@ -805,7 +805,7 @@ qboolean ConstOptimize(vm_t *vm, int callProcOfsSyscall)
 		return qtrue;
 
 	case OP_STORE2:
-		EmitMovEAXStack(vm, (vm->dataMask & ~1));
+		EmitMovEAXStack(vm, vm->dataMask);
 #if idx64
 		Emit1(0x66);					// mov word ptr [r9 + eax], 0x1234
 		EmitRexString(0x41, "C7 04 01");
@@ -1377,7 +1377,7 @@ void VM_Compile(vm_t *vm, vmHeader_t *header)
 		case OP_STORE4:
 			EmitMovEAXStack(vm, 0);	
 			EmitString("8B 54 9F FC");			// mov edx, dword ptr -4[edi + ebx * 4]
-			MASK_REG("E2", vm->dataMask & ~3);		// and edx, 0x12345678
+			MASK_REG("E2", vm->dataMask);		// and edx, 0x12345678
 #if idx64
 			EmitRexString(0x41, "89 04 11");		// mov dword ptr [r9 + edx], eax
 #else
@@ -1389,7 +1389,7 @@ void VM_Compile(vm_t *vm, vmHeader_t *header)
 		case OP_STORE2:
 			EmitMovEAXStack(vm, 0);	
 			EmitString("8B 54 9F FC");			// mov edx, dword ptr -4[edi + ebx * 4]
-			MASK_REG("E2", vm->dataMask & ~1);		// and edx, 0x12345678
+			MASK_REG("E2", vm->dataMask);		// and edx, 0x12345678
 #if idx64
 			Emit1(0x66);					// mov word ptr [r9 + edx], eax
 			EmitRexString(0x41, "89 04 11");
diff --git a/SP/code/qcommon/vm.c b/SP/code/qcommon/vm.c
index 6b9d0e2..50b0fa4 100644
--- a/SP/code/qcommon/vm.c
+++ b/SP/code/qcommon/vm.c
@@ -460,13 +460,15 @@ vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc, qboolean unpure)
 	if(alloc)
 	{
 		// allocate zero filled space for initialized and uninitialized data
-		vm->dataBase = Hunk_Alloc(dataLength, h_high);
+		// leave some space beyond data mask so we can secure all mask operations
+		vm->dataAlloc = dataLength + 4;
+		vm->dataBase = Hunk_Alloc(vm->dataAlloc, h_high);
 		vm->dataMask = dataLength - 1;
 	}
 	else
 	{
 		// clear the data, but make sure we're not clearing more than allocated
-		if(vm->dataMask + 1 != dataLength)
+		if(vm->dataAlloc != dataLength + 4)
 		{
 			VM_Free(vm);
 			FS_FreeFile(header.v);
@@ -476,7 +478,7 @@ vmHeader_t *VM_LoadQVM( vm_t *vm, qboolean alloc, qboolean unpure)
 			return NULL;
 		}
 		
-		Com_Memset(vm->dataBase, 0, dataLength);
+		Com_Memset(vm->dataBase, 0, vm->dataAlloc);
 	}
 
 	// copy the intialized data
diff --git a/SP/code/qcommon/vm_interpreted.c b/SP/code/qcommon/vm_interpreted.c
index f630d05..cb86a08 100644
--- a/SP/code/qcommon/vm_interpreted.c
+++ b/SP/code/qcommon/vm_interpreted.c
@@ -436,31 +436,31 @@ nextInstruction2:
 				return 0;
 			}
 #endif
-			r0 = opStack[opStackOfs] = *(int *) &image[r0 & dataMask & ~3 ];
+			r0 = opStack[opStackOfs] = *(int *) &image[ r0 & dataMask ];
 			goto nextInstruction2;
 		case OP_LOAD2:
-			r0 = opStack[opStackOfs] = *(unsigned short *)&image[ r0&dataMask&~1 ];
+			r0 = opStack[opStackOfs] = *(unsigned short *)&image[ r0 & dataMask ];
 			goto nextInstruction2;
 		case OP_LOAD1:
-			r0 = opStack[opStackOfs] = image[ r0&dataMask ];
+			r0 = opStack[opStackOfs] = image[ r0 & dataMask ];
 			goto nextInstruction2;
 
 		case OP_STORE4:
-			*(int *)&image[ r1&(dataMask & ~3) ] = r0;
+			*(int *)&image[ r1 & dataMask ] = r0;
 			opStackOfs -= 2;
 			goto nextInstruction;
 		case OP_STORE2:
-			*(short *)&image[ r1&(dataMask & ~1) ] = r0;
+			*(short *)&image[ r1 & dataMask ] = r0;
 			opStackOfs -= 2;
 			goto nextInstruction;
 		case OP_STORE1:
-			image[ r1&dataMask ] = r0;
+			image[ r1 & dataMask ] = r0;
 			opStackOfs -= 2;
 			goto nextInstruction;
 
 		case OP_ARG:
 			// single byte offset from programStack
-			*(int *)&image[ (codeImage[programCounter] + programStack)&dataMask&~3 ] = r0;
+			*(int *)&image[ (codeImage[programCounter] + programStack) & dataMask ] = r0;
 			opStackOfs--;
 			programCounter += 1;
 			goto nextInstruction;
diff --git a/SP/code/qcommon/vm_local.h b/SP/code/qcommon/vm_local.h
index d1b60c5..4e9dab9 100644
--- a/SP/code/qcommon/vm_local.h
+++ b/SP/code/qcommon/vm_local.h
@@ -170,6 +170,7 @@ struct vm_s {
 
 	byte		*dataBase;
 	int			dataMask;
+	int			dataAlloc;			// actually allocated
 
 	int			heapLength;			// length of QVMs data
 	int			heapAlloc;			// QVM's current allocate point
diff --git a/SP/code/qcommon/vm_x86.c b/SP/code/qcommon/vm_x86.c
index 9ee2679..2435a6e 100644
--- a/SP/code/qcommon/vm_x86.c
+++ b/SP/code/qcommon/vm_x86.c
@@ -790,7 +790,7 @@ qboolean ConstOptimize(vm_t *vm, int callProcOfsSyscall)
 		return qtrue;
 
 	case OP_STORE4:
-		EmitMovEAXStack(vm, (vm->dataMask & ~3));
+		EmitMovEAXStack(vm, vm->dataMask);
 #if idx64
 		EmitRexString(0x41, "C7 04 01");		// mov dword ptr [r9 + eax], 0x12345678
 		Emit4(Constant4());
@@ -805,7 +805,7 @@ qboolean ConstOptimize(vm_t *vm, int callProcOfsSyscall)
 		return qtrue;
 
 	case OP_STORE2:
-		EmitMovEAXStack(vm, (vm->dataMask & ~1));
+		EmitMovEAXStack(vm, vm->dataMask);
 #if idx64
 		Emit1(0x66);					// mov word ptr [r9 + eax], 0x1234
 		EmitRexString(0x41, "C7 04 01");
@@ -1377,7 +1377,7 @@ void VM_Compile(vm_t *vm, vmHeader_t *header)
 		case OP_STORE4:
 			EmitMovEAXStack(vm, 0);	
 			EmitString("8B 54 9F FC");			// mov edx, dword ptr -4[edi + ebx * 4]
-			MASK_REG("E2", vm->dataMask & ~3);		// and edx, 0x12345678
+			MASK_REG("E2", vm->dataMask);		// and edx, 0x12345678
 #if idx64
 			EmitRexString(0x41, "89 04 11");		// mov dword ptr [r9 + edx], eax
 #else
@@ -1389,7 +1389,7 @@ void VM_Compile(vm_t *vm, vmHeader_t *header)
 		case OP_STORE2:
 			EmitMovEAXStack(vm, 0);	
 			EmitString("8B 54 9F FC");			// mov edx, dword ptr -4[edi + ebx * 4]
-			MASK_REG("E2", vm->dataMask & ~1);		// and edx, 0x12345678
+			MASK_REG("E2", vm->dataMask);		// and edx, 0x12345678
 #if idx64
 			Emit1(0x66);					// mov word ptr [r9 + edx], eax
 			EmitRexString(0x41, "89 04 11");

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/iortcw.git



More information about the Pkg-games-commits mailing list