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:
Pierre 2011-09-04 15:37:53 +02:00
parent 54f3828555
commit a902c720e0
6 changed files with 125 additions and 125 deletions

View File

@ -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);

View File

@ -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));

View File

@ -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,9 +86,6 @@ 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_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]; // u16 val = g_dsp.r[src];
dmem_write(tmp1); dmem_write(tmp1);
@ -114,9 +108,6 @@ 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_and_saturate(sreg, tmp1, ZERO);
else
dsp_op_read_reg(sreg, tmp1, ZERO); dsp_op_read_reg(sreg, tmp1, ZERO);
dmem_write(tmp1); dmem_write(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];

View File

@ -39,9 +39,6 @@ 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_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); dsp_op_read_reg(DSP_REG_CR, RAX, ZERO);
SHL(16, R(EAX), Imm8(8)); SHL(16, R(EAX), Imm8(8));
@ -101,9 +98,6 @@ 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_and_saturate(reg, tmp1);
else
dsp_op_read_reg(reg, tmp1); dsp_op_read_reg(reg, tmp1);
dmem_write_imm(address, tmp1); dmem_write_imm(address, tmp1);
@ -227,9 +221,6 @@ 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_and_saturate(sreg, tmp1);
else
dsp_op_read_reg(sreg, tmp1); 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,9 +240,6 @@ 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_and_saturate(sreg, tmp1);
else
dsp_op_read_reg(sreg, tmp1); 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,9 +261,6 @@ 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_and_saturate(sreg, tmp1);
else
dsp_op_read_reg(sreg, tmp1); 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,9 +282,6 @@ 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_and_saturate(sreg, tmp1);
else
dsp_op_read_reg(sreg, tmp1); 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);

View File

@ -31,9 +31,6 @@ 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_and_saturate(sreg, EDX);
else
dsp_op_read_reg(sreg, EDX); 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);

View File

@ -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,8 +240,36 @@ 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)
{ {
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
MOVSX(32, 16, host_dreg, R(host_dreg));
#else
MOVSX(64, 16, host_dreg, R(host_dreg));
#endif
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 //we already know this is ACCM0 or ACCM1
#ifdef _M_IX86 // All32 #ifdef _M_IX86 // All32
gpr.readReg(reg, host_dreg, extend); gpr.readReg(reg, host_dreg, extend);
@ -326,6 +354,12 @@ void DSPEmitter::dsp_op_read_reg_and_saturate(int reg, Gen::X64Reg host_dreg, DS
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
// //