Index: configure.ac
===================================================================
RCS file: /cvsroot/pcsx-df/pcsx-df/configure.ac,v
retrieving revision 1.8
diff -a -u -r1.8 configure.ac
--- configure.ac	29 Nov 2008 06:29:36 -0000	1.8
+++ configure.ac	30 Nov 2008 14:58:31 -0000
@@ -9,6 +9,7 @@
 
 AC_PROG_CC
 AM_PROG_CC_C_O
+AC_PROG_CXX
 AC_PROG_RANLIB
 AC_PROG_LIBTOOL
 AC_PROG_INSTALL
@@ -75,7 +76,6 @@
 DFBINIMAGE=""
 
 if test "$BUILD_DFBINIMAGE" = "yes"; then
-	AC_PROG_CXX
 
 	AC_CHECK_PROG(FLTKCONFIG, fltk-config, fltk-config)
 	fltk_cxxflags=`fltk-config --cxxflags`
Index: gui/Makefile.am
===================================================================
RCS file: /cvsroot/pcsx-df/pcsx-df/gui/Makefile.am,v
retrieving revision 1.5
diff -a -u -r1.5 Makefile.am
--- gui/Makefile.am	30 Nov 2008 04:20:19 -0000	1.5
+++ gui/Makefile.am	30 Nov 2008 14:58:31 -0000
@@ -18,4 +18,4 @@
 	hdebug.c
 	
 pcsx_LDADD = \
-	$(GTK2_LIBS) $(GLADE2_LIBS) ../libpcsxcore/libpcsxcore.la
+	$(GTK2_LIBS) $(GLADE2_LIBS) ../libpcsxcore/libpcsxcore.la -lpthread
Index: libpcsxcore/psxbios.c
===================================================================
RCS file: /cvsroot/pcsx-df/pcsx-df/libpcsxcore/psxbios.c,v
retrieving revision 1.7
diff -a -u -r1.7 psxbios.c
--- libpcsxcore/psxbios.c	9 Mar 2008 12:01:37 -0000	1.7
+++ libpcsxcore/psxbios.c	30 Nov 2008 14:58:33 -0000
@@ -511,7 +511,7 @@
 		}
 
 		// next chunk
-		chunk = (u32*)((u32)chunk + csize + 4);
+		chunk = (u32*)((uptr)chunk + csize + 4);
 	}
 	// if neccessary free memory on end of heap
 	if(colflag == 1) *newchunk = SWAP32(dsize | 1);
@@ -527,7 +527,7 @@
 
 	// search an unused chunk that is big enough until the end of the heap
 	while((dsize>csize || cstat==0) && chunk<heap_end ) {
-		chunk = (u32*)((u32)chunk + csize + 4);
+		chunk = (u32*)((uptr)chunk + csize + 4);
 		csize = ((u32)*chunk) & 0xfffffffc;
 		cstat = ((u32)*chunk) & 1;
 	}
@@ -543,7 +543,7 @@
 	else {
 		// split free chunk
 		*chunk = SWAP32(dsize);
-		newchunk = (u32*)((u32)chunk + dsize + 4);
+		newchunk = (u32*)((uptr)chunk + dsize + 4);
 		*newchunk = SWAP32((csize - dsize - 4) & 0xfffffffc | 1);
 	}
 
@@ -606,10 +606,10 @@
 	size &= 0xfffffffc;
 	
 	heap_addr = (u32*)Ra0;
-	heap_end = (u32*)((u32)heap_addr + size);
+	heap_end = (u32*)((uptr)heap_addr + size);
 	*heap_addr = SWAP32(size | 1);
 
-	SysPrintf("InitHeap %lx,%lx : %lx %lx\n",a0,a1, (u32)heap_addr-(u32)psxM, size);
+	SysPrintf("InitHeap %lx,%lx : %lx %lx\n",a0,a1, (uptr)heap_addr-(uptr)psxM, size);
 
 	pc0 = ra;
 }
Index: libpcsxcore/psxmem.c
===================================================================
RCS file: /cvsroot/pcsx-df/pcsx-df/libpcsxcore/psxmem.c,v
retrieving revision 1.2
diff -a -u -r1.2 psxmem.c
--- libpcsxcore/psxmem.c	29 Dec 2007 22:18:00 -0000	1.2
+++ libpcsxcore/psxmem.c	30 Nov 2008 14:58:33 -0000
@@ -53,15 +53,8 @@
 	memset(psxMemRLUT, 0, 0x10000 * sizeof(void*));
 	memset(psxMemWLUT, 0, 0x10000 * sizeof(void*));
 
-#ifdef __x86_64__
-	//Note: this has to be synced with the locations chosen in ix86_64/iR3000A-64.c
-	//Picked a spot somewhat close to a random function psxMemWrite32
-	psxM = mmap(&psxMemWrite32 - 0xc000000, 0x00220000,
-		PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-#else
 	psxM = mmap(0, 0x00220000,
 		PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-#endif
 	psxP = &psxM[0x200000];
 	psxH = &psxM[0x210000];
 	psxR = (char*)malloc(0x00080000);
Index: libpcsxcore/ix86_64/iR3000A-64.c
===================================================================
RCS file: /cvsroot/pcsx-df/pcsx-df/libpcsxcore/ix86_64/iR3000A-64.c,v
retrieving revision 1.2
diff -a -u -r1.2 iR3000A-64.c
--- libpcsxcore/ix86_64/iR3000A-64.c	29 Dec 2007 22:18:01 -0000	1.2
+++ libpcsxcore/ix86_64/iR3000A-64.c	30 Nov 2008 14:58:34 -0000
@@ -26,26 +26,24 @@
 #include "../r3000a.h"
 #include "../psxhle.h"
 
-//For mmap
 #include <sys/mman.h>
 
-uptr** psxRecLUT;
+uptr* psxRecLUT;
+
+#define PTRMULT (sizeof(uptr)/sizeof(u32))
 
 #undef PC_REC
 #undef PC_REC8
 #undef PC_REC16
 #undef PC_REC32
-#define PC_REC(x)	(psxRecLUT[x >> 16] + (x & 0xffff))
-#define PC_REC8(x)	(*(u8 *)PC_REC(x))
-#define PC_REC16(x) (*(u16*)PC_REC(x))
-#define PC_REC32(x) (*(u32*)PC_REC(x))
+#define PC_REC(x)	(psxRecLUT[(x) >> 16] + PTRMULT*((x) & 0xffff))
+#define PC_RECP(x) (*(uptr*)PC_REC(x))
 
-#define RECMEM_SIZE		(32*1024*1024)
-#define STACKSIZE		0x18
+#define RECMEM_SIZE		(PTRMULT*8*1024*1024)
 
 static char *recMem;	/* the recompiled blocks will be here */
-static uptr *recRAM;	/* and the ptr to the blocks here */
-static uptr *recROM;	/* and here */
+static char *recRAM;	/* and the ptr to the blocks here */
+static char *recROM;	/* and here */
 
 static u32 pc;			/* recompiler pc */
 static u32 pcold;		/* recompiler oldpc */
@@ -54,7 +52,6 @@
 static u32 target;		/* branch target */
 static u32 resp;
 
-
 typedef struct {
 	int state;
 	u32 k;
@@ -78,6 +75,15 @@
 static void (*recCP2[64])();
 static void (*recCP2BSC[32])();
 
+#define STACKSIZE		0x18
+static void StackRes()
+{
+#ifdef __x86_64__
+	ADD64ItoR(RSP, STACKSIZE);
+#else
+	if (resp) ADD32ItoR(ESP, resp);
+#endif
+}
 
 static void MapConst(int reg, u32 _const) {
 	iRegs[reg].k = _const;
@@ -103,8 +109,7 @@
 	/* store cycle */
 	count = (pc - pcold)/4;
 	ADD32ItoM((uptr)&psxRegs.cycle, count);
-	//if (resp) ADD64ItoR(RSP, resp);
-	ADD64ItoR(RSP, STACKSIZE);
+	StackRes();
 	RET();
 }
 
@@ -155,15 +160,13 @@
 		/* store cycle */
 		count = (pc - pcold)/4;
 		ADD32ItoM((uptr)&psxRegs.cycle, count);
-		//if (resp) ADD32ItoR(ESP, resp);
 
 		//PUSH64M((uptr)&target);
 		MOV32MtoR(X86ARG2, (uptr)&target);
 		//PUSHI(_Rt_);
 		MOV64ItoR(X86ARG1, _Rt_);
 		CALLFunc((uptr)psxDelayTest);
-		//ADD32ItoR(ESP, 2*8);
-		ADD64ItoR(RSP, STACKSIZE);
+		StackRes();
 		RET();
 		return;
 	}
@@ -189,7 +192,6 @@
 		/* store cycle */
 		count = (pc - pcold)/4;
 		ADD32ItoM((uptr)&psxRegs.cycle, count);
-		//if (resp) ADD32ItoR(ESP, resp);
 
 		//PUSHI(branchPC);
 		MOV64ItoR(X86ARG2, branchPC);
@@ -197,7 +199,7 @@
 		MOV64ItoR(X86ARG1, _Rt_);
 		CALLFunc((uptr)psxDelayTest);
 		//ADD32ItoR(ESP, 2*8);
-		ADD64ItoR(RSP, STACKSIZE);
+		StackRes();
 		RET();
 		return;
 	}
@@ -210,13 +212,10 @@
 	/* store cycle */
 	count = (pc - pcold)/4;
 	ADD32ItoM((uptr)&psxRegs.cycle, count);
-	//if (resp) ADD32ItoR(RSP, resp);
-
-	//done calling functions
-	ADD64ItoR(RSP, STACKSIZE);
+	StackRes();
 
 		RET();
-	/*
+	//* XXX?
 	// maybe just happened an interruption, check so
 	CMP32ItoM((uptr)&psxRegs.pc, branchPC);
 	j8Ptr[0] = JE8(0);
@@ -224,9 +223,8 @@
 	RET();
 
 	x86SetJ8(j8Ptr[0]);
-	MOV64MtoR(RAX, (uptr)PC_REC(branchPC));
-	//TEST32RtoR(RAX, RAX);
-	AND64RtoR(RAX,RAX);
+	MOV64MtoR(RAX, PC_REC(branchPC));
+	TEST64RtoR(RAX,RAX);
 	j8Ptr[1] = JNE8(0);
 
 	RET();
@@ -236,7 +234,7 @@
 	RET();
 	//JMP32R(EAX);
 	JMPR(EAX);
-	*/
+	//*/
 }
 
 static void iBranch(u32 branchPC, int savectx) {
@@ -265,8 +263,7 @@
 		//PUSHI(_Rt_);
 		MOV64ItoR(X86ARG1,_Rt_);
 		CALLFunc((uptr)psxDelayTest);
-		//ADD32ItoR(ESP, 2*8);
-		ADD64ItoR(RSP, STACKSIZE);
+		StackRes();
 		RET();
 		return;
 	}
@@ -281,7 +278,7 @@
 	count = (pc - pcold)/4;
 	ADD32ItoM((uptr)&psxRegs.cycle, count);
 	
-	ADD64ItoR(RSP, STACKSIZE);
+	StackRes();
 
 	// maybe just happened an interruption, check so
 	CMP32ItoM((uptr)&psxRegs.pc, branchPC);
@@ -290,9 +287,8 @@
 	RET();
 
 	x86SetJ8(j8Ptr[1]);
-	MOV64MtoR(RAX, (uptr)PC_REC(branchPC));
-	//TEST32RtoR(EAX, EAX);
-	AND64RtoR(RAX,RAX);
+	MOV64MtoR(RAX, PC_REC(branchPC));
+	TEST64RtoR(RAX, RAX);
 	j8Ptr[2] = JNE8(0);
 
 	RET();
@@ -404,45 +400,41 @@
 
 static void recRecompile();
 
-#define RECRAM_POS (&psxMemWrite32 - (0x280000*sizeof(void*)) - 0xc000000)
-#define RECMEM_POS (RECRAM_POS - RECMEM_SIZE)
-
 static int recInit() {
 	int i;
 
-	psxRecLUT = (uptr**) malloc(0x010000 * sizeof(void*));
+	psxRecLUT = (uptr*) malloc(0x010000 * sizeof(uptr));
 
-	recMem = mmap(RECMEM_POS,
-	//recMem = mmap(0,
-		RECMEM_SIZE,
+	recMem = mmap(0,
+		RECMEM_SIZE + PTRMULT*0x1000,
 		PROT_EXEC | PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
-	memset(recMem, 0, RECMEM_SIZE);
 
-	recRAM = mmap(RECRAM_POS,
-		0x280000*sizeof(void*),
+	recRAM = mmap(0,
+		0x280000*PTRMULT,
 		PROT_WRITE | PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 	//recRAM = (uptr*) malloc(0x200000 * sizeof(void*));
 	//recROM = (uptr*) malloc(0x080000 * sizeof(void*));
-	recROM = &recRAM[0x200000];
+	recROM = &recRAM[0x200000*PTRMULT];
 
 	if (recRAM == NULL || recROM == NULL || recMem == NULL || psxRecLUT == NULL) {
 		SysMessage("Error allocating memory"); return -1;
 	}
-	memset(recRAM, 0, 0x200000 * sizeof(void*));
-	memset(recROM, 0, 0x080000 * sizeof(void*));
+	memset(recMem, 0, RECMEM_SIZE);
+	memset(recRAM, 0, 0x200000 * PTRMULT);
+	memset(recROM, 0, 0x080000 * PTRMULT);
 
-	for (i=0; i<0x80; i++) psxRecLUT[i + 0x0000] = &recRAM[((i & 0x1f) << 16)];
-	memcpy(psxRecLUT + 0x8000, psxRecLUT, 0x80 * sizeof(void*));
-	memcpy(psxRecLUT + 0xa000, psxRecLUT, 0x80 * sizeof(void*));
+	for (i=0; i<0x80; i++) psxRecLUT[i + 0x0000] = (uptr)&recRAM[PTRMULT*((i & 0x1f) << 16)];
+	memcpy(psxRecLUT + 0x8000, psxRecLUT, 0x80 * sizeof(uptr));
+	memcpy(psxRecLUT + 0xa000, psxRecLUT, 0x80 * sizeof(uptr));
 
-	for (i=0; i<0x08; i++) psxRecLUT[i + 0xbfc0] = &recROM[(i << 16)];
+	for (i=0; i<0x08; i++) psxRecLUT[i + 0xbfc0] = (uptr)&recROM[PTRMULT*(i << 16)];
 
 	return 0;
 }
 
 static void recReset() {
-	memset(recRAM, 0, 0x200000 * sizeof(void*));
-	memset(recROM, 0, 0x080000 * sizeof(void*));
+	memset(recRAM, 0, 0x200000 * PTRMULT);
+	memset(recROM, 0, 0x080000 * PTRMULT);
 
 	//x86Init();
 	cpudetectInit();
@@ -458,9 +450,9 @@
 	if (recMem == NULL) return;
 	free(psxRecLUT);
 	//free(recMem);
-	munmap(recMem, RECMEM_SIZE);
+	munmap(recMem, RECMEM_SIZE + PTRMULT*0x1000);
 	//free(recRAM);
-	munmap(recMem, 0x280000*sizeof(void*));
+	munmap(recRAM, 0x280000*PTRMULT);
 	//free(recROM);
 	x86Shutdown();
 }
@@ -472,18 +464,23 @@
 	SysRunGui();
 }
 
-__inline static void execute() {
-	void (**recFunc)();
-	char *p;
+/*__inline*/ static void execute() {
+	void (*recFunc)();
+	uptr *p;
 
-	p =	(char*)PC_REC(psxRegs.pc);
-	if (p != NULL) 
-		recFunc = (void (**)()) p;
-	else { recError(); return; }
+	p = (uptr *)PC_REC(psxRegs.pc);
+	// if (!p) { recError(); return; }
 
-	if (*recFunc == 0) {
+	if (*p == 0) {
 		recRecompile();
 	}
+
+	if (*p < (uptr)recMem || *p >= (uptr)recMem + RECMEM_SIZE)
+	{
+		recError();
+		return;
+	}
+	recFunc = (void (*)())*p;
 	(*recFunc)();
 }
 
@@ -496,7 +493,7 @@
 }
 
 static void recClear(u32 Addr, u32 Size) {
-	memset((void*)PC_REC(Addr), 0, Size * sizeof(void*) * 4);
+	memset((void*)PC_REC(Addr), 0, Size * sizeof(uptr));
 }
 
 static void recNULL() {
@@ -1205,12 +1202,29 @@
 
 static void SetArg_OfB(x86IntRegType arg) {
 	if (IsConst(_Rs_))
+#ifdef __x86_64__
 		MOV64ItoR(arg, iRegs[_Rs_].k + _Imm_);
+#else
+		PUSH32I  (iRegs[_Rs_].k + _Imm_);
+#endif
 	else {
+#ifdef __x86_64__
 		MOV32MtoR(arg, (uptr)&psxRegs.GPR.r[_Rs_]);
 		if (_Imm_)
 			ADD32ItoR(arg, _Imm_);
+#else
+		if (_Imm_) {
+			MOV32MtoR(EAX, (u32)&psxRegs.GPR.r[_Rs_]);
+			ADD32ItoR(EAX, _Imm_);
+			PUSH32R  (EAX);
+		} else {
+			PUSH32M  ((u32)&psxRegs.GPR.r[_Rs_]);
+		}
+#endif
 	}
+#ifndef __x86_64__
+	resp += 4;
+#endif
 }
 
 #if 1
@@ -1248,7 +1262,6 @@
 //		SysPrintf("unhandled r8 %x\n", addr);
 	}
 
-	//iPushOfB();
 	SetArg_OfB(X86ARG1);
 	CALLFunc((uptr)psxMemRead8);
 	if (_Rt_) {
@@ -1257,7 +1270,6 @@
 		MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
 	}
 //	ADD32ItoR(ESP, 4);
-	//resp+= 4;
 }
 
 static void recLBU() {
@@ -1294,7 +1306,6 @@
 //		SysPrintf("unhandled r8u %x\n", addr);
 	}
 
-	//iPushOfB();
 	SetArg_OfB(X86ARG1);
 	CALLFunc((uptr)psxMemRead8);
 	if (_Rt_) {
@@ -1303,7 +1314,6 @@
 		MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
 	}
 //	ADD32ItoR(ESP, 4);
-	//resp+= 4;
 }
 
 static void recLH() {
@@ -1340,7 +1350,6 @@
 //		SysPrintf("unhandled r16 %x\n", addr);
 	}
 
-	//iPushOfB();
 	SetArg_OfB(X86ARG1);
 	CALLFunc((uptr)psxMemRead16);
 	if (_Rt_) {
@@ -1349,7 +1358,6 @@
 		MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
 	}
 //	ADD32ItoR(ESP, 4);
-	//resp+= 4;
 }
 
 static void recLHU() {
@@ -1396,7 +1404,7 @@
 				MOVZX32R16toR(EAX, EAX);
 				MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
 #ifndef __WIN32__
-				//resp+= 4;
+				resp+= 4;
 #endif
 				return;
 			}
@@ -1410,7 +1418,7 @@
 					CALLFunc((uptr)psxRcntRcount);
 					MOVZX32R16toR(EAX, EAX);
 					MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
-					//resp+= 4;
+					resp+= 4;
 					return;
 
 				case 0x1f801104: case 0x1f801114: case 0x1f801124:
@@ -1433,7 +1441,6 @@
 //		SysPrintf("unhandled r16u %x\n", addr);
 	}
 
