diff --git a/Source/Core/Core/Src/DSP/DSPEmitter.h b/Source/Core/Core/Src/DSP/DSPEmitter.h index 7fcb9a74f6..a59dd05ca6 100644 --- a/Source/Core/Core/Src/DSP/DSPEmitter.h +++ b/Source/Core/Core/Src/DSP/DSPEmitter.h @@ -120,8 +120,8 @@ public: void dsp_op_write_reg_imm(int reg, u16 val); void dsp_conditional_extend_accum(int reg); void dsp_conditional_extend_accum_imm(int reg, u16 val); + void dsp_op_read_reg_dont_saturate(int reg, Gen::X64Reg host_dreg, DSPJitSignExtend extend = NONE); void dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, DSPJitSignExtend extend = NONE); - void dsp_op_read_reg_and_saturate(int reg, Gen::X64Reg host_dreg, DSPJitSignExtend extend = NONE); // Commands void dar(const UDSPInstruction opc); diff --git a/Source/Core/Core/Src/DSP/Jit/DSPJitBranch.cpp b/Source/Core/Core/Src/DSP/Jit/DSPJitBranch.cpp index 252550b84c..deeaea28c9 100644 --- a/Source/Core/Core/Src/DSP/Jit/DSPJitBranch.cpp +++ b/Source/Core/Core/Src/DSP/Jit/DSPJitBranch.cpp @@ -334,7 +334,8 @@ void DSPEmitter::loop(const UDSPInstruction opc) { u16 reg = opc & 0x1f; // u16 cnt = g_dsp.r[reg]; - dsp_op_read_reg(reg, RDX, ZERO); +//todo: check if we can use normal variant here + dsp_op_read_reg_dont_saturate(reg, RDX, ZERO); u16 loop_pc = compilePC + 1; CMP(16, R(EDX), Imm16(0)); @@ -403,7 +404,8 @@ void DSPEmitter::bloop(const UDSPInstruction opc) { u16 reg = opc & 0x1f; // u16 cnt = g_dsp.r[reg]; - dsp_op_read_reg(reg, RDX, ZERO); +//todo: check if we can use normal variant here + dsp_op_read_reg_dont_saturate(reg, RDX, ZERO); u16 loop_pc = dsp_imem_read(compilePC + 1); CMP(16, R(EDX), Imm16(0)); diff --git a/Source/Core/Core/Src/DSP/Jit/DSPJitExtOps.cpp b/Source/Core/Core/Src/DSP/Jit/DSPJitExtOps.cpp index 40e39a89e9..91dae79ade 100644 --- a/Source/Core/Core/Src/DSP/Jit/DSPJitExtOps.cpp +++ b/Source/Core/Core/Src/DSP/Jit/DSPJitExtOps.cpp @@ -68,11 +68,8 @@ void DSPEmitter::mv(const UDSPInstruction opc) { u8 sreg = (opc & 0x3) + DSP_REG_ACL0; u8 dreg = ((opc >> 2) & 0x3); - if (sreg >= DSP_REG_ACM0) { - dsp_op_read_reg_and_saturate(sreg, RBX, ZERO); - storeIndex = dreg + DSP_REG_AXL0; - } else - pushExtValueFromReg(dreg + DSP_REG_AXL0, sreg); + dsp_op_read_reg(sreg, RBX, ZERO); + storeIndex = dreg + DSP_REG_AXL0; } // S @$arD, $acS.S @@ -89,10 +86,7 @@ void DSPEmitter::s(const UDSPInstruction opc) X64Reg tmp1; gpr.getFreeXReg(tmp1); - if (sreg >= DSP_REG_ACM0) - dsp_op_read_reg_and_saturate(sreg, tmp1, ZERO); - else - dsp_op_read_reg(sreg, tmp1, ZERO); + dsp_op_read_reg(sreg, tmp1, ZERO); // u16 val = g_dsp.r[src]; dmem_write(tmp1); @@ -114,10 +108,7 @@ void DSPEmitter::sn(const UDSPInstruction opc) X64Reg tmp1; gpr.getFreeXReg(tmp1); - if (sreg >= DSP_REG_ACM0) - dsp_op_read_reg_and_saturate(sreg, tmp1, ZERO); - else - dsp_op_read_reg(sreg, tmp1, ZERO); + dsp_op_read_reg(sreg, tmp1, ZERO); dmem_write(tmp1); gpr.putXReg(tmp1); @@ -187,7 +178,7 @@ void DSPEmitter::ls(const UDSPInstruction opc) X64Reg tmp1; gpr.getFreeXReg(tmp1); - dsp_op_read_reg_and_saturate(sreg + DSP_REG_ACM0, tmp1, ZERO); + dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO); dmem_write(tmp1); gpr.putXReg(tmp1); @@ -214,7 +205,7 @@ void DSPEmitter::lsn(const UDSPInstruction opc) X64Reg tmp1; gpr.getFreeXReg(tmp1); - dsp_op_read_reg_and_saturate(sreg + DSP_REG_ACM0, tmp1, ZERO); + dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO); dmem_write(tmp1); gpr.putXReg(tmp1); @@ -240,7 +231,7 @@ void DSPEmitter::lsm(const UDSPInstruction opc) X64Reg tmp1; gpr.getFreeXReg(tmp1); - dsp_op_read_reg_and_saturate(sreg + DSP_REG_ACM0, tmp1, ZERO); + dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO); dmem_write(tmp1); gpr.putXReg(tmp1); @@ -267,7 +258,7 @@ void DSPEmitter::lsnm(const UDSPInstruction opc) X64Reg tmp1; gpr.getFreeXReg(tmp1); - dsp_op_read_reg_and_saturate(sreg + DSP_REG_ACM0, tmp1, ZERO); + dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO); dmem_write(tmp1); gpr.putXReg(tmp1); @@ -292,7 +283,7 @@ void DSPEmitter::sl(const UDSPInstruction opc) X64Reg tmp1; gpr.getFreeXReg(tmp1); - dsp_op_read_reg_and_saturate(sreg + DSP_REG_ACM0, tmp1, ZERO); + dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO); dmem_write(tmp1); gpr.putXReg(tmp1); @@ -318,7 +309,7 @@ void DSPEmitter::sln(const UDSPInstruction opc) X64Reg tmp1; gpr.getFreeXReg(tmp1); - dsp_op_read_reg_and_saturate(sreg + DSP_REG_ACM0, tmp1, ZERO); + dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO); dmem_write(tmp1); gpr.putXReg(tmp1); @@ -344,7 +335,7 @@ void DSPEmitter::slm(const UDSPInstruction opc) X64Reg tmp1; gpr.getFreeXReg(tmp1); - dsp_op_read_reg_and_saturate(sreg + DSP_REG_ACM0, tmp1, ZERO); + dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO); dmem_write(tmp1); gpr.putXReg(tmp1); @@ -370,7 +361,7 @@ void DSPEmitter::slnm(const UDSPInstruction opc) X64Reg tmp1; gpr.getFreeXReg(tmp1); - dsp_op_read_reg_and_saturate(sreg + DSP_REG_ACM0, tmp1, ZERO); + dsp_op_read_reg(sreg + DSP_REG_ACM0, tmp1, ZERO); dmem_write(tmp1); gpr.putXReg(tmp1); @@ -649,14 +640,8 @@ void DSPEmitter::ldaxnm(const UDSPInstruction opc) increase_addr_reg(DSP_REG_AR3, DSP_REG_AR3); } - -// Push value from g_dsp.r[sreg] into EBX and stores the destinationindex in -// storeIndex -void DSPEmitter::pushExtValueFromReg(u16 dreg, u16 sreg) { - dsp_op_read_reg(sreg, RBX, ZERO); - storeIndex = dreg; -} - +// Push value from address in g_dsp.r[sreg] into EBX and stores the +// destinationindex in storeIndex void DSPEmitter::pushExtValueFromMem(u16 dreg, u16 sreg) { // u16 addr = g_dsp.r[addr]; diff --git a/Source/Core/Core/Src/DSP/Jit/DSPJitLoadStore.cpp b/Source/Core/Core/Src/DSP/Jit/DSPJitLoadStore.cpp index 248ed8f945..38255f0c47 100644 --- a/Source/Core/Core/Src/DSP/Jit/DSPJitLoadStore.cpp +++ b/Source/Core/Core/Src/DSP/Jit/DSPJitLoadStore.cpp @@ -39,10 +39,7 @@ void DSPEmitter::srs(const UDSPInstruction opc) X64Reg tmp1; gpr.getFreeXReg(tmp1); - if (reg >= DSP_REG_ACM0) - dsp_op_read_reg_and_saturate(reg, tmp1, ZERO); - else - dsp_op_read_reg(reg, tmp1, ZERO); + dsp_op_read_reg(reg, tmp1, ZERO); dsp_op_read_reg(DSP_REG_CR, RAX, ZERO); SHL(16, R(EAX), Imm8(8)); OR(16, R(EAX), Imm16(opc & 0xFF)); @@ -101,10 +98,7 @@ void DSPEmitter::sr(const UDSPInstruction opc) X64Reg tmp1; gpr.getFreeXReg(tmp1); - if (reg >= DSP_REG_ACM0) - dsp_op_read_reg_and_saturate(reg, tmp1); - else - dsp_op_read_reg(reg, tmp1); + dsp_op_read_reg(reg, tmp1); dmem_write_imm(address, tmp1); gpr.putXReg(tmp1); @@ -227,10 +221,7 @@ void DSPEmitter::srr(const UDSPInstruction opc) X64Reg tmp1; gpr.getFreeXReg(tmp1); - if (sreg >= DSP_REG_ACM0) - dsp_op_read_reg_and_saturate(sreg, tmp1); - else - dsp_op_read_reg(sreg, tmp1); + dsp_op_read_reg(sreg, tmp1); dsp_op_read_reg(dreg, RAX, ZERO); dmem_write(tmp1); @@ -249,10 +240,7 @@ void DSPEmitter::srrd(const UDSPInstruction opc) X64Reg tmp1; gpr.getFreeXReg(tmp1); - if (sreg >= DSP_REG_ACM0) - dsp_op_read_reg_and_saturate(sreg, tmp1); - else - dsp_op_read_reg(sreg, tmp1); + dsp_op_read_reg(sreg, tmp1); dsp_op_read_reg(dreg, RAX, ZERO); dmem_write(tmp1); @@ -273,10 +261,7 @@ void DSPEmitter::srri(const UDSPInstruction opc) X64Reg tmp1; gpr.getFreeXReg(tmp1); - if (sreg >= DSP_REG_ACM0) - dsp_op_read_reg_and_saturate(sreg, tmp1); - else - dsp_op_read_reg(sreg, tmp1); + dsp_op_read_reg(sreg, tmp1); dsp_op_read_reg(dreg, RAX, ZERO); dmem_write(tmp1); @@ -297,10 +282,7 @@ void DSPEmitter::srrn(const UDSPInstruction opc) X64Reg tmp1; gpr.getFreeXReg(tmp1); - if (sreg >= DSP_REG_ACM0) - dsp_op_read_reg_and_saturate(sreg, tmp1); - else - dsp_op_read_reg(sreg, tmp1); + dsp_op_read_reg(sreg, tmp1); dsp_op_read_reg(dreg, RAX, ZERO); dmem_write(tmp1); diff --git a/Source/Core/Core/Src/DSP/Jit/DSPJitMisc.cpp b/Source/Core/Core/Src/DSP/Jit/DSPJitMisc.cpp index e26db20ecf..6138bc5455 100644 --- a/Source/Core/Core/Src/DSP/Jit/DSPJitMisc.cpp +++ b/Source/Core/Core/Src/DSP/Jit/DSPJitMisc.cpp @@ -31,10 +31,7 @@ void DSPEmitter::mrr(const UDSPInstruction opc) u8 sreg = opc & 0x1f; u8 dreg = (opc >> 5) & 0x1f; - if (sreg >= DSP_REG_ACM0) - dsp_op_read_reg_and_saturate(sreg, EDX); - else - dsp_op_read_reg(sreg, EDX); + dsp_op_read_reg(sreg, EDX); dsp_op_write_reg(dreg, EDX); dsp_conditional_extend_accum(dreg); } diff --git a/Source/Core/Core/Src/DSP/Jit/DSPJitUtil.cpp b/Source/Core/Core/Src/DSP/Jit/DSPJitUtil.cpp index 38c4dc23ca..adf4d33276 100644 --- a/Source/Core/Core/Src/DSP/Jit/DSPJitUtil.cpp +++ b/Source/Core/Core/Src/DSP/Jit/DSPJitUtil.cpp @@ -206,7 +206,7 @@ void DSPEmitter::dsp_conditional_extend_accum_imm(int reg, u16 val) } } -void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, DSPJitSignExtend extend) +void DSPEmitter::dsp_op_read_reg_dont_saturate(int reg, Gen::X64Reg host_dreg, DSPJitSignExtend extend) { switch (reg & 0x1f) { case DSP_REG_ST0: @@ -240,91 +240,125 @@ void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, DSPJitSignExten } } -void DSPEmitter::dsp_op_read_reg_and_saturate(int reg, Gen::X64Reg host_dreg, DSPJitSignExtend extend) +void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, DSPJitSignExtend extend) { - //we already know this is ACCM0 or ACCM1 + switch (reg & 0x1f) { + case DSP_REG_ST0: + case DSP_REG_ST1: + case DSP_REG_ST2: + case DSP_REG_ST3: + dsp_reg_load_stack(reg - DSP_REG_ST0, host_dreg); + switch(extend) { + case SIGN: #ifdef _M_IX86 // All32 - gpr.readReg(reg, host_dreg, extend); + MOVSX(32, 16, host_dreg, R(host_dreg)); #else - OpArg acc_reg; - gpr.getReg(reg-DSP_REG_ACM0+DSP_REG_ACC0_64, acc_reg); + MOVSX(64, 16, host_dreg, R(host_dreg)); #endif - OpArg sr_reg; - gpr.getReg(DSP_REG_SR,sr_reg); + break; + case ZERO: +#ifdef _M_IX86 // All32 + MOVZX(32, 16, host_dreg, R(host_dreg)); +#else + MOVZX(64, 16, host_dreg, R(host_dreg)); +#endif + break; + case NONE: + default: + break; + } + return; + case DSP_REG_ACM0: + case DSP_REG_ACM1: { + //we already know this is ACCM0 or ACCM1 +#ifdef _M_IX86 // All32 + gpr.readReg(reg, host_dreg, extend); +#else + OpArg acc_reg; + gpr.getReg(reg-DSP_REG_ACM0+DSP_REG_ACC0_64, acc_reg); +#endif + OpArg sr_reg; + gpr.getReg(DSP_REG_SR,sr_reg); - DSPJitRegCache c(gpr); - TEST(16, sr_reg, Imm16(SR_40_MODE_BIT)); - FixupBranch not_40bit = J_CC(CC_Z, true); + DSPJitRegCache c(gpr); + TEST(16, sr_reg, Imm16(SR_40_MODE_BIT)); + FixupBranch not_40bit = J_CC(CC_Z, true); #ifdef _M_IX86 // All32 - DSPJitRegCache c2(gpr); - gpr.putReg(DSP_REG_SR, false); - X64Reg tmp1; - gpr.getFreeXReg(tmp1); - gpr.readReg(reg-DSP_REG_ACM0+DSP_REG_ACH0, tmp1, NONE); - MOVSX(32,16,host_dreg,R(host_dreg)); - SHL(32, R(tmp1), Imm8(16)); - MOV(16,R(tmp1),R(host_dreg)); - CMP(32,R(host_dreg), R(tmp1)); + DSPJitRegCache c2(gpr); + gpr.putReg(DSP_REG_SR, false); + X64Reg tmp1; + gpr.getFreeXReg(tmp1); + gpr.readReg(reg-DSP_REG_ACM0+DSP_REG_ACH0, tmp1, NONE); + MOVSX(32,16,host_dreg,R(host_dreg)); + SHL(32, R(tmp1), Imm8(16)); + MOV(16,R(tmp1),R(host_dreg)); + CMP(32,R(host_dreg), R(tmp1)); - FixupBranch no_saturate = J_CC(CC_Z); + FixupBranch no_saturate = J_CC(CC_Z); - CMP(32,R(tmp1),Imm32(0)); - FixupBranch negative = J_CC(CC_LE); + CMP(32,R(tmp1),Imm32(0)); + FixupBranch negative = J_CC(CC_LE); - MOV(32,R(host_dreg),Imm32(0x7fff));//this works for all extend modes - FixupBranch done_positive = J(); + MOV(32,R(host_dreg),Imm32(0x7fff));//this works for all extend modes + FixupBranch done_positive = J(); - SetJumpTarget(negative); - if (extend == NONE || extend == ZERO) - MOV(32,R(host_dreg),Imm32(0x00008000)); - else - MOV(32,R(host_dreg),Imm32(0xffff8000)); - FixupBranch done_negative = J(); + SetJumpTarget(negative); + if (extend == NONE || extend == ZERO) + MOV(32,R(host_dreg),Imm32(0x00008000)); + else + MOV(32,R(host_dreg),Imm32(0xffff8000)); + FixupBranch done_negative = J(); - SetJumpTarget(no_saturate); - if (extend == ZERO) - MOVZX(32,16,host_dreg,R(host_dreg)); - SetJumpTarget(done_positive); - SetJumpTarget(done_negative); - gpr.putXReg(tmp1); - gpr.flushRegs(c2); - SetJumpTarget(not_40bit); - gpr.flushRegs(c); + SetJumpTarget(no_saturate); + if (extend == ZERO) + MOVZX(32,16,host_dreg,R(host_dreg)); + SetJumpTarget(done_positive); + SetJumpTarget(done_negative); + gpr.putXReg(tmp1); + gpr.flushRegs(c2); + SetJumpTarget(not_40bit); + gpr.flushRegs(c); #else - MOVSX(64,32,host_dreg,acc_reg); - CMP(64,R(host_dreg),acc_reg); - FixupBranch no_saturate = J_CC(CC_Z); + MOVSX(64,32,host_dreg,acc_reg); + CMP(64,R(host_dreg),acc_reg); + FixupBranch no_saturate = J_CC(CC_Z); - CMP(64,acc_reg,Imm32(0)); - FixupBranch negative = J_CC(CC_LE); + CMP(64,acc_reg,Imm32(0)); + FixupBranch negative = J_CC(CC_LE); - MOV(64,R(host_dreg),Imm32(0x7fff));//this works for all extend modes - FixupBranch done_positive = J(); + MOV(64,R(host_dreg),Imm32(0x7fff));//this works for all extend modes + FixupBranch done_positive = J(); - SetJumpTarget(negative); - if (extend == NONE || extend == ZERO) - MOV(64,R(host_dreg),Imm32(0x00008000)); - else - MOV(64,R(host_dreg),Imm32(0xffff8000)); - FixupBranch done_negative = J(); + SetJumpTarget(negative); + if (extend == NONE || extend == ZERO) + MOV(64,R(host_dreg),Imm32(0x00008000)); + else + MOV(64,R(host_dreg),Imm32(0xffff8000)); + FixupBranch done_negative = J(); - SetJumpTarget(no_saturate); - SetJumpTarget(not_40bit); + SetJumpTarget(no_saturate); + SetJumpTarget(not_40bit); - MOV(64, R(host_dreg), acc_reg); - if (extend == NONE || extend == ZERO) - SHR(64, R(host_dreg), Imm8(16)); - else - SAR(64, R(host_dreg), Imm8(16)); - SetJumpTarget(done_positive); - SetJumpTarget(done_negative); - gpr.flushRegs(c); - gpr.putReg(reg-DSP_REG_ACM0+DSP_REG_ACC0_64, false); + MOV(64, R(host_dreg), acc_reg); + if (extend == NONE || extend == ZERO) + SHR(64, R(host_dreg), Imm8(16)); + else + SAR(64, R(host_dreg), Imm8(16)); + SetJumpTarget(done_positive); + SetJumpTarget(done_negative); + gpr.flushRegs(c); + gpr.putReg(reg-DSP_REG_ACM0+DSP_REG_ACC0_64, false); #endif - gpr.putReg(DSP_REG_SR, false); + gpr.putReg(DSP_REG_SR, false); + } + return; + default: + gpr.readReg(reg, host_dreg, extend); + return; + } } // addr math