Skip to content
Permalink
Browse files
Merge pull request #10709 from Pokechu22/dsp-lle-update-sr-16
DSP LLE JIT: Fix Update_SR_Register16_OverS32
  • Loading branch information
lioncash committed Jun 3, 2022
2 parents 566da9f + f88b7ab commit c8ab236
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 67 deletions.
@@ -257,8 +257,8 @@ class DSPEmitter final : public JIT::DSPEmitter, public Gen::X64CodeBlock
{
UpdateSR64AddSub(val1, val2, result, scratch, true);
}
void Update_SR_Register16(Gen::X64Reg val = Gen::EAX);
void Update_SR_Register16_OverS32(Gen::X64Reg val = Gen::EAX);
void Update_SR_Register16(Gen::X64Reg val);
void Update_SR_Register16_OverS32(Gen::X64Reg val, Gen::X64Reg full_val, Gen::X64Reg scratch);

// Register helpers
void setCompileSR(u16 bit);
@@ -152,9 +152,9 @@ void DSPEmitter::tstaxh(const UDSPInstruction opc)
{
u8 reg = (opc >> 8) & 0x1;
// s16 val = dsp_get_ax_h(reg);
get_ax_h(reg);
get_ax_h(reg, EAX);
// Update_SR_Register16(val);
Update_SR_Register16();
Update_SR_Register16(EAX);
}
}

@@ -301,16 +301,18 @@ void DSPEmitter::xorr(const UDSPInstruction opc)
u8 dreg = (opc >> 8) & 0x1;
u8 sreg = (opc >> 9) & 0x1;
// u16 accm = g_dsp.r.acm[dreg] ^ g_dsp.r.axh[sreg];
get_acc_m(dreg, RAX);
X64Reg accm = RAX;
get_acc_m(dreg, accm);
get_ax_h(sreg, RDX);
XOR(64, R(RAX), R(RDX));
XOR(64, R(accm), R(RDX));
// g_dsp.r.acm[dreg] = accm;
set_acc_m(dreg);
set_acc_m(dreg, R(accm));
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
if (FlagsNeeded())
{
get_long_acc(dreg, RCX);
Update_SR_Register16_OverS32();
X64Reg acc_full = RCX;
get_long_acc(dreg, acc_full);
Update_SR_Register16_OverS32(accm, acc_full, RDX);
}
}

@@ -326,16 +328,18 @@ void DSPEmitter::andr(const UDSPInstruction opc)
u8 dreg = (opc >> 8) & 0x1;
u8 sreg = (opc >> 9) & 0x1;
// u16 accm = g_dsp.r.acm[dreg] & g_dsp.r.axh[sreg];
get_acc_m(dreg, RAX);
X64Reg accm = RAX;
get_acc_m(dreg, accm);
get_ax_h(sreg, RDX);
AND(64, R(RAX), R(RDX));
AND(64, R(accm), R(RDX));
// g_dsp.r.acm[dreg] = accm;
set_acc_m(dreg);
set_acc_m(dreg, R(accm));
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
if (FlagsNeeded())
{
get_long_acc(dreg, RCX);
Update_SR_Register16_OverS32();
X64Reg acc_full = RCX;
get_long_acc(dreg, acc_full);
Update_SR_Register16_OverS32(accm, acc_full, RDX);
}
}

@@ -351,16 +355,18 @@ void DSPEmitter::orr(const UDSPInstruction opc)
u8 dreg = (opc >> 8) & 0x1;
u8 sreg = (opc >> 9) & 0x1;
// u16 accm = g_dsp.r.acm[dreg] | g_dsp.r.axh[sreg];
get_acc_m(dreg, RAX);
X64Reg accm = RAX;
get_acc_m(dreg, accm);
get_ax_h(sreg, RDX);
OR(64, R(RAX), R(RDX));
OR(64, R(accm), R(RDX));
// g_dsp.r.acm[dreg] = accm;
set_acc_m(dreg);
set_acc_m(dreg, R(accm));
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
if (FlagsNeeded())
{
get_long_acc(dreg, RCX);
Update_SR_Register16_OverS32();
X64Reg acc_full = RCX;
get_long_acc(dreg, acc_full);
Update_SR_Register16_OverS32(accm, acc_full, RDX);
}
}