-	//iPushOfB();
 	SetArg_OfB(X86ARG1);
 	CALLFunc((uptr)psxMemRead16);
 	if (_Rt_) {
@@ -1442,7 +1449,6 @@
 		MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
 	}
 //	ADD32ItoR(ESP, 4);
-	//resp+= 4;
 }
 
 static void recLW() {
@@ -1498,10 +1504,7 @@
 					if (!_Rt_) return;
 					iRegs[_Rt_].state = ST_UNK;
 
-					//CALLFunc((uptr)GPU_readData);
-					MOV64ItoR(RAX, (uptr)GPU_readData);
-					CALL64R(RAX);
-
+					CALLFunc((uptr)GPU_readData);
 					MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
 					return;
 
@@ -1509,10 +1512,7 @@
 					if (!_Rt_) return;
 					iRegs[_Rt_].state = ST_UNK;
 
-					//CALLFunc((uptr)GPU_readStatus);
-					MOV64ItoR(RAX, (uptr)GPU_readStatus);
-					CALL64R(RAX);
-
+					CALLFunc((uptr)GPU_readStatus);
 					MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
 					return;
 			}
@@ -1520,7 +1520,6 @@
 //		SysPrintf("unhandled r32 %x\n", addr);
 	}
 
-	//iPushOfB();
 	SetArg_OfB(X86ARG1);
 	CALLFunc((uptr)psxMemRead32);
 	if (_Rt_) {
@@ -1528,7 +1527,6 @@
 		MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
 	}
 //	ADD32ItoR(ESP, 4);
-	//resp+= 4;
 }
 
 extern u32 LWL_MASK[4];
@@ -1659,15 +1657,12 @@
 	}
 
 	SysPrintf("recLWBlock %d: %d\n", count, IsConst(_Rs_));
-	//iPushOfB();
 	SetArg_OfB(X86ARG1);
 	CALLFunc((uptr)psxMemPointer);
 //	ADD32ItoR(ESP, 4);
-	//resp+= 4;
 
 	respsave = resp; resp = 0;
-	//TEST32RtoR(EAX, EAX);
-	AND64RtoR(RAX,RAX);
+	TEST64RtoR(RAX,RAX);
 	j32Ptr[4] = JZ32(0);
 	XOR32RtoR(ECX, ECX);
 	for (i=0; i<count; i++, code++) {
@@ -1685,7 +1680,9 @@
 		psxRegs.code = *code;
 		recLW();
 	}
-	//ADD32ItoR(ESP, resp);
+#ifndef __x86_64__
+	ADD32ItoR(ESP, resp);
+#endif
 	x86SetJ32(j32Ptr[5]);
 	resp = respsave;
 }
@@ -1735,21 +1732,13 @@
 		MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
 		if (_Imm_) ADD32ItoR(EAX, _Imm_);
 	}
-	//PUSH64R  (EAX);
+	PUSHR(EAX);
 	AND32ItoR(EAX, ~3);
-	//PUSH64R  (EAX);
 	MOV32RtoR(X86ARG1, EAX);
 	CALLFunc((uptr)psxMemRead32);
 
+	POPR   (EDX);
 	if (_Rt_) {
-		//ADD32ItoR(ESP, 4);
-		//POP64R   (EDX);
-		if (IsConst(_Rs_)) MOV32ItoR(EDX, iRegs[_Rs_].k + _Imm_);
-		else {
-			MOV32MtoR(EDX, (uptr)&psxRegs.GPR.r[_Rs_]);
-			if (_Imm_) ADD32ItoR(EDX, _Imm_);
-		}
-
 		AND32ItoR(EDX, 0x3); // shift = addr & 3;
 
 		MOV64ItoR(ECX, (uptr)LWR_SHIFT);
@@ -1771,7 +1760,6 @@
 		iRegs[_Rt_].state = ST_UNK;
 		MOV32RtoM((uptr)&psxRegs.GPR.r[_Rt_], EAX);
 	//} else {
-		//ADD64ItoR(RSP, 8);
 		//resp+= 8;
 	}
 }
@@ -1811,11 +1799,9 @@
 	} else {
 		MOV32MtoR(X86ARG2, (uptr)&psxRegs.GPR.r[_Rt_]);
 	}
-	//iPushOfB();
 	SetArg_OfB(X86ARG1);
 	CALLFunc((uptr)psxMemWrite8);
 //	ADD32ItoR(ESP, 8);
-	//resp+= 8;
 }
 
 static void recSH() {
@@ -1848,17 +1834,12 @@
 		if (t == 0x1f80) {
 			if (addr >= 0x1f801c00 && addr < 0x1f801e00) {
 				if (IsConst(_Rt_)) {
-					//PUSHI(iRegs[_Rt_].k);
 					MOV64ItoR(X86ARG2, iRegs[_Rt_].k);
 				} else {
-					//PUSH64M((uptr)&psxRegs.GPR.r[_Rt_]);
 					MOV32MtoR(X86ARG2, (uptr)&psxRegs.GPR.r[_Rt_]);
 				}
-				//PUSHI  (addr);
 				MOV64ItoR(X86ARG1, addr);
-				//CALLFunc  ((uptr)SPU_writeRegister);
-				MOV64ItoR(RAX, (uptr)SPU_writeRegister);
-				CALL64R(RAX);
+				CALLFunc  ((uptr)SPU_writeRegister);
 #ifndef __WIN32__
 				//resp+= 8;
 #endif
@@ -1873,11 +1854,9 @@
 	} else {
 		MOV32MtoR(X86ARG2, (uptr)&psxRegs.GPR.r[_Rt_]);
 	}
-	//iPushOfB();
 	SetArg_OfB(X86ARG1);
 	CALLFunc((uptr)psxMemWrite16);
 //	ADD32ItoR(ESP, 8);
-	//resp+= 8;
 }
 
 static void recSW() {
@@ -1928,15 +1907,11 @@
 
 				case 0x1f801810:
 					if (IsConst(_Rt_)) {
-						//PUSHI(iRegs[_Rt_].k);
 						MOV64ItoR(X86ARG1, iRegs[_Rt_].k);
 					} else {
-						//PUSH64M((uptr)&psxRegs.GPR.r[_Rt_]);
 						MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rt_]);
 					}
-					//CALLFunc((uptr)GPU_writeData);
-					MOV64ItoR(RAX, (uptr)GPU_writeData);
-					CALL64R(RAX);
+					CALLFunc((uptr)GPU_writeData);
 #ifndef __WIN32__
 					//resp+= 4;
 #endif
@@ -1944,15 +1919,11 @@
 
 				case 0x1f801814:
 					if (IsConst(_Rt_)) {
-						//PUSHI(iRegs[_Rt_].k);
 						MOV64ItoR(X86ARG1, iRegs[_Rt_].k);
 					} else {
-						//PUSH64M((uptr)&psxRegs.GPR.r[_Rt_]);
 						MOV32MtoR(X86ARG1, (uptr)&psxRegs.GPR.r[_Rt_]);
 					}
-					//CALLFunc((uptr)GPU_writeStatus);
-					MOV64ItoR(RAX, (uptr)GPU_writeStatus);
-					CALL64R(RAX);
+					CALLFunc((uptr)GPU_writeStatus);
 #ifndef __WIN32__
 					//resp+= 4;
 #endif
@@ -2009,15 +1980,13 @@
 	}
 
 	SysPrintf("recSWBlock %d: %d\n", count, IsConst(_Rs_));
-	//iPushOfB();
 	SetArg_OfB(X86ARG1);
 	CALLFunc((uptr)psxMemPointer);
 //	ADD32ItoR(ESP, 4);
 	//resp+= 4;
 
 	respsave = resp; resp = 0;
-	//TEST32RtoR(EAX, EAX);
-	AND64RtoR(RAX,RAX);
+	TEST64RtoR(RAX,RAX);
 	j32Ptr[4] = JZ32(0);
 	XOR32RtoR(ECX, ECX);
 	for (i=0, code = PSXM(pc); i<count; i++, code++) {
@@ -2081,21 +2050,13 @@
 		MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
 		if (_Imm_) ADD32ItoR(EAX, _Imm_);
 	}
-	//PUSH64R  (EAX);
+	PUSHR  (EAX);
 	AND32ItoR(EAX, ~3);
-	
-	//PUSH64R  (EAX);
 	MOV32RtoR(X86ARG1, EAX);
-	CALLFunc((uptr)psxMemRead32);
 
-	//ADD32ItoR(ESP, 4);
-	//POP64R   (EDX);
-	if (IsConst(_Rs_)) MOV32ItoR(EDX, iRegs[_Rs_].k + _Imm_);
-	else {
-		MOV32MtoR(EDX, (uptr)&psxRegs.GPR.r[_Rs_]);
-		if (_Imm_) ADD32ItoR(EDX, _Imm_);
-	}
+	CALLFunc((uptr)psxMemRead32);
 
+	POPR   (EDX);
 	AND32ItoR(EDX, 0x3); // shift = addr & 3;
 
 	MOV64ItoR(ECX, (uptr)SWL_MASK);
@@ -2112,7 +2073,6 @@
 	SHR32CLtoR(EDX); // _rRt_ >> SWL_SHIFT[shift]
 
 	OR32RtoR (EAX, EDX);
-	//PUSH64R  (EAX);
 	MOV32RtoR(X86ARG2, EAX);
 
 	if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
@@ -2121,7 +2081,6 @@
 		if (_Imm_) ADD32ItoR(EAX, _Imm_);
 	}
 	AND32ItoR(EAX, ~3);
-	//PUSH64R  (EAX);
 	MOV32RtoR(X86ARG1, EAX);
 
 	CALLFunc((uptr)psxMemWrite32);
@@ -2169,23 +2128,14 @@
 		MOV32MtoR(EAX, (uptr)&psxRegs.GPR.r[_Rs_]);
 		if (_Imm_) ADD32ItoR(EAX, _Imm_);
 	}
-	//PUSH64R  (EAX);
+	PUSHR  (EAX);
 	
 	AND32ItoR(EAX, ~3);
-	
-	//PUSH64R  (EAX);
 	MOV32RtoR(X86ARG1, EAX);
 
 	CALLFunc((uptr)psxMemRead32);
 
-	//ADD32ItoR(ESP, 4);
-	//POP64R   (EDX);
-	if (IsConst(_Rs_)) MOV32ItoR(EDX, iRegs[_Rs_].k + _Imm_);
-	else {
-		MOV32MtoR(EDX, (uptr)&psxRegs.GPR.r[_Rs_]);
-		if (_Imm_) ADD32ItoR(EDX, _Imm_);
-	}
-
+	POPR   (EDX);
 	AND32ItoR(EDX, 0x3); // shift = addr & 3;
 
 	MOV64ItoR(ECX, (uptr)SWR_MASK);
@@ -2202,7 +2152,6 @@
 	SHL32CLtoR(EDX); // _rRt_ << SWR_SHIFT[shift]
 
 	OR32RtoR (EAX, EDX);
-	//PUSH64R  (EAX);
 	MOV32RtoR(X86ARG2, EAX);
 
 	if (IsConst(_Rs_)) MOV32ItoR(EAX, iRegs[_Rs_].k + _Imm_);
@@ -2211,7 +2160,6 @@
 		if (_Imm_) ADD32ItoR(EAX, _Imm_);
 	}
 	AND32ItoR(EAX, ~3);
-	//PUSH64R  (EAX);
 	MOV32RtoR(X86ARG1, EAX);
 	CALLFunc((uptr)psxMemWrite32);
 //	ADD32ItoR(ESP, 8);
@@ -2396,8 +2344,6 @@
 
 	MOV32ItoR(EAX, pc - 4);
 	MOV32RtoM((uptr)&psxRegs.pc, EAX);
-	//PUSHI  (branch == 1 ? 1 : 0);
-	//PUSHI  (0x20);
 	MOV64ItoR(X86ARG2, branch == 1 ? 1 : 0);
 	MOV64ItoR(X86ARG1, 0x20);
 	CALLFunc((uptr)psxException);
