From 2a54c445a064eb678a7f9a10d9827991edda65d3 Mon Sep 17 00:00:00 2001 From: skidau Date: Fri, 17 Dec 2010 03:34:50 +0000 Subject: [PATCH] LLE JIT: Added another 9 DSP Load/Store instructions to the JIT. Fixed a couple bugs in the 32bit and Linux builds. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6599 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/DSPCore/Src/DSPEmitter.h | 14 +- Source/Core/DSPCore/Src/DSPTables.cpp | 18 +- .../Core/DSPCore/Src/Jit/DSPJitLoadStore.cpp | 221 ++++++++++++------ Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp | 51 +++- 4 files changed, 216 insertions(+), 88 deletions(-) diff --git a/Source/Core/DSPCore/Src/DSPEmitter.h b/Source/Core/DSPCore/Src/DSPEmitter.h index 5884cd50ce..bc3992a523 100644 --- a/Source/Core/DSPCore/Src/DSPEmitter.h +++ b/Source/Core/DSPCore/Src/DSPEmitter.h @@ -61,10 +61,11 @@ public: void decrement_addr_reg(int reg); void increase_addr_reg(int reg); void decrease_addr_reg(int reg); - void dmem_write(); - void dmem_write_imm(u16 addr); + void imem_read(); void dmem_read(); void dmem_read_imm(u16 addr); + void dmem_write(); + void dmem_write_imm(u16 addr); // Ext command helpers void pushExtValueFromReg(u16 dreg, u16 sreg); @@ -132,6 +133,15 @@ public: void lr(const UDSPInstruction opc); void sr(const UDSPInstruction opc); void si(const UDSPInstruction opc); + void lrr(const UDSPInstruction opc); + void lrrd(const UDSPInstruction opc); + void lrri(const UDSPInstruction opc); + void srr(const UDSPInstruction opc); + void srrd(const UDSPInstruction opc); + void srri(const UDSPInstruction opc); + void ilrr(const UDSPInstruction opc); + void ilrrd(const UDSPInstruction opc); + void ilrri(const UDSPInstruction opc); // Arithmetic void addr(const UDSPInstruction opc); diff --git a/Source/Core/DSPCore/Src/DSPTables.cpp b/Source/Core/DSPCore/Src/DSPTables.cpp index 6ed6e86925..f03b6f5e92 100644 --- a/Source/Core/DSPCore/Src/DSPTables.cpp +++ b/Source/Core/DSPCore/Src/DSPTables.cpp @@ -178,9 +178,9 @@ const DSPOPCTemplate opcodes[] = {"ANDF", 0x02a0, 0xfeff, DSPInterpreter::andf, NULL, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true}, {"ANDCF", 0x02c0, 0xfeff, DSPInterpreter::andcf, NULL, 2, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_IMM, 2, 1, 0, 0xffff}}, false, false, false, true}, - {"ILRR", 0x0210, 0xfefc, DSPInterpreter::ilrr, NULL, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false}, - {"ILRRD", 0x0214, 0xfefc, DSPInterpreter::ilrrd, NULL, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false}, - {"ILRRI", 0x0218, 0xfefc, DSPInterpreter::ilrri, NULL, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false}, + {"ILRR", 0x0210, 0xfefc, DSPInterpreter::ilrr, &DSPEmitter::ilrr, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false}, + {"ILRRD", 0x0214, 0xfefc, DSPInterpreter::ilrrd, &DSPEmitter::ilrrd, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false}, + {"ILRRI", 0x0218, 0xfefc, DSPInterpreter::ilrri, &DSPEmitter::ilrri, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false}, {"ILRRN", 0x021c, 0xfefc, DSPInterpreter::ilrrn, NULL, 1, 2, {{P_ACCM, 1, 0, 8, 0x0100}, {P_PRG, 1, 0, 0, 0x0003}}, false, false, false, false}, // LOOPS @@ -190,14 +190,14 @@ const DSPOPCTemplate opcodes[] = {"BLOOPI", 0x1100, 0xff00, DSPInterpreter::bloopi, NULL, 2, 2, {{P_IMM, 1, 0, 0, 0x00ff}, {P_ADDR_I, 2, 1, 0, 0xffff}}, false, true, false, true}, // load and store value pointed by indexing reg and increment; LRR/SRR variants - {"LRR", 0x1800, 0xff80, DSPInterpreter::lrr, NULL, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}}, false, false, false, false}, - {"LRRD", 0x1880, 0xff80, DSPInterpreter::lrrd, NULL, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}}, false, false, false, false}, - {"LRRI", 0x1900, 0xff80, DSPInterpreter::lrri, NULL, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}}, false, false, false, false}, + {"LRR", 0x1800, 0xff80, DSPInterpreter::lrr, &DSPEmitter::lrr, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}}, false, false, false, false}, + {"LRRD", 0x1880, 0xff80, DSPInterpreter::lrrd, &DSPEmitter::lrrd, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}}, false, false, false, false}, + {"LRRI", 0x1900, 0xff80, DSPInterpreter::lrri, &DSPEmitter::lrri, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}}, false, false, false, false}, {"LRRN", 0x1980, 0xff80, DSPInterpreter::lrrn, NULL, 1, 2, {{P_REG, 1, 0, 0, 0x001f}, {P_PRG, 1, 0, 5, 0x0060}}, false, false, false, false}, - {"SRR", 0x1a00, 0xff80, DSPInterpreter::srr, NULL, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}}, false, false, false, false}, - {"SRRD", 0x1a80, 0xff80, DSPInterpreter::srrd, NULL, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}}, false, false, false, false}, - {"SRRI", 0x1b00, 0xff80, DSPInterpreter::srri, NULL, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}}, false, false, false, false}, + {"SRR", 0x1a00, 0xff80, DSPInterpreter::srr, &DSPEmitter::srr, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}}, false, false, false, false}, + {"SRRD", 0x1a80, 0xff80, DSPInterpreter::srrd, &DSPEmitter::srrd, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}}, false, false, false, false}, + {"SRRI", 0x1b00, 0xff80, DSPInterpreter::srri, &DSPEmitter::srri, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}}, false, false, false, false}, {"SRRN", 0x1b80, 0xff80, DSPInterpreter::srrn, NULL, 1, 2, {{P_PRG, 1, 0, 5, 0x0060}, {P_REG, 1, 0, 0, 0x001f}}, false, false, false, false}, //2 diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitLoadStore.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitLoadStore.cpp index 52cee5a364..c98c5c067c 100644 --- a/Source/Core/DSPCore/Src/Jit/DSPJitLoadStore.cpp +++ b/Source/Core/DSPCore/Src/Jit/DSPJitLoadStore.cpp @@ -36,7 +36,7 @@ void DSPEmitter::srs(const UDSPInstruction opc) //u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc & 0xFF); #ifdef _M_IX86 // All32 MOVZX(32, 16, ECX, M(&g_dsp.r[reg])); - MOV(32, R(EAX), M(&g_dsp.r[DSP_REG_CR])); + MOVZX(32, 8, EAX, M(&g_dsp.r[DSP_REG_CR])); #else MOV(64, R(R11), ImmPtr(g_dsp.r)); MOVZX(64, 16, RCX, MDisp(R11,reg*2)); @@ -57,7 +57,7 @@ void DSPEmitter::lrs(const UDSPInstruction opc) u8 reg = ((opc >> 8) & 0x7) + 0x18; //u16 addr = (g_dsp.r[DSP_REG_CR] << 8) | (opc & 0xFF); #ifdef _M_IX86 // All32 - MOV(32, R(ECX), M(&g_dsp.r[DSP_REG_CR])); + MOVZX(32, 8, ECX, M(&g_dsp.r[DSP_REG_CR])); SHL(16, R(ECX), Imm8(8)); OR(8, R(ECX), Imm8(opc & 0xFF)); dmem_read(); @@ -118,47 +118,65 @@ void DSPEmitter::si(const UDSPInstruction opc) // 0001 1000 0ssd dddd // Move value from data memory pointed by addressing register $S to register $D. // FIXME: Perform additional operation depending on destination register. -//void DSPEmitter::lrr(const UDSPInstruction opc) -//{ -// u8 sreg = (opc >> 5) & 0x3; -// u8 dreg = opc & 0x1f; +void DSPEmitter::lrr(const UDSPInstruction opc) +{ + u8 sreg = (opc >> 5) & 0x3; + u8 dreg = opc & 0x1f; -// u16 val = dsp_dmem_read(dsp_op_read_reg(sreg)); -// dsp_op_write_reg(dreg, val); -// dsp_conditional_extend_accum(dreg); -//} + dsp_op_read_reg(sreg, ECX); +#ifdef _M_IX86 // All32 + MOVZX(32, 16, ECX, R(ECX)); +#else + MOVZX(64, 16, ECX, R(ECX)); +#endif + dmem_read(); + dsp_op_write_reg(dreg, EAX); + dsp_conditional_extend_accum(dreg); +} // LRRD $D, @$S // 0001 1000 1ssd dddd // Move value from data memory pointed by addressing register $S toregister $D. // Decrement register $S. // FIXME: Perform additional operation depending on destination register. -//void DSPEmitter::lrrd(const UDSPInstruction opc) -//{ -// u8 sreg = (opc >> 5) & 0x3; -// u8 dreg = opc & 0x1f; +void DSPEmitter::lrrd(const UDSPInstruction opc) +{ + u8 sreg = (opc >> 5) & 0x3; + u8 dreg = opc & 0x1f; -// u16 val = dsp_dmem_read(dsp_op_read_reg(sreg)); -// dsp_op_write_reg(dreg, val); -// dsp_conditional_extend_accum(dreg); -// g_dsp.r[sreg] = dsp_decrement_addr_reg(sreg); -//} + dsp_op_read_reg(sreg, ECX); +#ifdef _M_IX86 // All32 + MOVZX(32, 16, ECX, R(ECX)); +#else + MOVZX(64, 16, ECX, R(ECX)); +#endif + dmem_read(); + dsp_op_write_reg(dreg, EAX); + dsp_conditional_extend_accum(dreg); + decrement_addr_reg(sreg); +} // LRRI $D, @$S // 0001 1001 0ssd dddd // Move value from data memory pointed by addressing register $S to register $D. // Increment register $S. // FIXME: Perform additional operation depending on destination register. -//void DSPEmitter::lrri(const UDSPInstruction opc) -//{ -// u8 sreg = (opc >> 5) & 0x3; -// u8 dreg = opc & 0x1f; +void DSPEmitter::lrri(const UDSPInstruction opc) +{ + u8 sreg = (opc >> 5) & 0x3; + u8 dreg = opc & 0x1f; -// u16 val = dsp_dmem_read(dsp_op_read_reg(sreg)); -// dsp_op_write_reg(dreg, val); -// dsp_conditional_extend_accum(dreg); -// g_dsp.r[sreg] = dsp_increment_addr_reg(sreg); -//} + dsp_op_read_reg(sreg, ECX); +#ifdef _M_IX86 // All32 + MOVZX(32, 16, ECX, R(ECX)); +#else + MOVZX(64, 16, ECX, R(ECX)); +#endif + dmem_read(); + dsp_op_write_reg(dreg, EAX); + dsp_conditional_extend_accum(dreg); + increment_addr_reg(sreg); +} // LRRN $D, @$S // 0001 1001 1ssd dddd @@ -181,45 +199,62 @@ void DSPEmitter::si(const UDSPInstruction opc) // Store value from source register $S to a memory location pointed by // addressing register $D. // FIXME: Perform additional operation depending on source register. -//void DSPEmitter::srr(const UDSPInstruction opc) -//{ -// u8 dreg = (opc >> 5) & 0x3; -// u8 sreg = opc & 0x1f; +void DSPEmitter::srr(const UDSPInstruction opc) +{ + u8 dreg = (opc >> 5) & 0x3; + u8 sreg = opc & 0x1f; -// u16 val = dsp_op_read_reg(sreg); -// dsp_dmem_write(g_dsp.r[dreg], val); -//} + dsp_op_read_reg(sreg, ECX); +#ifdef _M_IX86 // All32 + MOVZX(32, 16, EAX, M(&g_dsp.r[dreg])); +#else + MOV(64, R(R11), ImmPtr(g_dsp.r)); + MOVZX(64, 16, RAX, MDisp(R11,dreg*2)); +#endif + dmem_write(); +} // SRRD @$D, $S // 0001 1010 1dds ssss // Store value from source register $S to a memory location pointed by // addressing register $D. Decrement register $D. // FIXME: Perform additional operation depending on source register. -//void DSPEmitter::srrd(const UDSPInstruction opc) -//{ -// u8 dreg = (opc >> 5) & 0x3; -// u8 sreg = opc & 0x1f; +void DSPEmitter::srrd(const UDSPInstruction opc) +{ + u8 dreg = (opc >> 5) & 0x3; + u8 sreg = opc & 0x1f; -// u16 val = dsp_op_read_reg(sreg); -// dsp_dmem_write(g_dsp.r[dreg], val); -// g_dsp.r[dreg] = dsp_decrement_addr_reg(dreg); -//} + dsp_op_read_reg(sreg, ECX); +#ifdef _M_IX86 // All32 + MOVZX(32, 16, EAX, M(&g_dsp.r[dreg])); +#else + MOV(64, R(R11), ImmPtr(g_dsp.r)); + MOVZX(64, 16, RAX, MDisp(R11,dreg*2)); +#endif + dmem_write(); + decrement_addr_reg(dreg); +} // SRRI @$D, $S // 0001 1011 0dds ssss // Store value from source register $S to a memory location pointed by // addressing register $D. Increment register $D. // FIXME: Perform additional operation depending on source register. -//void DSPEmitter::srri(const UDSPInstruction opc) -//{ -// u8 dreg = (opc >> 5) & 0x3; -// u8 sreg = opc & 0x1f; +void DSPEmitter::srri(const UDSPInstruction opc) +{ + u8 dreg = (opc >> 5) & 0x3; + u8 sreg = opc & 0x1f; -// u16 val = dsp_op_read_reg(sreg); - -// dsp_dmem_write(g_dsp.r[dreg], val); -// g_dsp.r[dreg] = dsp_increment_addr_reg(dreg); -//} + dsp_op_read_reg(sreg, ECX); +#ifdef _M_IX86 // All32 + MOVZX(32, 16, EAX, M(&g_dsp.r[dreg])); +#else + MOV(64, R(R11), ImmPtr(g_dsp.r)); + MOVZX(64, 16, RAX, MDisp(R11,dreg*2)); +#endif + dmem_write(); + increment_addr_reg(dreg); +} // SRRN @$D, $S // 0001 1011 1dds ssss @@ -240,42 +275,78 @@ void DSPEmitter::si(const UDSPInstruction opc) // 0000 001d 0001 00ss // Move value from instruction memory pointed by addressing register // $arS to mid accumulator register $acD.m. -//void DSPEmitter::ilrr(const UDSPInstruction opc) -//{ -// u16 reg = opc & 0x3; -// u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1); +void DSPEmitter::ilrr(const UDSPInstruction opc) +{ + u16 reg = opc & 0x3; + u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1); -// g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]); -// dsp_conditional_extend_accum(dreg); -//} +#ifdef _M_IX86 // All32 + MOVZX(32, 16, ECX, M(&g_dsp.r[reg])); +#else + MOV(64, R(R11), ImmPtr(g_dsp.r)); + MOVZX(64, 16, RCX, MDisp(R11,reg*2)); +#endif + imem_read(); +#ifdef _M_IX86 // All32 + MOV(16, M(&g_dsp.r[dreg]), R(EAX)); +#else + MOV(64, R(R11), ImmPtr(g_dsp.r)); + MOV(16, MDisp(R11,dreg*2), R(RAX)); +#endif + dsp_conditional_extend_accum(dreg); +} // ILRRD $acD.m, @$arS // 0000 001d 0001 01ss // Move value from instruction memory pointed by addressing register // $arS to mid accumulator register $acD.m. Decrement addressing register $arS. -//void DSPEmitter::ilrrd(const UDSPInstruction opc) -//{ -// u16 reg = opc & 0x3; -// u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1); +void DSPEmitter::ilrrd(const UDSPInstruction opc) +{ + u16 reg = opc & 0x3; + u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1); -// g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]); -// dsp_conditional_extend_accum(dreg); -// g_dsp.r[reg] = dsp_decrement_addr_reg(reg); -//} +#ifdef _M_IX86 // All32 + MOVZX(32, 16, ECX, M(&g_dsp.r[reg])); +#else + MOV(64, R(R11), ImmPtr(g_dsp.r)); + MOVZX(64, 16, RCX, MDisp(R11,reg*2)); +#endif + imem_read(); +#ifdef _M_IX86 // All32 + MOV(16, M(&g_dsp.r[dreg]), R(EAX)); +#else + MOV(64, R(R11), ImmPtr(g_dsp.r)); + MOV(16, MDisp(R11,dreg*2), R(RAX)); +#endif + dsp_conditional_extend_accum(dreg); + dsp_decrement_addr_reg(reg); +} // ILRRI $acD.m, @$S // 0000 001d 0001 10ss // Move value from instruction memory pointed by addressing register // $arS to mid accumulator register $acD.m. Increment addressing register $arS. -//void DSPEmitter::ilrri(const UDSPInstruction opc) -//{ -// u16 reg = opc & 0x3; -// u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1); +void DSPEmitter::ilrri(const UDSPInstruction opc) +{ + u16 reg = opc & 0x3; + u16 dreg = DSP_REG_ACM0 + ((opc >> 8) & 1); -// g_dsp.r[dreg] = dsp_imem_read(g_dsp.r[reg]); -// dsp_conditional_extend_accum(dreg); -// g_dsp.r[reg] = dsp_increment_addr_reg(reg); -//} +#ifdef _M_IX86 // All32 + MOVZX(32, 16, ECX, M(&g_dsp.r[reg])); +#else + MOV(64, R(R11), ImmPtr(g_dsp.r)); + MOVZX(64, 16, RCX, MDisp(R11,reg*2)); +#endif + imem_read(); +#ifdef _M_IX86 // All32 + MOV(16, M(&g_dsp.r[dreg]), R(EAX)); +#else + MOV(64, R(R11), ImmPtr(g_dsp.r)); + MOV(16, MDisp(R11,dreg*2), R(RAX)); +#endif + dsp_conditional_extend_accum(dreg); + dsp_increment_addr_reg(reg); +} // ILRRN $acD.m, @$arS // 0000 001d 0001 11ss diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp index 0d9a70295f..3d0cb8d38f 100644 --- a/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp +++ b/Source/Core/DSPCore/Src/Jit/DSPJitUtil.cpp @@ -338,7 +338,12 @@ void DSPEmitter::dmem_write_imm(u16 addr) switch (addr >> 12) { case 0x0: // 0xxx DRAM +#ifdef _M_IX86 // All32 MOV(16, M(&g_dsp.dram[addr & DSP_DRAM_MASK]), R(ECX)); +#else + MOV(64, R(RDX), ImmPtr(g_dsp.dram)); + MOV(16, MDisp(RDX,(addr & DSP_DRAM_MASK)*2), R(ECX)); +#endif break; case 0xf: // Fxxx HW regs @@ -352,8 +357,40 @@ void DSPEmitter::dmem_write_imm(u16 addr) } } -// EAX - the result of the read (used by caller) -// ECX - the address to read +// In: ECX - the address to read +// Out: EAX - the result of the read (used by caller) +// ESI - Base +void DSPEmitter::imem_read() +{ + // if (addr == 0) + CMP(16, R(ECX), Imm16(0x0fff)); + FixupBranch irom = J_CC(CC_A); + // return g_dsp.iram[addr & DSP_IRAM_MASK]; + AND(16, R(ECX), Imm16(DSP_IRAM_MASK)); +#ifdef _M_X64 + MOV(64, R(ESI), ImmPtr(g_dsp.iram)); +#else + MOV(32, R(ESI), ImmPtr(g_dsp.iram)); +#endif + MOV(16, R(EAX), MComplex(ESI, ECX, 2, 0)); + + FixupBranch end = J(); + SetJumpTarget(irom); + // else if (addr == 0x8) + // return g_dsp.irom[addr & DSP_IROM_MASK]; + AND(16, R(ECX), Imm16(DSP_IROM_MASK)); +#ifdef _M_X64 + MOV(64, R(ESI), ImmPtr(g_dsp.irom)); +#else + MOV(32, R(ESI), ImmPtr(g_dsp.irom)); +#endif + MOV(16, R(EAX), MComplex(ESI,ECX,2,0)); + + SetJumpTarget(end); +} + +// In: ECX - the address to read +// Out: EAX - the result of the read (used by caller) // ESI - Base // Trashes R11 on gdsp_ifx_read void DSPEmitter::dmem_read() @@ -399,11 +436,21 @@ void DSPEmitter::dmem_read_imm(u16 addr) switch (addr >> 12) { case 0x0: // 0xxx DRAM +#ifdef _M_IX86 // All32 MOV(16, R(EAX), M(&g_dsp.dram[addr & DSP_DRAM_MASK])); +#else + MOV(64, R(RDX), ImmPtr(g_dsp.dram)); + MOV(16, R(EAX), MDisp(RDX,(addr & DSP_DRAM_MASK)*2)); +#endif break; case 0x1: // 1xxx COEF +#ifdef _M_IX86 // All32 MOV(16, R(EAX), Imm16(g_dsp.coef[addr & DSP_COEF_MASK])); +#else + MOV(64, R(RDX), ImmPtr(g_dsp.coef)); + MOV(16, R(EAX), MDisp(RDX,(addr & DSP_COEF_MASK)*2)); +#endif break; case 0xf: // Fxxx HW regs