arm64: Implement ext and ins.

This commit is contained in:
Unknown W. Brackets committed 2015-06-28 08:45:17 -07:00
1 parent 803170b992
commit 0a5b1c030b
3 files changed
+50 -2

No files matched your search

+4
View File
@@ -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);
+1 -1
View File
@@ -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);
+45 -1
View File
@@ -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) {