@@ -2859,8 +2805,6 @@
 static void recHLE() {
 	iFlushRegs();
 
-	//MOV32ItoR(EAX, (uptr)psxHLEt[psxRegs.code & 0xffff]);
-	//CALL32R(EAX);
 	CALLFunc((uptr)psxHLEt[psxRegs.code & 0xffff]);
 	branch = 2;
 	iRet();
@@ -2931,13 +2875,13 @@
 	resp = 0;
 
 	/* if x86Ptr reached the mem limit reset whole mem */
-	if (((uptr)x86Ptr - (uptr)recMem) >= (RECMEM_SIZE - 0x10000))
+	if (((uptr)x86Ptr - (uptr)recMem) >= (RECMEM_SIZE - PTRMULT*0x10000))
 		recReset();
 
 	x86Align(32);
 	ptr = x86Ptr;
 
-	*PC_REC(psxRegs.pc) = (uptr)x86Ptr;
+	PC_RECP(psxRegs.pc) = x86Ptr;
 	pc = psxRegs.pc;
 	pcold = pc;
 
Index: libpcsxcore/ix86_64/ix86-64.c
===================================================================
RCS file: /cvsroot/pcsx-df/pcsx-df/libpcsxcore/ix86_64/ix86-64.c,v
retrieving revision 1.2
diff -a -u -r1.2 ix86-64.c
--- libpcsxcore/ix86_64/ix86-64.c	29 Dec 2007 22:18:01 -0000	1.2
+++ libpcsxcore/ix86_64/ix86-64.c	30 Nov 2008 14:58:36 -0000
@@ -14,8 +14,6 @@
 #include <assert.h>
 #include "ix86-64.h"
 
-#define SWAP(x, y) { *(u32*)&y ^= *(u32*)&x; *(u32*)&x ^= *(u32*)&y; *(u32*)&y ^= *(u32*)&x; }
-
 #ifdef __x86_64__
 
 #ifdef _MSC_VER
@@ -29,7 +27,7 @@
 #else
 // standard calling convention
 
-// registers saved by calling functions (no need to flush them across calls)
+// registers saved by called functions (no need to flush them across calls)
 x86IntRegType g_x86savedregs[] = { RBX, RBP, R12, R13, R14, R15 };
 // temp registers that need to be saved across calls
 x86IntRegType g_x86tempregs[] = { RCX, RDX, R8, R9, R10, R11, RSI, RDI };
@@ -121,24 +119,54 @@
 {
 }
 
-void write64( u64 val )
-{ 
-#ifdef _DEBUG
-   CheckX86Ptr( );
-#endif
-
-   *(u64*)x86Ptr = val; 
-   x86Ptr += 8; 
-}
-
-void ModRM( int mod, int rm, int reg )
+void writeVAROP(unsigned opl, u64 op)
 {
-	write8( ( mod << 6 ) | ( (rm & 7) << 3 ) | ( reg & 7 ) );
+	while (opl--)
+	{
+		write8(op & 0xFF);
+		op >>= 8;
+	}
 }
 
-void SibSB( int ss, int rm, int index )
+#define writeVARROP(REX, opl, op) ({ \
+		if (opl > 1 && ((op & 0xFF) == 0x66 || (op & 0xFF) == 0xF3 || (op & 0xFF) == 0xF2)) { \
+			write8(op & 0xFF); \
+			opl --; \
+			op >>= 8; \
+		} \
+		REX; \
+		writeVAROP(opl, op); \
+	})
+
+void MEMADDR_OP(bool w, unsigned opl, u64 op, bool isreg, int reg, uptr p, sptr off)
 {
-	write8( ( ss << 6 ) | ( rm << 3 ) | ( index ) );
+#ifdef __x86_64__
+	sptr pr = MEMADDR_(p, 5 + opl + (w || reg >= 8) + off);
+	if (SPTR32(pr))
+	{
+		writeVARROP(RexR(w, reg), opl, op);
+		ModRM(0, reg, DISP32);
+		write32(pr);
+	}
+	else if (UPTR32(p))
+	{
+		writeVARROP(RexR(w, reg), opl, op);
+		ModRM(0, reg, SIB);
+		SibSB(0, SIB, DISP32);
+		write32(p);
+	}
+	else
+	{
+		assert(!isreg || reg != X86_TEMP);
+		MOV64ItoR(X86_TEMP, p);
+		writeVARROP(RexRB(w, reg, X86_TEMP), opl, op);
+		ModRM(0, reg, X86_TEMP);
+	}
+#else
+	writeVARROP(RexR(w, reg), opl, op);
+	ModRM(0, reg, DISP32);
+	write32(p);
+#endif
 }
 
 void SET8R( int cc, int to )
@@ -180,13 +208,9 @@
 	ModRM( 3, to, from );
 }
 
-void CMOV32MtoR( int cc, int to, uptr from )
+void CMOV32MtoR( int cc, x86IntRegType to, uptr from )
 {
-    RexR(0, to);
-	write8( 0x0F );
-	write8( cc );
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, cc), true, to, from, 0);
 }
 
 ////////////////////////////////////////////////////
@@ -301,35 +325,44 @@
 /* mov r64 to m64 */
 void MOV64RtoM( uptr to, x86IntRegType from ) 
 {
-	RexR(1, from);
-	write8( 0x89 );
-	ModRM( 0, from, DISP32 );
-	write32( (u32)MEMADDR(to, 4) );
+	if (from == RAX)
+	{
+		RexR(1, 0);
+		write8(0xA3);
+		write64(to);
+	}
+	else
+	{
+		MEMADDR_OP(1, VAROP1(0x89), true, from, to, 0);
+	}
 }
 
 /* mov m64 to r64 */
 void MOV64MtoR( x86IntRegType to, uptr from ) 
 {
-	RexR(1, to);
-	write8( 0x8B );
-	ModRM( 0, to, DISP32 );
-	write32( (u32)MEMADDR(from, 4) ); 
+	if (to == RAX)
+	{
+		RexR(1, 0);
+		write8(0xA1);
+		write64(from);
+	}
+	else
+	{
+		MEMADDR_OP(1, VAROP1(0x8B), true, to, from, 0);
+	}
 }
 
 /* mov imm32 to m64 */
 void MOV64I32toM(uptr to, u32 from ) 
 {
-	Rex(1, 0, 0, 0);
-	write8( 0xC7 );
-	ModRM( 0, 0, DISP32 );
-	write32( MEMADDR(to, 8) );
-	write32( from ); 
+	MEMADDR_OP(1, VAROP1(0xC7), false, 0, to, 4);
+	write32(from);
 }
 
 // mov imm64 to r64
 void MOV64ItoR( x86IntRegType to, u64 from)
 {
-    RexB(1, to);
+	RexB(1, to);
 	write8( 0xB8 | (to & 0x7) ); 
 	write64( from );
 }
@@ -396,19 +429,29 @@
 /* mov r32 to m32 */
 void MOV32RtoM( uptr to, x86IntRegType from ) 
 {
-    RexR(0, from);
-	write8( 0x89 );
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) );
+	if (from == EAX)
+	{
+		write8(0xA3);
+		write64(to);
+	}
+	else
+	{
+		MEMADDR_OP(0, VAROP1(0x89), true, from, to, 0);
+	}
 }
 
 /* mov m32 to r32 */
 void MOV32MtoR( x86IntRegType to, uptr from ) 
 {
-	RexR(0, to);
-	write8( 0x8B );
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	if (to == RAX)
+	{
+		write8(0xA1);
+		write64(from);
+	}
+	else
+	{
+		MEMADDR_OP(0, VAROP1(0x8B), true, to, from, 0);
+	}
 }
 
 /* mov [r32] to r32 */
@@ -474,18 +517,8 @@
 /* mov imm32 to m32 */
 void MOV32ItoM(uptr to, u32 from ) 
 {
-	write8( 0xC7 );
-	
-	if (to <= 0xffffffff)	{
-		ModRM( 0, 0, 0x4 );
-		SibSB( 0, 0x4, 0x5 );
-		write32( (u32)to );
-	} else {
-		assert((sptr)MEMADDR(to,8) <= 0x7fffffff && (sptr)MEMADDR(to,8) >= -0x7fffffff);
-		ModRM( 0, 0, DISP32 );
-		write32( MEMADDR(to, 8) );
-	}
-	write32( from ); 
+	MEMADDR_OP(0, VAROP1(0xC7), false, 0, to, 4);
+	write32(from);
 }
 
 // mov imm32 to [r32+off]
@@ -508,21 +541,31 @@
 /* mov r16 to m16 */
 void MOV16RtoM(uptr to, x86IntRegType from ) 
 {
-	write8( 0x66 );
-    RexR(0,from);
-	write8( 0x89 );
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) );
+	if (from == EAX)
+	{
+		write8(0x66);
+		write8(0xA3);
+		write64(to);
+	}
+	else
+	{
+		MEMADDR_OP(0, VAROP2(0x66, 0x89), true, from, to, 0);
+	}
 }
 
 /* mov m16 to r16 */
 void MOV16MtoR( x86IntRegType to, uptr from ) 
 {
-	write8( 0x66 );
-    RexR(0,to);
-	write8( 0x8B );
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	if (to == EAX)
+	{
+		write8(0x66);
+		write8(0xA1);
+		write64(from);
+	}
+	else
+	{
+		MEMADDR_OP(0, VAROP2(0x66, 0x8B), true, to, from, 0);
+	}
 }
 
 void MOV16RmtoR( x86IntRegType to, x86IntRegType from) 
@@ -562,10 +605,7 @@
 /* mov imm16 to m16 */
 void MOV16ItoM( uptr to, u16 from ) 
 {
-	write8( 0x66 );
-	write8( 0xC7 );
-	ModRM( 0, 0, DISP32 );
-	write32( MEMADDR(to, 6) );
+	MEMADDR_OP(0, VAROP2(0x66, 0xC7), false, 0, to, 2);
 	write16( from ); 
 }
 
@@ -607,19 +647,29 @@
 /* mov r8 to m8 */
 void MOV8RtoM( uptr to, x86IntRegType from ) 
 {
-    RexR(0,from);
-	write8( 0x88 );
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) );
+	if (from == EAX)
+	{
+		write8(0xA2);
+		write64(to);
+	}
+	else
+	{
+		MEMADDR_OP(0, VAROP1(0x88), true, from, to, 0);
+	}
 }
 
 /* mov m8 to r8 */
 void MOV8MtoR( x86IntRegType to, uptr from ) 
 {
-    RexR(0,to);
-	write8( 0x8A );
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	if (to == EAX)
+	{
+		write8(0xA0);
+		write64(from);
+	}
+	else
+	{
+		MEMADDR_OP(0, VAROP1(0x8A), true, to, from, 0);
+	}
 }
 
 /* mov [r32] to r8 */
@@ -647,9 +697,7 @@
 /* mov imm8 to m8 */
 void MOV8ItoM( uptr to, u8 from ) 
 {
-	write8( 0xC6 );
-	ModRM( 0, 0, DISP32 );
-	write32( MEMADDR(to, 5) );
+	MEMADDR_OP(0, VAROP1(0xC6), false, 0, to, 1);
 	write8( from ); 
 }
 
@@ -705,10 +753,7 @@
 /* movsx m8 to r32 */
 void MOVSX32M8toR( x86IntRegType to, uptr from ) 
 {
-    RexR(0,to);
-	write16( 0xBE0F ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0xBE), true, to, from, 0);
 }
 
 /* movsx r16 to r32 */
@@ -736,10 +781,7 @@
 /* movsx m16 to r32 */
 void MOVSX32M16toR( x86IntRegType to, uptr from ) 
 {
-    RexR(0,to);
-	write16( 0xBF0F ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0xBF), true, to, from, 0);
 }
 
 /* movzx r8 to r32 */
@@ -767,10 +809,7 @@
 /* movzx m8 to r32 */
 void MOVZX32M8toR( x86IntRegType to, uptr from ) 
 {
-    RexR(0,to);
-	write16( 0xB60F ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0xB6), true, to, from, 0);
 }
 
 /* movzx r16 to r32 */
@@ -798,10 +837,7 @@
 /* movzx m16 to r32 */
 void MOVZX32M16toR( x86IntRegType to, uptr from ) 
 {
-    RexR(0,to);
-	write16( 0xB70F ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0xB7), true, to, from, 0);
 }
 
 #ifdef __x86_64__
@@ -831,10 +867,7 @@
 /* movzx m8 to r64 */
 void MOVZX64M8toR( x86IntRegType to, uptr from ) 
 {
-    RexR(1,to);
-	write16( 0xB60F ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(1, VAROP2(0x0F, 0xB6), true, to, from, 0);
 }
 
 /* movzx r16 to r64 */
@@ -862,10 +895,7 @@
 /* movzx m16 to r64 */
 void MOVZX64M16toR( x86IntRegType to, uptr from ) 
 {
-    RexR(1,to);
-	write16( 0xB70F ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(1, VAROP2(0x0F, 0xB7), true, to, from, 0);
 }
 #endif
 
@@ -1068,23 +1098,29 @@
 /* add imm32 to r64 */
 void ADD64ItoR( x86IntRegType to, u32 from ) 
 {
-	Rex(1, 0, 0, to >> 3);
-	if ( to == EAX) {
-		write8( 0x05 ); 
-	} else {
-		write8( 0x81 ); 
+	RexB(1, to);
+	if (from <= 0x7f)
+	{
+		write8(0x83);
 		ModRM( 3, 0, to );
+		write8(from);
+	}
+	else
+	{
+		if (to == RAX) {
+			write8( 0x05 ); 
+		} else  {
+			write8( 0x81 ); 
+			ModRM( 3, 0, to );
+		}
+		write32( from );
 	}
-	write32( from );
 }
 
 /* add m64 to r64 */
 void ADD64MtoR( x86IntRegType to, uptr from ) 
 {
-	Rex(1, to >> 3, 0, 0);
-	write8( 0x03 ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(1, VAROP1(0x03), true, to, from, 0);
 }
 
 /* add r64 to r64 */
@@ -1112,10 +1148,8 @@
 /* add imm32 to m32 */
 void ADD32ItoM( uptr to, u32 from ) 
 {
-	write8( 0x81 ); 
-	ModRM( 0, 0, DISP32 );
-	write32( MEMADDR(to, 8) );
-	write32( from );
+	MEMADDR_OP(0, VAROP1(0x81), false, 0, to, 4);
+	write32(from);
 }
 
 // add imm32 to [r32+off]
@@ -1138,19 +1172,13 @@
 /* add r32 to m32 */
 void ADD32RtoM(uptr to, x86IntRegType from ) 
 {
-    RexR(0,from);
-	write8( 0x01 ); 
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) );
+	MEMADDR_OP(0, VAROP1(0x01), true, from, to, 0);
 }
 
 /* add m32 to r32 */
 void ADD32MtoR( x86IntRegType to, uptr from ) 
 {
-    RexR(0,to);
-	write8( 0x03 ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP1(0x03), true, to, from, 0);
 }
 
 // add r16 to r16 
@@ -1182,40 +1210,26 @@
 /* add imm16 to m16 */
 void ADD16ItoM( uptr to, u16 from ) 
 {
-	write8( 0x66 );
-	write8( 0x81 ); 
-	ModRM( 0, 0, DISP32 );
-	write32( MEMADDR(to, 6) );
+	MEMADDR_OP(0, VAROP2(0x66, 0x81), false, 0, to, 2);
 	write16( from );
 }
 
 /* add r16 to m16 */
 void ADD16RtoM(uptr to, x86IntRegType from ) 
 {
-	write8( 0x66 );
-    RexR(0,from);
-	write8( 0x01 ); 
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) );
+	MEMADDR_OP(0, VAROP2(0x66, 0x01), true, from, to, 0);
 }
 
 /* add m16 to r16 */
 void ADD16MtoR( x86IntRegType to, uptr from ) 
 {
-	write8( 0x66 );
-    RexR(0,to);
-	write8( 0x03 ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x66, 0x03), true, to, from, 0);
 }
 
 // add m8 to r8
 void ADD8MtoR( x86IntRegType to, uptr from )
 {
-    RexR(0,to);
-	write8( 0x02 ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP1(0x02), true, to, from, 0);
 }
 
 /* adc imm32 to r32 */
@@ -1235,10 +1249,8 @@
 /* adc imm32 to m32 */
 void ADC32ItoM( uptr to, u32 from ) 
 {
-	write8( 0x81 ); 
-	ModRM( 0, 2, DISP32 );
-	write32( MEMADDR(to, 8) );
-	write32( from );
+	MEMADDR_OP(0, VAROP1(0x81), false, 2, to, 4);
+	write32(from);
 }
 
 /* adc r32 to r32 */
@@ -1252,19 +1264,13 @@
 /* adc m32 to r32 */
 void ADC32MtoR( x86IntRegType to, uptr from ) 
 {
-    RexR(0,to);
-	write8( 0x13 ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0x13), true, to, from, 0);
 }
 
 // adc r32 to m32 
 void ADC32RtoM( uptr to, x86IntRegType from )
 {
-    RexR(0,from);
-	write8( 0x11 ); 
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) );
+	MEMADDR_OP(0, VAROP1(0x11), true, from, to, 0);
 }
 
 
@@ -1285,9 +1291,7 @@
 /* inc m32 */
 void INC32M( uptr to ) 
 {
-	write8( 0xFF );
-	ModRM( 0, 0, DISP32 );
-	write32( MEMADDR(to, 4) );
+	MEMADDR_OP(0, VAROP1(0xFF), false, 0, to, 0);
 }
 
 /* inc r16 */
