Merge pull request #4777 from lioncash/dspstack

DSPCore: Convert DSP stack register enum into an enum class
This commit is contained in:
Markus Wick
2017-02-04 08:27:11 +01:00
committed by GitHub
9 changed files with 118 additions and 99 deletions

View File

@ -218,8 +218,8 @@ void DSPCore_CheckExceptions()
if (Interpreter::dsp_SR_is_flag_set(SR_INT_ENABLE) || (i == EXP_INT)) if (Interpreter::dsp_SR_is_flag_set(SR_INT_ENABLE) || (i == EXP_INT))
{ {
// store pc and sr until RTI // store pc and sr until RTI
dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc); dsp_reg_store_stack(StackRegister::Call, g_dsp.pc);
dsp_reg_store_stack(DSP_STACK_D, g_dsp.r.sr); dsp_reg_store_stack(StackRegister::Data, g_dsp.r.sr);
g_dsp.pc = i * 2; g_dsp.pc = i * 2;
g_dsp.exceptions &= ~(1 << i); g_dsp.exceptions &= ~(1 << i);

View File

@ -161,11 +161,12 @@ enum : u32
DSP_CMBL = 0xff // CPU Mailbox L DSP_CMBL = 0xff // CPU Mailbox L
}; };
// Stacks enum class StackRegister
enum : int
{ {
DSP_STACK_C, Call,
DSP_STACK_D Data,
LoopAddress,
LoopCounter
}; };
// cr (Not g_dsp.r[CR]) bits // cr (Not g_dsp.r[CR]) bits

View File

@ -3,38 +3,44 @@
// Licensed under GPLv2+ // Licensed under GPLv2+
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "Common/CommonTypes.h"
#include "Core/DSP/DSPCore.h"
#include "Core/DSP/DSPStacks.h" #include "Core/DSP/DSPStacks.h"
#include <cstddef>
#include "Common/CommonTypes.h"
#include "Core/DSP/DSPCore.h"
// Stacks. The stacks are outside the DSP RAM, in dedicated hardware. // Stacks. The stacks are outside the DSP RAM, in dedicated hardware.
namespace DSP namespace DSP
{ {
static void dsp_reg_stack_push(int stack_reg) static void dsp_reg_stack_push(size_t stack_reg)
{ {
g_dsp.reg_stack_ptr[stack_reg]++; g_dsp.reg_stack_ptr[stack_reg]++;
g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK; g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK;
g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]] = g_dsp.r.st[stack_reg]; g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]] = g_dsp.r.st[stack_reg];
} }
static void dsp_reg_stack_pop(int stack_reg) static void dsp_reg_stack_pop(size_t stack_reg)
{ {
g_dsp.r.st[stack_reg] = g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]]; g_dsp.r.st[stack_reg] = g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]];
g_dsp.reg_stack_ptr[stack_reg]--; g_dsp.reg_stack_ptr[stack_reg]--;
g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK; g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK;
} }
void dsp_reg_store_stack(int stack_reg, u16 val) void dsp_reg_store_stack(StackRegister stack_reg, u16 val)
{ {
dsp_reg_stack_push(stack_reg); const auto reg_index = static_cast<size_t>(stack_reg);
g_dsp.r.st[stack_reg] = val;
dsp_reg_stack_push(reg_index);
g_dsp.r.st[reg_index] = val;
} }
u16 dsp_reg_load_stack(int stack_reg) u16 dsp_reg_load_stack(StackRegister stack_reg)
{ {
u16 val = g_dsp.r.st[stack_reg]; const auto reg_index = static_cast<size_t>(stack_reg);
dsp_reg_stack_pop(stack_reg);
const u16 val = g_dsp.r.st[reg_index];
dsp_reg_stack_pop(reg_index);
return val; return val;
} }
} // namespace DSP } // namespace DSP

View File

