Blob Blame History Raw
diff -up quake3-1.36/code/qcommon/vm.c~ quake3-1.36/code/qcommon/vm.c
--- quake3-1.36/code/qcommon/vm.c~	2011-07-28 10:55:29.000000000 +0200
+++ quake3-1.36/code/qcommon/vm.c	2015-12-04 20:06:27.438606467 +0100
@@ -35,6 +35,7 @@ and one exported function: Perform
 
 #include "vm_local.h"
 
+static cvar_t *qvm_unaligned;
 
 vm_t	*currentVM = NULL;
 vm_t	*lastVM    = NULL;
@@ -74,6 +75,8 @@ void VM_Init( void ) {
 	Cvar_Get( "vm_game", "2", CVAR_ARCHIVE );	// !@# SHIP WITH SET TO 2
 	Cvar_Get( "vm_ui", "2", CVAR_ARCHIVE );		// !@# SHIP WITH SET TO 2
 
+	qvm_unaligned = Cvar_Get ("qvm_unaligned", "0", 0);
+
 	Cmd_AddCommand ("vmprofile", VM_VmProfile_f );
 	Cmd_AddCommand ("vminfo", VM_VmInfo_f );
 
@@ -616,6 +619,12 @@ vm_t *VM_Create( const char *module, int
 
 	vm->compiled = qfalse;
 
+	if ( qvm_unaligned->integer ) {
+		vm->unaligned = qtrue;
+		/* Only the interpreter supports unaligned mode */
+		interpret = VMI_BYTECODE;
+	}
+
 #ifdef NO_VM_COMPILED
 	if(interpret >= VMI_COMPILED) {
 		Com_Printf("Architecture doesn't have a bytecode compiler, using interpreter\n");
diff -up quake3-1.36/code/qcommon/vm_interpreted.c~ quake3-1.36/code/qcommon/vm_interpreted.c
--- quake3-1.36/code/qcommon/vm_interpreted.c~	2011-07-28 10:55:29.000000000 +0200
+++ quake3-1.36/code/qcommon/vm_interpreted.c	2015-12-04 20:05:10.330624764 +0100
@@ -443,21 +443,37 @@ nextInstruction2:
 				return 0;
 			}
 #endif
-			r0 = opStack[opStackOfs] = *(int *) &image[r0 & dataMask & ~3 ];
+			if (vm->unaligned) {
+				r0 = opStack[opStackOfs] = *(int *) &image[r0 & dataMask ];
+			} else {
+				r0 = opStack[opStackOfs] = *(int *) &image[r0 & dataMask & ~3 ];
+			}
 			goto nextInstruction2;
 		case OP_LOAD2:
-			r0 = opStack[opStackOfs] = *(unsigned short *)&image[ r0&dataMask&~1 ];
+			if (vm->unaligned) {
+				r0 = opStack[opStackOfs] = *(unsigned short *)&image[ r0&dataMask ];
+			} else {
+				r0 = opStack[opStackOfs] = *(unsigned short *)&image[ r0&dataMask&~1 ];
+			}
 			goto nextInstruction2;
 		case OP_LOAD1:
 			r0 = opStack[opStackOfs] = image[ r0&dataMask ];
 			goto nextInstruction2;
 
 		case OP_STORE4:
-			*(int *)&image[ r1&(dataMask & ~3) ] = r0;
+			if (vm->unaligned) {
+				*(int *)&image[ r1&(dataMask) ] = r0;
+			} else {
+				*(int *)&image[ r1&(dataMask & ~3) ] = r0;
+			}
 			opStackOfs -= 2;
 			goto nextInstruction;
 		case OP_STORE2:
-			*(short *)&image[ r1&(dataMask & ~1) ] = r0;
+			if (vm->unaligned) {
+				*(short *)&image[ r1&(dataMask) ] = r0;
+			} else {
+				*(short *)&image[ r1&(dataMask & ~1) ] = r0;
+			}
 			opStackOfs -= 2;
 			goto nextInstruction;
 		case OP_STORE1:
@@ -467,7 +483,11 @@ nextInstruction2:
 
 		case OP_ARG:
 			// single byte offset from programStack
-			*(int *)&image[ (codeImage[programCounter] + programStack)&dataMask&~3 ] = r0;
+			if (vm->unaligned) {
+				*(int *)&image[ (codeImage[programCounter] + programStack)&dataMask ] = r0;
+			} else {
+				*(int *)&image[ (codeImage[programCounter] + programStack)&dataMask&~3 ] = r0;
+			}
 			opStackOfs--;
 			programCounter += 1;
 			goto nextInstruction;
diff -up quake3-1.36/code/qcommon/vm_local.h~ quake3-1.36/code/qcommon/vm_local.h
--- quake3-1.36/code/qcommon/vm_local.h~	2011-07-28 10:55:29.000000000 +0200
+++ quake3-1.36/code/qcommon/vm_local.h	2015-12-04 20:06:44.798152081 +0100
@@ -174,6 +174,8 @@ struct vm_s {
 
 	byte		*jumpTableTargets;
 	int			numJumpTableTargets;
+
+	qboolean		unaligned;		// If set do not align loads and stores
 };