@@ -1301,10 +1305,7 @@
 /* inc m16 */
 void INC16M( uptr to ) 
 {
-	write8( 0x66 );
-	write8( 0xFF );
-	ModRM( 0, 0, DISP32 );
-	write32( MEMADDR(to, 4) );
+	MEMADDR_OP(0, VAROP2(0x66, 0xFF), false, 0, to, 0);
 }
 
 
@@ -1312,14 +1313,23 @@
 void SUB64ItoR( x86IntRegType to, u32 from ) 
 {
 	RexB(1, to);
-	if ( to == EAX ) {
-		write8( 0x2D ); 
-	} 
-    else {
-		write8( 0x81 ); 
+	if (from <= 0x7f)
+	{
+		write8(0x83);
 		ModRM( 3, 5, to );
+		write8(from);
+	}
+	else
+	{
+		if ( to == RAX ) {
+			write8( 0x2D ); 
+		} 
+		else {
+			write8( 0x81 ); 
+			ModRM( 3, 5, to );
+		}
+		write32( from ); 
 	}
-	write32( from ); 
 }
 
 /* sub r64 to r64 */
@@ -1333,10 +1343,7 @@
 /* sub m64 to r64 */
 void SUB64MtoR( x86IntRegType to, uptr from ) 
 {
-	RexR(1, to);
-	write8( 0x2B ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(1, VAROP1(0x2B), true, to, from, 0);
 }
 
 /* sub imm32 to r32 */
@@ -1356,10 +1363,8 @@
 /* sub imm32 to m32 */
 void SUB32ItoM( uptr to, u32 from ) 
 {
-	write8( 0x81 ); 
-	ModRM( 0, 5, DISP32 );
-	write32( MEMADDR(to, 8) );
-	write32( from );
+	MEMADDR_OP(0, VAROP1(0x81), false, 5, to, 4);
+	write32(from);
 }
 
 /* sub r32 to r32 */
@@ -1373,19 +1378,13 @@
 /* sub m32 to r32 */
 void SUB32MtoR( x86IntRegType to, uptr from ) 
 {
-    RexR(0,to);
-	write8( 0x2B ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0x2B), true, to, from, 0);
 }
 
 // sub r32 to m32 
 void SUB32RtoM( uptr to, x86IntRegType from )
 {
-    RexR(0,from);
-	write8( 0x29 ); 
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) );
+	MEMADDR_OP(0, VAROP1(0x29), true, from, to, 0);
 }
 
 // sub r16 to r16 
@@ -1412,20 +1411,13 @@
 
 /* sub imm16 to m16 */
 void SUB16ItoM( uptr to, u16 from ) {
-	write8( 0x66 ); 
-	write8( 0x81 ); 
-	ModRM( 0, 5, DISP32 );
-	write32( MEMADDR(to, 6) );
+	MEMADDR_OP(0, VAROP2(0x66, 0x81), false, 5, to, 2);
 	write16( from );
 }
 
 /* sub m16 to r16 */
 void SUB16MtoR( x86IntRegType to, uptr from ) {
-	write8( 0x66 ); 
-    RexR(0,to);
-	write8( 0x2B ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x66, 0x2B), true, to, from, 0);
 }
 
 /* sbb r64 to r64 */
@@ -1449,9 +1441,7 @@
 
 /* sbb imm32 to m32 */
 void SBB32ItoM( uptr to, u32 from ) {
-	write8( 0x81 );
-	ModRM( 0, 3, DISP32 );
-	write32( MEMADDR(to, 8) );
+	MEMADDR_OP(0, VAROP1(0x81), false, 3, to, 4);
 	write32( from );
 }
 
@@ -1466,19 +1456,13 @@
 /* sbb m32 to r32 */
 void SBB32MtoR( x86IntRegType to, uptr from ) 
 {
-    RexR(0,to);
-	write8( 0x1B ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0x1B), true, to, from, 0);
 }
 
 /* sbb r32 to m32 */
 void SBB32RtoM( uptr to, x86IntRegType from ) 
 {
-    RexR(0,from);
-	write8( 0x19 ); 
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) );
+	MEMADDR_OP(0, VAROP1(0x19), true, from, to, 0);
 }
 
 #ifdef __x86_64__
@@ -1499,9 +1483,7 @@
 /* dec m32 */
 void DEC32M( uptr to ) 
 {
-	write8( 0xFF );
-	ModRM( 0, 1, DISP32 );
-	write32( MEMADDR(to, 4) );
+	MEMADDR_OP(0, VAROP1(0xFF), false, 1, to, 0);
 }
 
 /* dec r16 */
@@ -1515,10 +1497,7 @@
 /* dec m16 */
 void DEC16M( uptr to ) 
 {
-	write8( 0x66 );
-	write8( 0xFF );
-	ModRM( 0, 1, DISP32 );
-	write32( MEMADDR(to, 4) );
+	MEMADDR_OP(0, VAROP2(0x66, 0xFF), false, 1, to, 0);
 }
 
 /* mul eax by r32 to edx:eax */
@@ -1540,17 +1519,13 @@
 /* mul eax by m32 to edx:eax */
 void MUL32M( uptr from ) 
 {
-	write8( 0xF7 ); 
-	ModRM( 0, 4, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xF7), false, 4, from, 0);
 }
 
 /* imul eax by m32 to edx:eax */
 void IMUL32M( uptr from ) 
 {
-	write8( 0xF7 ); 
-	ModRM( 0, 5, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xF7), false, 5, from, 0);
 }
 
 /* imul r32 by r32 to r32 */
@@ -1580,17 +1555,13 @@
 /* div eax by m32 to edx:eax */
 void DIV32M( uptr from ) 
 {
-	write8( 0xF7 ); 
-	ModRM( 0, 6, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xF7), false, 6, from, 0);
 }
 
 /* idiv eax by m32 to edx:eax */
 void IDIV32M( uptr from ) 
 {
-	write8( 0xF7 ); 
-	ModRM( 0, 7, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xF7), false, 7, from, 0);
 }
 
 ////////////////////////////////////
@@ -1662,15 +1633,11 @@
 {
    if ( from == 1 )
    {
-      write8( 0xD1 );
-      ModRM( 0, 4, DISP32 );
-	  write32( MEMADDR(to, 4) );
+	   MEMADDR_OP(0, VAROP1(0xD1), false, 4, to, 0);
    }
    else
    {
-      write8( 0xC1 ); 
-      ModRM( 0, 4, DISP32 );
-	  write32( MEMADDR(to, 5) );
+	   MEMADDR_OP(0, VAROP1(0xC1), false, 4, to, 1);
       write8( from ); 
    }
 }
@@ -1735,15 +1702,11 @@
 {
    if ( from == 1 )
    {
-      write8( 0xD1 );
-      ModRM( 0, 5, DISP32 );
-	  write32( MEMADDR(to, 4) );
+	   MEMADDR_OP(0, VAROP1(0xD1), false, 5, to, 0);
    }
    else
    {
-      write8( 0xC1 ); 
-      ModRM( 0, 5, DISP32 );
-	  write32( MEMADDR(to, 5) );
+	   MEMADDR_OP(0, VAROP1(0xC1), false, 5, to, 1);
       write8( from ); 
    }
 }
@@ -1814,10 +1777,15 @@
 /* sar imm8 to m32 */
 void SAR32ItoM( uptr to, u8 from )
 {
-	write8( 0xC1 ); 
-	ModRM( 0, 7, DISP32 );
-	write32( MEMADDR(to, 5) );
-	write8( from );
+	if (from == 1)
+	{
+		MEMADDR_OP(0, VAROP1(0xD1), false, 7, to, 0);
+	}
+	else
+	{
+		MEMADDR_OP(0, VAROP1(0xC1), false, 7, to, 1);
+		write8( from );
+	}
 }
 
 /* sar cl to r32 */
@@ -1914,10 +1882,7 @@
 /* or m64 to r64 */
 void OR64MtoR( x86IntRegType to, uptr from ) 
 {
-	RexR(1, to);
-	write8( 0x0B ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(1, VAROP1(0x0B), true, to, from, 0);
 }
 
 /* or r64 to r64 */
@@ -1931,10 +1896,7 @@
 // or r32 to m64
 void OR64RtoM(uptr to, x86IntRegType from ) 
 {
-    RexR(1,from);
-	write8( 0x09 ); 
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) );
+	MEMADDR_OP(1, VAROP1(0x09), true, from, to, 0);
 }
 
 /* or imm32 to r32 */
@@ -1954,10 +1916,8 @@
 /* or imm32 to m32 */
 void OR32ItoM(uptr to, u32 from ) 
 {
-	write8( 0x81 ); 
-	ModRM( 0, 1, DISP32 );
-	write32( MEMADDR(to, 8) );
-	write32( from ); 
+	MEMADDR_OP(0, VAROP1(0x81), false, 1, to, 4);
+	write32(from);
 }
 
 /* or r32 to r32 */
@@ -1971,19 +1931,13 @@
 /* or r32 to m32 */
 void OR32RtoM(uptr to, x86IntRegType from ) 
 {
-    RexR(0,from);
-	write8( 0x09 ); 
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) );
+	MEMADDR_OP(0, VAROP1(0x09), true, from, to, 0);
 }
 
 /* or m32 to r32 */
 void OR32MtoR( x86IntRegType to, uptr from ) 
 {
-    RexR(0,to);
-	write8( 0x0B ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0x0B), true, to, from, 0);
 }
 
 // or r16 to r16
@@ -2013,31 +1967,20 @@
 // or imm16 to m316
 void OR16ItoM( uptr to, u16 from )
 {
-    write8(0x66);
-	write8( 0x81 ); 
-	ModRM( 0, 1, DISP32 );
-	write32( MEMADDR(to, 6) );
+	MEMADDR_OP(0, VAROP2(0x66, 0x81), false, 1, to, 2);
 	write16( from ); 
 }
 
 /* or m16 to r16 */
 void OR16MtoR( x86IntRegType to, uptr from ) 
 {
-    write8(0x66);
-    RexR(0,to);
-	write8( 0x0B ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x66, 0x0B), true, to, from, 0);
 }
 
 // or r16 to m16 
 void OR16RtoM( uptr to, x86IntRegType from )
 {
-    write8(0x66);
-    RexR(0,from);
-	write8( 0x09 ); 
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) );
+	MEMADDR_OP(0, VAROP2(0x66, 0x09), true, from, to, 0);
 }
 
 // or r8 to r8
@@ -2051,28 +1994,20 @@
 // or r8 to m8
 void OR8RtoM( uptr to, x86IntRegType from )
 {
-    RexR(0,from);
-	write8( 0x08 ); 
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) ); 
+	MEMADDR_OP(0, VAROP1(0x08), true, from, to, 0);
 }
 
 // or imm8 to m8
 void OR8ItoM( uptr to, u8 from )
 {
-	write8( 0x80 ); 
-	ModRM( 0, 1, DISP32 );
-	write32( MEMADDR(to, 5) );
+	MEMADDR_OP(0, VAROP1(0x80), false, 1, to, 1);
 	write8( from ); 
 }
 
 // or m8 to r8
 void OR8MtoR( x86IntRegType to, uptr from )
 {
-    RexR(0,to);
-	write8( 0x0A ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0x0A), true, to, from, 0);
 }
 
 /* xor imm32 to r64 */
@@ -2099,19 +2034,13 @@
 /* xor m64 to r64 */
 void XOR64MtoR( x86IntRegType to, uptr from ) 
 {
-	RexR(1, to);
-	write8( 0x33 ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(1, VAROP1(0x33), true, to, from, 0);
 }
 
 /* xor r64 to m64 */
 void XOR64RtoM( uptr to, x86IntRegType from ) 
 {
-    RexR(1,from);
-	write8( 0x31 ); 
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) );
+	MEMADDR_OP(1, VAROP1(0x31), true, from, to, 0);
 }
 
 /* xor imm32 to r32 */
@@ -2131,9 +2060,7 @@
 /* xor imm32 to m32 */
 void XOR32ItoM( uptr to, u32 from ) 
 {
-	write8( 0x81 ); 
-	ModRM( 0, 6, DISP32 );
-	write32( MEMADDR(to, 8) ); 
+	MEMADDR_OP(0, VAROP1(0x81), false, 6, to, 4);
 	write32( from ); 
 }
 
@@ -2157,19 +2084,13 @@
 /* xor r32 to m32 */
 void XOR32RtoM( uptr to, x86IntRegType from ) 
 {
-    RexR(0,from);
-	write8( 0x31 ); 
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) );
+	MEMADDR_OP(0, VAROP1(0x31), true, from, to, 0);
 }
 
 /* xor m32 to r32 */
 void XOR32MtoR( x86IntRegType to, uptr from ) 
 {
-    RexR(0,to);
-	write8( 0x33 ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0x33), true, to, from, 0);
 }
 
 // xor imm16 to r16
@@ -2190,11 +2111,7 @@
 // xor r16 to m16
 void XOR16RtoM( uptr to, x86IntRegType from )
 {
-    write8(0x66);
-    RexR(0,from);
-	write8( 0x31 ); 
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) );
+	MEMADDR_OP(0, VAROP2(0x66, 0x31), true, from, to, 0);
 }
 
 /* and imm32 to r64 */
@@ -2213,19 +2130,13 @@
 /* and m64 to r64 */
 void AND64MtoR( x86IntRegType to, uptr from ) 
 {
-	RexR(1, to);
-	write8( 0x23 ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(1, VAROP1(0x23), true, to, from, 0);
 }
 
 /* and r64 to m64 */
 void AND64RtoM( uptr to, x86IntRegType from ) 
 {
-	RexR(1, from);
-	write8( 0x21 ); 
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) ); 
+	MEMADDR_OP(1, VAROP1(0x21), true, from, to, 0);
 }
 
 /* and r64 to r64 */
@@ -2239,10 +2150,7 @@
 /* and imm32 to m64 */
 void AND64I32toM( uptr to, u32 from ) 
 {
-    Rex(1,0,0,0);
-	write8( 0x81 ); 
-	ModRM( 0, 0x4, DISP32 );
-	write32( MEMADDR(to, 8) );
+	MEMADDR_OP(1, VAROP1(0x81), false, 4, to, 4);
 	write32( from ); 
 }
 
@@ -2271,18 +2179,14 @@
 /* and imm32 to m32 */
 void AND32ItoM( uptr to, u32 from ) 
 {
-	write8( 0x81 ); 
-	ModRM( 0, 0x4, DISP32 );
-	write32( MEMADDR(to, 8) );
-	write32( from ); 
+	MEMADDR_OP(0, VAROP1(0x81), false, 4, to, 4);
+	write32(from);
 }
 
 /* and sign ext imm8 to m32 */
 void AND32I8toM( uptr to, u8 from ) 
 {
-	write8( 0x83 ); 
-	ModRM( 0, 0x4, DISP32 );
-	write32( MEMADDR(to, 5) );
+	MEMADDR_OP(0, VAROP1(0x83), false, 4, to, 1);
 	write8( from ); 
 }
 
@@ -2297,19 +2201,13 @@
 /* and r32 to m32 */
 void AND32RtoM( uptr to, x86IntRegType from ) 
 {
-    RexR(0,from);
-	write8( 0x21 ); 
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) ); 
+	MEMADDR_OP(0, VAROP1(0x21), true, from, to, 0);
 }
 
 /* and m32 to r32 */
 void AND32MtoR( x86IntRegType to, uptr from ) 
 {
-    RexR(0,to);
-	write8( 0x23 ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0x23), true, to, from, 0);
 }
 
 // and r16 to r16
@@ -2338,30 +2236,20 @@
 /* and imm16 to m16 */
 void AND16ItoM( uptr to, u16 from ) 
 {
-	write8( 0x8166 ); 
-	ModRM( 0, 0x4, DISP32 );
-	write32( MEMADDR(to, 6) );
+	MEMADDR_OP(0, VAROP2(0x66, 0x81), false, 4, to, 2);
 	write16( from ); 
 }
 
 /* and r16 to m16 */
 void AND16RtoM( uptr to, x86IntRegType from ) 
 {
-	write8( 0x66 );
-    RexR(0,from);
-	write8( 0x21 ); 
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x66, 0x21), true, from, to, 0);
 }
 
 /* and m16 to r16 */
 void AND16MtoR( x86IntRegType to, uptr from ) 
 {
-	write8( 0x66 );
-    RexR(0,to);
-	write8( 0x23 ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4)); 
+	MEMADDR_OP(0, VAROP2(0x66, 0x23), true, to, from, 0);
 }
 
 /* and imm8 to r8 */
