From 14739c55c34d16208380bec5f2502b3267dd5a43 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Wed, 15 Mar 2017 21:46:31 +0000 Subject: [PATCH 1/2] DSP/Jit: PIE support --- Source/Core/Core/DSP/Jit/DSPEmitter.cpp | 55 ++++++++++++++---- Source/Core/Core/DSP/Jit/DSPEmitter.h | 8 +++ Source/Core/Core/DSP/Jit/DSPJitBranch.cpp | 58 +++++++++---------- Source/Core/Core/DSP/Jit/DSPJitMultiplier.cpp | 7 ++- Source/Core/Core/DSP/Jit/DSPJitRegCache.cpp | 49 ++++++++-------- Source/Core/Core/DSP/Jit/DSPJitRegCache.h | 3 +- Source/Core/Core/DSP/Jit/DSPJitUtil.cpp | 18 +++--- 7 files changed, 122 insertions(+), 76 deletions(-) diff --git a/Source/Core/Core/DSP/Jit/DSPEmitter.cpp b/Source/Core/Core/DSP/Jit/DSPEmitter.cpp index 13a7f6f0ba..16c794fcc7 100644 --- a/Source/Core/Core/DSP/Jit/DSPEmitter.cpp +++ b/Source/Core/Core/DSP/Jit/DSPEmitter.cpp @@ -5,6 +5,7 @@ #include "Core/DSP/Jit/DSPEmitter.h" #include +#include #include #include "Common/Assert.h" @@ -105,10 +106,10 @@ void DSPEmitter::ClearIRAMandDSPJITCodespaceReset() void DSPEmitter::checkExceptions(u32 retval) { // Check for interrupts and exceptions - TEST(8, M(&g_dsp.exceptions), Imm8(0xff)); + TEST(8, M_SDSP_exceptions(), Imm8(0xff)); FixupBranch skipCheck = J_CC(CC_Z, true); - MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc)); + MOV(16, M_SDSP_pc(), Imm16(m_compile_pc)); DSPJitRegCache c(m_gpr); m_gpr.SaveRegs(); @@ -138,7 +139,7 @@ void DSPEmitter::FallBackToInterpreter(UDSPInstruction inst) // of block. // Fallbacks to interpreter need this for fetching immediate values - MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 1)); + MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 1)); } // Fall back to interpreter @@ -250,18 +251,18 @@ void DSPEmitter::Compile(u16 start_addr) // by the analyzer. if (Analyzer::GetCodeFlags(static_cast(m_compile_pc - 1u)) & Analyzer::CODE_LOOP_END) { - MOVZX(32, 16, EAX, M(&(g_dsp.r.st[2]))); + MOVZX(32, 16, EAX, M_SDSP_r_st(2)); TEST(32, R(EAX), R(EAX)); FixupBranch rLoopAddressExit = J_CC(CC_LE, true); - MOVZX(32, 16, EAX, M(&g_dsp.r.st[3])); + MOVZX(32, 16, EAX, M_SDSP_r_st(3)); TEST(32, R(EAX), R(EAX)); FixupBranch rLoopCounterExit = J_CC(CC_LE, true); if (!opcode->branch) { // branch insns update the g_dsp.pc - MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc)); + MOV(16, M_SDSP_pc(), Imm16(m_compile_pc)); } // These functions branch and therefore only need to be called in the @@ -296,7 +297,7 @@ void DSPEmitter::Compile(u16 start_addr) else if (!opcode->jitFunc) { // look at g_dsp.pc if we actually branched - MOV(16, R(AX), M(&g_dsp.pc)); + MOV(16, R(AX), M_SDSP_pc()); CMP(16, R(AX), Imm16(m_compile_pc)); FixupBranch rNoBranch = J_CC(CC_Z, true); @@ -328,7 +329,7 @@ void DSPEmitter::Compile(u16 start_addr) if (fixup_pc) { - MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc)); + MOV(16, M_SDSP_pc(), Imm16(m_compile_pc)); } m_blocks[start_addr] = (DSPCompiledCode)entryPoint; @@ -415,21 +416,23 @@ void DSPEmitter::CompileDispatcher() BitSet32 registers_used = ABI_ALL_CALLEE_SAVED & BitSet32(0xffff); ABI_PushRegistersAndAdjustStack(registers_used, 8); + MOV(64, R(R15), ImmPtr(&g_dsp)); + const u8* dispatcherLoop = GetCodePtr(); FixupBranch exceptionExit; if (Host::OnThread()) { - CMP(8, M(const_cast(&g_dsp.external_interrupt_waiting)), Imm8(0)); + CMP(8, M_SDSP_external_interrupt_waiting(), Imm8(0)); exceptionExit = J_CC(CC_NE); } // Check for DSP halt - TEST(8, M(&g_dsp.cr), Imm8(CR_HALT)); + TEST(8, M_SDSP_cr(), Imm8(CR_HALT)); FixupBranch _halt = J_CC(CC_NE); // Execute block. Cycles executed returned in EAX. - MOVZX(64, 16, ECX, M(&g_dsp.pc)); + MOVZX(64, 16, ECX, M_SDSP_pc()); MOV(64, R(RBX), ImmPtr(m_blocks.data())); JMPptr(MComplex(RBX, RCX, SCALE_8, 0)); @@ -452,6 +455,36 @@ void DSPEmitter::CompileDispatcher() RET(); } +Gen::OpArg DSPEmitter::M_SDSP_pc() +{ + return MDisp(R15, static_cast(offsetof(SDSP, pc))); +} + +Gen::OpArg DSPEmitter::M_SDSP_exceptions() +{ + return MDisp(R15, static_cast(offsetof(SDSP, exceptions))); +} + +Gen::OpArg DSPEmitter::M_SDSP_cr() +{ + return MDisp(R15, static_cast(offsetof(SDSP, cr))); +} + +Gen::OpArg DSPEmitter::M_SDSP_external_interrupt_waiting() +{ + return MDisp(R15, static_cast(offsetof(SDSP, external_interrupt_waiting))); +} + +Gen::OpArg DSPEmitter::M_SDSP_r_st(size_t index) +{ + return MDisp(R15, static_cast(offsetof(SDSP, r.st[index]))); +} + +Gen::OpArg DSPEmitter::M_SDSP_reg_stack_ptr(size_t index) +{ + return MDisp(R15, static_cast(offsetof(SDSP, reg_stack_ptr[index]))); +} + } // namespace x86 } // namespace JIT } // namespace DSP diff --git a/Source/Core/Core/DSP/Jit/DSPEmitter.h b/Source/Core/Core/DSP/Jit/DSPEmitter.h index 56238c3b06..d3aa1269f0 100644 --- a/Source/Core/Core/DSP/Jit/DSPEmitter.h +++ b/Source/Core/Core/DSP/Jit/DSPEmitter.h @@ -279,6 +279,14 @@ private: void dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, RegisterExtension extend = RegisterExtension::None); + // SDSP memory offset helpers + Gen::OpArg M_SDSP_pc(); + Gen::OpArg M_SDSP_exceptions(); + Gen::OpArg M_SDSP_cr(); + Gen::OpArg M_SDSP_external_interrupt_waiting(); + Gen::OpArg M_SDSP_r_st(size_t index); + Gen::OpArg M_SDSP_reg_stack_ptr(size_t index); + // Ext command helpers void popExtValueToReg(); void pushExtValueFromMem(u16 dreg, u16 sreg); diff --git a/Source/Core/Core/DSP/Jit/DSPJitBranch.cpp b/Source/Core/Core/DSP/Jit/DSPJitBranch.cpp index 287971c605..960b7c4482 100644 --- a/Source/Core/Core/DSP/Jit/DSPJitBranch.cpp +++ b/Source/Core/Core/DSP/Jit/DSPJitBranch.cpp @@ -136,7 +136,7 @@ void DSPEmitter::r_jcc(const UDSPInstruction opc) // If the block is unconditional, attempt to link block if (opcode->uncond_branch) WriteBlockLink(dest); - MOV(16, M(&g_dsp.pc), Imm16(dest)); + MOV(16, M_SDSP_pc(), Imm16(dest)); WriteBranchExit(); } // Generic jmp implementation @@ -148,7 +148,7 @@ void DSPEmitter::r_jcc(const UDSPInstruction opc) // NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit void DSPEmitter::jcc(const UDSPInstruction opc) { - MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 2)); + MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 2)); ReJitConditional(opc, &DSPEmitter::r_jcc); } @@ -158,7 +158,7 @@ void DSPEmitter::r_jmprcc(const UDSPInstruction opc) // reg can only be DSP_REG_ARx and DSP_REG_IXx now, // no need to handle DSP_REG_STx. dsp_op_read_reg(reg, RAX); - MOV(16, M(&g_dsp.pc), R(EAX)); + MOV(16, M_SDSP_pc(), R(EAX)); WriteBranchExit(); } // Generic jmpr implementation @@ -168,7 +168,7 @@ void DSPEmitter::r_jmprcc(const UDSPInstruction opc) // NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit void DSPEmitter::jmprcc(const UDSPInstruction opc) { - MOV(16, M(&g_dsp.pc), Imm16(m_compile_pc + 1)); + MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 1)); ReJitConditional(opc, &DSPEmitter::r_jmprcc); } @@ -182,7 +182,7 @@ void DSPEmitter::r_call(const UDSPInstruction opc) // If the block is unconditional, attempt to link block if (opcode->uncond_branch) WriteBlockLink(dest); - MOV(16, M(&g_dsp.pc), Imm16(dest)); + MOV(16, M_SDSP_pc(), Imm16(dest)); WriteBranchExit(); } // Generic call implementation @@ -195,7 +195,7 @@ void DSPEmitter::r_call(const UDSPInstruction opc) // NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit void DSPEmitter::call(const UDSPInstruction opc) { - MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 2)); + MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 2)); ReJitConditional(opc, &DSPEmitter::r_call); } @@ -205,7 +205,7 @@ void DSPEmitter::r_callr(const UDSPInstruction opc) MOV(16, R(DX), Imm16(m_compile_pc + 1)); dsp_reg_store_stack(StackRegister::Call); dsp_op_read_reg(reg, RAX); - MOV(16, M(&g_dsp.pc), R(EAX)); + MOV(16, M_SDSP_pc(), R(EAX)); WriteBranchExit(); } // Generic callr implementation @@ -217,13 +217,13 @@ void DSPEmitter::r_callr(const UDSPInstruction opc) // NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit void DSPEmitter::callr(const UDSPInstruction opc) { - MOV(16, M(&g_dsp.pc), Imm16(m_compile_pc + 1)); + MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 1)); ReJitConditional(opc, &DSPEmitter::r_callr); } void DSPEmitter::r_ifcc(const UDSPInstruction opc) { - MOV(16, M(&g_dsp.pc), Imm16(m_compile_pc + 1)); + MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 1)); } // Generic if implementation // IFcc @@ -235,7 +235,7 @@ void DSPEmitter::ifcc(const UDSPInstruction opc) const u16 address = m_compile_pc + 1; const DSPOPCTemplate* const op_template = GetOpTemplate(dsp_imem_read(address)); - MOV(16, M(&g_dsp.pc), Imm16(address + op_template->size)); + MOV(16, M_SDSP_pc(), Imm16(address + op_template->size)); ReJitConditional(opc, &DSPEmitter::r_ifcc); WriteBranchExit(); } @@ -243,7 +243,7 @@ void DSPEmitter::ifcc(const UDSPInstruction opc) void DSPEmitter::r_ret(const UDSPInstruction opc) { dsp_reg_load_stack(StackRegister::Call); - MOV(16, M(&g_dsp.pc), R(DX)); + MOV(16, M_SDSP_pc(), R(DX)); WriteBranchExit(); } @@ -255,7 +255,7 @@ void DSPEmitter::r_ret(const UDSPInstruction opc) // NOTE: Cannot use FallBackToInterpreter(opc) here because of the need to write branch exit void DSPEmitter::ret(const UDSPInstruction opc) { - MOV(16, M(&g_dsp.pc), Imm16(m_compile_pc + 1)); + MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 1)); ReJitConditional(opc, &DSPEmitter::r_ret); } @@ -271,7 +271,7 @@ void DSPEmitter::rti(const UDSPInstruction opc) dsp_op_write_reg(DSP_REG_SR, RDX); // g_dsp.pc = dsp_reg_load_stack(StackRegister::Call); dsp_reg_load_stack(StackRegister::Call); - MOV(16, M(&g_dsp.pc), R(DX)); + MOV(16, M_SDSP_pc(), R(DX)); } // HALT @@ -279,10 +279,10 @@ void DSPEmitter::rti(const UDSPInstruction opc) // Stops execution of DSP code. Sets bit DSP_CR_HALT in register DREG_CR. void DSPEmitter::halt(const UDSPInstruction opc) { - OR(16, M(&g_dsp.cr), Imm16(4)); + OR(16, M_SDSP_cr(), Imm16(4)); // g_dsp.pc = dsp_reg_load_stack(StackRegister::Call); dsp_reg_load_stack(StackRegister::Call); - MOV(16, M(&g_dsp.pc), R(DX)); + MOV(16, M_SDSP_pc(), R(DX)); } // LOOP handling: Loop stack is used to control execution of repeated blocks of @@ -293,20 +293,20 @@ void DSPEmitter::halt(const UDSPInstruction opc) // continues at next opcode. void DSPEmitter::HandleLoop() { - MOVZX(32, 16, EAX, M(&g_dsp.r.st[2])); - MOVZX(32, 16, ECX, M(&g_dsp.r.st[3])); + MOVZX(32, 16, EAX, M_SDSP_r_st(2)); + MOVZX(32, 16, ECX, M_SDSP_r_st(3)); TEST(32, R(RCX), R(RCX)); FixupBranch rLoopCntG = J_CC(CC_LE, true); CMP(16, R(RAX), Imm16(m_compile_pc - 1)); FixupBranch rLoopAddrG = J_CC(CC_NE, true); - SUB(16, M(&(g_dsp.r.st[3])), Imm16(1)); - CMP(16, M(&(g_dsp.r.st[3])), Imm16(0)); + SUB(16, M_SDSP_r_st(3), Imm16(1)); + CMP(16, M_SDSP_r_st(3), Imm16(0)); FixupBranch loadStack = J_CC(CC_LE, true); - MOVZX(32, 16, ECX, M(&(g_dsp.r.st[0]))); - MOV(16, M(&g_dsp.pc), R(RCX)); + MOVZX(32, 16, ECX, M_SDSP_r_st(0)); + MOV(16, M_SDSP_pc(), R(RCX)); FixupBranch loopUpdated = J(true); SetJumpTarget(loadStack); @@ -346,12 +346,12 @@ void DSPEmitter::loop(const UDSPInstruction opc) MOV(16, R(RDX), Imm16(loop_pc)); dsp_reg_store_stack(StackRegister::LoopAddress); m_gpr.FlushRegs(c); - MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 1)); + MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 1)); FixupBranch exit = J(true); SetJumpTarget(cnt); // dsp_skip_inst(); - MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size)); + MOV(16, M_SDSP_pc(), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size)); WriteBranchExit(); m_gpr.FlushRegs(c, false); SetJumpTarget(exit); @@ -379,12 +379,12 @@ void DSPEmitter::loopi(const UDSPInstruction opc) MOV(16, R(RDX), Imm16(cnt)); dsp_reg_store_stack(StackRegister::LoopCounter); - MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 1)); + MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 1)); } else { // dsp_skip_inst(); - MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size)); + MOV(16, M_SDSP_pc(), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size)); WriteBranchExit(); } } @@ -414,14 +414,14 @@ void DSPEmitter::bloop(const UDSPInstruction opc) dsp_reg_store_stack(StackRegister::Call); MOV(16, R(RDX), Imm16(loop_pc)); dsp_reg_store_stack(StackRegister::LoopAddress); - MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 2)); + MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 2)); m_gpr.FlushRegs(c, true); FixupBranch exit = J(true); SetJumpTarget(cnt); // g_dsp.pc = loop_pc; // dsp_skip_inst(); - MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size)); + MOV(16, M_SDSP_pc(), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size)); WriteBranchExit(); m_gpr.FlushRegs(c, false); SetJumpTarget(exit); @@ -451,13 +451,13 @@ void DSPEmitter::bloopi(const UDSPInstruction opc) MOV(16, R(RDX), Imm16(cnt)); dsp_reg_store_stack(StackRegister::LoopCounter); - MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 2)); + MOV(16, M_SDSP_pc(), Imm16(m_compile_pc + 2)); } else { // g_dsp.pc = loop_pc; // dsp_skip_inst(); - MOV(16, M(&g_dsp.pc), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size)); + MOV(16, M_SDSP_pc(), Imm16(loop_pc + GetOpTemplate(dsp_imem_read(loop_pc))->size)); WriteBranchExit(); } } diff --git a/Source/Core/Core/DSP/Jit/DSPJitMultiplier.cpp b/Source/Core/Core/DSP/Jit/DSPJitMultiplier.cpp index 77d6e38032..7378763158 100644 --- a/Source/Core/Core/DSP/Jit/DSPJitMultiplier.cpp +++ b/Source/Core/Core/DSP/Jit/DSPJitMultiplier.cpp @@ -6,6 +6,8 @@ // Multiplier and product register control +#include + #include "Common/CommonTypes.h" #include "Core/DSP/DSPCore.h" @@ -151,9 +153,10 @@ void DSPEmitter::multiply_mulx(u8 axh0, u8 axh1) // direct use of prod regs by AX/AXWII (look @that part of ucode). void DSPEmitter::clrp(const UDSPInstruction opc) { + int offset = static_cast(offsetof(SDSP, r.prod.val)); // 64bit move to memory does not work. use 2 32bits - MOV(32, M(((u32*)&g_dsp.r.prod.val) + 0), Imm32(0xfff00000U)); - MOV(32, M(((u32*)&g_dsp.r.prod.val) + 1), Imm32(0x001000ffU)); + MOV(32, MDisp(R15, offset + 0 * sizeof(u32)), Imm32(0xfff00000U)); + MOV(32, MDisp(R15, offset + 1 * sizeof(u32)), Imm32(0x001000ffU)); } // TSTPROD diff --git a/Source/Core/Core/DSP/Jit/DSPJitRegCache.cpp b/Source/Core/Core/DSP/Jit/DSPJitRegCache.cpp index 1734353ba0..ec4f9b5ea2 100644 --- a/Source/Core/Core/DSP/Jit/DSPJitRegCache.cpp +++ b/Source/Core/Core/DSP/Jit/DSPJitRegCache.cpp @@ -5,6 +5,7 @@ #include "Core/DSP/Jit/DSPJitRegCache.h" #include +#include #include "Common/Assert.h" #include "Common/Logging/Log.h" @@ -26,7 +27,7 @@ namespace x86 constexpr std::array s_allocation_order = { {R8, R9, R10, R11, R12, R13, R14, R15, RSI, RDI, RBX, RCX, RDX, RAX, RBP}}; -static void* GetRegisterPointer(size_t reg) +static Gen::OpArg GetRegisterPointer(size_t reg) { switch (reg) { @@ -34,60 +35,60 @@ static void* GetRegisterPointer(size_t reg) case DSP_REG_AR1: case DSP_REG_AR2: case DSP_REG_AR3: - return &g_dsp.r.ar[reg - DSP_REG_AR0]; + return MDisp(R15, static_cast(offsetof(SDSP, r.ar[reg - DSP_REG_AR0]))); case DSP_REG_IX0: case DSP_REG_IX1: case DSP_REG_IX2: case DSP_REG_IX3: - return &g_dsp.r.ix[reg - DSP_REG_IX0]; + return MDisp(R15, static_cast(offsetof(SDSP, r.ix[reg - DSP_REG_IX0]))); case DSP_REG_WR0: case DSP_REG_WR1: case DSP_REG_WR2: case DSP_REG_WR3: - return &g_dsp.r.wr[reg - DSP_REG_WR0]; + return MDisp(R15, static_cast(offsetof(SDSP, r.wr[reg - DSP_REG_WR0]))); case DSP_REG_ST0: case DSP_REG_ST1: case DSP_REG_ST2: case DSP_REG_ST3: - return &g_dsp.r.st[reg - DSP_REG_ST0]; + return MDisp(R15, static_cast(offsetof(SDSP, r.st[reg - DSP_REG_ST0]))); case DSP_REG_ACH0: case DSP_REG_ACH1: - return &g_dsp.r.ac[reg - DSP_REG_ACH0].h; + return MDisp(R15, static_cast(offsetof(SDSP, r.ac[reg - DSP_REG_ACH0].h))); case DSP_REG_CR: - return &g_dsp.r.cr; + return MDisp(R15, static_cast(offsetof(SDSP, r.cr))); case DSP_REG_SR: - return &g_dsp.r.sr; + return MDisp(R15, static_cast(offsetof(SDSP, r.sr))); case DSP_REG_PRODL: - return &g_dsp.r.prod.l; + return MDisp(R15, static_cast(offsetof(SDSP, r.prod.l))); case DSP_REG_PRODM: - return &g_dsp.r.prod.m; + return MDisp(R15, static_cast(offsetof(SDSP, r.prod.m))); case DSP_REG_PRODH: - return &g_dsp.r.prod.h; + return MDisp(R15, static_cast(offsetof(SDSP, r.prod.h))); case DSP_REG_PRODM2: - return &g_dsp.r.prod.m2; + return MDisp(R15, static_cast(offsetof(SDSP, r.prod.m2))); case DSP_REG_AXL0: case DSP_REG_AXL1: - return &g_dsp.r.ax[reg - DSP_REG_AXL0].l; + return MDisp(R15, static_cast(offsetof(SDSP, r.ax[reg - DSP_REG_AXL0].l))); case DSP_REG_AXH0: case DSP_REG_AXH1: - return &g_dsp.r.ax[reg - DSP_REG_AXH0].h; + return MDisp(R15, static_cast(offsetof(SDSP, r.ax[reg - DSP_REG_AXH0].h))); case DSP_REG_ACL0: case DSP_REG_ACL1: - return &g_dsp.r.ac[reg - DSP_REG_ACL0].l; + return MDisp(R15, static_cast(offsetof(SDSP, r.ac[reg - DSP_REG_ACL0].l))); case DSP_REG_ACM0: case DSP_REG_ACM1: - return &g_dsp.r.ac[reg - DSP_REG_ACM0].m; + return MDisp(R15, static_cast(offsetof(SDSP, r.ac[reg - DSP_REG_ACM0].m))); case DSP_REG_AX0_32: case DSP_REG_AX1_32: - return &g_dsp.r.ax[reg - DSP_REG_AX0_32].val; + return MDisp(R15, static_cast(offsetof(SDSP, r.ax[reg - DSP_REG_AX0_32].val))); case DSP_REG_ACC0_64: case DSP_REG_ACC1_64: - return &g_dsp.r.ac[reg - DSP_REG_ACC0_64].val; + return MDisp(R15, static_cast(offsetof(SDSP, r.ac[reg - DSP_REG_ACC0_64].val))); case DSP_REG_PROD_64: - return &g_dsp.r.prod.val; + return MDisp(R15, static_cast(offsetof(SDSP, r.prod.val))); default: _assert_msg_(DSPLLE, 0, "cannot happen"); - return nullptr; + return M(static_cast(nullptr)); } } @@ -129,7 +130,7 @@ DSPJitRegCache::DSPJitRegCache(DSPEmitter& emitter) m_xregs[R12].guest_reg = DSP_REG_NONE; m_xregs[R13].guest_reg = DSP_REG_NONE; m_xregs[R14].guest_reg = DSP_REG_NONE; - m_xregs[R15].guest_reg = DSP_REG_NONE; + m_xregs[R15].guest_reg = DSP_REG_STATIC; // reserved for SDSP pointer for (size_t i = 0; i < m_regs.size(); i++) { @@ -141,7 +142,7 @@ DSPJitRegCache::DSPJitRegCache(DSPEmitter& emitter) m_regs[i].parentReg = DSP_REG_NONE; m_regs[i].shift = 0; m_regs[i].host_reg = INVALID_REG; - m_regs[i].loc = M(m_regs[i].mem); + m_regs[i].loc = m_regs[i].mem; } for (unsigned int i = 0; i < 32; i++) @@ -374,7 +375,7 @@ void DSPJitRegCache::FlushRegs() _assert_msg_(DSPLLE, m_xregs[R12].guest_reg == DSP_REG_NONE, "wrong xreg state for %d", R12); _assert_msg_(DSPLLE, m_xregs[R13].guest_reg == DSP_REG_NONE, "wrong xreg state for %d", R13); _assert_msg_(DSPLLE, m_xregs[R14].guest_reg == DSP_REG_NONE, "wrong xreg state for %d", R14); - _assert_msg_(DSPLLE, m_xregs[R15].guest_reg == DSP_REG_NONE, "wrong xreg state for %d", R15); + _assert_msg_(DSPLLE, m_xregs[R15].guest_reg == DSP_REG_STATIC, "wrong xreg state for %d", R15); m_use_ctr = 0; } @@ -654,7 +655,7 @@ void DSPJitRegCache::MovToMemory(size_t reg) _assert_msg_(DSPLLE, m_regs[reg].shift == 0, "still shifted??"); // move to mem - OpArg tmp = M(m_regs[reg].mem); + OpArg tmp = m_regs[reg].mem; if (m_regs[reg].dirty) { diff --git a/Source/Core/Core/DSP/Jit/DSPJitRegCache.h b/Source/Core/Core/DSP/Jit/DSPJitRegCache.h index fd4897c928..9d55d37ff5 100644 --- a/Source/Core/Core/DSP/Jit/DSPJitRegCache.h +++ b/Source/Core/Core/DSP/Jit/DSPJitRegCache.h @@ -5,6 +5,7 @@ #pragma once #include + #include "Common/x64Emitter.h" namespace DSP @@ -143,7 +144,7 @@ private: struct DynamicReg { Gen::OpArg loc; - void* mem; + Gen::OpArg mem; size_t size; bool dirty; bool used; diff --git a/Source/Core/Core/DSP/Jit/DSPJitUtil.cpp b/Source/Core/Core/DSP/Jit/DSPJitUtil.cpp index 6ad61868e8..842362c1fb 100644 --- a/Source/Core/Core/DSP/Jit/DSPJitUtil.cpp +++ b/Source/Core/Core/DSP/Jit/DSPJitUtil.cpp @@ -25,15 +25,15 @@ void DSPEmitter::dsp_reg_stack_push(StackRegister stack_reg) // g_dsp.reg_stack_ptr[reg_index]++; // g_dsp.reg_stack_ptr[reg_index] &= DSP_STACK_MASK; - MOV(8, R(AL), M(&g_dsp.reg_stack_ptr[reg_index])); + MOV(8, R(AL), M_SDSP_reg_stack_ptr(reg_index)); ADD(8, R(AL), Imm8(1)); AND(8, R(AL), Imm8(DSP_STACK_MASK)); - MOV(8, M(&g_dsp.reg_stack_ptr[reg_index]), R(AL)); + MOV(8, M_SDSP_reg_stack_ptr(reg_index), R(AL)); X64Reg tmp1 = m_gpr.GetFreeXReg(); X64Reg tmp2 = m_gpr.GetFreeXReg(); // g_dsp.reg_stack[reg_index][g_dsp.reg_stack_ptr[reg_index]] = g_dsp.r[DSP_REG_ST0 + reg_index]; - MOV(16, R(tmp1), M(&g_dsp.r.st[reg_index])); + MOV(16, R(tmp1), M_SDSP_r_st(reg_index)); MOVZX(64, 8, RAX, R(AL)); MOV(64, R(tmp2), ImmPtr(g_dsp.reg_stack[reg_index])); MOV(16, MComplex(tmp2, EAX, SCALE_2, 0), R(tmp1)); @@ -49,13 +49,13 @@ void DSPEmitter::dsp_reg_stack_pop(StackRegister stack_reg) const auto reg_index = static_cast(stack_reg); // g_dsp.r[DSP_REG_ST0 + reg_index] = g_dsp.reg_stack[reg_index][g_dsp.reg_stack_ptr[reg_index]]; - MOV(8, R(AL), M(&g_dsp.reg_stack_ptr[reg_index])); + MOV(8, R(AL), M_SDSP_reg_stack_ptr(reg_index)); X64Reg tmp1 = m_gpr.GetFreeXReg(); X64Reg tmp2 = m_gpr.GetFreeXReg(); MOVZX(64, 8, RAX, R(AL)); MOV(64, R(tmp2), ImmPtr(g_dsp.reg_stack[reg_index])); MOV(16, R(tmp1), MComplex(tmp2, EAX, SCALE_2, 0)); - MOV(16, M(&g_dsp.r.st[reg_index]), R(tmp1)); + MOV(16, M_SDSP_r_st(reg_index), R(tmp1)); m_gpr.PutXReg(tmp1); m_gpr.PutXReg(tmp2); @@ -63,7 +63,7 @@ void DSPEmitter::dsp_reg_stack_pop(StackRegister stack_reg) // g_dsp.reg_stack_ptr[reg_index] &= DSP_STACK_MASK; SUB(8, R(AL), Imm8(1)); AND(8, R(AL), Imm8(DSP_STACK_MASK)); - MOV(8, M(&g_dsp.reg_stack_ptr[reg_index]), R(AL)); + MOV(8, M_SDSP_reg_stack_ptr(reg_index), R(AL)); } void DSPEmitter::dsp_reg_store_stack(StackRegister stack_reg, Gen::X64Reg host_sreg) @@ -76,13 +76,13 @@ void DSPEmitter::dsp_reg_store_stack(StackRegister stack_reg, Gen::X64Reg host_s dsp_reg_stack_push(stack_reg); // g_dsp.r[DSP_REG_ST0 + stack_reg] = val; - MOV(16, M(&g_dsp.r.st[static_cast(stack_reg)]), R(EDX)); + MOV(16, M_SDSP_r_st(static_cast(stack_reg)), R(EDX)); } void DSPEmitter::dsp_reg_load_stack(StackRegister stack_reg, Gen::X64Reg host_dreg) { // u16 val = g_dsp.r[DSP_REG_ST0 + stack_reg]; - MOV(16, R(EDX), M(&g_dsp.r.st[static_cast(stack_reg)])); + MOV(16, R(EDX), M_SDSP_r_st(static_cast(stack_reg))); dsp_reg_stack_pop(stack_reg); @@ -97,7 +97,7 @@ void DSPEmitter::dsp_reg_store_stack_imm(StackRegister stack_reg, u16 val) dsp_reg_stack_push(stack_reg); // g_dsp.r[DSP_REG_ST0 + stack_reg] = val; - MOV(16, M(&g_dsp.r.st[static_cast(stack_reg)]), Imm16(val)); + MOV(16, M_SDSP_r_st(static_cast(stack_reg)), Imm16(val)); } void DSPEmitter::dsp_op_write_reg(int reg, Gen::X64Reg host_sreg) From 5e7d01dea40b402d134f902f33ee2cd76ede4a9a Mon Sep 17 00:00:00 2001 From: MerryMage Date: Fri, 17 Mar 2017 17:09:50 +0000 Subject: [PATCH 2/2] DSPJitRegCache: Remove ebp_store Restoring RBP before function calls is a no-op. --- Source/Core/Core/DSP/Jit/DSPJitRegCache.cpp | 30 +-------------------- 1 file changed, 1 insertion(+), 29 deletions(-) diff --git a/Source/Core/Core/DSP/Jit/DSPJitRegCache.cpp b/Source/Core/Core/DSP/Jit/DSPJitRegCache.cpp index ec4f9b5ea2..2cda9196c1 100644 --- a/Source/Core/Core/DSP/Jit/DSPJitRegCache.cpp +++ b/Source/Core/Core/DSP/Jit/DSPJitRegCache.cpp @@ -380,8 +380,6 @@ void DSPJitRegCache::FlushRegs() m_use_ctr = 0; } -static u64 ebp_store; - void DSPJitRegCache::LoadRegs(bool emit) { for (size_t i = 0; i < m_regs.size(); i++) @@ -391,11 +389,6 @@ void DSPJitRegCache::LoadRegs(bool emit) MovToHostReg(i, m_regs[i].host_reg, emit); } } - - if (emit) - { - m_emitter.MOV(64, M(&ebp_store), R(RBP)); - } } void DSPJitRegCache::SaveRegs() @@ -411,8 +404,6 @@ void DSPJitRegCache::SaveRegs() _assert_msg_(DSPLLE, !m_regs[i].loc.IsSimpleReg(), "register %zu is still a simple reg", i); } - - m_emitter.MOV(64, R(RBP), M(&ebp_store)); } void DSPJitRegCache::PushRegs() @@ -455,14 +446,10 @@ void DSPJitRegCache::PushRegs() m_xregs[i].guest_reg == DSP_REG_NONE || m_xregs[i].guest_reg == DSP_REG_STATIC, "register %zu is still used", i); } - - m_emitter.MOV(64, R(RBP), M(&ebp_store)); } void DSPJitRegCache::PopRegs() { - m_emitter.MOV(64, M(&ebp_store), R(RBP)); - int push_count = 0; for (int i = static_cast(m_xregs.size() - 1); i >= 0; i--) { @@ -493,22 +480,7 @@ void DSPJitRegCache::PopRegs() X64Reg DSPJitRegCache::MakeABICallSafe(X64Reg reg) { - if (reg != RBP) - { - return reg; - } - - size_t rbp_guest = m_xregs[RBP].guest_reg; - m_xregs[RBP].guest_reg = DSP_REG_USED; - X64Reg safe = FindSpillFreeXReg(); - _assert_msg_(DSPLLE, safe != INVALID_REG, "could not find register"); - if (safe == INVALID_REG) - { - m_emitter.INT3(); - } - m_xregs[RBP].guest_reg = rbp_guest; - m_emitter.MOV(64, R(safe), R(reg)); - return safe; + return reg; } void DSPJitRegCache::MovToHostReg(size_t reg, X64Reg host_reg, bool load)