@@ -375,16 +381,18 @@ void DSPEmitter::andc(const UDSPInstruction opc)
{
u8 dreg = (opc >> 8) & 0x1;
// u16 accm = g_dsp.r.acm[dreg] & g_dsp.r.acm[1 - dreg];
get_acc_m(dreg, RAX);
X64Reg accm = RAX;
get_acc_m(dreg, accm);
get_acc_m(1 - dreg, RDX);
AND(64, R(RAX), R(RDX));
AND(64, R(accm), R(RDX));
// g_dsp.r.acm[dreg] = accm;
set_acc_m(dreg);
set_acc_m(dreg, R(accm));
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
if (FlagsNeeded())
{
get_long_acc(dreg, RCX);
Update_SR_Register16_OverS32();
X64Reg acc_full = RCX;
get_long_acc(dreg, acc_full);
Update_SR_Register16_OverS32(accm, acc_full, RDX);
}
}

@@ -399,16 +407,18 @@ void DSPEmitter::orc(const UDSPInstruction opc)
{
u8 dreg = (opc >> 8) & 0x1;
// u16 accm = g_dsp.r.acm[dreg] | g_dsp.r.acm[1 - dreg];
get_acc_m(dreg, RAX);
X64Reg accm = RAX;
get_acc_m(dreg, accm);
get_acc_m(1 - dreg, RDX);
OR(64, R(RAX), R(RDX));
OR(64, R(accm), R(RDX));
// g_dsp.r.acm[dreg] = accm;
set_acc_m(dreg);
set_acc_m(dreg, R(accm));
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
if (FlagsNeeded())
{
get_long_acc(dreg, RCX);
Update_SR_Register16_OverS32();
X64Reg acc_full = RCX;
get_long_acc(dreg, acc_full);
Update_SR_Register16_OverS32(accm, acc_full, RDX);
}
}

@@ -422,16 +432,18 @@ void DSPEmitter::xorc(const UDSPInstruction opc)
{
u8 dreg = (opc >> 8) & 0x1;
// u16 accm = g_dsp.r.acm[dreg] ^ g_dsp.r.acm[1 - dreg];
get_acc_m(dreg, RAX);
X64Reg accm = RAX;
get_acc_m(dreg, accm);
get_acc_m(1 - dreg, RDX);
XOR(64, R(RAX), R(RDX));
XOR(64, R(accm), R(RDX));
// g_dsp.r.acm[dreg] = accm;
set_acc_m(dreg);
set_acc_m(dreg, R(accm));
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
if (FlagsNeeded())
{
get_long_acc(dreg, RCX);
Update_SR_Register16_OverS32();
X64Reg acc_full = RCX;
get_long_acc(dreg, acc_full);
Update_SR_Register16_OverS32(accm, acc_full, RDX);
}
}

@@ -445,15 +457,17 @@ void DSPEmitter::notc(const UDSPInstruction opc)
{
u8 dreg = (opc >> 8) & 0x1;
// u16 accm = g_dsp.r.acm[dreg] ^ 0xffff;
get_acc_m(dreg, RAX);
NOT(16, R(AX));
X64Reg accm = RAX;
get_acc_m(dreg, accm);
NOT(16, R(accm));
// g_dsp.r.acm[dreg] = accm;
set_acc_m(dreg);
set_acc_m(dreg, R(accm));
// Update_SR_Register16((s16)accm, false, false, isOverS32(dsp_get_long_acc(dreg)));
if (FlagsNeeded())
{
get_long_acc(dreg, RCX);
Update_SR_Register16_OverS32();
X64Reg acc_full = RCX;
get_long_acc(dreg, acc_full);
Update_SR_Register16_OverS32(accm, acc_full, RDX);
}
}

@@ -470,14 +484,16 @@ void DSPEmitter::xori(const UDSPInstruction opc)
// u16 imm = dsp_fetch_code();
const u16 imm = m_dsp_core.DSPState().ReadIMEM(m_compile_pc + 1);
// g_dsp.r.acm[reg] ^= imm;
get_acc_m(reg, RAX);
XOR(16, R(RAX), Imm16(imm));
set_acc_m(reg);
X64Reg accm = RAX;
get_acc_m(reg, accm);
XOR(16, R(accm), Imm16(imm));
set_acc_m(reg, R(accm));
// Update_SR_Register16((s16)g_dsp.r.acm[reg], false, false, isOverS32(dsp_get_long_acc(reg)));
if (FlagsNeeded())
{
get_long_acc(reg, RCX);
Update_SR_Register16_OverS32();
X64Reg acc_full = RCX;
get_long_acc(reg, acc_full);
Update_SR_Register16_OverS32(accm, acc_full, RDX);
}
}