@@ -2380,9 +2268,7 @@
 /* and imm8 to m8 */
 void AND8ItoM( uptr to, u8 from ) 
 {
-	write8( 0x80 ); 
-	ModRM( 0, 0x4, DISP32 );
-	write32( MEMADDR(to, 5) );
+	MEMADDR_OP(0, VAROP1(0x80), false, 4, to, 1);
 	write8( from ); 
 }
 
@@ -2397,19 +2283,13 @@
 /* and r8 to m8 */
 void AND8RtoM( uptr to, x86IntRegType from ) 
 {
-    RexR(0,from);
-	write8( 0x20 ); 
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) ); 
+	MEMADDR_OP(0, VAROP1(0x20), true, from, to, 0);
 }
 
 /* and m8 to r8 */
 void AND8MtoR( x86IntRegType to, uptr from ) 
 {
-    RexR(0,to);
-	write8( 0x22 ); 
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4)); 
+	MEMADDR_OP(0, VAROP1(0x22), true, to, from, 0);
 }
 
 /* not r64 */
@@ -2431,9 +2311,7 @@
 // not m32 
 void NOT32M( uptr from )
 {
-	write8( 0xF7 ); 
-	ModRM( 0, 2, DISP32 );
-	write32( MEMADDR(from, 4)); 
+	MEMADDR_OP(0, VAROP1(0xF7), false, 2, from, 0);
 }
 
 /* neg r64 */
@@ -2454,9 +2332,7 @@
 
 void NEG32M( uptr from )
 {
-	write8( 0xF7 ); 
-	ModRM( 0, 3, DISP32 );
-	write32( MEMADDR(from, 4)); 
+	MEMADDR_OP(0, VAROP1(0xF7), false, 3, from, 0);
 }
 
 /* neg r16 */
@@ -2494,9 +2370,9 @@
 /* jmp rel32 */
 u32* JMP32( uptr to ) 
 {
-    assert( (sptr)to <= 0x7fffffff && (sptr)to >= -0x7fffffff );
+    assert(SPTR32((sptr)to));
 	write8( 0xE9 ); 
-	write32( to ); 
+	write32( (sptr)to ); 
 	return (u32*)(x86Ptr - 4 );
 }
 
@@ -2511,9 +2387,8 @@
 // jmp m32 
 void JMP32M( uptr to )
 {
-	write8( 0xFF ); 
-	ModRM( 0, 4, DISP32 );
-	write32( MEMADDR(to, 4)); 
+	/* FIXME */
+	MEMADDR_OP(0, VAROP1(0xFF), false, 4, to, 0);
 }
 
 /* jp rel8 */
@@ -2756,13 +2631,20 @@
 /* call func */
 void CALLFunc( uptr func ) 
 {
-    func -= ( (uptr)x86Ptr + 5 );
-    assert( (sptr)func <= 0x7fffffff && (sptr)func >= -0x7fffffff );
-    CALL32(func);
+    sptr p = MEMADDR_(func, 5);
+    if (SPTR32(p))
+    {
+	    CALL32(p);
+    }
+    else
+    {
+	    MOV64ItoR(X86_TEMP, func);
+	    CALL64R(X86_TEMP);
+    }
 }
 
 /* call rel32 */
-void CALL32( u32 to )
+void CALL32( s32 to )
 {
 	write8( 0xE8 ); 
 	write32( to ); 
@@ -2771,6 +2653,7 @@
 /* call r32 */
 void CALL32R( x86IntRegType to ) 
 {
+	RexB(0, to);
 	write8( 0xFF );
 	ModRM( 3, 2, to );
 }
@@ -2783,15 +2666,6 @@
 	ModRM( 3, 2, to );
 }
 
-/* call m32 */
-void CALL32M( uptr to ) 
-{
-	write8( 0xFF );
-	ModRM( 0, 2, DISP32 );
-	write32( MEMADDR(to, 4) );
-}
-
-
 ////////////////////////////////////
 // misc instructions               /
 ////////////////////////////////////
@@ -2813,10 +2687,7 @@
 /* cmp m64 to r64 */
 void CMP64MtoR( x86IntRegType to, uptr from ) 
 {
-	RexR(1, to);
-	write8( 0x3B );
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(1, VAROP1(0x3B), true, 2, from, 0);
 }
 
 // cmp r64 to r64 
@@ -2844,10 +2715,8 @@
 /* cmp imm32 to m32 */
 void CMP32ItoM( uptr to, u32 from ) 
 {
-	write8( 0x81 ); 
-	ModRM( 0, 7, DISP32 );
-	write32( MEMADDR(to, 8) ); 
-	write32( from ); 
+	MEMADDR_OP(0, VAROP1(0x81), false, 7, to, 4);
+	write32(from);
 }
 
 /* cmp r32 to r32 */
@@ -2861,10 +2730,7 @@
 /* cmp m32 to r32 */
 void CMP32MtoR( x86IntRegType to, uptr from ) 
 {
-    RexR(0,to);
-	write8( 0x3B );
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0x3B), true, to, from, 0);
 }
 
 // cmp imm8 to [r32]
@@ -2889,9 +2755,7 @@
 // cmp imm8 to [r32]
 void CMP32I8toM( uptr to, u8 from)
 {
-	write8( 0x83 );
-	ModRM( 0, 7, DISP32 );
-	write32( MEMADDR(to, 5) ); 
+	MEMADDR_OP(0, VAROP1(0x83), false, 7, to, 1);
 	write8( from ); 
 }
 
@@ -2915,10 +2779,7 @@
 /* cmp imm16 to m16 */
 void CMP16ItoM( uptr to, u16 from ) 
 {
-	write8( 0x66 ); 
-	write8( 0x81 ); 
-	ModRM( 0, 7, DISP32 );
-	write32( MEMADDR(to, 6) ); 
+	MEMADDR_OP(0, VAROP2(0x66, 0x81), false, 7, to, 2);
 	write16( from ); 
 }
 
@@ -2934,11 +2795,7 @@
 /* cmp m16 to r16 */
 void CMP16MtoR( x86IntRegType to, uptr from ) 
 {
-	write8( 0x66 ); 
-    RexR(0,to);
-	write8( 0x3B );
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x66, 0x3B), true, to, from, 0);
 }
 
 // cmp imm8 to r8
@@ -2960,10 +2817,15 @@
 // cmp m8 to r8
 void CMP8MtoR( x86IntRegType to, uptr from )
 {
-    RexR(0,to);
-	write8( 0x3A );
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0x3A), true, to, from, 0);
+}
+
+/* test r64 to r64 */
+void TEST64RtoR( x86IntRegType to, x86IntRegType from ) 
+{
+	RexRB(1, from, to);
+	write8( 0x85 ); 
+	ModRM( 3, from, to );
 }
 
 /* test imm32 to r32 */
@@ -2984,9 +2846,7 @@
 
 void TEST32ItoM( uptr to, u32 from )
 {
-	write8( 0xF7 );
-	ModRM( 0, 0, DISP32 );
-	write32( MEMADDR(to, 8) );
+	MEMADDR_OP(0, VAROP1(0xF7), false, 0, to, 4);
 	write32( from );
 }
 
@@ -3052,9 +2912,7 @@
 // test imm8 to r8
 void TEST8ItoM( uptr to, u8 from )
 {
-	write8( 0xF6 );
-	ModRM( 0, 0, DISP32 );
-	write32( MEMADDR(to, 5) );
+	MEMADDR_OP(0, VAROP1(0xF6), false, 0, to, 1);
 	write8( from );
 }
 
@@ -3108,9 +2966,7 @@
 /* push m64 */
 void PUSH64M( uptr from ) 
 {
-	write8( 0xFF );
-	ModRM( 0, 6, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xFF), false, 6, from, 0);
 }
 
 /* pop r64 */
@@ -3131,9 +2987,7 @@
 /* push m32 */
 void PUSH32M( uptr from ) 
 {
-    write8( 0xFF );
-	ModRM( 0, 6, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xFF), false, 6, from, 0);
 }
 
 /* pop r32 */
Index: libpcsxcore/ix86_64/ix86-64.h
===================================================================
RCS file: /cvsroot/pcsx-df/pcsx-df/libpcsxcore/ix86_64/ix86-64.h,v
retrieving revision 1.1.1.1
diff -a -u -r1.1.1.1 ix86-64.h
--- libpcsxcore/ix86_64/ix86-64.h	8 Oct 2007 21:13:28 -0000	1.1.1.1
+++ libpcsxcore/ix86_64/ix86-64.h	30 Nov 2008 14:58:39 -0000
@@ -14,6 +14,8 @@
 #endif
 
 #include "../psxcommon.h"       // Basic types header
+#include <assert.h>
+#include <stdbool.h>
 
 #if defined(__MINGW32__)
 #define PCSX2_ALIGNED16(x) __declspec(align(16)) x
@@ -204,33 +206,27 @@
 
 #ifdef __x86_64__
 #define X86_64ASSERT() assert(0)
-#define MEMADDR(addr, oplen)	((addr) - ((u64)x86Ptr + ((u64)oplen)))
+#define MEMADDR_(addr, oplen)	(sptr)((uptr)(addr) - ((uptr)x86Ptr + ((u64)(oplen))))
+#define	SPTR32(addr)		((addr) < 0x80000000L && (addr) >= -0x80000000L)
+#define	UPTR32(addr)		((addr) < 0x100000000L)
+#define MEMADDR(addr, oplen)	({ sptr _a = MEMADDR_(addr, oplen); assert(SPTR32(_a)); _a; })
 #else
 #define X86_64ASSERT()
+#define SPTR32(a) 1
+#define UPTR32(a) 1
 #define MEMADDR(addr, oplen)	(addr)
 #endif
 
 #ifdef __x86_64__
-#define Rex( w, r, x, b ) write8( 0x40 | ((w) << 3) | ((r) << 2) | ((x) << 1) | (b) );
-#define RexR(w, reg) if( w||(reg)>=8 ) { Rex(w, (reg)>=8, 0, 0); }
-#define RexB(w, base) if( w||(base)>=8 ) { Rex(w, 0, 0, (base)>=8); }
-#define RexRB(w, reg, base) if( w || (reg) >= 8 || (base)>=8 ) { Rex(w, (reg)>=8, 0, (base)>=8); }
-#define RexRXB(w, reg, index, base) if( w||(reg) >= 8 || (index) >= 8 || (base) >= 8 ) { \
-        Rex(w, (reg)>=8, (index)>=8, (base)>=8);                           \
-    }
+#define Rex( w, r, x, b ) write8( 0x40 | ((w) << 3) | ((r) << 2) | ((x) << 1) | (b) )
 #else
-#define Rex(w,r,x,b) assert(0);
-#define RexR(w, reg) if( w||(reg)>=8 ) assert(0);
-#define RexB(w, base) if( w||(base)>=8 ) assert(0);
-#define RexRB(w, reg, base) if( w||(reg) >= 8 || (base)>=8 ) assert(0);
-#define RexRXB(w, reg, index, base) if( w||(reg) >= 8 || (index) >= 8 || (base) >= 8 ) assert(0);
+#define Rex(w,r,x,b) assert(0)
 #endif
-
-void write8( int val );
-void write16( int val );
-void write32( u32 val );
-void write64( u64 val );
-
+#define RexRXB(w, reg, index, base) if(w || (reg) >= 8 || (index) >= 8 || (base) >= 8 ) \
+        Rex(w, (reg)>=8, (index)>=8, (base)>=8)
+#define RexR(w, reg) RexRXB(w, reg, 0, 0)
+#define RexB(w, base) RexRXB(w, 0, 0, base)
+#define RexRB(w, reg, base) RexRXB(w, reg, 0, base)
 
 void x86SetPtr( char *ptr );
 void x86Shutdown( void );
@@ -246,14 +242,19 @@
 u64 GetCPUTick( void );
 
 // General Helper functions
-void ModRM( int mod, int rm, int reg );
-void SibSB( int ss, int rm, int index );
+#define ModRM(mod, rm, reg) write8( ( mod << 6 ) | ( (rm & 7) << 3 ) | ( reg & 7 ) )
+#define SibSB(ss, rm, index) write8( ( ss << 6 ) | ( rm << 3 ) | ( index ) )
 void SET8R( int cc, int to );
 u8* J8Rel( int cc, int to );
 u32* J32Rel( int cc, u32 to );
 void CMOV32RtoR( int cc, int to, int from );
 void CMOV32MtoR( int cc, int to, uptr from );
 
+void MEMADDR_OP(bool w, unsigned opl, u64 op, bool isreg, int reg, uptr p, sptr off);
+
+#define VAROP1(op) 1, op
+#define VAROP2(op1, op2) 2, (op1) | ((op2) << 8)
+
 //******************
 // IX86 intructions 
 //******************
@@ -527,6 +528,7 @@
 
 // sub m64 to r64 
 void SUB64MtoR( x86IntRegType to, uptr from );
+void SUB64ItoR( x86IntRegType to, u32 from );
 
 // sub imm32 to r32 
 void SUB32ItoR( x86IntRegType to, u32 from );
@@ -882,13 +884,13 @@
 u32*  JS32( u32 to );
 
 // call func 
-void CALLFunc( uptr func); // based on CALL32
+void CALLFunc( uptr func);
 // call rel32 
-void CALL32( u32 to );
+void CALL32( s32 to );
 // call r32 
 void CALL32R( x86IntRegType to );
 // call m32 
-void CALL32M( uptr to );
+void CALL64R( x86IntRegType to );
 
 
 ////////////////////////////////////
@@ -931,6 +933,8 @@
 // cmp m8 to r8
 void CMP8MtoR( x86IntRegType to, uptr from );
 
+// test r64 to r64
+void TEST64RtoR( x86IntRegType to, x86IntRegType from );
 // test imm32 to r32 
 void TEST32ItoR( x86IntRegType to, u32 from );
 // test imm32 to m32 
@@ -1040,11 +1044,11 @@
 //******************
 
 // fild m32 to fpu reg stack 
-void FILD32( u32 from );
+void FILD32( uptr from );
 // fistp m32 from fpu reg stack 
-void FISTP32( u32 from );
+void FISTP32( uptr from );
 // fld m32 to fpu reg stack 
-void FLD32( u32 from );
+void FLD32( uptr from );
 // fld st(i)
 void FLD(int st);
 // fld1 (push +1.0f on the stack)
@@ -1052,16 +1056,16 @@
 // fld1 (push log_2 e on the stack)
 void FLDL2E();
 // fst m32 from fpu reg stack 
-void FST32( u32 to );
+void FST32( uptr to );
 // fstp m32 from fpu reg stack 
-void FSTP32( u32 to );
+void FSTP32( uptr to );
 // fstp st(i)
 void FSTP(int st);
 
 // fldcw fpu control word from m16 
-void FLDCW( u32 from );
+void FLDCW( uptr from );
 // fstcw fpu control word to m16 
-void FNSTCW( u32 to );
+void FNSTCW( uptr to );
 void FXAM();
 void FDECSTP();
 // frndint
@@ -1092,13 +1096,13 @@
 void FDIV320toRP( x86IntRegType src );
 
 // fadd m32 to fpu reg stack 
-void FADD32( u32 from );
+void FADD32( uptr from );
 // fsub m32 to fpu reg stack 
-void FSUB32( u32 from );
+void FSUB32( uptr from );
 // fmul m32 to fpu reg stack 
-void FMUL32( u32 from );
+void FMUL32( uptr from );
 // fdiv m32 to fpu reg stack 
-void FDIV32( u32 from );
+void FDIV32( uptr from );
 // fcomi st, st( i) 
 void FCOMI( x86IntRegType src );
 // fcomip st, st( i) 
@@ -1108,7 +1112,7 @@
 // fucomip st, st( i) 
 void FUCOMIP( x86IntRegType src );
 // fcom m32 to fpu reg stack 
-void FCOM32( u32 from );
+void FCOM32( uptr from );
 // fabs fpu reg stack 
 void FABS( void );
 // fsqrt fpu reg stack 
@@ -1136,7 +1140,7 @@
 void FCMOVNBE32( x86IntRegType from );
 // fcmovnu fpu reg to fpu reg stack 
 void FCMOVNU32( x86IntRegType from );
-void FCOMP32( u32 from );
+void FCOMP32( uptr from );
 void FNSTSWtoAX( void );
 
 // probably a little extreme here, but x86-64 should NOT use MMX
@@ -1743,7 +1747,7 @@
 void SSE2EMU_MOVD_XMM_to_R( x86IntRegType to, x86SSERegType from );
 void SSE2EMU_CVTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from );
 void SSE2EMU_CVTDQ2PS_M128_to_XMM( x86SSERegType to, uptr from );
-void SSE2EMU_MOVD_XMM_to_M32( u32 to, x86SSERegType from );
+void SSE2EMU_MOVD_XMM_to_M32( uptr to, x86SSERegType from );
 void SSE2EMU_MOVD_R_to_XMM( x86SSERegType to, x86IntRegType from );
 
 ////////////////////////////////////////////////////
@@ -1753,22 +1757,17 @@
 #define WRITECHECK()
 #endif
 
-#define write8(val )  {  \
-	*(u8*)x86Ptr = (u8)val; \
-	x86Ptr++; \
-} \
-
-#define write16(val ) \
-{ \
-	*(u16*)x86Ptr = (u16)val; \
-	x86Ptr += 2;  \
-} \
-
-#define write32( val ) \
-{ \
-	*(u32*)x86Ptr = val; \
-	x86Ptr += 4; \
-} \
+#define writeVAL(val) ({ \
+		WRITECHECK(); \
+		*(typeof(val)*)x86Ptr = (val); \
+		x86Ptr += sizeof(val); \
+		(void)0; \
+	})
+
+#define write8(val )  writeVAL((u8)(val))
+#define write16(val ) writeVAL((u16)(val))
+#define write32( val ) writeVAL((u32)(val))
+#define write64( val ) writeVAL((u64)(val))
 
 #ifdef __cplusplus
 }
Index: libpcsxcore/ix86_64/ix86_3dnow.c
===================================================================
RCS file: /cvsroot/pcsx-df/pcsx-df/libpcsxcore/ix86_64/ix86_3dnow.c,v
retrieving revision 1.1.1.1
diff -a -u -r1.1.1.1 ix86_3dnow.c
--- libpcsxcore/ix86_64/ix86_3dnow.c	8 Oct 2007 21:13:28 -0000	1.1.1.1
+++ libpcsxcore/ix86_64/ix86_3dnow.c	30 Nov 2008 14:58:39 -0000
@@ -15,38 +15,31 @@
 
 void PFCMPEQMtoR( x86IntRegType to, uptr from )
 {
-	write16( 0x0F0F );
-	ModRM( 0, to, DISP32 ); 
-	write32( from ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
 	write8( 0xB0 );
 }
 
 void PFCMPGTMtoR( x86IntRegType to, uptr from )
 {
-	write16( 0x0F0F );
-	ModRM( 0, to, DISP32 ); 
-	write32( from ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
 	write8( 0xA0 );
 }
 
 void PFCMPGEMtoR( x86IntRegType to, uptr from )
 {
-	write16( 0x0F0F );
-	ModRM( 0, to, DISP32 ); 
-	write32( from ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
 	write8( 0x90 );
 }
 
 void PFADDMtoR( x86IntRegType to, uptr from )
 {
-	write16( 0x0F0F );
-	ModRM( 0, to, DISP32 ); 
-	write32( from ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
 	write8( 0x9E );
 }
 
 void PFADDRtoR( x86IntRegType to, x86IntRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x0F0F );
 	ModRM( 3, to, from );
 	write8( 0x9E );
@@ -54,14 +47,13 @@
 
 void PFSUBMtoR( x86IntRegType to, uptr from )
 {
-	write16( 0x0F0F );
-	ModRM( 0, to, DISP32 ); 
-	write32( from ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
 	write8( 0x9A );
 }
 
 void PFSUBRtoR( x86IntRegType to, x86IntRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x0F0F );
 	ModRM( 3, to, from ); 
 	write8( 0x9A );
@@ -69,14 +61,13 @@
 
 void PFMULMtoR( x86IntRegType to, uptr from )
 {
-	write16( 0x0F0F );
-	ModRM( 0, to, DISP32 ); 
-	write32( from ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
 	write8( 0xB4 );
 }
 
 void PFMULRtoR( x86IntRegType to, x86IntRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x0F0F );
 	ModRM( 3, to, from ); 
 	write8( 0xB4 );
@@ -84,14 +75,13 @@
 
 void PFRCPMtoR( x86IntRegType to, uptr from )
 {
-	write16( 0x0F0F );
-	ModRM( 0, to, DISP32 ); 
-	write32( from ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
 	write8( 0x96 );
 }
 
 void PFRCPRtoR( x86IntRegType to, x86IntRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x0F0F );
 	ModRM( 3, to, from ); 
 	write8( 0x96 );
@@ -99,6 +89,7 @@
 
 void PFRCPIT1RtoR( x86IntRegType to, x86IntRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x0F0F );
 	ModRM( 3, to, from ); 
 	write8( 0xA6 );
@@ -106,6 +97,7 @@
 
 void PFRCPIT2RtoR( x86IntRegType to, x86IntRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x0F0F );
 	ModRM( 3, to, from ); 
 	write8( 0xB6 );
@@ -113,6 +105,7 @@
 
 void PFRSQRTRtoR( x86IntRegType to, x86IntRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x0F0F );
 	ModRM( 3, to, from ); 
 	write8( 0x97 );
@@ -120,6 +113,7 @@
 
 void PFRSQIT1RtoR( x86IntRegType to, x86IntRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x0F0F );
 	ModRM( 3, to, from ); 
 	write8( 0xA7 );
@@ -127,14 +121,13 @@
 
 void PF2IDMtoR( x86IntRegType to, uptr from )
 {
-	write16( 0x0F0F );
-	ModRM( 0, to, DISP32 ); 
-	write32( from ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
 	write8( 0x1D );
 }
 
 void PF2IDRtoR( x86IntRegType to, x86IntRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x0F0F );
 	ModRM( 3, to, from ); 
 	write8( 0x1D );
@@ -142,14 +135,13 @@
 
 void PI2FDMtoR( x86IntRegType to, uptr from )
 {
-	write16( 0x0F0F );
-	ModRM( 0, to, DISP32 ); 
-	write32( from ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
 	write8( 0x0D );
 }
 
 void PI2FDRtoR( x86IntRegType to, x86IntRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x0F0F );
 	ModRM( 3, to, from ); 
 	write8( 0x0D );
@@ -157,14 +149,13 @@
 
 void PFMAXMtoR( x86IntRegType to, uptr from )
 {
-	write16( 0x0F0F );
-	ModRM( 0, to, DISP32 ); 
-	write32( from ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
 	write8( 0xA4 );
 }
 
 void PFMAXRtoR( x86IntRegType to, x86IntRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x0F0F );
 	ModRM( 3, to, from ); 
 	write8( 0xA4 );
@@ -172,14 +163,13 @@
 
 void PFMINMtoR( x86IntRegType to, uptr from )
 {
-	write16( 0x0F0F );
-	ModRM( 0, to, DISP32 ); 
-	write32( from ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0x0F), true, to, from, 1);
 	write8( 0x94 );
 }
 
 void PFMINRtoR( x86IntRegType to, x86IntRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x0F0F );
 	ModRM( 3, to, from );
 	write8( 0x94 );
Index: libpcsxcore/ix86_64/ix86_cpudetect.c
===================================================================
RCS file: /cvsroot/pcsx-df/pcsx-df/libpcsxcore/ix86_64/ix86_cpudetect.c,v
retrieving revision 1.1.1.1
diff -a -u -r1.1.1.1 ix86_cpudetect.c
--- libpcsxcore/ix86_64/ix86_cpudetect.c	8 Oct 2007 21:13:28 -0000	1.1.1.1
+++ libpcsxcore/ix86_64/ix86_cpudetect.c	30 Nov 2008 14:58:39 -0000
@@ -38,8 +38,8 @@
 CPUINFO cpuinfo;
 
 #define cpuid(cmd,a,b,c,d) \
-  __asm__ __volatile__("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1" \
-		: "=a" (a), "=r" (b), "=c" (c), "=d" (d)  : "0" (cmd))
+  __asm__ __volatile__("cpuid" \
+		: "=a" (a), "=b" (b), "=c" (c), "=d" (d)  : "0" (cmd))
 
 static s32 iCpuId( u32 cmd, u32 *regs ) 
 {
Index: libpcsxcore/ix86_64/ix86_fpu.c
===================================================================
RCS file: /cvsroot/pcsx-df/pcsx-df/libpcsxcore/ix86_64/ix86_fpu.c,v
retrieving revision 1.1.1.1
diff -a -u -r1.1.1.1 ix86_fpu.c
--- libpcsxcore/ix86_64/ix86_fpu.c	8 Oct 2007 21:13:28 -0000	1.1.1.1
+++ libpcsxcore/ix86_64/ix86_fpu.c	30 Nov 2008 14:58:39 -0000
@@ -10,27 +10,21 @@
 /********************/
 
 /* fild m32 to fpu reg stack */
-void FILD32( u32 from )
+void FILD32( uptr from )
 {
-	write8( 0xDB );
-	ModRM( 0, 0x0, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xDB), false, 0, from, 0);
 }
 
 /* fistp m32 from fpu reg stack */
-void FISTP32( u32 from ) 
+void FISTP32( uptr from ) 
 {
-	write8( 0xDB );
-	ModRM( 0, 0x3, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xDB), false, 3, from, 0);
 }
 
 /* fld m32 to fpu reg stack */
-void FLD32( u32 from )
+void FLD32( uptr from )
 {
-	write8( 0xD9 );
-	ModRM( 0, 0x0, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xD9), false, 0, from, 0);
 }
 
 // fld st(i)
@@ -40,38 +34,30 @@
 void FLDL2E() { write16(0xead9); }
 
 /* fst m32 from fpu reg stack */
-void FST32( u32 to ) 
+void FST32( uptr to ) 
 {
-   write8( 0xD9 );
-   ModRM( 0, 0x2, DISP32 );
-   write32( MEMADDR(to, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xD9), false, 2, to, 0);
 }
 
 /* fstp m32 from fpu reg stack */
-void FSTP32( u32 to )
+void FSTP32( uptr to )
 {
-	write8( 0xD9 );
-	ModRM( 0, 0x3, DISP32 );
-	write32( MEMADDR(to, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xD9), false, 3, to, 0);
 }
 
 // fstp st(i)
 void FSTP(int st) { write16(0xd8dd+(st<<8)); }
 
 /* fldcw fpu control word from m16 */
-void FLDCW( u32 from )
+void FLDCW( uptr from )
 {
-	write8( 0xD9 );
-	ModRM( 0, 0x5, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xD9), false, 5, from, 0);
 }
 
 /* fnstcw fpu control word to m16 */
-void FNSTCW( u32 to ) 
+void FNSTCW( uptr to ) 
 {
-	write8( 0xD9 );
-	ModRM( 0, 0x7, DISP32 );
-	write32( MEMADDR(to, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xD9), false, 7, to, 0);
 }
 
 void FNSTSWtoAX( void ) 
@@ -160,35 +146,27 @@
 }
 
 /* fadd m32 to fpu reg stack */
-void FADD32( u32 from ) 
+void FADD32( uptr from ) 
 {
-	write8( 0xD8 );
-	ModRM( 0, 0x0, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xD8), false, 0, from, 0);
 }
 
 /* fsub m32 to fpu reg stack */
-void FSUB32( u32 from ) 
+void FSUB32( uptr from ) 
 {
-	write8( 0xD8 );
-	ModRM( 0, 0x4, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xD8), false, 4, from, 0);
 }
 
 /* fmul m32 to fpu reg stack */
-void FMUL32( u32 from )
+void FMUL32( uptr from )
 {
-	write8( 0xD8 );
-	ModRM( 0, 0x1, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xD8), false, 1, from, 0);
 }
 
 /* fdiv m32 to fpu reg stack */
-void FDIV32( u32 from ) 
+void FDIV32( uptr from ) 
 {
-	write8( 0xD8 );
-	ModRM( 0, 0x6, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xD8), false, 6, from, 0);
 }
 
 /* fabs fpu reg stack */
@@ -241,19 +219,15 @@
 }
 
 /* fcom m32 to fpu reg stack */
-void FCOM32( u32 from ) 
+void FCOM32( uptr from ) 
 {
-	write8( 0xD8 );
-	ModRM( 0, 0x2, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xD8), false, 2, from, 0);
 }
 
 /* fcomp m32 to fpu reg stack */
-void FCOMP32( u32 from )
+void FCOMP32( uptr from )
 {
-	write8( 0xD8 );
-	ModRM( 0, 0x3, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP1(0xD8), false, 3, from, 0);
 }
 
 #define FCMOV32( low, high ) \
Index: libpcsxcore/ix86_64/ix86_mmx.c
===================================================================
RCS file: /cvsroot/pcsx-df/pcsx-df/libpcsxcore/ix86_64/ix86_mmx.c,v
retrieving revision 1.1.1.1
diff -a -u -r1.1.1.1 ix86_mmx.c
--- libpcsxcore/ix86_64/ix86_mmx.c	8 Oct 2007 21:13:28 -0000	1.1.1.1
+++ libpcsxcore/ix86_64/ix86_mmx.c	30 Nov 2008 14:58:39 -0000
@@ -14,28 +14,26 @@
 /* movq m64 to r64 */
 void MOVQMtoR( x86MMXRegType to, uptr from )
 {
-	write16( 0x6F0F );
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0x6F), true, to, from, 0);
 }
 
 /* movq r64 to m64 */
 void MOVQRtoM( uptr to, x86MMXRegType from ) 
 {
-	write16( 0x7F0F );
-	ModRM( 0, from, DISP32 );
-	write32(MEMADDR(to, 4)); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0x7F), true, from, to, 0);
 }
 
 /* pand r64 to r64 */
 void PANDRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xDB0F );
 	ModRM( 3, to, from ); 
 }
 
 void PANDNRtoR( x86MMXRegType to, x86MMXRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0xDF0F );
 	ModRM( 3, to, from ); 
 }
@@ -43,6 +41,7 @@
 /* por r64 to r64 */
 void PORRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xEB0F );
 	ModRM( 3, to, from ); 
 }
@@ -50,6 +49,7 @@
 /* pxor r64 to r64 */
 void PXORRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xEF0F );
 	ModRM( 3, to, from ); 
 }
@@ -57,6 +57,7 @@
 /* psllq r64 to r64 */
 void PSLLQRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xF30F );
 	ModRM( 3, to, from ); 
 }
@@ -64,14 +65,13 @@
 /* psllq m64 to r64 */
 void PSLLQMtoR( x86MMXRegType to, uptr from ) 
 {
-	write16( 0xF30F ); 
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0xF3), true, to, from, 0);
 }
 
 /* psllq imm8 to r64 */
 void PSLLQItoR( x86MMXRegType to, u8 from ) 
 {
+	RexB(0, to);
 	write16( 0x730F ); 
 	ModRM( 3, 6, to); 
 	write8( from ); 
@@ -80,6 +80,7 @@
 /* psrlq r64 to r64 */
 void PSRLQRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xD30F ); 
 	ModRM( 3, to, from ); 
 }
@@ -87,14 +88,13 @@
 /* psrlq m64 to r64 */
 void PSRLQMtoR( x86MMXRegType to, uptr from ) 
 {
-	write16( 0xD30F ); 
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0xD3), true, to, from, 0);
 }
 
 /* psrlq imm8 to r64 */
 void PSRLQItoR( x86MMXRegType to, u8 from ) 
 {
+	RexB(0, to);
 	write16( 0x730F );
 	ModRM( 3, 2, to); 
 	write8( from ); 
@@ -103,6 +103,7 @@
 /* paddusb r64 to r64 */
 void PADDUSBRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xDC0F ); 
 	ModRM( 3, to, from ); 
 }
@@ -110,14 +111,13 @@
 /* paddusb m64 to r64 */
 void PADDUSBMtoR( x86MMXRegType to, uptr from ) 
 {
-	write16( 0xDC0F ); 
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0xDC), true, to, from, 0);
 }
 
 /* paddusw r64 to r64 */
 void PADDUSWRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xDD0F ); 
 	ModRM( 3, to, from ); 
 }
