JitArm64: Improve codegen in ANDI2R and friends
The codegen for the functions themselves, not for the emitted code. This seems to save 32 bytes per function. We also get rid of the oddity we had before where ANDI2R would do masking for 32-bit operations but the other functions wouldn't.
This commit is contained in:
parent
a8e1e1ae48
commit
dc60bc5f1e
|
@ -4039,9 +4039,19 @@ void ARM64FloatEmitter::ABI_PopRegisters(BitSet32 registers, ARM64Reg tmp)
|
|||
void ARM64XEmitter::ANDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
|
||||
{
|
||||
if (!Is64Bit(Rn))
|
||||
imm &= 0xFFFFFFFF;
|
||||
{
|
||||
// To handle 32-bit logical immediates, the very easiest thing is to repeat
|
||||
// the input value twice to make a 64-bit word. The correct encoding of that
|
||||
// as a logical immediate will also be the correct encoding of the 32-bit
|
||||
// value.
|
||||
//
|
||||
// Doing this here instead of in the LogicalImm constructor makes it easier
|
||||
// to check if the input is all ones.
|
||||
|
||||
if (imm != (Is64Bit(Rn) ? 0xFFFF'FFFF'FFFF'FFFF : 0xFFFF'FFFF))
|
||||
imm = (imm << 32) | (imm & 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
if ((~imm) == 0)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
@ -4049,7 +4059,7 @@ void ARM64XEmitter::ANDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
|
|||
{
|
||||
MOVZ(Rd, 0);
|
||||
}
|
||||
else if (const auto result = LogicalImm(imm, Is64Bit(Rn) ? GPRSize::B64 : GPRSize::B32))
|
||||
else if (const auto result = LogicalImm(imm, GPRSize::B64))
|
||||
{
|
||||
AND(Rd, Rn, result);
|
||||
}
|
||||
|
@ -4065,15 +4075,28 @@ void ARM64XEmitter::ANDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
|
|||
|
||||
void ARM64XEmitter::ORRI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
|
||||
{
|
||||
if (!Is64Bit(Rn))
|
||||
{
|
||||
// To handle 32-bit logical immediates, the very easiest thing is to repeat
|
||||
// the input value twice to make a 64-bit word. The correct encoding of that
|
||||
// as a logical immediate will also be the correct encoding of the 32-bit
|
||||
// value.
|
||||
//
|
||||
// Doing this here instead of in the LogicalImm constructor makes it easier
|
||||
// to check if the input is all ones.
|
||||
|
||||
imm = (imm << 32) | (imm & 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
if (imm == 0)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else if (imm == (Is64Bit(Rn) ? 0xFFFF'FFFF'FFFF'FFFF : 0xFFFF'FFFF))
|
||||
else if ((~imm) == 0)
|
||||
{
|
||||
MOVN(Rd, 0);
|
||||
}
|
||||
else if (const auto result = LogicalImm(imm, Is64Bit(Rn) ? GPRSize::B64 : GPRSize::B32))
|
||||
else if (const auto result = LogicalImm(imm, GPRSize::B64))
|
||||
{
|
||||
ORR(Rd, Rn, result);
|
||||
}
|
||||
|
@ -4089,15 +4112,28 @@ void ARM64XEmitter::ORRI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
|
|||
|
||||
void ARM64XEmitter::EORI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
|
||||
{
|
||||
if (!Is64Bit(Rn))
|
||||
{
|
||||
// To handle 32-bit logical immediates, the very easiest thing is to repeat
|
||||
// the input value twice to make a 64-bit word. The correct encoding of that
|
||||
// as a logical immediate will also be the correct encoding of the 32-bit
|
||||
// value.
|
||||
//
|
||||
// Doing this here instead of in the LogicalImm constructor makes it easier
|
||||
// to check if the input is all ones.
|
||||
|
||||
imm = (imm << 32) | (imm & 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
if (imm == 0)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else if (imm == (Is64Bit(Rn) ? 0xFFFF'FFFF'FFFF'FFFF : 0xFFFF'FFFF))
|
||||
else if ((~imm) == 0)
|
||||
{
|
||||
MVN(Rd, Rn);
|
||||
}
|
||||
else if (const auto result = LogicalImm(imm, Is64Bit(Rn) ? GPRSize::B64 : GPRSize::B32))
|
||||
else if (const auto result = LogicalImm(imm, GPRSize::B64))
|
||||
{
|
||||
EOR(Rd, Rn, result);
|
||||
}
|
||||
|
@ -4113,16 +4149,29 @@ void ARM64XEmitter::EORI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
|
|||
|
||||
void ARM64XEmitter::ANDSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch)
|
||||
{
|
||||
if (!Is64Bit(Rn))
|
||||
{
|
||||
// To handle 32-bit logical immediates, the very easiest thing is to repeat
|
||||
// the input value twice to make a 64-bit word. The correct encoding of that
|
||||
// as a logical immediate will also be the correct encoding of the 32-bit
|
||||
// value.
|
||||
//
|
||||
// Doing this here instead of in the LogicalImm constructor makes it easier
|
||||
// to check if the input is all ones.
|
||||
|
||||
imm = (imm << 32) | (imm & 0xFFFFFFFF);
|
||||
}
|
||||
|
||||
if (imm == 0)
|
||||
{
|
||||
ANDS(Rd, Is64Bit(Rn) ? ARM64Reg::ZR : ARM64Reg::WZR,
|
||||
Is64Bit(Rn) ? ARM64Reg::ZR : ARM64Reg::WZR);
|
||||
}
|
||||
else if (imm == (Is64Bit(Rn) ? 0xFFFF'FFFF'FFFF'FFFF : 0xFFFF'FFFF))
|
||||
else if ((~imm) == 0)
|
||||
{
|
||||
ANDS(Rd, Rn, Rn);
|
||||
}
|
||||
else if (const auto result = LogicalImm(imm, Is64Bit(Rn) ? GPRSize::B64 : GPRSize::B32))
|
||||
else if (const auto result = LogicalImm(imm, GPRSize::B64))
|
||||
{
|
||||
ANDS(Rd, Rn, result);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue