mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
arm64: Implement ext and ins.
This commit is contained in:
1 parent
803170b992
commit
0a5b1c030b
3 files changed
+50
-2
No files matched your search
@@ -592,6 +592,10 @@ public:
|
||||
void SBFM(ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms);
|
||||
void UBFM(ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms);
|
||||
|
||||
void BFI(ARM64Reg Rd, ARM64Reg Rn, int lsb, int width) {
|
||||
BFM(Rd, Rn, (64 - lsb) % (Is64Bit(Rd) ? 64 : 32), width - 1);
|
||||
}
|
||||
|
||||
// Extract register (ROR with two inputs, if same then faster on A67)
|
||||
void EXTR(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, u32 shift);
|
||||
|
||||
|
||||
@@ -573,7 +573,7 @@ namespace MIPSComp
|
||||
} else {
|
||||
gpr.MapDirtyIn(rt, rs, false);
|
||||
#ifdef HAVE_ARMV7
|
||||
BFI(gpr.R(rt), gpr.R(rs), pos, size-pos);
|
||||
BFI(gpr.R(rt), gpr.R(rs), pos, size - pos);
|
||||
#else
|
||||
ANDI2R(SCRATCHREG1, gpr.R(rs), sourcemask, SCRATCHREG2);
|
||||
ANDI2R(gpr.R(rt), gpr.R(rt), destmask, SCRATCHREG2);
|
||||
|
||||
@@ -410,7 +410,51 @@ void Arm64Jit::Comp_ShiftType(MIPSOpcode op) {
|
||||
}
|
||||
|
||||
void Arm64Jit::Comp_Special3(MIPSOpcode op) {
|
||||
DISABLE;
|
||||
CONDITIONAL_DISABLE;
|
||||
MIPSGPReg rs = _RS;
|
||||
MIPSGPReg rt = _RT;
|
||||
|
||||
int pos = _POS;
|
||||
int size = _SIZE + 1;
|
||||
u32 mask = (1 << size) - 1;
|
||||
|
||||
// Don't change $zr.
|
||||
if (rt == 0)
|
||||
return;
|
||||
|
||||
switch (op & 0x3f) {
|
||||
case 0x0: //ext
|
||||
if (gpr.IsImm(rs)) {
|
||||
gpr.SetImm(rt, (gpr.GetImm(rs) >> pos) & mask);
|
||||
return;
|
||||
}
|
||||
|
||||
gpr.MapDirtyIn(rt, rs);
|
||||
UBFX(gpr.R(rt), gpr.R(rs), pos, size);
|
||||
break;
|
||||
|
||||
case 0x4: //ins
|
||||
{
|
||||
u32 sourcemask = mask >> pos;
|
||||
u32 destmask = ~(sourcemask << pos);
|
||||
if (gpr.IsImm(rs)) {
|
||||
u32 inserted = (gpr.GetImm(rs) & sourcemask) << pos;
|
||||
if (gpr.IsImm(rt)) {
|
||||
gpr.SetImm(rt, (gpr.GetImm(rt) & destmask) | inserted);
|
||||
return;
|
||||
}
|
||||
|
||||
// It might be nice to avoid flushing rs, but it's the a little slower and
|
||||
// usually more instructions. Not worth it.
|
||||
gpr.MapDirtyIn(rt, rs, false);
|
||||
BFI(gpr.R(rt), gpr.R(rs), pos, size - pos);
|
||||
} else {
|
||||
gpr.MapDirtyIn(rt, rs, false);
|
||||
BFI(gpr.R(rt), gpr.R(rs), pos, size - pos);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Arm64Jit::Comp_Allegrex(MIPSOpcode op) {
|
||||
|
||||
Reference in new issue
Block a user