@@ -125,14 +125,13 @@
 /* paddusw m64 to r64 */
 void PADDUSWMtoR( x86MMXRegType to, uptr from ) 
 {
-	write16( 0xDD0F ); 
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0xDD), true, to, from, 0);
 }
 
 /* paddb r64 to r64 */
 void PADDBRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xFC0F ); 
 	ModRM( 3, to, from ); 
 }
@@ -140,14 +139,13 @@
 /* paddb m64 to r64 */
 void PADDBMtoR( x86MMXRegType to, uptr from ) 
 {
-	write16( 0xFC0F ); 
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0xFC), true, to, from, 0);
 }
 
 /* paddw r64 to r64 */
 void PADDWRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xFD0F ); 
 	ModRM( 3, to, from ); 
 }
@@ -155,14 +153,13 @@
 /* paddw m64 to r64 */
 void PADDWMtoR( x86MMXRegType to, uptr from ) 
 {
-	write16( 0xFD0F ); 
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0xFD), true, to, from, 0);
 }
 
 /* paddd r64 to r64 */
 void PADDDRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xFE0F ); 
 	ModRM( 3, to, from ); 
 }
@@ -170,9 +167,7 @@
 /* paddd m64 to r64 */
 void PADDDMtoR( x86MMXRegType to, uptr from ) 
 {
-	write16( 0xFE0F ); 
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0xFE), true, to, from, 0);
 }
 
 /* emms */
@@ -183,12 +178,14 @@
 
 void PADDSBRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xEC0F ); 
 	ModRM( 3, to, from ); 
 }
 
 void PADDSWRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xED0F );
 	ModRM( 3, to, from ); 
 }
@@ -196,26 +193,27 @@
 // paddq m64 to r64 (sse2 only?)
 void PADDQMtoR( x86MMXRegType to, uptr from )
 {
-	write16( 0xD40F ); 
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0xD4), true, to, from, 0);
 }
 
 // paddq r64 to r64 (sse2 only?)
 void PADDQRtoR( x86MMXRegType to, x86MMXRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0xD40F ); 
 	ModRM( 3, to, from ); 
 }
 
 void PSUBSBRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xE80F ); 
 	ModRM( 3, to, from ); 
 }
 
 void PSUBSWRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xE90F );
 	ModRM( 3, to, from ); 
 }
@@ -223,37 +221,40 @@
 
 void PSUBBRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xF80F ); 
 	ModRM( 3, to, from ); 
 }
 
 void PSUBWRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xF90F ); 
 	ModRM( 3, to, from ); 
 }
 
 void PSUBDRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xFA0F ); 
 	ModRM( 3, to, from ); 
 }
 
 void PSUBDMtoR( x86MMXRegType to, uptr from )
 {
-	write16( 0xFA0F ); 
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0xFA), true, to, from, 0);
 }
 
 void PSUBUSBRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xD80F ); 
 	ModRM( 3, to, from ); 
 }
 
 void PSUBUSWRtoR( x86MMXRegType to, x86MMXRegType from ) 
 {
+	RexRB(0, to, from);
 	write16( 0xD90F ); 
 	ModRM( 3, to, from ); 
 }
@@ -261,14 +262,13 @@
 // psubq m64 to r64 (sse2 only?)
 void PSUBQMtoR( x86MMXRegType to, uptr from )
 {
-	write16( 0xFB0F ); 
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0xFB), true, to, from, 0);
 }
 
 // psubq r64 to r64 (sse2 only?)
 void PSUBQRtoR( x86MMXRegType to, x86MMXRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0xFB0F ); 
 	ModRM( 3, to, from ); 
 }
@@ -276,70 +276,72 @@
 // pmuludq m64 to r64 (sse2 only?)
 void PMULUDQMtoR( x86MMXRegType to, uptr from )
 {
-	write16( 0xF40F ); 
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0xF4), true, to, from, 0);
 }
 
 // pmuludq r64 to r64 (sse2 only?)
 void PMULUDQRtoR( x86MMXRegType to, x86MMXRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0xF40F ); 
 	ModRM( 3, to, from ); 
 }
 
 void PCMPEQBRtoR( x86MMXRegType to, x86MMXRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x740F ); 
 	ModRM( 3, to, from ); 
 }
 
 void PCMPEQWRtoR( x86MMXRegType to, x86MMXRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x750F ); 
 	ModRM( 3, to, from ); 
 }
 
 void PCMPEQDRtoR( x86MMXRegType to, x86MMXRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x760F ); 
 	ModRM( 3, to, from ); 
 }
 
 void PCMPEQDMtoR( x86MMXRegType to, uptr from )
 {
-	write16( 0x760F );
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0x76), true, to, from, 0);
 }
 
 void PCMPGTBRtoR( x86MMXRegType to, x86MMXRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x640F ); 
 	ModRM( 3, to, from ); 
 }
 
 void PCMPGTWRtoR( x86MMXRegType to, x86MMXRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x650F ); 
 	ModRM( 3, to, from ); 
 }
 
 void PCMPGTDRtoR( x86MMXRegType to, x86MMXRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x660F ); 
 	ModRM( 3, to, from ); 
 }
 
 void PCMPGTDMtoR( x86MMXRegType to, uptr from )
 {
-	write16( 0x660F );
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0x66), true, to, from, 0);
 }
 
 void PSRLWItoR( x86MMXRegType to, u8 from )
 {
+	RexB(0, to);
 	write16( 0x710F );
 	ModRM( 3, 2 , to ); 
 	write8( from );
@@ -347,6 +349,7 @@
 
 void PSRLDItoR( x86MMXRegType to, u8 from )
 {
+	RexB(0, to);
 	write16( 0x720F );
 	ModRM( 3, 2 , to ); 
 	write8( from );
@@ -354,12 +357,14 @@
 
 void PSRLDRtoR( x86MMXRegType to, x86MMXRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0xD20F );
 	ModRM( 3, to, from ); 
 }
 
 void PSLLWItoR( x86MMXRegType to, u8 from )
 {
+	RexB(0, to);
 	write16( 0x710F );
 	ModRM( 3, 6 , to ); 
 	write8( from );
@@ -367,6 +372,7 @@
 
 void PSLLDItoR( x86MMXRegType to, u8 from )
 {
+	RexB(0, to);
 	write16( 0x720F );
 	ModRM( 3, 6 , to ); 
 	write8( from );
@@ -374,12 +380,14 @@
 
 void PSLLDRtoR( x86MMXRegType to, x86MMXRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0xF20F );
 	ModRM( 3, to, from ); 
 }
 
 void PSRAWItoR( x86MMXRegType to, u8 from )
 {
+	RexB(0, to);
 	write16( 0x710F );
 	ModRM( 3, 4 , to ); 
 	write8( from );
@@ -387,6 +395,7 @@
 
 void PSRADItoR( x86MMXRegType to, u8 from )
 {
+	RexB(0, to);
 	write16( 0x720F );
 	ModRM( 3, 4 , to ); 
 	write8( from );
@@ -394,6 +403,7 @@
 
 void PSRADRtoR( x86MMXRegType to, x86MMXRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0xE20F );
 	ModRM( 3, to, from ); 
 }
@@ -401,76 +411,70 @@
 /* por m64 to r64 */
 void PORMtoR( x86MMXRegType to, uptr from ) 
 {
-	write16( 0xEB0F );
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0xEB), true, to, from, 0);
 }
 
 /* pxor m64 to r64 */
 void PXORMtoR( x86MMXRegType to, uptr from ) 
 {
-	write16( 0xEF0F );
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0xEF), true, to, from, 0);
 }
 
 /* pand m64 to r64 */
 void PANDMtoR( x86MMXRegType to, uptr from ) 
 {
-	//u64 rip = (u64)x86Ptr + 7;
-	write16( 0xDB0F );
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0xDB), true, to, from, 0);
 }
 
 void PANDNMtoR( x86MMXRegType to, uptr from )
 {
-	write16( 0xDF0F );
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0xDF), true, to, from, 0);
 }
 
 void PUNPCKHDQRtoR( x86MMXRegType to, x86MMXRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x6A0F );
 	ModRM( 3, to, from );
 }
 
 void PUNPCKHDQMtoR( x86MMXRegType to, uptr from )
 {
-	write16( 0x6A0F );
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0x6A), true, to, from, 0);
 }
 
 void PUNPCKLDQRtoR( x86MMXRegType to, x86MMXRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x620F );
 	ModRM( 3, to, from );
 }
 
 void PUNPCKLDQMtoR( x86MMXRegType to, uptr from )
 {
-	write16( 0x620F );
-	ModRM( 0, to, DISP32 ); 
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0x62), true, to, from, 0);
 }
 
 void MOVQ64ItoR( x86MMXRegType reg, u64 i ) 
 {
-	MOVQMtoR( reg, ( u32 )(x86Ptr) + 2 + 7 );
+	RexR(0, reg);
+	write16(0x6F0F);
+	ModRM(0, reg, DISP32);
+	write32(2);
 	JMP8( 8 );
 	write64( i );
 }
 
 void MOVQRtoR( x86MMXRegType to, x86MMXRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x6F0F );
 	ModRM( 3, to, from );
 }
 
 void MOVQRmtoROffset( x86MMXRegType to, x86IntRegType from, u32 offset )
 {
+	RexRB(0, to, from);
 	write16( 0x6F0F );
 
 	if( offset < 128 ) {
@@ -485,6 +489,7 @@
 
 void MOVQRtoRmOffset( x86IntRegType to, x86MMXRegType from, u32 offset )
 {
+	RexRB(0, from, to);
 	write16( 0x7F0F );
 
 	if( offset < 128 ) {
@@ -500,33 +505,32 @@
 /* movd m32 to r64 */
 void MOVDMtoMMX( x86MMXRegType to, uptr from ) 
 {
-	write16( 0x6E0F );
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0x6E), true, to, from, 0);
 }
 
 /* movd r64 to m32 */
 void MOVDMMXtoM( uptr to, x86MMXRegType from ) 
 {
-	write16( 0x7E0F );
-	ModRM( 0, from, DISP32 );
-	write32( MEMADDR(to, 4) ); 
+	MEMADDR_OP(0, VAROP2(0x0F, 0x7E), true, from, to, 0);
 }
 
 void MOVD32RtoMMX( x86MMXRegType to, x86IntRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x6E0F );
 	ModRM( 3, to, from );
 }
 
 void MOVD32RmtoMMX( x86MMXRegType to, x86IntRegType from )
 {
+	RexRB(0, to, from);
 	write16( 0x6E0F );
 	ModRM( 0, to, from );
 }
 
 void MOVD32RmOffsettoMMX( x86MMXRegType to, x86IntRegType from, u32 offset )
 {
+	RexRB(0, to, from);
 	write16( 0x6E0F );
 
 	if( offset < 128 ) {
@@ -541,12 +545,14 @@
 
 void MOVD32MMXtoR( x86IntRegType to, x86MMXRegType from )
 {
+	RexRB(0, from, to);
 	write16( 0x7E0F );
 	ModRM( 3, from, to );
 }
 
 void MOVD32MMXtoRm( x86IntRegType to, x86MMXRegType from )
 {
+	RexRB(0, from, to);
 	write16( 0x7E0F );
 	ModRM( 0, from, to );
 	if( to >= 4 ) {
@@ -559,6 +565,7 @@
 
 void MOVD32MMXtoRmOffset( x86IntRegType to, x86MMXRegType from, u32 offset )
 {
+	RexRB(0, from, to);
 	write16( 0x7E0F );
 
 	if( offset < 128 ) {
@@ -588,25 +595,28 @@
 // untested
 void PACKSSWBMMXtoMMX(x86MMXRegType to, x86MMXRegType from)
 {
+	RexRB(0, to, from);
 	write16( 0x630F );
 	ModRM( 3, to, from ); 
 }
 
 void PACKSSDWMMXtoMMX(x86MMXRegType to, x86MMXRegType from)
 {
+	RexRB(0, to, from);
 	write16( 0x6B0F );
 	ModRM( 3, to, from ); 
 }
 
 void PMOVMSKBMMXtoR(x86IntRegType to, x86MMXRegType from)
 {
+	RexRB(0, to, from);
 	write16( 0xD70F ); 
 	ModRM( 3, to, from );
 }
 
 void PINSRWRtoMMX( x86MMXRegType to, x86SSERegType from, u8 imm8 )
 {
-	if (to > 7 || from > 7) Rex(1, to >> 3, 0, from >> 3);
+	RexRB(0, to, from);
 	write16( 0xc40f );
 	ModRM( 3, to, from );
 	write8( imm8 );
@@ -614,6 +624,7 @@
 
 void PSHUFWRtoR(x86MMXRegType to, x86MMXRegType from, u8 imm8)
 {
+	RexRB(0, to, from);
 	write16(0x700f);
 	ModRM( 3, to, from );
 	write8(imm8);
@@ -621,14 +632,13 @@
 
 void PSHUFWMtoR(x86MMXRegType to, uptr from, u8 imm8)
 {
-	write16( 0x700f );
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0x70), true, to, from, 1 /* XXX was 0? */);
 	write8(imm8);
 }
 
 void MASKMOVQRtoR(x86MMXRegType to, x86MMXRegType from)
 {
+	RexRB(0, to, from);
 	write16(0xf70f);
 	ModRM( 3, to, from );
 }
Index: libpcsxcore/ix86_64/ix86_sse.c
===================================================================
RCS file: /cvsroot/pcsx-df/pcsx-df/libpcsxcore/ix86_64/ix86_sse.c,v
retrieving revision 1.1.1.1
diff -a -u -r1.1.1.1 ix86_sse.c
--- libpcsxcore/ix86_64/ix86_sse.c	8 Oct 2007 21:13:28 -0000	1.1.1.1
+++ libpcsxcore/ix86_64/ix86_sse.c	30 Nov 2008 14:58:40 -0000
@@ -15,39 +15,25 @@
 /* SSE instructions */
 /********************/
 
-#define SSEMtoR( code, overb ) \
+#define SSEMtoRv( nc, code, overb ) \
 	assert( cpucaps.hasStreamingSIMDExtensions ); \
 	assert( to < XMMREGS ) ; \
-	RexR(0, to);             \
-	write16( code ); \
-	ModRM( 0, to, DISP32 ); \
-	write32( MEMADDR(from, 4 + overb) ); \
+	MEMADDR_OP(0, nc, code, true, to, from, overb)
+
+#define SSEMtoR( code, overb ) SSEMtoRv(2, code, overb)
 
-#define SSERtoM( code, overb ) \
+#define SSERtoMv( nc, code, overb ) \
 	assert( cpucaps.hasStreamingSIMDExtensions ); \
 	assert( from < XMMREGS) ; \
-    RexR(0, from);  \
-	write16( code ); \
-	ModRM( 0, from, DISP32 ); \
-	write32( MEMADDR(to, 4 + overb) ); \
+	MEMADDR_OP(0, nc, code, true, from, to, overb)
+
+#define SSERtoM( code, overb ) SSERtoMv( 2, code, overb ) \
 
 #define SSE_SS_MtoR( code, overb ) \
-	assert( cpucaps.hasStreamingSIMDExtensions ); \
-	assert( to < XMMREGS ) ; \
-	write8( 0xf3 ); \
-    RexR(0, to);                      \
-	write16( code ); \
-	ModRM( 0, to, DISP32 ); \
-	write32( MEMADDR(from, 4 + overb) ); \
+	SSEMtoRv(3, (code << 8) | 0xF3, overb)
 
 #define SSE_SS_RtoM( code, overb ) \
-	assert( cpucaps.hasStreamingSIMDExtensions ); \
-	assert( from < XMMREGS) ; \
-	write8( 0xf3 ); \
-	RexR(0, from); \
-	write16( code ); \
-	ModRM( 0, from, DISP32 ); \
-	write32( MEMADDR(to, 4 + overb) ); \
+	SSERtoMv(3, (code << 8) | 0xF3, overb)
 
 #define SSERtoR( code ) \
 	assert( cpucaps.hasStreamingSIMDExtensions ); \
@@ -57,12 +43,10 @@
 	ModRM( 3, to, from );
 
 #define SSEMtoR66( code ) \
-	write8( 0x66 ); \
-	SSEMtoR( code, 0 );
+	SSEMtoRv( 3, (code << 8) | 0x66, 0 )
 
 #define SSERtoM66( code ) \
-	write8( 0x66 ); \
-	SSERtoM( code, 0 );
+	SSERtoMv( 3, (code << 8) | 0x66, 0 )
 
 #define SSERtoR66( code ) \
 	write8( 0x66 ); \
@@ -275,7 +259,7 @@
 {
 	if( !cpucaps.hasStreamingSIMD2Extensions ) SSE2EMU_MOVQ_M64_to_XMM(to, from);
 	else {
-		write8(0xf3); SSEMtoR( 0x7e0f, 0);
+		SSE_SS_MtoR( 0x7e0f, 0);
 	}
 }
 
@@ -283,7 +267,7 @@
 {
 	if( !cpucaps.hasStreamingSIMD2Extensions ) SSE2EMU_MOVQ_XMM_to_XMM(to, from);
 	else {
-		write8(0xf3); SSERtoR( 0x7e0f);
+		SSE_SS_RtoR( 0x7e0f);
 	}
 }
 
@@ -308,8 +292,7 @@
 {
 	if( !cpucaps.hasStreamingSIMD2Extensions ) SSE2EMU_MOVQ2DQ_MM_to_XMM(to, from);
 	else {
-		write8(0xf3);
-		SSERtoR( 0xd60f);
+		SSE_SS_RtoR( 0xd60f);
 	}
 }
 #endif
@@ -532,10 +515,7 @@
 
 void SSE_UCOMISS_M32_to_XMM( x86SSERegType to, uptr from )
 {
-    RexR(0, to);
-	write16( 0x2e0f );
-	ModRM( 0, to, DISP32 );
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0x2E), true, to, from, 0);
 }
 
 void SSE_UCOMISS_XMM_to_XMM( x86SSERegType to, x86SSERegType from )
@@ -603,7 +583,7 @@
 void SSE_CVTPS2PI_XMM_to_MM( x86MMXRegType to, x86SSERegType from )   { SSERtoR( 0x2d0f ); }
 #endif
 
-void SSE_CVTTSS2SI_M32_to_R32(x86IntRegType to, uptr from) { write8(0xf3); SSEMtoR(0x2c0f, 0); }
+void SSE_CVTTSS2SI_M32_to_R32(x86IntRegType to, uptr from) { SSE_SS_MtoR(0x2c0f, 0); }
 void SSE_CVTTSS2SI_XMM_to_R32(x86IntRegType to, x86SSERegType from)
 {
 	write8(0xf3);
@@ -612,7 +592,7 @@
 	ModRM(3, to, from);
 }
 
-void SSE_CVTSI2SS_M32_to_XMM(x86SSERegType to, uptr from) { write8(0xf3); SSEMtoR(0x2a0f, 0); }
+void SSE_CVTSI2SS_M32_to_XMM(x86SSERegType to, uptr from) { SSE_SS_MtoR(0x2a0f, 0); }
 void SSE_CVTSI2SS_R_to_XMM(x86SSERegType to, x86IntRegType from)
 {
 	write8(0xf3);
@@ -634,7 +614,7 @@
 void SSE2_CVTPS2DQ_M128_to_XMM( x86SSERegType to, uptr from )        { SSEMtoR66( 0x5b0f ); }
 void SSE2_CVTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from )   { SSERtoR66( 0x5b0f ); }
 
-void SSE2_CVTTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { write8(0xf3); SSERtoR(0x5b0f); }
+void SSE2_CVTTPS2DQ_XMM_to_XMM( x86SSERegType to, x86SSERegType from ) { SSE_SS_RtoR(0x5b0f); }
 /////////////////////////////////////////////////////////////////////////////////////
 //**********************************************************************************/
 //MINPS: Return Packed Single-Precision FP Minimum                                 *
@@ -700,12 +680,12 @@
 		write8( imm8 );
 	}
 }
-void SSE2_PSHUFD_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 )	{ SSEMtoR66( 0x700F ); write8( imm8 ); }
+void SSE2_PSHUFD_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 )	{ SSEMtoRv( 3, 0x700F66, 1 ); write8( imm8 ); }
 
 void SSE2_PSHUFLW_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { write8(0xF2); SSERtoR(0x700F); write8(imm8); }
-void SSE2_PSHUFLW_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { write8(0xF2); SSEMtoR(0x700F, 1); write8(imm8); }
-void SSE2_PSHUFHW_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { write8(0xF3); SSERtoR(0x700F); write8(imm8); }
-void SSE2_PSHUFHW_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { write8(0xF3); SSEMtoR(0x700F, 1); write8(imm8); }
+void SSE2_PSHUFLW_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { SSEMtoRv(3, 0x700FF2, 1); write8(imm8); }
+void SSE2_PSHUFHW_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) { SSE_SS_RtoR(0x700F); write8(imm8); }
+void SSE2_PSHUFHW_M128_to_XMM( x86SSERegType to, uptr from, u8 imm8 ) { SSE_SS_MtoR(0x700F, 1); write8(imm8); }
 
 ///////////////////////////////////////////////////////////////////////////////////
 //**********************************************************************************/