@@ -493,14 +509,16 @@ void DSPEmitter::andi(const UDSPInstruction opc)
// u16 imm = dsp_fetch_code();
const u16 imm = m_dsp_core.DSPState().ReadIMEM(m_compile_pc + 1);
// g_dsp.r.acm[reg] &= imm;
get_acc_m(reg, RAX);
AND(16, R(RAX), Imm16(imm));
set_acc_m(reg);
X64Reg accm = RAX;
get_acc_m(reg, accm);
AND(16, R(accm), Imm16(imm));
set_acc_m(reg, R(accm));
// Update_SR_Register16((s16)g_dsp.r.acm[reg], false, false, isOverS32(dsp_get_long_acc(reg)));
if (FlagsNeeded())
{
get_long_acc(reg, RCX);
Update_SR_Register16_OverS32();
X64Reg acc_full = RCX;
get_long_acc(reg, acc_full);
Update_SR_Register16_OverS32(accm, acc_full, RDX);
}
}

@@ -516,14 +534,16 @@ void DSPEmitter::ori(const UDSPInstruction opc)
// u16 imm = dsp_fetch_code();
const u16 imm = m_dsp_core.DSPState().ReadIMEM(m_compile_pc + 1);
// g_dsp.r.acm[reg] |= imm;
get_acc_m(reg, RAX);
OR(16, R(RAX), Imm16(imm));
set_acc_m(reg);
X64Reg accm = RAX;
get_acc_m(reg, accm);
OR(16, R(accm), Imm16(imm));
set_acc_m(reg, R(accm));
// Update_SR_Register16((s16)g_dsp.r.acm[reg], false, false, isOverS32(dsp_get_long_acc(reg)));
if (FlagsNeeded())
{
get_long_acc(reg, RCX);
Update_SR_Register16_OverS32();
X64Reg acc_full = RCX;
get_long_acc(reg, acc_full);
Update_SR_Register16_OverS32(accm, acc_full, RDX);
}
}

@@ -114,15 +114,15 @@ void DSPEmitter::UpdateSR64AddSub(Gen::X64Reg val1, Gen::X64Reg val2, Gen::X64Re
Update_SR_Register(result, scratch);
}

// In: RAX: s64 _Value
// In: RAX: s16 _Value (middle)
void DSPEmitter::Update_SR_Register16(X64Reg val)
{
const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
AND(16, sr_reg, Imm16(~SR_CMP_MASK));

// // 0x04
// if (_Value == 0) g_dsp.r[DSP_REG_SR] |= SR_ARITH_ZERO;
TEST(64, R(val), R(val));
TEST(16, R(val), R(val));
FixupBranch notZero = J_CC(CC_NZ);
OR(16, sr_reg, Imm16(SR_ARITH_ZERO | SR_TOP2BITS));
FixupBranch end = J();
@@ -149,26 +149,25 @@ void DSPEmitter::Update_SR_Register16(X64Reg val)
m_gpr.PutReg(DSP_REG_SR);
}

// In: RAX: s64 _Value
// Clobbers RCX
void DSPEmitter::Update_SR_Register16_OverS32(Gen::X64Reg val)
// In: RAX: s16 _Value (middle)
// In: RDX: s64 _FullValue
// Clobbers scratch
void DSPEmitter::Update_SR_Register16_OverS32(Gen::X64Reg val, Gen::X64Reg full_val,
Gen::X64Reg scratch)
{
Update_SR_Register16(val);

const OpArg sr_reg = m_gpr.GetReg(DSP_REG_SR);
AND(16, sr_reg, Imm16(~SR_CMP_MASK));

// // 0x10
// if (_Value != (s32)_Value) g_dsp.r[DSP_REG_SR] |= SR_OVER_S32;
MOVSX(64, 32, RCX, R(val));
CMP(64, R(RCX), R(val));
// if (_FullValue != (s32)_FullValue) g_dsp.r[DSP_REG_SR] |= SR_OVER_S32;
MOVSX(64, 32, scratch, R(full_val));
CMP(64, R(scratch), R(full_val));
FixupBranch noOverS32 = J_CC(CC_E);
OR(16, sr_reg, Imm16(SR_OVER_S32));
SetJumpTarget(noOverS32);

m_gpr.PutReg(DSP_REG_SR);
// // 0x20 - Checks if top bits of m are equal
// if ((((u16)_Value >> 14) == 0) || (((u16)_Value >> 14) == 3))
// AND(32, R(val), Imm32(0xc0000000));
Update_SR_Register16(val);
}

} // namespace DSP::JIT::x64

0 comments on commit c8ab236

Please sign in to comment.