summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorMai <mai.iam2048@gmail.com>2023-12-17 14:45:55 -0500
committerGitHub <noreply@github.com>2023-12-17 14:45:55 -0500
commit559ea0593cb157f99e0ff5dc223acf6d2736d17d (patch)
tree305d31fc6ce1fa825a8a004d9f1fb90b2d0643f0 /Source
parentf0f0f975545f2be95321b258b2065403b210c71a (diff)
parentdc60bc5f1ef19fc92b2dd9c92655bf5f282106dd (diff)
Merge pull request #12432 from JosJuice/jitarm64-logic-i2r-opt
JitArm64: Add additional optimized cases to ANDI2R and friends
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Common/Arm64Emitter.cpp92
1 files changed, 87 insertions, 5 deletions
diff --git a/Source/Core/Common/Arm64Emitter.cpp b/Source/Core/Common/Arm64Emitter.cpp
index d70d48d72f..6f4f42c027 100644
--- a/Source/Core/Common/Arm64Emitter.cpp
+++ b/Source/Core/Common/Arm64Emitter.cpp
@@ -4039,9 +4039,27 @@ 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.
+
+ imm = (imm << 32) | (imm & 0xFFFFFFFF);
+ }
- if (const auto result = LogicalImm(imm, Is64Bit(Rn) ? GPRSize::B64 : GPRSize::B32))
+ if ((~imm) == 0)
+ {
+ // Do nothing
+ }
+ else if (imm == 0)
+ {
+ MOVZ(Rd, 0);
+ }
+ else if (const auto result = LogicalImm(imm, GPRSize::B64))
{
AND(Rd, Rn, result);
}
@@ -4057,7 +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 (const auto result = LogicalImm(imm, Is64Bit(Rn) ? GPRSize::B64 : GPRSize::B32))
+ 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) == 0)
+ {
+ MOVN(Rd, 0);
+ }
+ else if (const auto result = LogicalImm(imm, GPRSize::B64))
{
ORR(Rd, Rn, result);
}
@@ -4073,7 +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 (const auto result = LogicalImm(imm, Is64Bit(Rn) ? GPRSize::B64 : GPRSize::B32))
+ 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) == 0)
+ {
+ MVN(Rd, Rn);
+ }
+ else if (const auto result = LogicalImm(imm, GPRSize::B64))
{
EOR(Rd, Rn, result);
}
@@ -4089,7 +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 (const auto result = LogicalImm(imm, Is64Bit(Rn) ? GPRSize::B64 : GPRSize::B32))
+ 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) == 0)
+ {
+ ANDS(Rd, Rn, Rn);
+ }
+ else if (const auto result = LogicalImm(imm, GPRSize::B64))
{
ANDS(Rd, Rn, result);
}