@@ -740,9 +720,7 @@
 //STMXCSR : Store Streaming SIMD Extension Control/Status                         *
 //**********************************************************************************
 void SSE_STMXCSR( uptr from ) {
-	write16( 0xAE0F );
-	ModRM( 0, 0x3, DISP32 );
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0xAE), false, 3, from, 0);
 }
 
 /////////////////////////////////////////////////////////////////////////////////////
@@ -750,9 +728,7 @@
 //LDMXCSR : Load Streaming SIMD Extension Control/Status                         *
 //**********************************************************************************
 void SSE_LDMXCSR( uptr from ) {
-	write16( 0xAE0F );
-	ModRM( 0, 0x2, DISP32 );
-	write32( MEMADDR(from, 4) );
+	MEMADDR_OP(0, VAROP2(0x0F, 0xAE), false, 2, from, 0);
 }
 
 /////////////////////////////////////////////////////////////////////////////////////
@@ -926,16 +902,16 @@
 //PXOR : SSE Bitwise XOR                                                             *
 //**********************************************************************************
 void SSE2_PXOR_XMM_to_XMM( x86SSERegType to, x86SSERegType from ){ SSERtoR66( 0xEF0F ); }
-void SSE2_PXOR_M128_to_XMM( x86SSERegType to, uptr from ){ SSEMtoR66( 0xEF0F ) }; 
+void SSE2_PXOR_M128_to_XMM( x86SSERegType to, uptr from ){ SSEMtoR66( 0xEF0F ); } 
 ///////////////////////////////////////////////////////////////////////////////////////
 
 void SSE2_MOVDQA_M128_to_XMM(x86SSERegType to, uptr from) {SSEMtoR66(0x6F0F); }
 void SSE2_MOVDQA_XMM_to_M128( uptr to, x86SSERegType from ){SSERtoM66(0x7F0F);} 
 void SSE2_MOVDQA_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { SSERtoR66(0x6F0F); }
 
-void SSE2_MOVDQU_M128_to_XMM(x86SSERegType to, uptr from) { write8(0xF3); SSEMtoR(0x6F0F, 0); }
-void SSE2_MOVDQU_XMM_to_M128( uptr to, x86SSERegType from) { write8(0xF3); SSERtoM(0x7F0F, 0); }
-void SSE2_MOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { write8(0xF3); SSERtoR(0x6F0F); }
+void SSE2_MOVDQU_M128_to_XMM(x86SSERegType to, uptr from) { SSE_SS_MtoR(0x6F0F, 0); }
+void SSE2_MOVDQU_XMM_to_M128( uptr to, x86SSERegType from) { SSE_SS_RtoM(0x7F0F, 0); }
+void SSE2_MOVDQU_XMM_to_XMM( x86SSERegType to, x86SSERegType from) { SSE_SS_RtoR(0x6F0F); }
 
 // shift right logical
 
@@ -1136,7 +1112,7 @@
 void SSE2_MOVMSKPD_XMM_to_R32(x86IntRegType to, x86SSERegType from) { SSERtoR66(0x500F); }
 
 void SSE3_HADDPS_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { write8(0xf2); SSERtoR( 0x7c0f ); }
-void SSE3_HADDPS_M128_to_XMM(x86SSERegType to, uptr from){ write8(0xf2); SSEMtoR( 0x7c0f, 0 ); }
+void SSE3_HADDPS_M128_to_XMM(x86SSERegType to, uptr from){ SSEMtoRv( 3, 0x7c0fF2, 0 ); }
 
 void SSE3_MOVSLDUP_XMM_to_XMM(x86SSERegType to, x86SSERegType from) {
 	write8(0xf3);
@@ -1145,9 +1121,9 @@
 	ModRM( 3, to, from );
 }
 
-void SSE3_MOVSLDUP_M128_to_XMM(x86SSERegType to, uptr from) { write8(0xf3); SSEMtoR(0x120f, 0); }
-void SSE3_MOVSHDUP_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { write8(0xf3); SSERtoR(0x160f); }
-void SSE3_MOVSHDUP_M128_to_XMM(x86SSERegType to, uptr from) { write8(0xf3); SSEMtoR(0x160f, 0); }
+void SSE3_MOVSLDUP_M128_to_XMM(x86SSERegType to, uptr from) { SSE_SS_MtoR(0x120f, 0); }
+void SSE3_MOVSHDUP_XMM_to_XMM(x86SSERegType to, x86SSERegType from) { SSE_SS_RtoR(0x160f); }
+void SSE3_MOVSHDUP_M128_to_XMM(x86SSERegType to, uptr from) { SSE_SS_MtoR(0x160f, 0); }
 
 // SSE-X
 void SSEX_MOVDQA_M128_to_XMM( x86SSERegType to, uptr from )
@@ -1333,17 +1309,17 @@
 void SSE2EMU_MOVD_RmOffset_to_XMM( x86SSERegType to, x86IntRegType from, int offset )
 {
 	MOV32RmtoROffset(EAX, from, offset);
-	MOV32ItoM((u32)p+4, 0);
-	MOV32ItoM((u32)p+8, 0);
-	MOV32RtoM((u32)p, EAX);
-	MOV32ItoM((u32)p+12, 0);
-	SSE_MOVAPS_M128_to_XMM(to, (u32)p);
+	MOV32ItoM((uptr)p+4, 0);
+	MOV32ItoM((uptr)p+8, 0);
+	MOV32RtoM((uptr)p, EAX);
+	MOV32ItoM((uptr)p+12, 0);
+	SSE_MOVAPS_M128_to_XMM(to, (uptr)p);
 }
 
 void SSE2EMU_MOVD_XMM_to_RmOffset(x86IntRegType to, x86SSERegType from, int offset )
 {
-	SSE_MOVSS_XMM_to_M32((u32)p, from);
-	MOV32MtoR(EAX, (u32)p);
+	SSE_MOVSS_XMM_to_M32((uptr)p, from);
+	MOV32MtoR(EAX, (uptr)p);
 	MOV32RtoRmOffset(to, EAX, offset);
 }
 
@@ -1352,15 +1328,15 @@
 
 void SSE2EMU_MOVDQ2Q_XMM_to_MM( x86MMXRegType to, x86SSERegType from)
 {
-	SSE_MOVLPS_XMM_to_M64((u32)p, from);
-	MOVQMtoR(to, (u32)p);
+	SSE_MOVLPS_XMM_to_M64(p, from);
+	MOVQMtoR(to, p);
 	SetMMXstate();
 }
 
 void SSE2EMU_MOVQ2DQ_MM_to_XMM( x86SSERegType to, x86MMXRegType from)
 {
-	MOVQRtoM((u32)p, from);
-	SSE_MOVLPS_M64_to_XMM(to, (u32)p);
+	MOVQRtoM(p, from);
+	SSE_MOVLPS_M64_to_XMM(to, p);
 	SetMMXstate();
 }
 #endif
@@ -1369,8 +1345,8 @@
 /*  SSE2 Emulated functions for SSE CPU's by kekko							*/
 /****************************************************************************/
 void SSE2EMU_PSHUFD_XMM_to_XMM( x86SSERegType to, x86SSERegType from, u8 imm8 ) {
-	MOV32ItoR(EAX, (u32)&p);
-	MOV32ItoR(EBX, (u32)&p2);
+	MOV64ItoR(EAX, (uptr)&p);
+	MOV64ItoR(EBX, (uptr)&p2);
 	SSE_MOVUPSRtoRm(EAX, from);
 
 	MOV32ItoR(ECX, (u32)imm8);
@@ -1413,7 +1389,8 @@
 }
 
 void SSE2EMU_MOVD_XMM_to_R( x86IntRegType to, x86SSERegType from ) {
-	MOV32ItoR(to, (u32)&p);
+	/* XXX? */
+	MOV64ItoR(to, (uptr)&p);
 	SSE_MOVUPSRtoRm(to, from);
 	MOV32RmtoR(to, to);
 }
@@ -1428,18 +1405,18 @@
     SetFPUstate();
 	_freeMMXreg(7);
 #endif
-	SSE_MOVAPS_XMM_to_M128((u32)f, from);
+	SSE_MOVAPS_XMM_to_M128((uptr)f, from);
 	
-	FLD32((u32)&f[0]);
-	FISTP32((u32)&p2[0]);
-	FLD32((u32)&f[1]);
-	FISTP32((u32)&p2[1]);
-	FLD32((u32)&f[2]);
-	FISTP32((u32)&p2[2]);
-	FLD32((u32)&f[3]);
-	FISTP32((u32)&p2[3]);
+	FLD32((uptr)&f[0]);
+	FISTP32((uptr)&p2[0]);
+	FLD32((uptr)&f[1]);
+	FISTP32((uptr)&p2[1]);
+	FLD32((uptr)&f[2]);
+	FISTP32((uptr)&p2[2]);
+	FLD32((uptr)&f[3]);
+	FISTP32((uptr)&p2[3]);
 
-	SSE_MOVAPS_M128_to_XMM(to, (u32)p2);
+	SSE_MOVAPS_M128_to_XMM(to, (uptr)p2);
 }
 
 void SSE2EMU_CVTDQ2PS_M128_to_XMM( x86SSERegType to, uptr from ) {
@@ -1447,31 +1424,32 @@
     SetFPUstate();
 	_freeMMXreg(7);
 #endif
-	FILD32((u32)from);
-	FSTP32((u32)&f[0]);
-	FILD32((u32)from+4);
-	FSTP32((u32)&f[1]);
-	FILD32((u32)from+8);
-	FSTP32((u32)&f[2]);
-	FILD32((u32)from+12);
-	FSTP32((u32)&f[3]);
-
-	SSE_MOVAPS_M128_to_XMM(to, (u32)f);
+	FILD32(from);
+	FSTP32((uptr)&f[0]);
+	FILD32(from+4);
+	FSTP32((uptr)&f[1]);
+	FILD32(from+8);
+	FSTP32((uptr)&f[2]);
+	FILD32(from+12);
+	FSTP32((uptr)&f[3]);
+
+	SSE_MOVAPS_M128_to_XMM(to, (uptr)f);
 }
 
-void SSE2EMU_MOVD_XMM_to_M32( u32 to, x86SSERegType from ) {
-	MOV32ItoR(EAX, (u32)&p);
+void SSE2EMU_MOVD_XMM_to_M32( uptr to, x86SSERegType from ) {
+	/* XXX? */
+	MOV64ItoR(EAX, (uptr)&p);
 	SSE_MOVUPSRtoRm(EAX, from);
 	MOV32RmtoR(EAX, EAX);
 	MOV32RtoM(to, EAX);
 }
 
 void SSE2EMU_MOVD_R_to_XMM( x86SSERegType to, x86IntRegType from ) {
-	MOV32ItoM((u32)p+4, 0);
-	MOV32ItoM((u32)p+8, 0);
-	MOV32RtoM((u32)p, from);
-	MOV32ItoM((u32)p+12, 0);
-	SSE_MOVAPS_M128_to_XMM(to, (u32)p);
+	MOV32ItoM((uptr)p+4, 0);
+	MOV32ItoM((uptr)p+8, 0);
+	MOV32RtoM((uptr)p, from);
+	MOV32ItoM((uptr)p+12, 0);
+	SSE_MOVAPS_M128_to_XMM(to, (uptr)p);
 }
 
 #endif
