[AArch64] Implement BFI & UBFIZ in the emitter.
Also fixes a bug in the UBFX instruction emitter. Naughty Naughty PPSSPP, not testing emitter functions you add.
This commit is contained in:
parent
12fe42b2a3
commit
afc3d30f5c
|
@ -1523,6 +1523,21 @@ void ARM64XEmitter::UBFM(ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms)
|
||||||
{
|
{
|
||||||
EncodeBitfieldMOVInst(2, Rd, Rn, immr, imms);
|
EncodeBitfieldMOVInst(2, Rd, Rn, immr, imms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARM64XEmitter::BFI(ARM64Reg Rd, ARM64Reg Rn, u32 lsb, u32 width)
|
||||||
|
{
|
||||||
|
u32 size = Is64Bit(Rn) ? 64 : 32;
|
||||||
|
_assert_msg_(DYNA_REC, (lsb + width) <= size, "%s passed lsb %d and width %d which is greater than the register size!",
|
||||||
|
__FUNCTION__, lsb, width);
|
||||||
|
EncodeBitfieldMOVInst(1, Rd, Rn, (size - lsb) % size, width - 1);
|
||||||
|
}
|
||||||
|
void ARM64XEmitter::UBFIZ(ARM64Reg Rd, ARM64Reg Rn, u32 lsb, u32 width)
|
||||||
|
{
|
||||||
|
u32 size = Is64Bit(Rn) ? 64 : 32;
|
||||||
|
_assert_msg_(DYNA_REC, (lsb + width) <= size, "%s passed lsb %d and width %d which is greater than the register size!",
|
||||||
|
__FUNCTION__, lsb, width);
|
||||||
|
EncodeBitfieldMOVInst(2, Rd, Rn, (size - lsb) % size, width - 1);
|
||||||
|
}
|
||||||
void ARM64XEmitter::EXTR(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, u32 shift)
|
void ARM64XEmitter::EXTR(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, u32 shift)
|
||||||
{
|
{
|
||||||
bool sf = Is64Bit(Rd);
|
bool sf = Is64Bit(Rd);
|
||||||
|
|
|
@ -578,6 +578,8 @@ public:
|
||||||
void BFM(ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms);
|
void BFM(ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms);
|
||||||
void SBFM(ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms);
|
void SBFM(ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms);
|
||||||
void UBFM(ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms);
|
void UBFM(ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms);
|
||||||
|
void BFI(ARM64Reg Rd, ARM64Reg Rn, u32 lsb, u32 width);
|
||||||
|
void UBFIZ(ARM64Reg Rd, ARM64Reg Rn, u32 lsb, u32 width);
|
||||||
|
|
||||||
// Extract register (ROR with two inputs, if same then faster on A67)
|
// Extract register (ROR with two inputs, if same then faster on A67)
|
||||||
void EXTR(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, u32 shift);
|
void EXTR(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, u32 shift);
|
||||||
|
@ -591,7 +593,7 @@ public:
|
||||||
|
|
||||||
void UBFX(ARM64Reg Rd, ARM64Reg Rn, int lsb, int width)
|
void UBFX(ARM64Reg Rd, ARM64Reg Rn, int lsb, int width)
|
||||||
{
|
{
|
||||||
UBFM(Rd, Rn, lsb, lsb + width <= (Is64Bit(Rn) ? 64 : 32));
|
UBFM(Rd, Rn, lsb, lsb + width - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load Register (Literal)
|
// Load Register (Literal)
|
||||||
|
|
Loading…
Reference in New Issue