DSP/Jit: Fold the test for ACMx into dsp_op_read_reg()
adds a new dsp_op_read_reg_dont_saturate for the few cases where saturation is not appropriate
This commit is contained in:
parent
54f3828555
commit
a902c720e0
|
@ -120,8 +120,8 @@ public:
|
||||||
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);
|
||||||
void dsp_conditional_extend_accum_imm(int reg, u16 val);
|
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(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
|
// Commands
|
||||||
void dar(const UDSPInstruction opc);
|
void dar(const UDSPInstruction opc);
|
||||||
|
|
|
@ -334,7 +334,8 @@ void DSPEmitter::loop(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u16 reg = opc & 0x1f;
|
u16 reg = opc & 0x1f;
|
||||||
// u16 cnt = g_dsp.r[reg];
|
// 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;
|
u16 loop_pc = compilePC + 1;
|
||||||
|
|
||||||
CMP(16, R(EDX), Imm16(0));
|
CMP(16, R(EDX), Imm16(0));
|
||||||
|
@ -403,7 +404,8 @@ void DSPEmitter::bloop(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u16 reg = opc & 0x1f;
|
u16 reg = opc & 0x1f;
|
||||||
// u16 cnt = g_dsp.r[reg];
|
// 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);
|
u16 loop_pc = dsp_imem_read(compilePC + 1);
|
||||||
|
|
||||||
CMP(16, R(EDX), Imm16(0));
|
CMP(16, R(EDX), Imm16(0));
|
||||||
|
|
|
@ -68,11 +68,8 @@ void DSPEmitter::mv(const UDSPInstruction opc)
|
||||||
{
|
{
|
||||||
u8 sreg = (opc & 0x3) + DSP_REG_ACL0;
|
u8 sreg = (opc & 0x3) + DSP_REG_ACL0;
|
||||||
u8 dreg = ((opc >> 2) & 0x3);
|
u8 dreg = ((opc >> 2) & 0x3);
|
||||||
if (sreg >= DSP_REG_ACM0) {
|
dsp_op_read_reg(sreg, RBX, ZERO);
|
||||||
dsp_op_read_reg_and_saturate(sreg, RBX, ZERO);
|
storeIndex = dreg + DSP_REG_AXL0;
|
||||||
storeIndex = dreg + DSP_REG_AXL0;
|
|
||||||
} else
|
|
||||||
pushExtValueFromReg(dreg + DSP_REG_AXL0, sreg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// S @$arD, $acS.S
|
// S @$arD, $acS.S
|
||||||
|
@ -89,10 +86,7 @@ void DSPEmitter::s(const UDSPInstruction opc)
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(tmp1);
|
gpr.getFreeXReg(tmp1);
|
||||||
|
|
||||||
if (sreg >= DSP_REG_ACM0)
|
dsp_op_read_reg(sreg, tmp1, ZERO);
|
||||||
dsp_op_read_reg_and_saturate(sreg, tmp1, ZERO);
|
|
||||||
else
|
|
||||||
dsp_op_read_reg(sreg, tmp1, ZERO);
|
|
||||||
// u16 val = g_dsp.r[src];
|
// u16 val = g_dsp.r[src];
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
|
@ -114,10 +108,7 @@ void DSPEmitter::sn(const UDSPInstruction opc)
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(tmp1);
|
gpr.getFreeXReg(tmp1);
|
||||||
|
|
||||||
if (sreg >= DSP_REG_ACM0)
|
dsp_op_read_reg(sreg, tmp1, ZERO);
|
||||||
dsp_op_read_reg_and_saturate(sreg, tmp1, ZERO);
|
|
||||||
else
|
|
||||||
dsp_op_read_reg(sreg, tmp1, ZERO);
|
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.putXReg(tmp1);
|
gpr.putXReg(tmp1);
|
||||||
|
@ -187,7 +178,7 @@ void DSPEmitter::ls(const UDSPInstruction opc)
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(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);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.putXReg(tmp1);
|
gpr.putXReg(tmp1);
|
||||||
|
@ -214,7 +205,7 @@ void DSPEmitter::lsn(const UDSPInstruction opc)
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(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);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.putXReg(tmp1);
|
gpr.putXReg(tmp1);
|
||||||
|
@ -240,7 +231,7 @@ void DSPEmitter::lsm(const UDSPInstruction opc)
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(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);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.putXReg(tmp1);
|
gpr.putXReg(tmp1);
|
||||||
|
@ -267,7 +258,7 @@ void DSPEmitter::lsnm(const UDSPInstruction opc)
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(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);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.putXReg(tmp1);
|
gpr.putXReg(tmp1);
|
||||||
|
@ -292,7 +283,7 @@ void DSPEmitter::sl(const UDSPInstruction opc)
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(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);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.putXReg(tmp1);
|
gpr.putXReg(tmp1);
|
||||||
|
@ -318,7 +309,7 @@ void DSPEmitter::sln(const UDSPInstruction opc)
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(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);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.putXReg(tmp1);
|
gpr.putXReg(tmp1);
|
||||||
|
@ -344,7 +335,7 @@ void DSPEmitter::slm(const UDSPInstruction opc)
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(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);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.putXReg(tmp1);
|
gpr.putXReg(tmp1);
|
||||||
|
@ -370,7 +361,7 @@ void DSPEmitter::slnm(const UDSPInstruction opc)
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(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);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
gpr.putXReg(tmp1);
|
gpr.putXReg(tmp1);
|
||||||
|
@ -649,14 +640,8 @@ void DSPEmitter::ldaxnm(const UDSPInstruction opc)
|
||||||
increase_addr_reg(DSP_REG_AR3, DSP_REG_AR3);
|
increase_addr_reg(DSP_REG_AR3, DSP_REG_AR3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Push value from address in g_dsp.r[sreg] into EBX and stores the
|
||||||
// Push value from g_dsp.r[sreg] into EBX and stores the destinationindex in
|
// destinationindex in storeIndex
|
||||||
// storeIndex
|
|
||||||
void DSPEmitter::pushExtValueFromReg(u16 dreg, u16 sreg) {
|
|
||||||
dsp_op_read_reg(sreg, RBX, ZERO);
|
|
||||||
storeIndex = dreg;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DSPEmitter::pushExtValueFromMem(u16 dreg, u16 sreg) {
|
void DSPEmitter::pushExtValueFromMem(u16 dreg, u16 sreg) {
|
||||||
// u16 addr = g_dsp.r[addr];
|
// u16 addr = g_dsp.r[addr];
|
||||||
|
|
||||||
|
|
|
@ -39,10 +39,7 @@ void DSPEmitter::srs(const UDSPInstruction opc)
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(tmp1);
|
gpr.getFreeXReg(tmp1);
|
||||||
|
|
||||||
if (reg >= DSP_REG_ACM0)
|
dsp_op_read_reg(reg, tmp1, ZERO);
|
||||||
dsp_op_read_reg_and_saturate(reg, tmp1, ZERO);
|
|
||||||
else
|
|
||||||
dsp_op_read_reg(reg, tmp1, ZERO);
|
|
||||||
dsp_op_read_reg(DSP_REG_CR, RAX, ZERO);
|
dsp_op_read_reg(DSP_REG_CR, RAX, ZERO);
|
||||||
SHL(16, R(EAX), Imm8(8));
|
SHL(16, R(EAX), Imm8(8));
|
||||||
OR(16, R(EAX), Imm16(opc & 0xFF));
|
OR(16, R(EAX), Imm16(opc & 0xFF));
|
||||||
|
@ -101,10 +98,7 @@ void DSPEmitter::sr(const UDSPInstruction opc)
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(tmp1);
|
gpr.getFreeXReg(tmp1);
|
||||||
|
|
||||||
if (reg >= DSP_REG_ACM0)
|
dsp_op_read_reg(reg, tmp1);
|
||||||
dsp_op_read_reg_and_saturate(reg, tmp1);
|
|
||||||
else
|
|
||||||
dsp_op_read_reg(reg, tmp1);
|
|
||||||
dmem_write_imm(address, tmp1);
|
dmem_write_imm(address, tmp1);
|
||||||
|
|
||||||
gpr.putXReg(tmp1);
|
gpr.putXReg(tmp1);
|
||||||
|
@ -227,10 +221,7 @@ void DSPEmitter::srr(const UDSPInstruction opc)
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(tmp1);
|
gpr.getFreeXReg(tmp1);
|
||||||
|
|
||||||
if (sreg >= DSP_REG_ACM0)
|
dsp_op_read_reg(sreg, tmp1);
|
||||||
dsp_op_read_reg_and_saturate(sreg, tmp1);
|
|
||||||
else
|
|
||||||
dsp_op_read_reg(sreg, tmp1);
|
|
||||||
dsp_op_read_reg(dreg, RAX, ZERO);
|
dsp_op_read_reg(dreg, RAX, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
|
@ -249,10 +240,7 @@ void DSPEmitter::srrd(const UDSPInstruction opc)
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(tmp1);
|
gpr.getFreeXReg(tmp1);
|
||||||
|
|
||||||
if (sreg >= DSP_REG_ACM0)
|
dsp_op_read_reg(sreg, tmp1);
|
||||||
dsp_op_read_reg_and_saturate(sreg, tmp1);
|
|
||||||
else
|
|
||||||
dsp_op_read_reg(sreg, tmp1);
|
|
||||||
dsp_op_read_reg(dreg, RAX, ZERO);
|
dsp_op_read_reg(dreg, RAX, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
|
@ -273,10 +261,7 @@ void DSPEmitter::srri(const UDSPInstruction opc)
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(tmp1);
|
gpr.getFreeXReg(tmp1);
|
||||||
|
|
||||||
if (sreg >= DSP_REG_ACM0)
|
dsp_op_read_reg(sreg, tmp1);
|
||||||
dsp_op_read_reg_and_saturate(sreg, tmp1);
|
|
||||||
else
|
|
||||||
dsp_op_read_reg(sreg, tmp1);
|
|
||||||
dsp_op_read_reg(dreg, RAX, ZERO);
|
dsp_op_read_reg(dreg, RAX, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
|
@ -297,10 +282,7 @@ void DSPEmitter::srrn(const UDSPInstruction opc)
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(tmp1);
|
gpr.getFreeXReg(tmp1);
|
||||||
|
|
||||||
if (sreg >= DSP_REG_ACM0)
|
dsp_op_read_reg(sreg, tmp1);
|
||||||
dsp_op_read_reg_and_saturate(sreg, tmp1);
|
|
||||||
else
|
|
||||||
dsp_op_read_reg(sreg, tmp1);
|
|
||||||
dsp_op_read_reg(dreg, RAX, ZERO);
|
dsp_op_read_reg(dreg, RAX, ZERO);
|
||||||
dmem_write(tmp1);
|
dmem_write(tmp1);
|
||||||
|
|
||||||
|
|
|
@ -31,10 +31,7 @@ void DSPEmitter::mrr(const UDSPInstruction opc)
|
||||||
u8 sreg = opc & 0x1f;
|
u8 sreg = opc & 0x1f;
|
||||||
u8 dreg = (opc >> 5) & 0x1f;
|
u8 dreg = (opc >> 5) & 0x1f;
|
||||||
|
|
||||||
if (sreg >= DSP_REG_ACM0)
|
dsp_op_read_reg(sreg, EDX);
|
||||||
dsp_op_read_reg_and_saturate(sreg, EDX);
|
|
||||||
else
|
|
||||||
dsp_op_read_reg(sreg, EDX);
|
|
||||||
dsp_op_write_reg(dreg, EDX);
|
dsp_op_write_reg(dreg, EDX);
|
||||||
dsp_conditional_extend_accum(dreg);
|
dsp_conditional_extend_accum(dreg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
switch (reg & 0x1f) {
|
||||||
case DSP_REG_ST0:
|
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
|
#ifdef _M_IX86 // All32
|
||||||
gpr.readReg(reg, host_dreg, extend);
|
MOVSX(32, 16, host_dreg, R(host_dreg));
|
||||||
#else
|
#else
|
||||||
OpArg acc_reg;
|
MOVSX(64, 16, host_dreg, R(host_dreg));
|
||||||
gpr.getReg(reg-DSP_REG_ACM0+DSP_REG_ACC0_64, acc_reg);
|
|
||||||
#endif
|
#endif
|
||||||
OpArg sr_reg;
|
break;
|
||||||
gpr.getReg(DSP_REG_SR,sr_reg);
|
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);
|
DSPJitRegCache c(gpr);
|
||||||
TEST(16, sr_reg, Imm16(SR_40_MODE_BIT));
|
TEST(16, sr_reg, Imm16(SR_40_MODE_BIT));
|
||||||
FixupBranch not_40bit = J_CC(CC_Z, true);
|
FixupBranch not_40bit = J_CC(CC_Z, true);
|
||||||
|
|
||||||
#ifdef _M_IX86 // All32
|
#ifdef _M_IX86 // All32
|
||||||
DSPJitRegCache c2(gpr);
|
DSPJitRegCache c2(gpr);
|
||||||
gpr.putReg(DSP_REG_SR, false);
|
gpr.putReg(DSP_REG_SR, false);
|
||||||
X64Reg tmp1;
|
X64Reg tmp1;
|
||||||
gpr.getFreeXReg(tmp1);
|
gpr.getFreeXReg(tmp1);
|
||||||
gpr.readReg(reg-DSP_REG_ACM0+DSP_REG_ACH0, tmp1, NONE);
|
gpr.readReg(reg-DSP_REG_ACM0+DSP_REG_ACH0, tmp1, NONE);
|
||||||
MOVSX(32,16,host_dreg,R(host_dreg));
|
MOVSX(32,16,host_dreg,R(host_dreg));
|
||||||
SHL(32, R(tmp1), Imm8(16));
|
SHL(32, R(tmp1), Imm8(16));
|
||||||
MOV(16,R(tmp1),R(host_dreg));
|
MOV(16,R(tmp1),R(host_dreg));
|
||||||
CMP(32,R(host_dreg), R(tmp1));
|
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));
|
CMP(32,R(tmp1),Imm32(0));
|
||||||
FixupBranch negative = J_CC(CC_LE);
|
FixupBranch negative = J_CC(CC_LE);
|
||||||
|
|
||||||
MOV(32,R(host_dreg),Imm32(0x7fff));//this works for all extend modes
|
MOV(32,R(host_dreg),Imm32(0x7fff));//this works for all extend modes
|
||||||
FixupBranch done_positive = J();
|
FixupBranch done_positive = J();
|
||||||
|
|
||||||
SetJumpTarget(negative);
|
SetJumpTarget(negative);
|
||||||
if (extend == NONE || extend == ZERO)
|
if (extend == NONE || extend == ZERO)
|
||||||
MOV(32,R(host_dreg),Imm32(0x00008000));
|
MOV(32,R(host_dreg),Imm32(0x00008000));
|
||||||
else
|
else
|
||||||
MOV(32,R(host_dreg),Imm32(0xffff8000));
|
MOV(32,R(host_dreg),Imm32(0xffff8000));
|
||||||
FixupBranch done_negative = J();
|
FixupBranch done_negative = J();
|
||||||
|
|
||||||
SetJumpTarget(no_saturate);
|
SetJumpTarget(no_saturate);
|
||||||
if (extend == ZERO)
|
if (extend == ZERO)
|
||||||
MOVZX(32,16,host_dreg,R(host_dreg));
|
MOVZX(32,16,host_dreg,R(host_dreg));
|
||||||
SetJumpTarget(done_positive);
|
SetJumpTarget(done_positive);
|
||||||
SetJumpTarget(done_negative);
|
SetJumpTarget(done_negative);
|
||||||
gpr.putXReg(tmp1);
|
gpr.putXReg(tmp1);
|
||||||
gpr.flushRegs(c2);
|
gpr.flushRegs(c2);
|
||||||
SetJumpTarget(not_40bit);
|
SetJumpTarget(not_40bit);
|
||||||
gpr.flushRegs(c);
|
gpr.flushRegs(c);
|
||||||
#else
|
#else
|
||||||
|
|
||||||
MOVSX(64,32,host_dreg,acc_reg);
|
MOVSX(64,32,host_dreg,acc_reg);
|
||||||
CMP(64,R(host_dreg),acc_reg);
|
CMP(64,R(host_dreg),acc_reg);
|
||||||
FixupBranch no_saturate = J_CC(CC_Z);
|
FixupBranch no_saturate = J_CC(CC_Z);
|
||||||
|
|
||||||
CMP(64,acc_reg,Imm32(0));
|
CMP(64,acc_reg,Imm32(0));
|
||||||
FixupBranch negative = J_CC(CC_LE);
|
FixupBranch negative = J_CC(CC_LE);
|
||||||
|
|
||||||
MOV(64,R(host_dreg),Imm32(0x7fff));//this works for all extend modes
|
MOV(64,R(host_dreg),Imm32(0x7fff));//this works for all extend modes
|
||||||
FixupBranch done_positive = J();
|
FixupBranch done_positive = J();
|
||||||
|
|
||||||
SetJumpTarget(negative);
|
SetJumpTarget(negative);
|
||||||
if (extend == NONE || extend == ZERO)
|
if (extend == NONE || extend == ZERO)
|
||||||
MOV(64,R(host_dreg),Imm32(0x00008000));
|
MOV(64,R(host_dreg),Imm32(0x00008000));
|
||||||
else
|
else
|
||||||
MOV(64,R(host_dreg),Imm32(0xffff8000));
|
MOV(64,R(host_dreg),Imm32(0xffff8000));
|
||||||
FixupBranch done_negative = J();
|
FixupBranch done_negative = J();
|
||||||
|
|
||||||
SetJumpTarget(no_saturate);
|
SetJumpTarget(no_saturate);
|
||||||
SetJumpTarget(not_40bit);
|
SetJumpTarget(not_40bit);
|
||||||
|
|
||||||
MOV(64, R(host_dreg), acc_reg);
|
MOV(64, R(host_dreg), acc_reg);
|
||||||
if (extend == NONE || extend == ZERO)
|
if (extend == NONE || extend == ZERO)
|
||||||
SHR(64, R(host_dreg), Imm8(16));
|
SHR(64, R(host_dreg), Imm8(16));
|
||||||
else
|
else
|
||||||
SAR(64, R(host_dreg), Imm8(16));
|
SAR(64, R(host_dreg), Imm8(16));
|
||||||
SetJumpTarget(done_positive);
|
SetJumpTarget(done_positive);
|
||||||
SetJumpTarget(done_negative);
|
SetJumpTarget(done_negative);
|
||||||
gpr.flushRegs(c);
|
gpr.flushRegs(c);
|
||||||
gpr.putReg(reg-DSP_REG_ACM0+DSP_REG_ACC0_64, false);
|
gpr.putReg(reg-DSP_REG_ACM0+DSP_REG_ACC0_64, false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
gpr.putReg(DSP_REG_SR, false);
|
gpr.putReg(DSP_REG_SR, false);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
gpr.readReg(reg, host_dreg, extend);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// addr math
|
// addr math
|
||||||
|
|
Loading…
Reference in New Issue