@ -9,6 +9,8 @@
namespace DSP namespace DSP
{ {
void dsp_reg_store_stack(int stack_reg, u16 val); enum class StackRegister;
u16 dsp_reg_load_stack(int stack_reg);
void dsp_reg_store_stack(StackRegister stack_reg, u16 val);
u16 dsp_reg_load_stack(StackRegister stack_reg);
} // namespace DSP } // namespace DSP

View File

@ -28,7 +28,7 @@ void call(const UDSPInstruction opc)
u16 dest = dsp_fetch_code(); u16 dest = dsp_fetch_code();
if (CheckCondition(opc & 0xf)) if (CheckCondition(opc & 0xf))
{ {
dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc); dsp_reg_store_stack(StackRegister::Call, g_dsp.pc);
g_dsp.pc = dest; g_dsp.pc = dest;
} }
} }
@ -45,7 +45,7 @@ void callr(const UDSPInstruction opc)
{ {
u8 reg = (opc >> 5) & 0x7; u8 reg = (opc >> 5) & 0x7;
u16 addr = dsp_op_read_reg(reg); u16 addr = dsp_op_read_reg(reg);
dsp_reg_store_stack(DSP_STACK_C, g_dsp.pc); dsp_reg_store_stack(StackRegister::Call, g_dsp.pc);
g_dsp.pc = addr; g_dsp.pc = addr;
} }
} }
@ -100,7 +100,7 @@ void ret(const UDSPInstruction opc)
{ {
if (CheckCondition(opc & 0xf)) if (CheckCondition(opc & 0xf))
{ {
g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C); g_dsp.pc = dsp_reg_load_stack(StackRegister::Call);
} }
} }
@ -111,8 +111,8 @@ void ret(const UDSPInstruction opc)
// location. // location.
void rti(const UDSPInstruction opc) void rti(const UDSPInstruction opc)
{ {
g_dsp.r.sr = dsp_reg_load_stack(DSP_STACK_D); g_dsp.r.sr = dsp_reg_load_stack(StackRegister::Data);
g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C); g_dsp.pc = dsp_reg_load_stack(StackRegister::Call);
} }
// HALT // HALT
@ -150,9 +150,9 @@ void HandleLoop()
else else
{ {
// end of loop // end of loop
dsp_reg_load_stack(0); dsp_reg_load_stack(StackRegister::Call);
dsp_reg_load_stack(2); dsp_reg_load_stack(StackRegister::LoopAddress);
dsp_reg_load_stack(3); dsp_reg_load_stack(StackRegister::LoopCounter);
} }
} }
} }
@ -174,9 +174,9 @@ void loop(const UDSPInstruction opc)
if (cnt) if (cnt)
{ {
dsp_reg_store_stack(0, g_dsp.pc); dsp_reg_store_stack(StackRegister::Call, g_dsp.pc);
dsp_reg_store_stack(2, loop_pc); dsp_reg_store_stack(StackRegister::LoopAddress, loop_pc);
dsp_reg_store_stack(3, cnt); dsp_reg_store_stack(StackRegister::LoopCounter, cnt);
} }
else else
{ {
@ -199,9 +199,9 @@ void loopi(const UDSPInstruction opc)
if (cnt) if (cnt)
{ {
dsp_reg_store_stack(0, g_dsp.pc); dsp_reg_store_stack(StackRegister::Call, g_dsp.pc);
dsp_reg_store_stack(2, loop_pc); dsp_reg_store_stack(StackRegister::LoopAddress, loop_pc);
dsp_reg_store_stack(3, cnt); dsp_reg_store_stack(StackRegister::LoopCounter, cnt);
} }
else else
{ {
@ -226,9 +226,9 @@ void bloop(const UDSPInstruction opc)
if (cnt) if (cnt)
{ {
dsp_reg_store_stack(0, g_dsp.pc); dsp_reg_store_stack(StackRegister::Call, g_dsp.pc);
dsp_reg_store_stack(2, loop_pc); dsp_reg_store_stack(StackRegister::LoopAddress, loop_pc);
dsp_reg_store_stack(3, cnt); dsp_reg_store_stack(StackRegister::LoopCounter, cnt);
} }
else else
{ {
@ -253,9 +253,9 @@ void bloopi(const UDSPInstruction opc)
if (cnt) if (cnt)
{ {
dsp_reg_store_stack(0, g_dsp.pc); dsp_reg_store_stack(StackRegister::Call, g_dsp.pc);
dsp_reg_store_stack(2, loop_pc); dsp_reg_store_stack(StackRegister::LoopAddress, loop_pc);
dsp_reg_store_stack(3, cnt); dsp_reg_store_stack(StackRegister::LoopCounter, cnt);
} }
else else
{ {

View File

@ -117,7 +117,7 @@ static inline u16 dsp_op_read_reg(int _reg)
case DSP_REG_ST1: case DSP_REG_ST1:
case DSP_REG_ST2: case DSP_REG_ST2:
case DSP_REG_ST3: case DSP_REG_ST3:
return dsp_reg_load_stack(reg - DSP_REG_ST0); return dsp_reg_load_stack(static_cast<StackRegister>(reg - DSP_REG_ST0));
case DSP_REG_AR0: case DSP_REG_AR0:
case DSP_REG_AR1: case DSP_REG_AR1:
case DSP_REG_AR2: case DSP_REG_AR2:
@ -184,9 +184,8 @@ static inline void dsp_op_write_reg(int _reg, u16 val)
case DSP_REG_ST1: case DSP_REG_ST1:
case DSP_REG_ST2: case DSP_REG_ST2:
case DSP_REG_ST3: case DSP_REG_ST3:
dsp_reg_store_stack(reg - DSP_REG_ST0, val); dsp_reg_store_stack(static_cast<StackRegister>(reg - DSP_REG_ST0), val);
break; break;
case DSP_REG_AR0: case DSP_REG_AR0:
case DSP_REG_AR1: case DSP_REG_AR1:
case DSP_REG_AR2: case DSP_REG_AR2:

View File

@ -17,6 +17,8 @@
namespace DSP namespace DSP
{ {
enum class StackRegister;
namespace JIT namespace JIT
{ {
namespace x86 namespace x86
@ -100,11 +102,11 @@ public:
void nr(const UDSPInstruction opc); void nr(const UDSPInstruction opc);
void nop(const UDSPInstruction opc) {} void nop(const UDSPInstruction opc) {}
// Command helpers // Command helpers
void dsp_reg_stack_push(int stack_reg); void dsp_reg_stack_push(StackRegister stack_reg);
void dsp_reg_stack_pop(int stack_reg); void dsp_reg_stack_pop(StackRegister stack_reg);
void dsp_reg_store_stack(int stack_reg, Gen::X64Reg host_sreg = Gen::EDX); void dsp_reg_store_stack(StackRegister stack_reg, Gen::X64Reg host_sreg = Gen::EDX);
void dsp_reg_load_stack(int stack_reg, Gen::X64Reg host_dreg = Gen::EDX); void dsp_reg_load_stack(StackRegister stack_reg, Gen::X64Reg host_dreg = Gen::EDX);
void dsp_reg_store_stack_imm(int stack_reg, u16 val); void dsp_reg_store_stack_imm(StackRegister stack_reg, u16 val);
void dsp_op_write_reg(int reg, Gen::X64Reg host_sreg); void dsp_op_write_reg(int reg, Gen::X64Reg host_sreg);
void dsp_op_write_reg_imm(int reg, u16 val); void dsp_op_write_reg_imm(int reg, u16 val);
void dsp_conditional_extend_accum(int reg); void dsp_conditional_extend_accum(int reg);

View File

@ -174,7 +174,7 @@ void DSPEmitter::jmprcc(const UDSPInstruction opc)
void DSPEmitter::r_call(const UDSPInstruction opc) void DSPEmitter::r_call(const UDSPInstruction opc)
{ {
MOV(16, R(DX), Imm16(m_compile_pc + 2)); MOV(16, R(DX), Imm16(m_compile_pc + 2));
dsp_reg_store_stack(DSP_STACK_C); dsp_reg_store_stack(StackRegister::Call);
u16 dest = dsp_imem_read(m_compile_pc + 1); u16 dest = dsp_imem_read(m_compile_pc + 1);
const DSPOPCTemplate* opcode = GetOpTemplate(opc); const DSPOPCTemplate* opcode = GetOpTemplate(opc);
@ -202,7 +202,7 @@ void DSPEmitter::r_callr(const UDSPInstruction opc)
{ {
u8 reg = (opc >> 5) & 0x7; u8 reg = (opc >> 5) & 0x7;
MOV(16, R(DX), Imm16(m_compile_pc + 1)); MOV(16, R(DX), Imm16(m_compile_pc + 1));
dsp_reg_store_stack(DSP_STACK_C); dsp_reg_store_stack(StackRegister::Call);
dsp_op_read_reg(reg, RAX); dsp_op_read_reg(reg, RAX);
MOV(16, M(&g_dsp.pc), R(EAX)); MOV(16, M(&g_dsp.pc), R(EAX));
WriteBranchExit(); WriteBranchExit();
@ -241,7 +241,7 @@ void DSPEmitter::ifcc(const UDSPInstruction opc)
void DSPEmitter::r_ret(const UDSPInstruction opc) void DSPEmitter::r_ret(const UDSPInstruction opc)
{ {
dsp_reg_load_stack(DSP_STACK_C); dsp_reg_load_stack(StackRegister::Call);
MOV(16, M(&g_dsp.pc), R(DX)); MOV(16, M(&g_dsp.pc), R(DX));
WriteBranchExit(); WriteBranchExit();
} }
@ -265,11 +265,11 @@ void DSPEmitter::ret(const UDSPInstruction opc)
// location. // location.
void DSPEmitter::rti(const UDSPInstruction opc) void DSPEmitter::rti(const UDSPInstruction opc)
{ {
// g_dsp.r[DSP_REG_SR] = dsp_reg_load_stack(DSP_STACK_D); // g_dsp.r[DSP_REG_SR] = dsp_reg_load_stack(StackRegister::Data);
dsp_reg_load_stack(DSP_STACK_D); dsp_reg_load_stack(StackRegister::Data);
dsp_op_write_reg(DSP_REG_SR, RDX); dsp_op_write_reg(DSP_REG_SR, RDX);
// g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C); // g_dsp.pc = dsp_reg_load_stack(StackRegister::Call);
dsp_reg_load_stack(DSP_STACK_C); dsp_reg_load_stack(StackRegister::Call);
MOV(16, M(&g_dsp.pc), R(DX)); MOV(16, M(&g_dsp.pc), R(DX));
} }
@ -279,8 +279,8 @@ void DSPEmitter::rti(const UDSPInstruction opc)
void DSPEmitter::halt(const UDSPInstruction opc) void DSPEmitter::halt(const UDSPInstruction opc)
{ {
OR(16, M(&g_dsp.cr), Imm16(4)); OR(16, M(&g_dsp.cr), Imm16(4));
// g_dsp.pc = dsp_reg_load_stack(DSP_STACK_C); // g_dsp.pc = dsp_reg_load_stack(StackRegister::Call);
dsp_reg_load_stack(DSP_STACK_C); dsp_reg_load_stack(StackRegister::Call);
MOV(16, M(&g_dsp.pc), R(DX)); MOV(16, M(&g_dsp.pc), R(DX));
} }
@ -310,9 +310,9 @@ void DSPEmitter::HandleLoop()
SetJumpTarget(loadStack); SetJumpTarget(loadStack);
DSPJitRegCache c(m_gpr); DSPJitRegCache c(m_gpr);
dsp_reg_load_stack(0); dsp_reg_load_stack(StackRegister::Call);
dsp_reg_load_stack(2); dsp_reg_load_stack(StackRegister::LoopAddress);
dsp_reg_load_stack(3); dsp_reg_load_stack(StackRegister::LoopCounter);
m_gpr.FlushRegs(c); m_gpr.FlushRegs(c);
SetJumpTarget(loopUpdated); SetJumpTarget(loopUpdated);
@ -339,11 +339,11 @@ void DSPEmitter::loop(const UDSPInstruction opc)
TEST(16, R(EDX), R(EDX)); TEST(16, R(EDX), R(EDX));
DSPJitRegCache c(m_gpr); DSPJitRegCache c(m_gpr);
FixupBranch cnt = J_CC(CC_Z, true); FixupBranch cnt = J_CC(CC_Z, true);
dsp_reg_store_stack(3); dsp_reg_store_stack(StackRegister::LoopCounter);
MOV(16, R(RDX), Imm16(m_compile_pc + 1)); MOV(16, R(RDX), Imm16(m_compile_pc + 1));
dsp_reg_store_stack(0); dsp_reg_store_stack(StackRegister::Call);
MOV(16, R(RDX), Imm16(loop_pc)); MOV(16, R(RDX), Imm16(loop_pc));
dsp_reg_store_stack(2); dsp_reg_store_stack(StackRegister::LoopAddress);
m_gpr.FlushRegs(c); m_gpr.FlushRegs(c);
MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 1)); MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 1));
FixupBranch exit = J(true); FixupBranch exit = J(true);
@ -372,11 +372,11 @@ void DSPEmitter::loopi(const UDSPInstruction opc)
if (cnt) if (cnt)
{ {
MOV(16, R(RDX), Imm16(m_compile_pc + 1)); MOV(16, R(RDX), Imm16(m_compile_pc + 1));
dsp_reg_store_stack(0); dsp_reg_store_stack(StackRegister::Call);
MOV(16, R(RDX), Imm16(loop_pc)); MOV(16, R(RDX), Imm16(loop_pc));
dsp_reg_store_stack(2); dsp_reg_store_stack(StackRegister::LoopAddress);
MOV(16, R(RDX), Imm16(cnt)); MOV(16, R(RDX), Imm16(cnt));
dsp_reg_store_stack(3); dsp_reg_store_stack(StackRegister::LoopCounter);
MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 1)); MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 1));
} }
@ -408,11 +408,11 @@ void DSPEmitter::bloop(const UDSPInstruction opc)
TEST(16, R(EDX), R(EDX)); TEST(16, R(EDX), R(EDX));
DSPJitRegCache c(m_gpr); DSPJitRegCache c(m_gpr);
FixupBranch cnt = J_CC(CC_Z, true); FixupBranch cnt = J_CC(CC_Z, true);
dsp_reg_store_stack(3); dsp_reg_store_stack(StackRegister::LoopCounter);
MOV(16, R(RDX), Imm16(m_compile_pc + 2)); MOV(16, R(RDX), Imm16(m_compile_pc + 2));
dsp_reg_store_stack(0); dsp_reg_store_stack(StackRegister::Call);
MOV(16, R(RDX), Imm16(loop_pc)); MOV(16, R(RDX), Imm16(loop_pc));
dsp_reg_store_stack(2); dsp_reg_store_stack(StackRegister::LoopAddress);
MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 2)); MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 2));
m_gpr.FlushRegs(c, true); m_gpr.FlushRegs(c, true);
FixupBranch exit = J(true); FixupBranch exit = J(true);
@ -444,11 +444,11 @@ void DSPEmitter::bloopi(const UDSPInstruction opc)
if (cnt) if (cnt)
{ {
MOV(16, R(RDX), Imm16(m_compile_pc + 2)); MOV(16, R(RDX), Imm16(m_compile_pc + 2));
dsp_reg_store_stack(0); dsp_reg_store_stack(StackRegister::Call);
MOV(16, R(RDX), Imm16(loop_pc)); MOV(16, R(RDX), Imm16(loop_pc));
dsp_reg_store_stack(2); dsp_reg_store_stack(StackRegister::LoopAddress);
MOV(16, R(RDX), Imm16(cnt)); MOV(16, R(RDX), Imm16(cnt));
dsp_reg_store_stack(3); dsp_reg_store_stack(StackRegister::LoopCounter);
MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 2)); MOV(16, M(&(g_dsp.pc)), Imm16(m_compile_pc + 2));
} }

View File

@ -17,78 +17,87 @@ namespace JIT
namespace x86 namespace x86
{ {
// clobbers: // clobbers:
// EAX = (s8)g_dsp.reg_stack_ptr[stack_reg] // EAX = (s8)g_dsp.reg_stack_ptr[reg_index]
// expects: // expects:
void DSPEmitter::dsp_reg_stack_push(int stack_reg) void DSPEmitter::dsp_reg_stack_push(StackRegister stack_reg)
{ {
// g_dsp.reg_stack_ptr[stack_reg]++; const auto reg_index = static_cast<size_t>(stack_reg);
// g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK;
MOV(8, R(AL), M(&g_dsp.reg_stack_ptr[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]));
ADD(8, R(AL), Imm8(1)); ADD(8, R(AL), Imm8(1));
AND(8, R(AL), Imm8(DSP_STACK_MASK)); AND(8, R(AL), Imm8(DSP_STACK_MASK));
MOV(8, M(&g_dsp.reg_stack_ptr[stack_reg]), R(AL)); MOV(8, M(&g_dsp.reg_stack_ptr[reg_index]), R(AL));
X64Reg tmp1 = m_gpr.GetFreeXReg(); X64Reg tmp1 = m_gpr.GetFreeXReg();
X64Reg tmp2 = m_gpr.GetFreeXReg(); X64Reg tmp2 = m_gpr.GetFreeXReg();
// g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]] = g_dsp.r[DSP_REG_ST0 + stack_reg]; // 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[stack_reg])); MOV(16, R(tmp1), M(&g_dsp.r.st[reg_index]));
MOVZX(64, 8, RAX, R(AL)); MOVZX(64, 8, RAX, R(AL));
MOV(64, R(tmp2), ImmPtr(g_dsp.reg_stack[stack_reg])); MOV(64, R(tmp2), ImmPtr(g_dsp.reg_stack[reg_index]));
MOV(16, MComplex(tmp2, EAX, SCALE_2, 0), R(tmp1)); MOV(16, MComplex(tmp2, EAX, SCALE_2, 0), R(tmp1));
m_gpr.PutXReg(tmp1); m_gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp2); m_gpr.PutXReg(tmp2);
} }
// clobbers: // clobbers:
// EAX = (s8)g_dsp.reg_stack_ptr[stack_reg] // EAX = (s8)g_dsp.reg_stack_ptr[reg_index]
// expects: // expects:
void DSPEmitter::dsp_reg_stack_pop(int stack_reg) void DSPEmitter::dsp_reg_stack_pop(StackRegister stack_reg)
{ {
// g_dsp.r[DSP_REG_ST0 + stack_reg] = g_dsp.reg_stack[stack_reg][g_dsp.reg_stack_ptr[stack_reg]]; const auto reg_index = static_cast<size_t>(stack_reg);
MOV(8, R(AL), M(&g_dsp.reg_stack_ptr[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]));
X64Reg tmp1 = m_gpr.GetFreeXReg(); X64Reg tmp1 = m_gpr.GetFreeXReg();
X64Reg tmp2 = m_gpr.GetFreeXReg(); X64Reg tmp2 = m_gpr.GetFreeXReg();
MOVZX(64, 8, RAX, R(AL)); MOVZX(64, 8, RAX, R(AL));
MOV(64, R(tmp2), ImmPtr(g_dsp.reg_stack[stack_reg])); MOV(64, R(tmp2), ImmPtr(g_dsp.reg_stack[reg_index]));
MOV(16, R(tmp1), MComplex(tmp2, EAX, SCALE_2, 0)); MOV(16, R(tmp1), MComplex(tmp2, EAX, SCALE_2, 0));
MOV(16, M(&g_dsp.r.st[stack_reg]), R(tmp1)); MOV(16, M(&g_dsp.r.st[reg_index]), R(tmp1));
m_gpr.PutXReg(tmp1); m_gpr.PutXReg(tmp1);
m_gpr.PutXReg(tmp2); m_gpr.PutXReg(tmp2);
// g_dsp.reg_stack_ptr[stack_reg]--; // g_dsp.reg_stack_ptr[reg_index]--;
// g_dsp.reg_stack_ptr[stack_reg] &= DSP_STACK_MASK; // g_dsp.reg_stack_ptr[reg_index] &= DSP_STACK_MASK;
SUB(8, R(AL), Imm8(1)); SUB(8, R(AL), Imm8(1));
AND(8, R(AL), Imm8(DSP_STACK_MASK)); AND(8, R(AL), Imm8(DSP_STACK_MASK));
MOV(8, M(&g_dsp.reg_stack_ptr[stack_reg]), R(AL)); MOV(8, M(&g_dsp.reg_stack_ptr[reg_index]), R(AL));
} }
void DSPEmitter::dsp_reg_store_stack(int stack_reg, Gen::X64Reg host_sreg) void DSPEmitter::dsp_reg_store_stack(StackRegister stack_reg, Gen::X64Reg host_sreg)
{ {
if (host_sreg != EDX) if (host_sreg != EDX)
{ {
MOV(16, R(EDX), R(host_sreg)); MOV(16, R(EDX), R(host_sreg));
} }
dsp_reg_stack_push(stack_reg); dsp_reg_stack_push(stack_reg);
// g_dsp.r[DSP_REG_ST0 + stack_reg] = val; // g_dsp.r[DSP_REG_ST0 + stack_reg] = val;
MOV(16, M(&g_dsp.r.st[stack_reg]), R(EDX)); MOV(16, M(&g_dsp.r.st[static_cast<size_t>(stack_reg)]), R(EDX));
} }
void DSPEmitter::dsp_reg_load_stack(int stack_reg, Gen::X64Reg host_dreg) void DSPEmitter::dsp_reg_load_stack(StackRegister stack_reg, Gen::X64Reg host_dreg)
{ {
// u16 val = g_dsp.r[DSP_REG_ST0 + stack_reg]; // u16 val = g_dsp.r[DSP_REG_ST0 + stack_reg];
MOV(16, R(EDX), M(&g_dsp.r.st[stack_reg])); MOV(16, R(EDX), M(&g_dsp.r.st[static_cast<size_t>(stack_reg)]));
dsp_reg_stack_pop(stack_reg); dsp_reg_stack_pop(stack_reg);
if (host_dreg != EDX) if (host_dreg != EDX)
{ {
MOV(16, R(host_dreg), R(EDX)); MOV(16, R(host_dreg), R(EDX));
} }
} }
void DSPEmitter::dsp_reg_store_stack_imm(int stack_reg, u16 val) void DSPEmitter::dsp_reg_store_stack_imm(StackRegister stack_reg, u16 val)
{ {
dsp_reg_stack_push(stack_reg); dsp_reg_stack_push(stack_reg);
// g_dsp.r[DSP_REG_ST0 + stack_reg] = val; // g_dsp.r[DSP_REG_ST0 + stack_reg] = val;
MOV(16, M(&g_dsp.r.st[stack_reg]), Imm16(val)); MOV(16, M(&g_dsp.r.st[static_cast<size_t>(stack_reg)]), Imm16(val));
} }
void DSPEmitter::dsp_op_write_reg(int reg, Gen::X64Reg host_sreg) void DSPEmitter::dsp_op_write_reg(int reg, Gen::X64Reg host_sreg)
@ -106,7 +115,7 @@ void DSPEmitter::dsp_op_write_reg(int reg, Gen::X64Reg host_sreg)
case DSP_REG_ST1: case DSP_REG_ST1:
case DSP_REG_ST2: case DSP_REG_ST2:
case DSP_REG_ST3: case DSP_REG_ST3:
dsp_reg_store_stack(reg - DSP_REG_ST0, host_sreg); dsp_reg_store_stack(static_cast<StackRegister>(reg - DSP_REG_ST0), host_sreg);
break; break;
default: default:
@ -129,7 +138,7 @@ void DSPEmitter::dsp_op_write_reg_imm(int reg, u16 val)
case DSP_REG_ST1: case DSP_REG_ST1:
case DSP_REG_ST2: case DSP_REG_ST2:
case DSP_REG_ST3: case DSP_REG_ST3:
dsp_reg_store_stack_imm(reg - DSP_REG_ST0, val); dsp_reg_store_stack_imm(static_cast<StackRegister>(reg - DSP_REG_ST0), val);
break; break;
default: default:
@ -202,7 +211,7 @@ void DSPEmitter::dsp_op_read_reg_dont_saturate(int reg, Gen::X64Reg host_dreg,
case DSP_REG_ST1: case DSP_REG_ST1:
case DSP_REG_ST2: case DSP_REG_ST2:
case DSP_REG_ST3: case DSP_REG_ST3:
dsp_reg_load_stack(reg - DSP_REG_ST0, host_dreg); dsp_reg_load_stack(static_cast<StackRegister>(reg - DSP_REG_ST0), host_dreg);
switch (extend) switch (extend)
{ {
case RegisterExtension::Sign: case RegisterExtension::Sign:
@ -230,7 +239,7 @@ void DSPEmitter::dsp_op_read_reg(int reg, Gen::X64Reg host_dreg, RegisterExtensi
case DSP_REG_ST1: case DSP_REG_ST1:
case DSP_REG_ST2: case DSP_REG_ST2:
case DSP_REG_ST3: case DSP_REG_ST3:
dsp_reg_load_stack(reg - DSP_REG_ST0, host_dreg); dsp_reg_load_stack(static_cast<StackRegister>(reg - DSP_REG_ST0), host_dreg);
switch (extend) switch (extend)
{ {
case RegisterExtension::Sign: case RegisterExtension::Sign: