diff options
| author | Mai <mai.iam2048@gmail.com> | 2023-12-17 14:45:55 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-17 14:45:55 -0500 |
| commit | 559ea0593cb157f99e0ff5dc223acf6d2736d17d (patch) | |
| tree | 305d31fc6ce1fa825a8a004d9f1fb90b2d0643f0 /Source | |
| parent | f0f0f975545f2be95321b258b2065403b210c71a (diff) | |
| parent | dc60bc5f1ef19fc92b2dd9c92655bf5f282106dd (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.cpp | 92 |
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); } |
