mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
ARMJIT: Fix and use DIV, DIVU, INS and EXT (ARMv7 and VFPv4 implementations).
This commit is contained in:
parent
3587cef738
commit
a14a2fafa9
2 changed files with 40 additions and 19 deletions
|
@ -1156,13 +1156,39 @@ void ARMXEmitter::VMOV(ARMReg Dest, ARMReg Src)
|
|||
void ARMXEmitter::VCVT(ARMReg Dest, ARMReg Source, int flags)
|
||||
{
|
||||
bool single_reg = (Dest < D0) && (Source < D0);
|
||||
bool single_double = !single_reg && (Source < D0 || Dest < D0);
|
||||
bool single_to_double = Source < D0;
|
||||
int op = ((flags & TO_INT) ? (flags & ROUND_TO_ZERO) : (flags & IS_SIGNED)) ? 1 : 0;
|
||||
int op2 = ((flags & TO_INT) ? (flags & IS_SIGNED) : 0) ? 1 : 0;
|
||||
Dest = SubBase(Dest);
|
||||
Source = SubBase(Source);
|
||||
|
||||
if (single_reg)
|
||||
if (single_double)
|
||||
{
|
||||
// S32<->F64
|
||||
if ((flags & TO_INT) || (flags & TO_FLOAT))
|
||||
{
|
||||
if (single_to_double)
|
||||
{
|
||||
Write32(condition | (0x1D << 23) | ((Dest & 0x10) << 18) | (0x7 << 19) \
|
||||
| ((Dest & 0xF) << 12) | (op << 7) | (0x2D << 6) | ((Source & 0x1) << 5) | (Source >> 1));
|
||||
} else {
|
||||
Write32(condition | (0x1D << 23) | ((Dest & 0x1) << 22) | (0x7 << 19) | ((flags & TO_INT) << 18) | (op2 << 16) \
|
||||
| ((Dest & 0x1E) << 11) | (op << 7) | (0x2D << 6) | ((Source & 0x10) << 1) | (Source & 0xF));
|
||||
}
|
||||
}
|
||||
// F32<->F64
|
||||
else {
|
||||
if (single_to_double)
|
||||
{
|
||||
Write32(condition | (0x1D << 23) | ((Dest & 0x10) << 18) | (0x3 << 20) | (0x7 << 16) \
|
||||
| ((Dest & 0xF) << 12) | (0x2F << 6) | ((Source & 0x1) << 5) | (Source >> 1));
|
||||
} else {
|
||||
Write32(condition | (0x1D << 23) | ((Dest & 0x1) << 22) | (0x3 << 20) | (0x7 << 16) \
|
||||
| ((Dest & 0x1E) << 11) | (0x2B << 6) | ((Source & 0x10) << 1) | (Source & 0xF));
|
||||
}
|
||||
}
|
||||
} else if (single_reg) {
|
||||
Write32(condition | (0x1D << 23) | ((Dest & 0x1) << 22) | (0x7 << 19) | ((flags & TO_INT) << 18) | (op2 << 16) \
|
||||
| ((Dest & 0x1E) << 11) | (op << 7) | (0x29 << 6) | ((Source & 0x1) << 5) | (Source >> 1));
|
||||
} else {
|
||||
|
|
|
@ -382,12 +382,6 @@ namespace MIPSComp
|
|||
void Jit::Comp_Special3(u32 op)
|
||||
{
|
||||
CONDITIONAL_DISABLE;
|
||||
|
||||
bool useUBFXandBFI = false;
|
||||
|
||||
if (!cpu_info.bArmV7) {
|
||||
// useUBFXandBFI = true;
|
||||
}
|
||||
|
||||
int rs = _RS;
|
||||
int rt = _RT;
|
||||
|
@ -409,11 +403,8 @@ namespace MIPSComp
|
|||
return;
|
||||
}
|
||||
|
||||
// Reported to break Disgaea.
|
||||
DISABLE;
|
||||
|
||||
gpr.MapDirtyIn(rt, rs);
|
||||
if (useUBFXandBFI) {
|
||||
if (cpu_info.bArmV7) {
|
||||
UBFX(gpr.R(rt), gpr.R(rs), pos, size);
|
||||
} else {
|
||||
MOV(gpr.R(rt), Operand2(gpr.R(rs), ST_LSR, pos));
|
||||
|
@ -440,9 +431,9 @@ namespace MIPSComp
|
|||
}
|
||||
else
|
||||
{
|
||||
if (useUBFXandBFI) {
|
||||
if (cpu_info.bArmV7) {
|
||||
gpr.MapDirtyIn(rt, rs, false);
|
||||
BFI(gpr.R(rt), gpr.R(rs), pos, size);
|
||||
BFI(gpr.R(rt), gpr.R(rs), pos, size-pos);
|
||||
} else {
|
||||
gpr.MapDirtyIn(rt, rs, false);
|
||||
ANDI2R(R0, gpr.R(rs), sourcemask, R1);
|
||||
|
@ -554,40 +545,44 @@ namespace MIPSComp
|
|||
break;
|
||||
|
||||
case 26: //div
|
||||
DISABLE;
|
||||
gpr.MapDirtyDirtyInIn(MIPSREG_LO, MIPSREG_HI, rs, rt);
|
||||
if (cpu_info.bIDIVa)
|
||||
{
|
||||
gpr.MapDirtyDirtyInIn(MIPSREG_LO, MIPSREG_HI, rs, rt);
|
||||
SDIV(gpr.R(MIPSREG_LO), gpr.R(rs), gpr.R(rt));
|
||||
MUL(R0, gpr.R(rt), gpr.R(MIPSREG_LO));
|
||||
SUB(gpr.R(MIPSREG_HI), gpr.R(rs), Operand2(R0));
|
||||
} else {
|
||||
DISABLE;
|
||||
gpr.MapDirtyDirtyInIn(MIPSREG_LO, MIPSREG_HI, rs, rt);
|
||||
VMOV(S0, gpr.R(rs));
|
||||
VMOV(S1, gpr.R(rt));
|
||||
VCVT(D0, S0, TO_FLOAT | IS_SIGNED);
|
||||
VCVT(D1, S1, TO_FLOAT | IS_SIGNED);
|
||||
VDIV(D0, D0, D1);
|
||||
VCVT(gpr.R(MIPSREG_LO), D0, TO_INT | IS_SIGNED);
|
||||
VCVT(S0, D0, TO_INT);
|
||||
VMOV(gpr.R(MIPSREG_LO), S0);
|
||||
MUL(R0, gpr.R(rt), gpr.R(MIPSREG_LO));
|
||||
SUB(gpr.R(MIPSREG_HI), gpr.R(rs), Operand2(R0));
|
||||
}
|
||||
break;
|
||||
|
||||
case 27: //divu
|
||||
DISABLE;
|
||||
gpr.MapDirtyDirtyInIn(MIPSREG_LO, MIPSREG_HI, rs, rt);
|
||||
if (cpu_info.bIDIVa)
|
||||
{
|
||||
gpr.MapDirtyDirtyInIn(MIPSREG_LO, MIPSREG_HI, rs, rt);
|
||||
UDIV(gpr.R(MIPSREG_LO), gpr.R(rs), gpr.R(rt));
|
||||
MUL(R0, gpr.R(rt), gpr.R(MIPSREG_LO));
|
||||
SUB(gpr.R(MIPSREG_HI), gpr.R(rs), Operand2(R0));
|
||||
} else {
|
||||
DISABLE;
|
||||
gpr.MapDirtyDirtyInIn(MIPSREG_LO, MIPSREG_HI, rs, rt);
|
||||
VMOV(S0, gpr.R(rs));
|
||||
VMOV(S1, gpr.R(rt));
|
||||
VCVT(D0, S0, TO_FLOAT);
|
||||
VCVT(D1, S1, TO_FLOAT);
|
||||
VDIV(D0, D0, D1);
|
||||
VCVT(gpr.R(MIPSREG_LO), D0, TO_INT);
|
||||
VCVT(S0, D0, TO_INT);
|
||||
VMOV(gpr.R(MIPSREG_LO), S0);
|
||||
MUL(R0, gpr.R(rt), gpr.R(MIPSREG_LO));
|
||||
SUB(gpr.R(MIPSREG_HI), gpr.R(rs), Operand2(R0));
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue