From f3607c23085ed7c019e83832f4fd4ddd37af2525 Mon Sep 17 00:00:00 2001 From: TomW Date: Sat, 13 Jun 2015 16:14:35 +0100 Subject: [PATCH] Added code generation for : - FCOM/FUCOM - FSUBR/FSUBRP/FDIVR/FDIVRP - FLDCW/FSTCW - FILD/FIST/FISTP (16-bit, 32-bit and 64-bit variants) - FLD/FST/FSTP double precision - Integer and double precision variants of FADD/FSUB/FMUL/FDIV Also added 64-bit readmemq/writememq functions. --- src/386_common.h | 7 +- src/codegen.h | 8 +- src/codegen_ops.c | 303 +++++++++------ src/codegen_ops.h | 1 + src/codegen_ops_fpu.h | 315 ++++++++++++++- src/codegen_ops_x86.h | 879 +++++++++++++++++++++++++++++++++++++----- src/codegen_x86.c | 6 +- src/ibm.h | 2 + src/mem.c | 99 +++++ src/x86_ops_mmx.h | 3 +- src/x86_ops_mmx_mov.h | 24 +- 11 files changed, 1402 insertions(+), 245 deletions(-) diff --git a/src/386_common.h b/src/386_common.h index 5cc2ca7..267b963 100644 --- a/src/386_common.h +++ b/src/386_common.h @@ -5,11 +5,13 @@ extern uint16_t ea_rseg; #define readmemb(s,a) ((readlookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF)?readmemb386l(s,a): *(uint8_t *)(readlookup2[((s)+(a))>>12] + (s) + (a)) ) +#define readmemq(s,a) ((readlookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFF8)?readmemql(s,a):*(uint64_t *)(readlookup2[((s)+(a))>>12]+(s)+(a))) #define writememb(s,a,v) if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF) writememb386l(s,a,v); else *(uint8_t *)(writelookup2[((s) + (a)) >> 12] + (s) + (a)) = v #define writememw(s,a,v) if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFE) writememwl(s,a,v); else *(uint16_t *)(writelookup2[((s) + (a)) >> 12] + (s) + (a)) = v #define writememl(s,a,v) if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFFC) writememll(s,a,v); else *(uint32_t *)(writelookup2[((s) + (a)) >> 12] + (s) + (a)) = v +#define writememq(s,a,v) if (writelookup2[((s)+(a))>>12]==-1 || (s)==0xFFFFFFFF || (((s)+(a))&0xFFF)>0xFF8) writememql(s,a,v); else *(uint64_t *)(writelookup2[((s) + (a)) >> 12] + (s) + (a)) = v #define check_io_perm(port) if (!IOPLp || (eflags&VM_FLAG)) \ @@ -177,7 +179,7 @@ static inline uint32_t geteal() static inline uint64_t geteaq() { - return readmeml(easeg,eaaddr) | ((uint64_t)readmeml(easeg, eaaddr + 4) << 32); + return readmemq(easeg,eaaddr); } static inline uint8_t geteab_mem() @@ -198,8 +200,7 @@ static inline uint32_t geteal_mem() static inline void seteaq(uint64_t v) { - writememll(easeg, eaaddr, v & 0xffffffff); if (abrt) return; - writememll(easeg, eaaddr + 4, v >> 32); + writememql(easeg, eaaddr, v); } #define seteab(v) if (mod!=3) { if (eal_w) *(uint8_t *)eal_w=v; else writememb386l(easeg,eaaddr,v); } else if (rm&4) regs[rm&3].b.h=v; else regs[rm].b.l=v diff --git a/src/codegen.h b/src/codegen.h index e634df4..bf144f2 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -112,7 +112,7 @@ extern int block_pos; static inline void addbyte(uint8_t val) { codeblock[block_current].data[block_pos++] = val; - if (block_pos >= 1780) + if (block_pos >= 1760) { CPU_BLOCK_END(); } @@ -122,7 +122,7 @@ static inline void addword(uint16_t val) { *(uint16_t *)&codeblock[block_current].data[block_pos] = val; block_pos += 2; - if (block_pos >= 1780) + if (block_pos >= 1760) { CPU_BLOCK_END(); } @@ -132,7 +132,7 @@ static inline void addlong(uint32_t val) { *(uint32_t *)&codeblock[block_current].data[block_pos] = val; block_pos += 4; - if (block_pos >= 1780) + if (block_pos >= 1760) { CPU_BLOCK_END(); } @@ -151,4 +151,6 @@ extern int codegen_flags_changed; extern int codegen_fpu_entered; +extern int codegen_fpu_loaded_iq[8]; + #endif diff --git a/src/codegen_ops.c b/src/codegen_ops.c index 507b233..2e6b6fe 100644 --- a/src/codegen_ops.c +++ b/src/codegen_ops.c @@ -120,46 +120,46 @@ RecompOpFn recomp_opcodes_d8[512] = /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, +/*20*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, +/*30*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, /*40*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, +/*60*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, +/*70*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, /*80*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, +/*a0*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, +/*b0*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, /*c0*/ ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, +/*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, +/*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, +/*20*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, +/*30*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, /*40*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, +/*60*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, +/*70*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, /*80*/ ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFADDs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, ropFMULs, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, ropFCOMPs, +/*a0*/ ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, ropFSUBRs, +/*b0*/ ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, ropFDIVRs, /*c0*/ ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFADD, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, ropFMUL, -/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOM, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, ropFCOMP, +/*e0*/ ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUB, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, ropFSUBR, +/*f0*/ ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIV, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, ropFDIVR, }; RecompOpFn recomp_opcodes_d9[512] = @@ -168,18 +168,18 @@ RecompOpFn recomp_opcodes_d9[512] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, /*40*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, /*80*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*90*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, /*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -190,18 +190,18 @@ RecompOpFn recomp_opcodes_d9[512] = /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ /*00*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*10*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, /*40*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*50*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, /*80*/ ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, ropFLDs, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*90*/ ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, ropFSTPs, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, ropFLDCW, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, ropFSTCW, /*c0*/ ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFLD, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, ropFXCH, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -209,6 +209,53 @@ RecompOpFn recomp_opcodes_d9[512] = /*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; +RecompOpFn recomp_opcodes_da[512] = +{ + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, +/*10*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, +/*20*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, +/*30*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, + +/*40*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, +/*50*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, +/*60*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, +/*70*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, + +/*80*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, +/*90*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, +/*a0*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, +/*b0*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, +/*10*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, +/*20*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, +/*30*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, + +/*40*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, +/*50*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, +/*60*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, +/*70*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, + +/*80*/ ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFADDil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, ropFMULil, +/*90*/ ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, ropFCOMPil, +/*a0*/ ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, ropFSUBRil, +/*b0*/ ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, ropFDIVRil, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +}; + RecompOpFn recomp_opcodes_db[512] = { /*16-bit data*/ @@ -260,65 +307,65 @@ RecompOpFn recomp_opcodes_dc[512] = { /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, +/*10*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, +/*20*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, +/*30*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, +/*50*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, +/*60*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, +/*70*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, +/*90*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, +/*a0*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, +/*b0*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, /*c0*/ ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, +/*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*00*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, +/*10*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, +/*20*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, +/*30*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, +/*50*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, +/*60*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, +/*70*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFADDd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, ropFMULd, +/*90*/ ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, ropFCOMPd, +/*a0*/ ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, ropFSUBRd, +/*b0*/ ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, ropFDIVRd, /*c0*/ ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFADDr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, ropFMULr, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBRr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, ropFSUBr, +/*f0*/ ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVRr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, ropFDIVr, }; RecompOpFn recomp_opcodes_dd[512] = { /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, /*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, /*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -329,18 +376,18 @@ RecompOpFn recomp_opcodes_dd[512] = /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*00*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, /*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, /*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, ropFLDd, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, ropFSTPd, /*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -354,67 +401,67 @@ RecompOpFn recomp_opcodes_de[512] = { /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*00*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, +/*10*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, +/*20*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, +/*30*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, +/*50*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, +/*60*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, +/*70*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, +/*90*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, +/*a0*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, +/*b0*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, /*c0*/ ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, +/*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*00*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, +/*10*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, +/*20*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, +/*30*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, +/*50*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, +/*60*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, +/*70*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFADDiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, ropFMULiw, +/*90*/ ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, ropFCOMPiw, +/*a0*/ ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, ropFSUBRiw, +/*b0*/ ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIViw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, ropFDIVRiw, /*c0*/ ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFADDP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, ropFMULP, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBRP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, ropFSUBP, +/*f0*/ ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVRP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, ropFDIVP, }; RecompOpFn recomp_opcodes_df[512] = { /*16-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, @@ -423,20 +470,20 @@ RecompOpFn recomp_opcodes_df[512] = /*32-bit data*/ /* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ -/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*00*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, -/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*40*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, -/*80*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*80*/ ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, ropFILDw, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*90*/ ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, ropFISTPw, +/*a0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, ropFILDq, +/*b0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, ropFISTPq, /*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, diff --git a/src/codegen_ops.h b/src/codegen_ops.h index 391fa15..3f0d1be 100644 --- a/src/codegen_ops.h +++ b/src/codegen_ops.h @@ -4,6 +4,7 @@ extern RecompOpFn recomp_opcodes[512]; extern RecompOpFn recomp_opcodes_0f[512]; extern RecompOpFn recomp_opcodes_d8[512]; extern RecompOpFn recomp_opcodes_d9[512]; +extern RecompOpFn recomp_opcodes_da[512]; extern RecompOpFn recomp_opcodes_db[512]; extern RecompOpFn recomp_opcodes_dc[512]; extern RecompOpFn recomp_opcodes_dd[512]; diff --git a/src/codegen_ops_fpu.h b/src/codegen_ops_fpu.h index 872ce02..2396855 100644 --- a/src/codegen_ops_fpu.h +++ b/src/codegen_ops_fpu.h @@ -52,7 +52,41 @@ static uint32_t ropFLDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 return op_pc + 1; } +static uint32_t ropFLDd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + x86seg *target_seg; + + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_Q(target_seg); + + FP_LOAD_D(); + + return op_pc + 1; +} + +static uint32_t ropFILDw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + x86seg *target_seg; + + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_W(target_seg); + + FP_LOAD_IW(); + + return op_pc + 1; +} static uint32_t ropFILDl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { x86seg *target_seg; @@ -70,6 +104,25 @@ static uint32_t ropFILDl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint return op_pc + 1; } +static uint32_t ropFILDq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + x86seg *target_seg; + + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc); + + CHECK_SEG_READ(target_seg); + MEM_LOAD_ADDR_EA_Q(target_seg); + + FP_LOAD_IQ(); + + codegen_fpu_loaded_iq[(TOP - 1) & 7] = 1; + + return op_pc + 1; +} static uint32_t ropFSTs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { @@ -90,6 +143,26 @@ static uint32_t ropFSTs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 return op_pc + 1; } +static uint32_t ropFSTd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + x86seg *target_seg; + int host_reg1, host_reg2; + + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + FP_LOAD_REG_D(0, &host_reg1, &host_reg2); + + STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc); + + CHECK_SEG_WRITE(target_seg); + CHECK_SEG_LIMITS(target_seg, 7); + + MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); + + return op_pc + 1; +} static uint32_t ropFSTPs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { @@ -99,8 +172,92 @@ static uint32_t ropFSTPs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint return new_pc; } +static uint32_t ropFSTPd(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + uint32_t new_pc = ropFSTd(opcode, fetchdat, op_32, op_pc, block); + + FP_POP(); + + return new_pc; +} -static uint32_t ropFADDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +#define ropFarith(name, size, load, op) \ +static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ +{ \ + x86seg *target_seg; \ + \ + FP_ENTER(); \ + op_pc--; \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + \ + STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc); \ + \ + CHECK_SEG_READ(target_seg); \ + load(target_seg); \ + \ + op(FPU_ ## name); \ + \ + return op_pc + 1; \ +} + +ropFarith(ADD, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(DIV, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(DIVR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(MUL, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(SUB, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(SUBR, s, MEM_LOAD_ADDR_EA_L, FP_OP_S); +ropFarith(ADD, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(DIV, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(DIVR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(MUL, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(SUB, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(SUBR, d, MEM_LOAD_ADDR_EA_Q, FP_OP_D); +ropFarith(ADD, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(DIV, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(DIVR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(MUL, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(SUB, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(SUBR, iw, MEM_LOAD_ADDR_EA_W, FP_OP_IW); +ropFarith(ADD, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(DIV, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(DIVR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(MUL, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(SUB, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); +ropFarith(SUBR, il, MEM_LOAD_ADDR_EA_L, FP_OP_IL); + +#define ropFcompare(name, size, load, op) \ +static uint32_t ropF ## name ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ +{ \ + x86seg *target_seg; \ + \ + FP_ENTER(); \ + op_pc--; \ + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); \ + \ + STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc); \ + \ + CHECK_SEG_READ(target_seg); \ + load(target_seg); \ + \ + op(); \ + \ + return op_pc + 1; \ +} \ +static uint32_t ropF ## name ## P ## size(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) \ +{ \ + uint32_t new_pc = ropF ## name ## size(opcode, fetchdat, op_32, op_pc, block); \ + \ + FP_POP(); \ + \ + return new_pc; \ +} + +ropFcompare(COM, s, MEM_LOAD_ADDR_EA_L, FP_COMPARE_S); +ropFcompare(COM, d, MEM_LOAD_ADDR_EA_Q, FP_COMPARE_D); +ropFcompare(COM, iw, MEM_LOAD_ADDR_EA_W, FP_COMPARE_IW); +ropFcompare(COM, il, MEM_LOAD_ADDR_EA_L, FP_COMPARE_IL); + +/*static uint32_t ropFADDs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { x86seg *target_seg; @@ -167,7 +324,7 @@ static uint32_t ropFSUBs(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint FP_OP_S(FPU_SUB); return op_pc + 1; -} +}*/ static uint32_t ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) @@ -177,6 +334,13 @@ static uint32_t ropFADD(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 return op_pc; } +static uint32_t ropFCOM(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + FP_ENTER(); + FP_COMPARE_REG(0, opcode & 7); + + return op_pc; +} static uint32_t ropFDIV(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { FP_ENTER(); @@ -184,6 +348,13 @@ static uint32_t ropFDIV(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 return op_pc; } +static uint32_t ropFDIVR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + FP_ENTER(); + FP_OP_REG(FPU_DIVR, 0, opcode & 7); + + return op_pc; +} static uint32_t ropFMUL(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { FP_ENTER(); @@ -198,6 +369,13 @@ static uint32_t ropFSUB(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint3 return op_pc; } +static uint32_t ropFSUBR(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + FP_ENTER(); + FP_OP_REG(FPU_SUBR, 0, opcode & 7); + + return op_pc; +} static uint32_t ropFADDr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { @@ -206,6 +384,20 @@ static uint32_t ropFADDr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint return op_pc; } +static uint32_t ropFDIVr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + FP_ENTER(); + FP_OP_REG(FPU_DIV, opcode & 7, 0); + + return op_pc; +} +static uint32_t ropFDIVRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + FP_ENTER(); + FP_OP_REG(FPU_DIVR, opcode & 7, 0); + + return op_pc; +} static uint32_t ropFMULr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { FP_ENTER(); @@ -213,6 +405,20 @@ static uint32_t ropFMULr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint return op_pc; } +static uint32_t ropFSUBr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + FP_ENTER(); + FP_OP_REG(FPU_SUB, opcode & 7, 0); + + return op_pc; +} +static uint32_t ropFSUBRr(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + FP_ENTER(); + FP_OP_REG(FPU_SUBR, opcode & 7, 0); + + return op_pc; +} static uint32_t ropFADDP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { @@ -222,6 +428,14 @@ static uint32_t ropFADDP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint return op_pc; } +static uint32_t ropFCOMP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + FP_ENTER(); + FP_COMPARE_REG(0, opcode & 7); + FP_POP(); + + return op_pc; +} static uint32_t ropFDIVP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { FP_ENTER(); @@ -230,6 +444,14 @@ static uint32_t ropFDIVP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint return op_pc; } +static uint32_t ropFDIVRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + FP_ENTER(); + FP_OP_REG(FPU_DIVR, opcode & 7, 0); + FP_POP(); + + return op_pc; +} static uint32_t ropFMULP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { FP_ENTER(); @@ -246,6 +468,14 @@ static uint32_t ropFSUBP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint return op_pc; } +static uint32_t ropFSUBRP(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + FP_ENTER(); + FP_OP_REG(FPU_SUBR, opcode & 7, 0); + FP_POP(); + + return op_pc; +} static uint32_t ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) @@ -260,6 +490,25 @@ static uint32_t ropFSTSW_AX(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, u } +static uint32_t ropFISTw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + x86seg *target_seg; + int host_reg; + + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + host_reg = FP_LOAD_REG_INT_W(0); + + STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc); + + CHECK_SEG_WRITE(target_seg); + + MEM_STORE_ADDR_EA_W(target_seg, host_reg); + + return op_pc + 1; +} static uint32_t ropFISTl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { x86seg *target_seg; @@ -280,6 +529,14 @@ static uint32_t ropFISTl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint return op_pc + 1; } +static uint32_t ropFISTPw(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + uint32_t new_pc = ropFISTw(opcode, fetchdat, op_32, op_pc, block); + + FP_POP(); + + return new_pc; +} static uint32_t ropFISTPl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) { uint32_t new_pc = ropFISTl(opcode, fetchdat, op_32, op_pc, block); @@ -288,3 +545,57 @@ static uint32_t ropFISTPl(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uin return new_pc; } +static uint32_t ropFISTPq(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + x86seg *target_seg; + int host_reg1, host_reg2; + + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + FP_LOAD_REG_INT_Q(0, &host_reg1, &host_reg2); + + STORE_IMM_ADDR_L((uintptr_t)&oldpc, op_old_pc); + + CHECK_SEG_WRITE(target_seg); + + MEM_STORE_ADDR_EA_Q(target_seg, host_reg1, host_reg2); + + FP_POP(); + + return op_pc + 1; +} + + +static uint32_t ropFLDCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + x86seg *target_seg; + + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + CHECK_SEG_READ(target_seg); + + MEM_LOAD_ADDR_EA_W(target_seg); + STORE_HOST_REG_ADDR_W((uintptr_t)&npxc, 0); + + return op_pc + 1; +} +static uint32_t ropFSTCW(uint8_t opcode, uint32_t fetchdat, uint32_t op_32, uint32_t op_pc, codeblock_t *block) +{ + int host_reg; + x86seg *target_seg; + + FP_ENTER(); + op_pc--; + target_seg = FETCH_EA(op_ea_seg, fetchdat, op_ssegs, &op_pc, op_32); + + CHECK_SEG_WRITE(target_seg); + + host_reg = LOAD_VAR_W((uintptr_t)&npxc); + MEM_STORE_ADDR_EA_W(target_seg, host_reg); + + return op_pc + 1; +} diff --git a/src/codegen_ops_x86.h b/src/codegen_ops_x86.h index 1392d41..3ba492b 100644 --- a/src/codegen_ops_x86.h +++ b/src/codegen_ops_x86.h @@ -201,6 +201,13 @@ static void RELEASE_REG(int host_reg) host_reg_mapping[host_reg] = -1; } +static void STORE_HOST_REG_ADDR_W(uintptr_t addr, int host_reg) +{ + addbyte(0x66); /*MOVL [reg],host_reg*/ + addbyte(0x89); + addbyte(0x05 | (host_reg << 3)); + addlong(addr); +} static void STORE_HOST_REG_ADDR(uintptr_t addr, int host_reg) { addbyte(0x89); /*MOVL [reg],host_reg*/ @@ -668,6 +675,68 @@ static void MEM_LOAD_ADDR_EA_L(x86seg *seg) /*done:*/ host_reg_mapping[0] = 8; } +static void MEM_LOAD_ADDR_EA_Q(x86seg *seg) +{ + addbyte(0x8b); /*MOVL EDX, seg->base*/ + addbyte(0x05 | (REG_EDX << 3)); + addlong((uint32_t)&seg->base); + addbyte(0x89); /*MOV ESI, EDX*/ + addbyte(0xd6); + addbyte(0x01); /*ADDL EDX, EAX*/ + addbyte(0xc2); + addbyte(0x89); /*MOV EDI, EDX*/ + addbyte(0xd7); + addbyte(0x83); /*XOR EDI, -1*/ + addbyte(0xf7); + addbyte(-1); + addbyte(0xc1); /*SHR EDX, 12*/ + addbyte(0xea); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 0xff8*/ + addbyte(0xc7); + addlong(0xff8); + addbyte(0x8b); /*MOV EDX, readlookup2[EDX*4]*/ + addbyte(0x14); + addbyte(0x95); + addlong((uint32_t)readlookup2); + addbyte(0x74); /*JE slowpath*/ + addbyte(3+3+2+3+4+2); + addbyte(0x83); /*XOR EDI, -1*/ + addbyte(0xf7); + addbyte(-1); + addbyte(0x83); /*CMP EDX, -1*/ + addbyte(0xfa); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3+4+2); + addbyte(0x8b); /*MOV EAX, [EDX+EDI]*/ + addbyte(0x04); + addbyte(0x3a); + addbyte(0x8b); /*MOV EDX, [EDX+EDI+4]*/ + addbyte(0x54); + addbyte(0x3a); + addbyte(0x04); + addbyte(0xeb); /*JMP done*/ + addbyte(4+3+5+7+6); + addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/ + addbyte(0x44); + addbyte(0x24); + addbyte(0x04); + addbyte(0x89); /*MOV [ESP], ESI*/ + addbyte(0x34); + addbyte(0x24); + addbyte(0xe8); /*CALL readmemql*/ + addlong((uint32_t)readmemql - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*CMP abrt, 0*/ + addbyte(0x3d); + addlong((uint32_t)&abrt); + addbyte(0); + addbyte(0x0f); + addbyte(0x85); /*JNE end*/ + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ + host_reg_mapping[0] = 8; +} static void MEM_LOAD_ADDR_IMM_B(x86seg *seg, uint32_t addr) { @@ -864,6 +933,75 @@ static void MEM_STORE_ADDR_EA_L(x86seg *seg, int host_reg) addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); /*done:*/ } +static void MEM_STORE_ADDR_EA_Q(x86seg *seg, int host_reg, int host_reg2) +{ + addbyte(0x8b); /*MOVL ESI, seg->base*/ + addbyte(0x05 | (REG_ESI << 3)); + addlong((uint32_t)&seg->base); + addbyte(0x01); /*ADDL ESI, EAX*/ + addbyte(0xc0 | (REG_EAX << 3) | REG_ESI); + addbyte(0x89); /*MOV EDI, ESI*/ + addbyte(0xc0 | (REG_ESI << 3) | REG_EDI); + addbyte(0x83); /*XOR EDI, -1*/ + addbyte(0xf7); + addbyte(-1); + addbyte(0xc1); /*SHR ESI, 12*/ + addbyte(0xe8 | REG_ESI); + addbyte(12); + addbyte(0xf7); /*TEST EDI, 0xff8*/ + addbyte(0xc7); + addlong(0xff8); + addbyte(0x8b); /*MOV ESI, readlookup2[ESI*4]*/ + addbyte(0x04 | (REG_ESI << 3)); + addbyte(0x85 | (REG_ESI << 3)); + addlong((uint32_t)writelookup2); + addbyte(0x74); /*JE slowpath*/ + addbyte(3+3+2+3+4+2); + addbyte(0x83); /*XOR EDI, -1*/ + addbyte(0xf7); + addbyte(-1); + addbyte(0x83); /*CMP ESI, -1*/ + addbyte(0xf8 | REG_ESI); + addbyte(-1); + addbyte(0x74); /*JE slowpath*/ + addbyte(3+4+2); + addbyte(0x89); /*MOV [EDI+ESI],host_reg*/ + addbyte(0x04 | (host_reg << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0x89); /*MOV [EDI+ESI+4],host_reg2*/ + addbyte(0x44 | (host_reg2 << 3)); + addbyte(REG_EDI | (REG_ESI << 3)); + addbyte(0x04); + addbyte(0xeb); /*JMP done*/ + addbyte(4+5+4+4+3+5+7+6); + addbyte(0x89); /*slowpath: MOV [ESP+4], EAX*/ + addbyte(0x44); + addbyte(0x24); + addbyte(0x04); + addbyte(0xa1); /*MOV EAX, seg->base*/ + addlong((uint32_t)&seg->base); + addbyte(0x89); /*MOV [ESP+8], host_reg*/ + addbyte(0x44 | (host_reg << 3)); + addbyte(0x24); + addbyte(0x08); + addbyte(0x89); /*MOV [ESP+12], host_reg2*/ + addbyte(0x44 | (host_reg2 << 3)); + addbyte(0x24); + addbyte(0x0c); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xe8); /*CALL writememql*/ + addlong((uint32_t)writememql - (uint32_t)(&codeblock[block_current].data[block_pos + 4])); + addbyte(0x83); /*CMP abrt, 0*/ + addbyte(0x3d); + addlong((uint32_t)&abrt); + addbyte(0); + addbyte(0x0f); /*JNE end*/ + addbyte(0x85); + addlong(BLOCK_EXIT_OFFSET - (block_pos + 4)); + /*done:*/ +} static void MEM_STORE_ADDR_IMM_B(x86seg *seg, uint32_t addr, int host_reg) { @@ -1677,6 +1815,76 @@ static void FP_LOAD_S() addbyte(0x83); addlong((uintptr_t)tag); } +static void FP_LOAD_D() +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0x09); /*OR EAX, EDX*/ + addbyte(0xd0); + addbyte(0xdd); /*FLD [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x83); /*CMP EAX, 0*/ + addbyte(0xf8); + addbyte(0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x1c); + addbyte(0xdd); + addlong((uintptr_t)ST); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x83); + addlong((uintptr_t)tag); +} +static void FP_LOAD_IW() +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0xdf); /*FILDw [ESP]*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x83); /*CMP EAX, 0*/ + addbyte(0xf8); + addbyte(0); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x1c); + addbyte(0xdd); + addlong((uintptr_t)ST); + addbyte(0x0f); /*SETE [tag+EBX]*/ + addbyte(0x94); + addbyte(0x83); + addlong((uintptr_t)tag); +} static void FP_LOAD_IL() { addbyte(0x8b); /*MOV EBX, TOP*/ @@ -1709,6 +1917,50 @@ static void FP_LOAD_IL() addbyte(0x83); addlong((uintptr_t)tag); } +static void FP_LOAD_IQ() +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + addbyte(0x83); /*SUB EBX, 1*/ + addbyte(0xeb); + addbyte(1); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + addbyte(0x89); /*MOV [ST_i64+EBX*8], EAX*/ + addbyte(0x04); + addbyte(0xdd); + addlong((uint32_t)ST_i64); + addbyte(0x09); /*OR EAX, EDX*/ + addbyte(0xd0); + addbyte(0x89); /*MOV [ST_i64+4+EBX*8], EDX*/ + addbyte(0x14); + addbyte(0xdd); + addlong(((uint32_t)ST_i64) + 4); + addbyte(0x83); /*CMP EAX, 0*/ + addbyte(0xf8); + addbyte(0); + addbyte(0xdf); /*FILDl [ST_i64+EBX*8]*/ + addbyte(0x2c); + addbyte(0xdd); + addlong((uint32_t)ST_i64); + addbyte(0x0f); /*SETE AL*/ + addbyte(0x94); + addbyte(0xc0); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x1c); + addbyte(0xdd); + addlong((uintptr_t)ST); + addbyte(0x0c); /*OR AL, TAG_UINT64*/ + addbyte(TAG_UINT64); + addbyte(0x89); /*MOV TOP, EBX*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + addbyte(0x88); /*MOV [tag+EBX], AL*/ + addbyte(0x83); + addlong((uint32_t)tag); +} static int FP_LOAD_REG(int reg) { @@ -1738,9 +1990,98 @@ static int FP_LOAD_REG(int reg) return REG_EBX; } +static void FP_LOAD_REG_D(int reg, int *host_reg1, int *host_reg2) +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + if (reg) + { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc3); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + } + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x04); + addbyte(0xdd); + addlong((uintptr_t)ST); + addbyte(0xdd); /*FSTP [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + addbyte(0x8b); /*MOV EBX, [ESP]*/ + addbyte(0x04 | (REG_EBX << 3)); + addbyte(0x24); + addbyte(0x8b); /*MOV ECX, [ESP+4]*/ + addbyte(0x44 | (REG_ECX << 3)); + addbyte(0x24); + addbyte(0x04); + + *host_reg1 = REG_EBX; + *host_reg2 = REG_ECX; +} + + static double _fp_half = 0.5; -static int FP_LOAD_REG_INT(int reg) +static void FP_LOAD_ROUNDING() +{ + pclog("npxc %04x\n", npxc); + addbyte(0x8b); /*MOV EDX, npxc*/ + addbyte(0x15); + addlong((uintptr_t)&npxc); + addbyte(0xd9); /*FSTCW [ESP+8]*/ + addbyte(0x7c); + addbyte(0x24); + addbyte(0x08); + addbyte(0x89); /*MOV [ESP+12],EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x0c); + addbyte(0xd9); /*FLDCW [ESP+12]*/ + addbyte(0x6c); + addbyte(0x24); + addbyte(0x0c); +} +static void FP_RESTORE_ROUNDING() +{ + addbyte(0xd9); /*FLDCW [ESP+8]*/ + addbyte(0x6c); + addbyte(0x24); + addbyte(0x08); +} + +static int32_t x87_fround32(double b) +{ + switch ((npxc>>10)&3) + { + case 0: /*Nearest*/ + return (int32_t)(b+0.5); + case 1: /*Down*/ + return (int32_t)floor(b); + case 2: /*Up*/ + return (int32_t)ceil(b); + case 3: /*Chop*/ + return (int32_t)b; + } +} +static int64_t x87_fround64(double b) +{ + switch ((npxc>>10)&3) + { + case 0: /*Nearest*/ + return (int64_t)(b+0.5); + case 1: /*Down*/ + return (int64_t)floor(b); + case 2: /*Up*/ + return (int64_t)ceil(b); + case 3: /*Chop*/ + return (int64_t)b; + } +} +static int FP_LOAD_REG_INT_W(int reg) { addbyte(0x8b); /*MOV EBX, TOP*/ addbyte(0x1d); @@ -1759,99 +2100,147 @@ static int FP_LOAD_REG_INT(int reg) addbyte(0xdd); addlong((uintptr_t)ST); - /*Slightly dodgy assumption here, that the rounding mode will be the same - each time the block is called. It probably will be though. */ - switch ((npxc>>10)&3) - { - case 0: /*Nearest*/ - break; - case 1: /*Down*/ - addbyte(0x9b); /*FSTCW [ESP+4]*/ - addbyte(0xd9); - addbyte(0x7c); - addbyte(0x24); - addbyte(0x04); - addbyte(0xbe); /*MOVL ESI, 0x400*/ - addlong(0x400); - addbyte(0x0b); /*ORL ESI, [ESP+4]*/ - addbyte(0x74); - addbyte(0x24); - addbyte(0x04); - addbyte(0x81); /*ANDL ESI, ~0x800*/ - addbyte(0xe6); - addlong(~0x800); - addbyte(0x89); /*MOVL [ESP], ESI*/ - addbyte(0x34); - addbyte(0x24); - addbyte(0xd9); /*FLDCW [ESP]*/ - addbyte(0x2c); - addbyte(0x24); - break; - case 2: /*Up*/ - addbyte(0x9b); /*FSTCW [ESP+4]*/ - addbyte(0xd9); - addbyte(0x7c); - addbyte(0x24); - addbyte(0x04); - addbyte(0xbe); /*MOVL ESI, 0x800*/ - addlong(0x800); - addbyte(0x0b); /*ORL ESI, [ESP+4]*/ - addbyte(0x74); - addbyte(0x24); - addbyte(0x04); - addbyte(0x81); /*ANDL ESI, ~0x400*/ - addbyte(0xe6); - addlong(~0x400); - addbyte(0x89); /*MOVL [ESP], ESI*/ - addbyte(0x34); - addbyte(0x24); - addbyte(0xd9); /*FLDCW [ESP]*/ - addbyte(0x2c); - addbyte(0x24); - break; - case 3: /*Chop*/ - addbyte(0x9b); /*FSTCW [ESP+4]*/ - addbyte(0xd9); - addbyte(0x7c); - addbyte(0x24); - addbyte(0x04); - addbyte(0xbe); /*MOVL ESI, 0xc00*/ - addlong(0xc00); - addbyte(0x0b); /*ORL ESI, [ESP+4]*/ - addbyte(0x74); - addbyte(0x24); - addbyte(0x04); - addbyte(0x89); /*MOVL [ESP], ESI*/ - addbyte(0x34); - addbyte(0x24); - addbyte(0xd9); /*FLDCW [ESP]*/ - addbyte(0x2c); - addbyte(0x24); - break; - } + addbyte(0x89); /*MOV [ESP+8], EAX*/ + addbyte(0x44); + addbyte(0x24); + addbyte(0x08); - addbyte(0xdb); /*FISTPl [ESP]*/ + addbyte(0xdd); /*FSTP [ESP]*/ addbyte(0x1c); addbyte(0x24); - switch ((npxc>>10)&3) - { - case 1: /*Down*/ - case 2: /*Up*/ - case 3: /*Chop*/ - addbyte(0xd9); /*FLDCW [ESP+4]*/ - addbyte(0x6c); - addbyte(0x24); - addbyte(0x04); - break; - } - - addbyte(0x8b); /*MOV EAX, [ESP]*/ - addbyte(0x04 | (REG_EBX << 3)); + CALL_FUNC(x87_fround32); + + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + + addbyte(0x8b); /*MOV EAX, [ESP+8]*/ + addbyte(0x44); addbyte(0x24); + addbyte(0x08); return REG_EBX; } +static int FP_LOAD_REG_INT(int reg) +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + if (reg) + { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc3); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + } + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x04); + addbyte(0xdd); + addlong((uintptr_t)ST); + + addbyte(0x89); /*MOV [ESP+8], EAX*/ + addbyte(0x44); + addbyte(0x24); + addbyte(0x08); + + addbyte(0xdd); /*FSTP [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + + CALL_FUNC(x87_fround32); + + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + + addbyte(0x8b); /*MOV EAX, [ESP+8]*/ + addbyte(0x44); + addbyte(0x24); + addbyte(0x08); + + return REG_EBX; +} +static void FP_LOAD_REG_INT_Q(int reg, int *host_reg1, int *host_reg2) +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + if (reg) + { + addbyte(0x83); /*ADD EBX, reg*/ + addbyte(0xc3); + addbyte(reg); + addbyte(0x83); /*AND EBX, 7*/ + addbyte(0xe3); + addbyte(7); + } + if (codegen_fpu_loaded_iq[TOP] && (tag[TOP] & TAG_UINT64)) + { + /*If we know the register was loaded with FILDq in this block and + has not been modified, then we can skip most of the conversion + and just load the 64-bit integer representation directly */ + addbyte(0x8b); /*MOV ECX, [ST_i64+EBX*8]*/ + addbyte(0x0c); + addbyte(0xdd); + addlong((uint32_t)ST_i64+4); + addbyte(0x8b); /*MOV EBX, [ST_i64+EBX*8]*/ + addbyte(0x1c); + addbyte(0xdd); + addlong((uint32_t)ST_i64); + + return; + } + + addbyte(0xf6); /*TEST TAG[EBX], TAG_UINT64*/ + addbyte(0x83); + addlong((uintptr_t)tag); + addbyte(TAG_UINT64); + addbyte(0x74); /*JZ +*/ + addbyte(7+7+2); + + addbyte(0x8b); /*MOV ECX, [ST_i64+EBX*8]*/ + addbyte(0x0c); + addbyte(0xdd); + addlong((uint32_t)ST_i64+4); + addbyte(0x8b); /*MOV EBX, [ST_i64+EBX*8]*/ + addbyte(0x1c); + addbyte(0xdd); + addlong((uint32_t)ST_i64); + + addbyte(0xeb); /*JMP done*/ + addbyte(7+4+3+5+2+2+4); + + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x04); + addbyte(0xdd); + addlong((uintptr_t)ST); + + addbyte(0x89); /*MOV [ESP+8], EAX*/ + addbyte(0x44); + addbyte(0x24); + addbyte(0x08); + + addbyte(0xdd); /*FSTP [ESP]*/ + addbyte(0x1c); + addbyte(0x24); + + CALL_FUNC(x87_fround64); + + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + + addbyte(0x89); /*MOV ECX, EDX*/ + addbyte(0xd1); + + addbyte(0x8b); /*MOV EAX, [ESP+8]*/ + addbyte(0x44); + addbyte(0x24); + addbyte(0x08); + + *host_reg1 = REG_EBX; + *host_reg2 = REG_ECX; +} static void FP_POP() { @@ -1869,10 +2258,12 @@ static void FP_POP() addlong((uintptr_t)&TOP); } -#define FPU_ADD 0x00 -#define FPU_DIV 0x30 -#define FPU_MUL 0x08 -#define FPU_SUB 0x20 +#define FPU_ADD 0x00 +#define FPU_DIV 0x30 +#define FPU_DIVR 0x38 +#define FPU_MUL 0x08 +#define FPU_SUB 0x20 +#define FPU_SUBR 0x28 static void FP_OP_S(int op) { @@ -1898,6 +2289,256 @@ static void FP_OP_S(int op) addbyte(0xdd); addlong((uintptr_t)ST); } +static void FP_OP_D(int op) +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x04); + addbyte(0xdd); + addlong((uintptr_t)ST); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0xa3); + addlong((uintptr_t)tag); + addbyte(~TAG_UINT64); + addbyte(0xdc); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x1c); + addbyte(0xdd); + addlong((uintptr_t)ST); +} +static void FP_OP_IW(int op) +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x04); + addbyte(0xdd); + addlong((uintptr_t)ST); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0xa3); + addlong((uintptr_t)tag); + addbyte(~TAG_UINT64); + addbyte(0xde); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x1c); + addbyte(0xdd); + addlong((uintptr_t)ST); +} +static void FP_OP_IL(int op) +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x04); + addbyte(0xdd); + addlong((uintptr_t)ST); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0xa3); + addlong((uintptr_t)tag); + addbyte(~TAG_UINT64); + addbyte(0xda); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x1c); + addbyte(0xdd); + addlong((uintptr_t)ST); +} +static void FP_OP_IQ(int op) +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x04); + addbyte(0xdd); + addlong((uintptr_t)ST); + addbyte(0x80); /*AND tag[EBX], ~TAG_UINT64*/ + addbyte(0xa3); + addlong((uintptr_t)tag); + addbyte(~TAG_UINT64); + addbyte(0xdc); /*FADD [ESP]*/ + addbyte(0x04 | op); + addbyte(0x24); + addbyte(0xdd); /*FSTP [ST+EBX*8]*/ + addbyte(0x1c); + addbyte(0xdd); + addlong((uintptr_t)ST); +} + +#define C0 (1<<8) +#define C1 (1<<9) +#define C2 (1<<10) +#define C3 (1<<14) + +static void FP_COMPARE_S() +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x04); + addbyte(0xdd); + addlong((uintptr_t)ST); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x1d); + addlong(((uintptr_t)&npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0|C2|C3)) >> 8); + addbyte(0xd8); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0|C2|C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x1d); + addlong(((uintptr_t)&npxs) + 1); +} +static void FP_COMPARE_D() +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0x89); /*MOV [ESP+4], EDX*/ + addbyte(0x54); + addbyte(0x24); + addbyte(0x04); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x04); + addbyte(0xdd); + addlong((uintptr_t)ST); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x1d); + addlong(((uintptr_t)&npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0|C2|C3)) >> 8); + addbyte(0xdc); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0|C2|C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x1d); + addlong(((uintptr_t)&npxs) + 1); +} +static void FP_COMPARE_IW() +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x04); + addbyte(0xdd); + addlong((uintptr_t)ST); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x1d); + addlong(((uintptr_t)&npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0|C2|C3)) >> 8); + addbyte(0xde); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0|C2|C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x1d); + addlong(((uintptr_t)&npxs) + 1); +} +static void FP_COMPARE_IL() +{ + addbyte(0x8b); /*MOV EBX, TOP*/ + addbyte(0x1d); + addlong((uintptr_t)&TOP); + addbyte(0x89); /*MOV [ESP], EAX*/ + addbyte(0x04); + addbyte(0x24); + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x04); + addbyte(0xdd); + addlong((uintptr_t)ST); + addbyte(0x8a); /*MOV BL, [npxs+1]*/ + addbyte(0x1d); + addlong(((uintptr_t)&npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND BL, ~(C0|C2|C3)*/ + addbyte(0xe3); + addbyte((~(C0|C2|C3)) >> 8); + addbyte(0xda); /*FCOMP [ESP]*/ + addbyte(0x04 | 0x18); + addbyte(0x24); + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0|C2|C3) >> 8); + addbyte(0x08); /*OR BL, AH*/ + addbyte(0xe3); + addbyte(0x88); /*MOV [npxs+1], BL*/ + addbyte(0x1d); + addlong(((uintptr_t)&npxs) + 1); +} static void FP_OP_REG(int op, int dst, int src) { @@ -1951,6 +2592,64 @@ static void FP_OP_REG(int op, int dst, int src) } } +static void FP_COMPARE_REG(int dst, int src) +{ + addbyte(0xa1); /*MOV EAX, TOP*/ + addlong((uintptr_t)&TOP); + addbyte(0xbe); /*MOVL ESI, ST*/ + addlong((uintptr_t)ST); + addbyte(0x89); /*MOV EBX, EAX*/ + addbyte(0xc3); + if (src || dst) + { + addbyte(0x83); /*ADD EAX, 1*/ + addbyte(0xc0); + addbyte(src ? src : dst); + addbyte(0x83); /*AND EAX, 7*/ + addbyte(0xe0); + addbyte(7); + } + + addbyte(0x8a); /*MOV CL, [npxs+1]*/ + addbyte(0x0d); + addlong(((uintptr_t)&npxs) + 1); + addbyte(0xdb); /*FCLEX*/ + addbyte(0xe2); + addbyte(0x80); /*AND CL, ~(C0|C2|C3)*/ + addbyte(0xe1); + addbyte((~(C0|C2|C3)) >> 8); + + if (src) + { + addbyte(0xdd); /*FLD ST[EBX*8]*/ + addbyte(0x04); + addbyte(0xde); + addbyte(0xdc); /*FCOMP ST[EAX*8]*/ + addbyte(0x04 | 0x18); + addbyte(0xc6); + } + else + { + addbyte(0xdd); /*FLD [ESI+EAX*8]*/ + addbyte(0x04); + addbyte(0xc6); + addbyte(0xdc); /*FCOMP ST[EBX*8]*/ + addbyte(0x04 | 0x18); + addbyte(0xde); + } + + addbyte(0xdf); /*FSTSW AX*/ + addbyte(0xe0); + addbyte(0x80); /*AND AH, (C0|C2|C3)*/ + addbyte(0xe4); + addbyte((C0|C2|C3) >> 8); + addbyte(0x08); /*OR CL, AH*/ + addbyte(0xe1); + addbyte(0x88); /*MOV [npxs+1], CL*/ + addbyte(0x0d); + addlong(((uintptr_t)&npxs) + 1); +} + static void ZERO_EXTEND_W_B(int reg) { addbyte(0x0f); /*MOVZX regl, regb*/ diff --git a/src/codegen_x86.c b/src/codegen_x86.c index 47fe68f..1528590 100644 --- a/src/codegen_x86.c +++ b/src/codegen_x86.c @@ -23,6 +23,7 @@ int codegen_flags_changed = 0; int codegen_fpu_entered = 0; +int codegen_fpu_loaded_iq[8]; x86seg *op_ea_seg; int op_ssegs; uint32_t op_old_pc; @@ -257,6 +258,9 @@ void codegen_block_init(uint32_t phys_addr) codegen_flags_changed = 0; codegen_fpu_entered = 0; + + codegen_fpu_loaded_iq[0] = codegen_fpu_loaded_iq[1] = codegen_fpu_loaded_iq[2] = codegen_fpu_loaded_iq[3] = + codegen_fpu_loaded_iq[4] = codegen_fpu_loaded_iq[5] = codegen_fpu_loaded_iq[6] = codegen_fpu_loaded_iq[7] = 0; } void codegen_block_remove() @@ -771,7 +775,7 @@ void codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t break; case 0xda: op_table = (op_32 & 0x200) ? x86_dynarec_opcodes_da_a32 : x86_dynarec_opcodes_da_a16; - recomp_op_table = NULL; + recomp_op_table = recomp_opcodes_da; opcode_mask = 0xff; over = 1; pc_off = -1; diff --git a/src/ibm.h b/src/ibm.h index a167c53..7e1e214 100644 --- a/src/ibm.h +++ b/src/ibm.h @@ -36,6 +36,8 @@ uint16_t readmemwl(uint32_t seg, uint32_t addr); void writememwl(uint32_t seg, uint32_t addr, uint16_t val); uint32_t readmemll(uint32_t seg, uint32_t addr); void writememll(uint32_t seg, uint32_t addr, uint32_t val); +uint64_t readmemql(uint32_t seg, uint32_t addr); +void writememql(uint32_t seg, uint32_t addr, uint64_t val); uint8_t *getpccache(uint32_t a); diff --git a/src/mem.c b/src/mem.c index ba5dda4..4b086b8 100644 --- a/src/mem.c +++ b/src/mem.c @@ -1142,6 +1142,105 @@ void writememll(uint32_t seg, uint32_t addr, uint32_t val) // pclog("Bad writememll %08X %08X\n", addr2, val); } +uint64_t readmemql(uint32_t seg, uint32_t addr) +{ + uint32_t addr2 = mem_logical_addr = seg + addr; + if ((addr2&0xFFF)>0xFF8) + { + if (cr0>>31) + { + if (mmutranslate_read(addr2) == 0xffffffff) return 0xffffffff; + if (mmutranslate_read(addr2+7) == 0xffffffff) return 0xffffffff; + } + return readmemll(seg,addr)|((uint64_t)readmemll(seg,addr+4)<<32); + } + + if (seg==-1) + { + x86gpf("NULL segment", 0); + printf("NULL segment! rl %04X(%08X):%08X %02X %08X\n",CS,cs,pc,opcode,addr); + return -1; + } + + if (cr0>>31) + { + addr2 = mmutranslate_read(addr2); + if (addr2==0xFFFFFFFF) return 0xFFFFFFFF; + } + + addr2&=rammask; + + if (_mem_read_l[addr2 >> 14]) + return _mem_read_l[addr2 >> 14](addr2, _mem_priv_r[addr2 >> 14]) | + ((uint64_t)_mem_read_l[addr2 >> 14](addr2 + 4, _mem_priv_r[addr2 >> 14]) << 32); + + return readmemll(seg,addr) | ((uint64_t)readmemll(seg,addr+4)<<32); +} + +void writememql(uint32_t seg, uint32_t addr, uint64_t val) +{ + uint32_t addr2 = mem_logical_addr = seg + addr; + + if ((addr2 & 0xFFF) > 0xFF8) + { + if (cr0>>31) + { + if (mmutranslate_write(addr2) == 0xffffffff) return; + if (mmutranslate_write(addr2+7) == 0xffffffff) return; + } + writememll(seg, addr, val); + writememll(seg, addr+4, val >> 32); + return; + } + if (seg==-1) + { + x86gpf("NULL segment", 0); + printf("NULL segment! wl %04X(%08X):%08X %02X %08X\n",CS,cs,pc,opcode,addr); + return; + } + if (page_lookup[addr2>>12]) + { + page_lookup[addr2>>12]->write_l(addr2, val, page_lookup[addr2>>12]); + page_lookup[addr2>>12]->write_l(addr2 + 4, val >> 32, page_lookup[addr2>>12]); + return; + } + if (cr0>>31) + { + addr2 = mmutranslate_write(addr2); + if (addr2==0xFFFFFFFF) return; + } + + addr2&=rammask; + + if (_mem_write_l[addr2 >> 14]) + { + _mem_write_l[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); + _mem_write_l[addr2 >> 14](addr2+4, val >> 32, _mem_priv_w[addr2 >> 14]); + return; + } + if (_mem_write_w[addr2 >> 14]) + { + _mem_write_w[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); + _mem_write_w[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); + _mem_write_w[addr2 >> 14](addr2 + 4, val >> 32, _mem_priv_w[addr2 >> 14]); + _mem_write_w[addr2 >> 14](addr2 + 6, val >> 48, _mem_priv_w[addr2 >> 14]); + return; + } + if (_mem_write_b[addr2 >> 14]) + { + _mem_write_b[addr2 >> 14](addr2, val, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 1, val >> 8, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 2, val >> 16, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 3, val >> 24, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 4, val >> 32, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 5, val >> 40, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 6, val >> 48, _mem_priv_w[addr2 >> 14]); + _mem_write_b[addr2 >> 14](addr2 + 7, val >> 56, _mem_priv_w[addr2 >> 14]); + return; + } +// pclog("Bad writememql %08X %08X\n", addr2, val); +} + uint8_t mem_readb_phys(uint32_t addr) { mem_logical_addr = 0xffffffff; diff --git a/src/x86_ops_mmx.h b/src/x86_ops_mmx.h index 702070a..716221b 100644 --- a/src/x86_ops_mmx.h +++ b/src/x86_ops_mmx.h @@ -11,8 +11,7 @@ } \ else \ { \ - src.l[0] = readmeml(easeg, eaaddr); \ - src.l[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 1; \ + src.q = readmemq(easeg, eaaddr); if (abrt) return 1; \ CLOCK_CYCLES(2); \ } diff --git a/src/x86_ops_mmx_mov.h b/src/x86_ops_mmx_mov.h index dcc9868..bbe8f0c 100644 --- a/src/x86_ops_mmx_mov.h +++ b/src/x86_ops_mmx_mov.h @@ -94,12 +94,10 @@ static int opMOVQ_q_mm_a16(uint32_t fetchdat) } else { - uint32_t dst[2]; + uint64_t dst; - dst[0] = readmeml(easeg, eaaddr); - dst[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 1; - MM[reg].l[0] = dst[0]; - MM[reg].l[1] = dst[1]; + dst = readmemq(easeg, eaaddr); if (abrt) return 1; + MM[reg].q = dst; CLOCK_CYCLES(2); } return 0; @@ -116,12 +114,10 @@ static int opMOVQ_q_mm_a32(uint32_t fetchdat) } else { - uint32_t dst[2]; + uint64_t dst; - dst[0] = readmeml(easeg, eaaddr); - dst[1] = readmeml(easeg, eaaddr + 4); if (abrt) return 1; - MM[reg].l[0] = dst[0]; - MM[reg].l[1] = dst[1]; + dst = readmemq(easeg, eaaddr); if (abrt) return 1; + MM[reg].q = dst; CLOCK_CYCLES(2); } return 0; @@ -140,9 +136,7 @@ static int opMOVQ_mm_q_a16(uint32_t fetchdat) else { CHECK_WRITE(ea_seg, eaaddr, eaaddr + 7); - writememl(easeg, eaaddr, MM[reg].l[0]); - writememl(easeg, eaaddr + 4, MM[reg].l[1]); if (abrt) return 1; - CLOCK_CYCLES(2); + writememq(easeg, eaaddr, MM[reg].l[0]); } return 0; } @@ -159,9 +153,7 @@ static int opMOVQ_mm_q_a32(uint32_t fetchdat) else { CHECK_WRITE(ea_seg, eaaddr, eaaddr + 7); - writememl(easeg, eaaddr, MM[reg].l[0]); - writememl(easeg, eaaddr + 4, MM[reg].l[1]); if (abrt) return 1; - CLOCK_CYCLES(2); + writememq(easeg, eaaddr, MM[reg].q); } return 0; }