diff options
| author | Dentomologist <dentomologist@gmail.com> | 2021-02-06 10:50:33 -0800 |
|---|---|---|
| committer | Dentomologist <dentomologist@gmail.com> | 2021-03-13 10:10:59 -0800 |
| commit | f0f206714fd1754da93691ea13776500a9b6d278 (patch) | |
| tree | 966d0628b79f84e33844b7232778cde8d06e1114 /Source/Core/Common | |
| parent | 18d95dfcca463dd24e686d74066da96e27edbb3f (diff) | |
Arm64Gen: Convert ARM64Reg to enum class
Most changes are just adding ARM64Reg:: in front of the constants.
Diffstat (limited to 'Source/Core/Common')
| -rw-r--r-- | Source/Core/Common/Arm64Emitter.cpp | 498 | ||||
| -rw-r--r-- | Source/Core/Common/Arm64Emitter.h | 79 |
2 files changed, 236 insertions, 341 deletions
diff --git a/Source/Core/Common/Arm64Emitter.cpp b/Source/Core/Common/Arm64Emitter.cpp index ae07647339..3ffb64401f 100644 --- a/Source/Core/Common/Arm64Emitter.cpp +++ b/Source/Core/Common/Arm64Emitter.cpp @@ -507,8 +507,8 @@ void ARM64XEmitter::EncodeCompareBranchInst(u32 op, ARM64Reg Rt, const void* ptr ASSERT_MSG(DYNA_REC, distance >= -0x40000 && distance <= 0x3FFFF, "%s: Received too large distance: %" PRIx64, __func__, distance); - Rt = DecodeReg(Rt); - Write32((b64Bit << 31) | (0x34 << 24) | (op << 24) | (((u32)distance << 5) & 0xFFFFE0) | Rt); + Write32((b64Bit << 31) | (0x34 << 24) | (op << 24) | (((u32)distance << 5) & 0xFFFFE0) | + DecodeReg(Rt)); } void ARM64XEmitter::EncodeTestBranchInst(u32 op, ARM64Reg Rt, u8 bits, const void* ptr) @@ -524,9 +524,8 @@ void ARM64XEmitter::EncodeTestBranchInst(u32 op, ARM64Reg Rt, u8 bits, const voi ASSERT_MSG(DYNA_REC, distance >= -0x3FFF && distance < 0x3FFF, "%s: Received too large distance: %" PRIx64, __func__, distance); - Rt = DecodeReg(Rt); Write32((b64Bit << 31) | (0x36 << 24) | (op << 24) | (bits << 19) | - (((u32)distance << 5) & 0x7FFE0) | Rt); + (((u32)distance << 5) & 0x7FFE0) | DecodeReg(Rt)); } void ARM64XEmitter::EncodeUnconditionalBranchInst(u32 op, const void* ptr) @@ -546,8 +545,7 @@ void ARM64XEmitter::EncodeUnconditionalBranchInst(u32 op, const void* ptr) void ARM64XEmitter::EncodeUnconditionalBranchInst(u32 opc, u32 op2, u32 op3, u32 op4, ARM64Reg Rn) { - Rn = DecodeReg(Rn); - Write32((0x6B << 25) | (opc << 21) | (op2 << 16) | (op3 << 10) | (Rn << 5) | op4); + Write32((0x6B << 25) | (opc << 21) | (op2 << 16) | (op3 << 10) | (DecodeReg(Rn) << 5) | op4); } void ARM64XEmitter::EncodeExceptionInst(u32 instenc, u32 imm) @@ -561,7 +559,8 @@ void ARM64XEmitter::EncodeExceptionInst(u32 instenc, u32 imm) void ARM64XEmitter::EncodeSystemInst(u32 op0, u32 op1, u32 CRn, u32 CRm, u32 op2, ARM64Reg Rt) { - Write32((0x354 << 22) | (op0 << 19) | (op1 << 16) | (CRn << 12) | (CRm << 8) | (op2 << 5) | Rt); + Write32((0x354 << 22) | (op0 << 19) | (op1 << 16) | (CRn << 12) | (CRm << 8) | (op2 << 5) | + DecodeReg(Rt)); } void ARM64XEmitter::EncodeArithmeticInst(u32 instenc, bool flags, ARM64Reg Rd, ARM64Reg Rn, @@ -569,11 +568,9 @@ void ARM64XEmitter::EncodeArithmeticInst(u32 instenc, bool flags, ARM64Reg Rd, A { bool b64Bit = Is64Bit(Rd); - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); - Rm = DecodeReg(Rm); Write32((b64Bit << 31) | (flags << 29) | (ArithEnc[instenc] << 21) | - (Option.IsExtended() ? (1 << 21) : 0) | (Rm << 16) | Option.GetData() | (Rn << 5) | Rd); + (Option.IsExtended() ? (1 << 21) : 0) | (DecodeReg(Rm) << 16) | Option.GetData() | + (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64XEmitter::EncodeArithmeticCarryInst(u32 op, bool flags, ARM64Reg Rd, ARM64Reg Rn, @@ -581,10 +578,8 @@ void ARM64XEmitter::EncodeArithmeticCarryInst(u32 op, bool flags, ARM64Reg Rd, A { bool b64Bit = Is64Bit(Rd); - Rd = DecodeReg(Rd); - Rm = DecodeReg(Rm); - Rn = DecodeReg(Rn); - Write32((b64Bit << 31) | (op << 30) | (flags << 29) | (0xD0 << 21) | (Rm << 16) | (Rn << 5) | Rd); + Write32((b64Bit << 31) | (op << 30) | (flags << 29) | (0xD0 << 21) | (DecodeReg(Rm) << 16) | + (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64XEmitter::EncodeCondCompareImmInst(u32 op, ARM64Reg Rn, u32 imm, u32 nzcv, CCFlags cond) @@ -594,9 +589,8 @@ void ARM64XEmitter::EncodeCondCompareImmInst(u32 op, ARM64Reg Rn, u32 imm, u32 n ASSERT_MSG(DYNA_REC, !(imm & ~0x1F), "%s: too large immediate: %d", __func__, imm); ASSERT_MSG(DYNA_REC, !(nzcv & ~0xF), "%s: Flags out of range: %d", __func__, nzcv); - Rn = DecodeReg(Rn); Write32((b64Bit << 31) | (op << 30) | (1 << 29) | (0xD2 << 21) | (imm << 16) | (cond << 12) | - (1 << 11) | (Rn << 5) | nzcv); + (1 << 11) | (DecodeReg(Rn) << 5) | nzcv); } void ARM64XEmitter::EncodeCondCompareRegInst(u32 op, ARM64Reg Rn, ARM64Reg Rm, u32 nzcv, @@ -606,10 +600,8 @@ void ARM64XEmitter::EncodeCondCompareRegInst(u32 op, ARM64Reg Rn, ARM64Reg Rm, u ASSERT_MSG(DYNA_REC, !(nzcv & ~0xF), "%s: Flags out of range: %d", __func__, nzcv); - Rm = DecodeReg(Rm); - Rn = DecodeReg(Rn); - Write32((b64Bit << 31) | (op << 30) | (1 << 29) | (0xD2 << 21) | (Rm << 16) | (cond << 12) | - (Rn << 5) | nzcv); + Write32((b64Bit << 31) | (op << 30) | (1 << 29) | (0xD2 << 21) | (DecodeReg(Rm) << 16) | + (cond << 12) | (DecodeReg(Rn) << 5) | nzcv); } void ARM64XEmitter::EncodeCondSelectInst(u32 instenc, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, @@ -617,32 +609,25 @@ void ARM64XEmitter::EncodeCondSelectInst(u32 instenc, ARM64Reg Rd, ARM64Reg Rn, { bool b64Bit = Is64Bit(Rd); - Rd = DecodeReg(Rd); - Rm = DecodeReg(Rm); - Rn = DecodeReg(Rn); - Write32((b64Bit << 31) | (CondSelectEnc[instenc][0] << 30) | (0xD4 << 21) | (Rm << 16) | - (cond << 12) | (CondSelectEnc[instenc][1] << 10) | (Rn << 5) | Rd); + Write32((b64Bit << 31) | (CondSelectEnc[instenc][0] << 30) | (0xD4 << 21) | + (DecodeReg(Rm) << 16) | (cond << 12) | (CondSelectEnc[instenc][1] << 10) | + (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64XEmitter::EncodeData1SrcInst(u32 instenc, ARM64Reg Rd, ARM64Reg Rn) { bool b64Bit = Is64Bit(Rd); - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); Write32((b64Bit << 31) | (0x2D6 << 21) | (Data1SrcEnc[instenc][0] << 16) | - (Data1SrcEnc[instenc][1] << 10) | (Rn << 5) | Rd); + (Data1SrcEnc[instenc][1] << 10) | (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64XEmitter::EncodeData2SrcInst(u32 instenc, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) { bool b64Bit = Is64Bit(Rd); - Rd = DecodeReg(Rd); - Rm = DecodeReg(Rm); - Rn = DecodeReg(Rn); - Write32((b64Bit << 31) | (0x0D6 << 21) | (Rm << 16) | (Data2SrcEnc[instenc] << 10) | (Rn << 5) | - Rd); + Write32((b64Bit << 31) | (0x0D6 << 21) | (DecodeReg(Rm) << 16) | (Data2SrcEnc[instenc] << 10) | + (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64XEmitter::EncodeData3SrcInst(u32 instenc, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, @@ -650,12 +635,9 @@ void ARM64XEmitter::EncodeData3SrcInst(u32 instenc, ARM64Reg Rd, ARM64Reg Rn, AR { bool b64Bit = Is64Bit(Rd); - Rd = DecodeReg(Rd); - Rm = DecodeReg(Rm); - Rn = DecodeReg(Rn); - Ra = DecodeReg(Ra); - Write32((b64Bit << 31) | (0xD8 << 21) | (Data3SrcEnc[instenc][0] << 21) | (Rm << 16) | - (Data3SrcEnc[instenc][1] << 15) | (Ra << 10) | (Rn << 5) | Rd); + Write32((b64Bit << 31) | (0xD8 << 21) | (Data3SrcEnc[instenc][0] << 21) | (DecodeReg(Rm) << 16) | + (Data3SrcEnc[instenc][1] << 15) | (DecodeReg(Ra) << 10) | (DecodeReg(Rn) << 5) | + DecodeReg(Rd)); } void ARM64XEmitter::EncodeLogicalInst(u32 instenc, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, @@ -663,11 +645,9 @@ void ARM64XEmitter::EncodeLogicalInst(u32 instenc, ARM64Reg Rd, ARM64Reg Rn, ARM { bool b64Bit = Is64Bit(Rd); - Rd = DecodeReg(Rd); - Rm = DecodeReg(Rm); - Rn = DecodeReg(Rn); Write32((b64Bit << 31) | (LogicalEnc[instenc][0] << 29) | (0x5 << 25) | - (LogicalEnc[instenc][1] << 21) | Shift.GetData() | (Rm << 16) | (Rn << 5) | Rd); + (LogicalEnc[instenc][1] << 21) | Shift.GetData() | (DecodeReg(Rm) << 16) | + (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64XEmitter::EncodeLoadRegisterInst(u32 bitop, ARM64Reg Rt, u32 imm) @@ -677,22 +657,18 @@ void ARM64XEmitter::EncodeLoadRegisterInst(u32 bitop, ARM64Reg Rt, u32 imm) ASSERT_MSG(DYNA_REC, !(imm & 0xFFFFF), "%s: offset too large %d", __func__, imm); - Rt = DecodeReg(Rt); if (b64Bit && bitop != 0x2) // LDRSW(0x2) uses 64bit reg, doesn't have 64bit bit set bitop |= 0x1; - Write32((bitop << 30) | (bVec << 26) | (0x18 << 24) | (imm << 5) | Rt); + Write32((bitop << 30) | (bVec << 26) | (0x18 << 24) | (imm << 5) | DecodeReg(Rt)); } void ARM64XEmitter::EncodeLoadStoreExcInst(u32 instenc, ARM64Reg Rs, ARM64Reg Rt2, ARM64Reg Rn, ARM64Reg Rt) { - Rs = DecodeReg(Rs); - Rt2 = DecodeReg(Rt2); - Rn = DecodeReg(Rn); - Rt = DecodeReg(Rt); Write32((LoadStoreExcEnc[instenc][0] << 30) | (0x8 << 24) | (LoadStoreExcEnc[instenc][1] << 23) | - (LoadStoreExcEnc[instenc][2] << 22) | (LoadStoreExcEnc[instenc][3] << 21) | (Rs << 16) | - (LoadStoreExcEnc[instenc][4] << 15) | (Rt2 << 10) | (Rn << 5) | Rt); + (LoadStoreExcEnc[instenc][2] << 22) | (LoadStoreExcEnc[instenc][3] << 21) | + (DecodeReg(Rs) << 16) | (LoadStoreExcEnc[instenc][4] << 15) | (DecodeReg(Rt2) << 10) | + (DecodeReg(Rn) << 5) | DecodeReg(Rt)); } void ARM64XEmitter::EncodeLoadStorePairedInst(u32 op, ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn, @@ -719,10 +695,8 @@ void ARM64XEmitter::EncodeLoadStorePairedInst(u32 op, ARM64Reg Rt, ARM64Reg Rt2, else if (b64Bit && !bVec) opc = 2; - Rt = DecodeReg(Rt); - Rt2 = DecodeReg(Rt2); - Rn = DecodeReg(Rn); - Write32((opc << 30) | (bVec << 26) | (op << 22) | (imm << 15) | (Rt2 << 10) | (Rn << 5) | Rt); + Write32((opc << 30) | (bVec << 26) | (op << 22) | (imm << 15) | (DecodeReg(Rt2) << 10) | + (DecodeReg(Rn) << 5) | DecodeReg(Rt)); } void ARM64XEmitter::EncodeLoadStoreIndexedInst(u32 op, u32 op2, ARM64Reg Rt, ARM64Reg Rn, s32 imm) @@ -734,10 +708,8 @@ void ARM64XEmitter::EncodeLoadStoreIndexedInst(u32 op, u32 op2, ARM64Reg Rt, ARM ASSERT_MSG(DYNA_REC, !(imm < -256 || imm > 255), "%s: offset too large %d", __func__, imm); - Rt = DecodeReg(Rt); - Rn = DecodeReg(Rn); - Write32((b64Bit << 30) | (op << 22) | (bVec << 26) | (offset << 12) | (op2 << 10) | (Rn << 5) | - Rt); + Write32((b64Bit << 30) | (op << 22) | (bVec << 26) | (offset << 12) | (op2 << 10) | + (DecodeReg(Rn) << 5) | DecodeReg(Rt)); } void ARM64XEmitter::EncodeLoadStoreIndexedInst(u32 op, ARM64Reg Rt, ARM64Reg Rn, s32 imm, u8 size) @@ -757,9 +729,8 @@ void ARM64XEmitter::EncodeLoadStoreIndexedInst(u32 op, ARM64Reg Rt, ARM64Reg Rn, ASSERT_MSG(DYNA_REC, !(imm & ~0xFFF), "%s(IndexType::Unsigned): offset too large %d", __func__, imm); - Rt = DecodeReg(Rt); - Rn = DecodeReg(Rn); - Write32((b64Bit << 30) | (op << 22) | (bVec << 26) | (imm << 10) | (Rn << 5) | Rt); + Write32((b64Bit << 30) | (op << 22) | (bVec << 26) | (imm << 10) | (DecodeReg(Rn) << 5) | + DecodeReg(Rt)); } void ARM64XEmitter::EncodeMOVWideInst(u32 op, ARM64Reg Rd, u32 imm, ShiftAmount pos) @@ -768,30 +739,25 @@ void ARM64XEmitter::EncodeMOVWideInst(u32 op, ARM64Reg Rd, u32 imm, ShiftAmount ASSERT_MSG(DYNA_REC, !(imm & ~0xFFFF), "%s: immediate out of range: %d", __func__, imm); - Rd = DecodeReg(Rd); Write32((b64Bit << 31) | (op << 29) | (0x25 << 23) | (static_cast<u32>(pos) << 21) | (imm << 5) | - Rd); + DecodeReg(Rd)); } void ARM64XEmitter::EncodeBitfieldMOVInst(u32 op, ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms) { bool b64Bit = Is64Bit(Rd); - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); Write32((b64Bit << 31) | (op << 29) | (0x26 << 23) | (b64Bit << 22) | (immr << 16) | - (imms << 10) | (Rn << 5) | Rd); + (imms << 10) | (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64XEmitter::EncodeLoadStoreRegisterOffset(u32 size, u32 opc, ARM64Reg Rt, ARM64Reg Rn, ArithOption Rm) { - Rt = DecodeReg(Rt); - Rn = DecodeReg(Rn); - ARM64Reg decoded_Rm = DecodeReg(Rm.GetReg()); + const int decoded_Rm = DecodeReg(Rm.GetReg()); Write32((size << 30) | (opc << 22) | (0x1C1 << 21) | (decoded_Rm << 16) | Rm.GetData() | - (1 << 11) | (Rn << 5) | Rt); + (1 << 11) | (DecodeReg(Rn) << 5) | DecodeReg(Rt)); } void ARM64XEmitter::EncodeAddSubImmInst(u32 op, bool flags, u32 shift, u32 imm, ARM64Reg Rn, @@ -801,10 +767,8 @@ void ARM64XEmitter::EncodeAddSubImmInst(u32 op, bool flags, u32 shift, u32 imm, ASSERT_MSG(DYNA_REC, !(imm & ~0xFFF), "%s: immediate too large: %x", __func__, imm); - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); Write32((b64Bit << 31) | (op << 30) | (flags << 29) | (0x11 << 24) | (shift << 22) | (imm << 10) | - (Rn << 5) | Rd); + (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64XEmitter::EncodeLogicalImmInst(u32 op, ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms, @@ -814,11 +778,8 @@ void ARM64XEmitter::EncodeLogicalImmInst(u32 op, ARM64Reg Rd, ARM64Reg Rn, u32 i // Use Rn to determine bitness here. bool b64Bit = Is64Bit(Rn); - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); - Write32((b64Bit << 31) | (op << 29) | (0x24 << 23) | (n << 22) | (immr << 16) | (imms << 10) | - (Rn << 5) | Rd); + (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64XEmitter::EncodeLoadStorePair(u32 op, u32 load, IndexType type, ARM64Reg Rt, ARM64Reg Rt2, @@ -853,30 +814,24 @@ void ARM64XEmitter::EncodeLoadStorePair(u32 op, u32 load, IndexType type, ARM64R imm >>= 2; } - Rt = DecodeReg(Rt); - Rt2 = DecodeReg(Rt2); - Rn = DecodeReg(Rn); - ASSERT_MSG(DYNA_REC, imm >= -64 && imm < 64, "imm too large for load/store pair!"); Write32((op << 30) | (0b101 << 27) | (type_encode << 23) | (load << 22) | ((imm & 0x7F) << 15) | - (Rt2 << 10) | (Rn << 5) | Rt); + (DecodeReg(Rt2) << 10) | (DecodeReg(Rn) << 5) | DecodeReg(Rt)); } void ARM64XEmitter::EncodeAddressInst(u32 op, ARM64Reg Rd, s32 imm) { - Rd = DecodeReg(Rd); - - Write32((op << 31) | ((imm & 0x3) << 29) | (0x10 << 24) | ((imm & 0x1FFFFC) << 3) | Rd); + Write32((op << 31) | ((imm & 0x3) << 29) | (0x10 << 24) | ((imm & 0x1FFFFC) << 3) | + DecodeReg(Rd)); } void ARM64XEmitter::EncodeLoadStoreUnscaled(u32 size, u32 op, ARM64Reg Rt, ARM64Reg Rn, s32 imm) { ASSERT_MSG(DYNA_REC, !(imm < -256 || imm > 255), "%s received too large offset: %d", __func__, imm); - Rt = DecodeReg(Rt); - Rn = DecodeReg(Rn); - Write32((size << 30) | (0b111 << 27) | (op << 22) | ((imm & 0x1FF) << 12) | (Rn << 5) | Rt); + Write32((size << 30) | (0b111 << 27) | (op << 22) | ((imm & 0x1FF) << 12) | (DecodeReg(Rn) << 5) | + DecodeReg(Rt)); } static constexpr bool IsInRangeImm19(s64 distance) @@ -927,8 +882,8 @@ void ARM64XEmitter::SetJumpTarget(FixupBranch const& branch) ASSERT_MSG(DYNA_REC, IsInRangeImm19(distance), "%s(%d): Received too large distance: %" PRIx64, __func__, static_cast<int>(branch.type), distance); const bool b64Bit = Is64Bit(branch.reg); - const ARM64Reg reg = DecodeReg(branch.reg); - inst = (b64Bit << 31) | (0x1A << 25) | (Not << 24) | (MaskImm19(distance) << 5) | reg; + inst = (b64Bit << 31) | (0x1A << 25) | (Not << 24) | (MaskImm19(distance) << 5) | + DecodeReg(branch.reg); } break; case FixupBranch::Type::BConditional: @@ -943,9 +898,8 @@ void ARM64XEmitter::SetJumpTarget(FixupBranch const& branch) { ASSERT_MSG(DYNA_REC, IsInRangeImm14(distance), "%s(%d): Received too large distance: %" PRIx64, __func__, static_cast<int>(branch.type), distance); - const ARM64Reg reg = DecodeReg(branch.reg); inst = ((branch.bit & 0x20) << 26) | (0x1B << 25) | (Not << 24) | ((branch.bit & 0x1F) << 19) | - (MaskImm14(distance) << 5) | reg; + (MaskImm14(distance) << 5) | DecodeReg(branch.reg); } break; case FixupBranch::Type::B: @@ -1100,11 +1054,11 @@ void ARM64XEmitter::RET(ARM64Reg Rn) } void ARM64XEmitter::ERET() { - EncodeUnconditionalBranchInst(4, 0x1F, 0, 0, SP); + EncodeUnconditionalBranchInst(4, 0x1F, 0, 0, ARM64Reg::SP); } void ARM64XEmitter::DRPS() { - EncodeUnconditionalBranchInst(5, 0x1F, 0, 0, SP); + EncodeUnconditionalBranchInst(5, 0x1F, 0, 0, ARM64Reg::SP); } // Exception generation @@ -1170,7 +1124,7 @@ void ARM64XEmitter::_MSR(PStateField field, u8 imm) ASSERT_MSG(DYNA_REC, false, "Invalid PStateField to do a imm move to"); break; } - EncodeSystemInst(0, op1, 4, imm, op2, WSP); + EncodeSystemInst(0, op1, 4, imm, op2, ARM64Reg::WSP); } static void GetSystemReg(PStateField field, int& o0, int& op1, int& CRn, int& CRm, int& op2) @@ -1223,7 +1177,7 @@ void ARM64XEmitter::_MSR(PStateField field, ARM64Reg Rt) int o0 = 0, op1 = 0, CRn = 0, CRm = 0, op2 = 0; ASSERT_MSG(DYNA_REC, Is64Bit(Rt), "MSR: Rt must be 64-bit"); GetSystemReg(field, o0, op1, CRn, CRm, op2); - EncodeSystemInst(o0, op1, CRn, CRm, op2, DecodeReg(Rt)); + EncodeSystemInst(o0, op1, CRn, CRm, op2, Rt); } void ARM64XEmitter::MRS(ARM64Reg Rt, PStateField field) @@ -1231,7 +1185,7 @@ void ARM64XEmitter::MRS(ARM64Reg Rt, PStateField field) int o0 = 0, op1 = 0, CRn = 0, CRm = 0, op2 = 0; ASSERT_MSG(DYNA_REC, Is64Bit(Rt), "MRS: Rt must be 64-bit"); GetSystemReg(field, o0, op1, CRn, CRm, op2); - EncodeSystemInst(o0 | 4, op1, CRn, CRm, op2, DecodeReg(Rt)); + EncodeSystemInst(o0 | 4, op1, CRn, CRm, op2, Rt); } void ARM64XEmitter::CNTVCT(Arm64Gen::ARM64Reg Rt) @@ -1239,28 +1193,28 @@ void ARM64XEmitter::CNTVCT(Arm64Gen::ARM64Reg Rt) ASSERT_MSG(DYNA_REC, Is64Bit(Rt), "CNTVCT: Rt must be 64-bit"); // MRS <Xt>, CNTVCT_EL0 ; Read CNTVCT_EL0 into Xt - EncodeSystemInst(3 | 4, 3, 0xe, 0, 2, DecodeReg(Rt)); + EncodeSystemInst(3 | 4, 3, 0xe, 0, 2, Rt); } void ARM64XEmitter::HINT(SystemHint op) { - EncodeSystemInst(0, 3, 2, 0, static_cast<u32>(op), WSP); + EncodeSystemInst(0, 3, 2, 0, static_cast<u32>(op), ARM64Reg::WSP); } void ARM64XEmitter::CLREX() { - EncodeSystemInst(0, 3, 3, 0, 2, WSP); + EncodeSystemInst(0, 3, 3, 0, 2, ARM64Reg::WSP); } void ARM64XEmitter::DSB(BarrierType type) { - EncodeSystemInst(0, 3, 3, static_cast<u32>(type), 4, WSP); + EncodeSystemInst(0, 3, 3, static_cast<u32>(type), 4, ARM64Reg::WSP); } void ARM64XEmitter::DMB(BarrierType type) { - EncodeSystemInst(0, 3, 3, static_cast<u32>(type), 5, WSP); + EncodeSystemInst(0, 3, 3, static_cast<u32>(type), 5, ARM64Reg::WSP); } void ARM64XEmitter::ISB(BarrierType type) { - EncodeSystemInst(0, 3, 3, static_cast<u32>(type), 6, WSP); + EncodeSystemInst(0, 3, 3, static_cast<u32>(type), 6, ARM64Reg::WSP); } // Add/Subtract (extended register) @@ -1311,7 +1265,7 @@ void ARM64XEmitter::CMN(ARM64Reg Rn, ARM64Reg Rm) void ARM64XEmitter::CMN(ARM64Reg Rn, ARM64Reg Rm, ArithOption Option) { - EncodeArithmeticInst(0, true, Is64Bit(Rn) ? ZR : WZR, Rn, Rm, Option); + EncodeArithmeticInst(0, true, Is64Bit(Rn) ? ARM64Reg::ZR : ARM64Reg::WZR, Rn, Rm, Option); } void ARM64XEmitter::CMP(ARM64Reg Rn, ARM64Reg Rm) @@ -1321,7 +1275,7 @@ void ARM64XEmitter::CMP(ARM64Reg Rn, ARM64Reg Rm) void ARM64XEmitter::CMP(ARM64Reg Rn, ARM64Reg Rm, ArithOption Option) { - EncodeArithmeticInst(1, true, Is64Bit(Rn) ? ZR : WZR, Rn, Rm, Option); + EncodeArithmeticInst(1, true, Is64Bit(Rn) ? ARM64Reg::ZR : ARM64Reg::WZR, Rn, Rm, Option); } // Add/Subtract (with carry) @@ -1479,7 +1433,7 @@ void ARM64XEmitter::SMADDL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ARM64Reg Ra) } void ARM64XEmitter::SMULL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) { - SMADDL(Rd, Rn, Rm, SP); + SMADDL(Rd, Rn, Rm, ARM64Reg::SP); } void ARM64XEmitter::SMSUBL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ARM64Reg Ra) { @@ -1487,7 +1441,7 @@ void ARM64XEmitter::SMSUBL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ARM64Reg Ra) } void ARM64XEmitter::SMULH(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) { - EncodeData3SrcInst(4, Rd, Rn, Rm, SP); + EncodeData3SrcInst(4, Rd, Rn, Rm, ARM64Reg::SP); } void ARM64XEmitter::UMADDL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ARM64Reg Ra) { @@ -1495,7 +1449,7 @@ void ARM64XEmitter::UMADDL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ARM64Reg Ra) } void ARM64XEmitter::UMULL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) { - UMADDL(Rd, Rn, Rm, SP); + UMADDL(Rd, Rn, Rm, ARM64Reg::SP); } void ARM64XEmitter::UMSUBL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ARM64Reg Ra) { @@ -1503,15 +1457,15 @@ void ARM64XEmitter::UMSUBL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ARM64Reg Ra) } void ARM64XEmitter::UMULH(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) { - EncodeData3SrcInst(7, Rd, Rn, Rm, SP); + EncodeData3SrcInst(7, Rd, Rn, Rm, ARM64Reg::SP); } void ARM64XEmitter::MUL(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) { - EncodeData3SrcInst(0, Rd, Rn, Rm, SP); + EncodeData3SrcInst(0, Rd, Rn, Rm, ARM64Reg::SP); } void ARM64XEmitter::MNEG(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) { - EncodeData3SrcInst(1, Rd, Rn, Rm, SP); + EncodeData3SrcInst(1, Rd, Rn, Rm, ARM64Reg::SP); } // Logical (shifted register) @@ -1550,19 +1504,19 @@ void ARM64XEmitter::BICS(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ArithOption Shif void ARM64XEmitter::MOV(ARM64Reg Rd, ARM64Reg Rm, ArithOption Shift) { - ORR(Rd, Is64Bit(Rd) ? ZR : WZR, Rm, Shift); + ORR(Rd, Is64Bit(Rd) ? ARM64Reg::ZR : ARM64Reg::WZR, Rm, Shift); } void ARM64XEmitter::MOV(ARM64Reg Rd, ARM64Reg Rm) { if (IsGPR(Rd) && IsGPR(Rm)) - ORR(Rd, Is64Bit(Rd) ? ZR : WZR, Rm, ArithOption(Rm, ShiftType::LSL, 0)); + ORR(Rd, Is64Bit(Rd) ? ARM64Reg::ZR : ARM64Reg::WZR, Rm, ArithOption(Rm, ShiftType::LSL, 0)); else ASSERT_MSG(DYNA_REC, false, "Non-GPRs not supported in MOV"); } void ARM64XEmitter::MVN(ARM64Reg Rd, ARM64Reg Rm) { - ORN(Rd, Is64Bit(Rd) ? ZR : WZR, Rm, ArithOption(Rm, ShiftType::LSL, 0)); + ORN(Rd, Is64Bit(Rd) ? ARM64Reg::ZR : ARM64Reg::WZR, Rm, ArithOption(Rm, ShiftType::LSL, 0)); } void ARM64XEmitter::LSL(ARM64Reg Rd, ARM64Reg Rm, int shift) { @@ -1603,7 +1557,7 @@ void ARM64XEmitter::ORR(ARM64Reg Rd, ARM64Reg Rn, u32 immr, u32 imms, bool inver } void ARM64XEmitter::TST(ARM64Reg Rn, u32 immr, u32 imms, bool invert) { - EncodeLogicalImmInst(3, Is64Bit(Rn) ? ZR : WZR, Rn, immr, imms, invert); + EncodeLogicalImmInst(3, Is64Bit(Rn) ? ARM64Reg::ZR : ARM64Reg::WZR, Rn, immr, imms, invert); } // Add/subtract (immediate) @@ -1625,7 +1579,7 @@ void ARM64XEmitter::SUBS(ARM64Reg Rd, ARM64Reg Rn, u32 imm, bool shift) } void ARM64XEmitter::CMP(ARM64Reg Rn, u32 imm, bool shift) { - EncodeAddSubImmInst(1, true, shift, imm, Rn, Is64Bit(Rn) ? SP : WSP); + EncodeAddSubImmInst(1, true, shift, imm, Rn, Is64Bit(Rn) ? ARM64Reg::SP : ARM64Reg::WSP); } // Data Processing (Immediate) @@ -1684,10 +1638,9 @@ void ARM64XEmitter::EXTR(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, u32 shift) { bool sf = Is64Bit(Rd); bool N = sf; - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); - Rm = DecodeReg(Rm); - Write32((sf << 31) | (0x27 << 23) | (N << 22) | (Rm << 16) | (shift << 10) | (Rm << 5) | Rd); + + Write32((sf << 31) | (0x27 << 23) | (N << 22) | (DecodeReg(Rm) << 16) | (shift << 10) | + (DecodeReg(Rm) << 5) | DecodeReg(Rd)); } void ARM64XEmitter::SXTB(ARM64Reg Rd, ARM64Reg Rn) { @@ -1742,59 +1695,59 @@ void ARM64XEmitter::STP(IndexType type, ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn, // Load/Store Exclusive void ARM64XEmitter::STXRB(ARM64Reg Rs, ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(0, Rs, SP, Rt, Rn); + EncodeLoadStoreExcInst(0, Rs, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::STLXRB(ARM64Reg Rs, ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(1, Rs, SP, Rt, Rn); + EncodeLoadStoreExcInst(1, Rs, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::LDXRB(ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(2, SP, SP, Rt, Rn); + EncodeLoadStoreExcInst(2, ARM64Reg::SP, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::LDAXRB(ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(3, SP, SP, Rt, Rn); + EncodeLoadStoreExcInst(3, ARM64Reg::SP, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::STLRB(ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(4, SP, SP, Rt, Rn); + EncodeLoadStoreExcInst(4, ARM64Reg::SP, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::LDARB(ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(5, SP, SP, Rt, Rn); + EncodeLoadStoreExcInst(5, ARM64Reg::SP, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::STXRH(ARM64Reg Rs, ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(6, Rs, SP, Rt, Rn); + EncodeLoadStoreExcInst(6, Rs, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::STLXRH(ARM64Reg Rs, ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(7, Rs, SP, Rt, Rn); + EncodeLoadStoreExcInst(7, Rs, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::LDXRH(ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(8, SP, SP, Rt, Rn); + EncodeLoadStoreExcInst(8, ARM64Reg::SP, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::LDAXRH(ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(9, SP, SP, Rt, Rn); + EncodeLoadStoreExcInst(9, ARM64Reg::SP, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::STLRH(ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(10, SP, SP, Rt, Rn); + EncodeLoadStoreExcInst(10, ARM64Reg::SP, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::LDARH(ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(11, SP, SP, Rt, Rn); + EncodeLoadStoreExcInst(11, ARM64Reg::SP, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::STXR(ARM64Reg Rs, ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(12 + Is64Bit(Rt), Rs, SP, Rt, Rn); + EncodeLoadStoreExcInst(12 + Is64Bit(Rt), Rs, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::STLXR(ARM64Reg Rs, ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(14 + Is64Bit(Rt), Rs, SP, Rt, Rn); + EncodeLoadStoreExcInst(14 + Is64Bit(Rt), Rs, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::STXP(ARM64Reg Rs, ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn) { @@ -1806,27 +1759,27 @@ void ARM64XEmitter::STLXP(ARM64Reg Rs, ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn) } void ARM64XEmitter::LDXR(ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(20 + Is64Bit(Rt), SP, SP, Rt, Rn); + EncodeLoadStoreExcInst(20 + Is64Bit(Rt), ARM64Reg::SP, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::LDAXR(ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(22 + Is64Bit(Rt), SP, SP, Rt, Rn); + EncodeLoadStoreExcInst(22 + Is64Bit(Rt), ARM64Reg::SP, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::LDXP(ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn) { - EncodeLoadStoreExcInst(24 + Is64Bit(Rt), SP, Rt2, Rt, Rn); + EncodeLoadStoreExcInst(24 + Is64Bit(Rt), ARM64Reg::SP, Rt2, Rt, Rn); } void ARM64XEmitter::LDAXP(ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn) { - EncodeLoadStoreExcInst(26 + Is64Bit(Rt), SP, Rt2, Rt, Rn); + EncodeLoadStoreExcInst(26 + Is64Bit(Rt), ARM64Reg::SP, Rt2, Rt, Rn); } void ARM64XEmitter::STLR(ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(28 + Is64Bit(Rt), SP, SP, Rt, Rn); + EncodeLoadStoreExcInst(28 + Is64Bit(Rt), ARM64Reg::SP, ARM64Reg::SP, Rt, Rn); } void ARM64XEmitter::LDAR(ARM64Reg Rt, ARM64Reg Rn) { - EncodeLoadStoreExcInst(30 + Is64Bit(Rt), SP, SP, Rt, Rn); + EncodeLoadStoreExcInst(30 + Is64Bit(Rt), ARM64Reg::SP, ARM64Reg::SP, Rt, Rn); } // Load/Store no-allocate pair (offset) @@ -2153,7 +2106,7 @@ void ARM64XEmitter::MOVI2RImpl(ARM64Reg Rd, T imm) break; case Approach::ORRBase: - constexpr ARM64Reg zero_reg = sizeof(T) == 8 ? ZR : WZR; + constexpr ARM64Reg zero_reg = sizeof(T) == 8 ? ARM64Reg::ZR : ARM64Reg::WZR; const bool success = TryORRI2R(Rd, zero_reg, best_base); ASSERT(success); break; @@ -2225,21 +2178,21 @@ void ARM64XEmitter::ABI_PushRegisters(BitSet32 registers) // The first push must adjust the SP, else a context switch may invalidate everything below SP. if (num_regs & 1) { - STR(IndexType::Pre, (ARM64Reg)(X0 + *it++), SP, -stack_size); + STR(IndexType::Pre, ARM64Reg::X0 + *it++, ARM64Reg::SP, -stack_size); } else { - ARM64Reg first_reg = (ARM64Reg)(X0 + *it++); - ARM64Reg second_reg = (ARM64Reg)(X0 + *it++); - STP(IndexType::Pre, first_reg, second_reg, SP, -stack_size); + ARM64Reg first_reg = ARM64Reg::X0 + *it++; + ARM64Reg second_reg = ARM64Reg::X0 + *it++; + STP(IndexType::Pre, first_reg, second_reg, ARM64Reg::SP, -stack_size); } // Fast store for all other registers, this is always an even number. for (int i = 0; i < (num_regs - 1) / 2; i++) { - ARM64Reg odd_reg = (ARM64Reg)(X0 + *it++); - ARM64Reg even_reg = (ARM64Reg)(X0 + *it++); - STP(IndexType::Signed, odd_reg, even_reg, SP, 16 * (i + 1)); + ARM64Reg odd_reg = ARM64Reg::X0 + *it++; + ARM64Reg even_reg = ARM64Reg::X0 + *it++; + STP(IndexType::Signed, odd_reg, even_reg, ARM64Reg::SP, 16 * (i + 1)); } ASSERT_MSG(DYNA_REC, it == registers.end(), "%s registers don't match.", __func__); @@ -2255,10 +2208,10 @@ void ARM64XEmitter::ABI_PopRegisters(BitSet32 registers, BitSet32 ignore_mask) return; // We must adjust the SP in the end, so load the first (two) registers at least. - ARM64Reg first = (ARM64Reg)(X0 + *it++); + ARM64Reg first = ARM64Reg::X0 + *it++; ARM64Reg second; if (!(num_regs & 1)) - second = (ARM64Reg)(X0 + *it++); + second = ARM64Reg::X0 + *it++; else second = {}; @@ -2268,16 +2221,16 @@ void ARM64XEmitter::ABI_PopRegisters(BitSet32 registers, BitSet32 ignore_mask) // Fast load for all but the first (two) registers, this is always an even number. for (int i = 0; i < (num_regs - 1) / 2; i++) { - ARM64Reg odd_reg = (ARM64Reg)(X0 + *it++); - ARM64Reg even_reg = (ARM64Reg)(X0 + *it++); - LDP(IndexType::Signed, odd_reg, even_reg, SP, 16 * (i + 1)); + ARM64Reg odd_reg = ARM64Reg::X0 + *it++; + ARM64Reg even_reg = ARM64Reg::X0 + *it++; + LDP(IndexType::Signed, odd_reg, even_reg, ARM64Reg::SP, 16 * (i + 1)); } // Post loading the first (two) registers. if (num_regs & 1) - LDR(IndexType::Post, first, SP, stack_size); + LDR(IndexType::Post, first, ARM64Reg::SP, stack_size); else - LDP(IndexType::Post, first, second, SP, stack_size); + LDP(IndexType::Post, first, second, ARM64Reg::SP, stack_size); ASSERT_MSG(DYNA_REC, it == registers.end(), "%s registers don't match.", __func__); } @@ -2286,8 +2239,6 @@ void ARM64XEmitter::ABI_PopRegisters(BitSet32 registers, BitSet32 ignore_mask) void ARM64FloatEmitter::EmitLoadStoreImmediate(u8 size, u32 opc, IndexType type, ARM64Reg Rt, ARM64Reg Rn, s32 imm) { - Rt = DecodeReg(Rt); - Rn = DecodeReg(Rn); u32 encoded_size = 0; u32 encoded_imm = 0; @@ -2331,19 +2282,17 @@ void ARM64FloatEmitter::EmitLoadStoreImmediate(u8 size, u32 opc, IndexType type, } Write32((encoded_size << 30) | (0xF << 26) | (type == IndexType::Unsigned ? (1 << 24) : 0) | - (size == 128 ? (1 << 23) : 0) | (opc << 22) | (encoded_imm << 10) | (Rn << 5) | Rt); + (size == 128 ? (1 << 23) : 0) | (opc << 22) | (encoded_imm << 10) | (DecodeReg(Rn) << 5) | + DecodeReg(Rt)); } void ARM64FloatEmitter::EmitScalar2Source(bool M, bool S, u32 type, u32 opcode, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) { ASSERT_MSG(DYNA_REC, !IsQuad(Rd), "%s only supports double and single registers!", __func__); - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); - Rm = DecodeReg(Rm); - Write32((M << 31) | (S << 29) | (0b11110001 << 21) | (type << 22) | (Rm << 16) | (opcode << 12) | - (1 << 11) | (Rn << 5) | Rd); + Write32((M << 31) | (S << 29) | (0b11110001 << 21) | (type << 22) | (DecodeReg(Rm) << 16) | + (opcode << 12) | (1 << 11) | (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64FloatEmitter::EmitThreeSame(bool U, u32 size, u32 opcode, ARM64Reg Rd, ARM64Reg Rn, @@ -2351,31 +2300,23 @@ void ARM64FloatEmitter::EmitThreeSame(bool U, u32 size, u32 opcode, ARM64Reg Rd, { ASSERT_MSG(DYNA_REC, !IsSingle(Rd), "%s doesn't support singles!", __func__); bool quad = IsQuad(Rd); - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); - Rm = DecodeReg(Rm); - Write32((quad << 30) | (U << 29) | (0b1110001 << 21) | (size << 22) | (Rm << 16) | - (opcode << 11) | (1 << 10) | (Rn << 5) | Rd); + Write32((quad << 30) | (U << 29) | (0b1110001 << 21) | (size << 22) | (DecodeReg(Rm) << 16) | + (opcode << 11) | (1 << 10) | (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64FloatEmitter::EmitCopy(bool Q, u32 op, u32 imm5, u32 imm4, ARM64Reg Rd, ARM64Reg Rn) { - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); - Write32((Q << 30) | (op << 29) | (0b111 << 25) | (imm5 << 16) | (imm4 << 11) | (1 << 10) | - (Rn << 5) | Rd); + (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64FloatEmitter::Emit2RegMisc(bool Q, bool U, u32 size, u32 opcode, ARM64Reg Rd, ARM64Reg Rn) { ASSERT_MSG(DYNA_REC, !IsSingle(Rd), "%s doesn't support singles!", __func__); - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); Write32((Q << 30) | (U << 29) | (0b1110001 << 21) | (size << 22) | (opcode << 12) | (1 << 11) | - (Rn << 5) | Rd); + (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64FloatEmitter::EmitLoadStoreSingleStructure(bool L, bool R, u32 opcode, bool S, u32 size, @@ -2383,11 +2324,9 @@ void ARM64FloatEmitter::EmitLoadStoreSingleStructure(bool L, bool R, u32 opcode, { ASSERT_MSG(DYNA_REC, !IsSingle(Rt), "%s doesn't support singles!", __func__); bool quad = IsQuad(Rt); - Rt = DecodeReg(Rt); - Rn = DecodeReg(Rn); Write32((quad << 30) | (0b1101 << 24) | (L << 22) | (R << 21) | (opcode << 13) | (S << 12) | - (size << 10) | (Rn << 5) | Rt); + (size << 10) | (DecodeReg(Rn) << 5) | DecodeReg(Rt)); } void ARM64FloatEmitter::EmitLoadStoreSingleStructure(bool L, bool R, u32 opcode, bool S, u32 size, @@ -2395,33 +2334,26 @@ void ARM64FloatEmitter::EmitLoadStoreSingleStructure(bool L, bool R, u32 opcode, { ASSERT_MSG(DYNA_REC, !IsSingle(Rt), "%s doesn't support singles!", __func__); bool quad = IsQuad(Rt); - Rt = DecodeReg(Rt); - Rn = DecodeReg(Rn); - Rm = DecodeReg(Rm); - Write32((quad << 30) | (0x1B << 23) | (L << 22) | (R << 21) | (Rm << 16) | (opcode << 13) | - (S << 12) | (size << 10) | (Rn << 5) | Rt); + Write32((quad << 30) | (0x1B << 23) | (L << 22) | (R << 21) | (DecodeReg(Rm) << 16) | + (opcode << 13) | (S << 12) | (size << 10) | (DecodeReg(Rn) << 5) | DecodeReg(Rt)); } void ARM64FloatEmitter::Emit1Source(bool M, bool S, u32 type, u32 opcode, ARM64Reg Rd, ARM64Reg Rn) { ASSERT_MSG(DYNA_REC, !IsQuad(Rd), "%s doesn't support vector!", __func__); - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); Write32((M << 31) | (S << 29) | (0xF1 << 21) | (type << 22) | (opcode << 15) | (1 << 14) | - (Rn << 5) | Rd); + (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64FloatEmitter::EmitConversion(bool sf, bool S, u32 type, u32 rmode, u32 opcode, ARM64Reg Rd, ARM64Reg Rn) { - ASSERT_MSG(DYNA_REC, Rn <= SP, "%s only supports GPR as source!", __func__); - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); + ASSERT_MSG(DYNA_REC, Rn <= ARM64Reg::SP, "%s only supports GPR as source!", __func__); Write32((sf << 31) | (S << 29) | (0xF1 << 21) | (type << 22) | (rmode << 19) | (opcode << 16) | - (Rn << 5) | Rd); + (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64FloatEmitter::EmitConvertScalarToInt(ARM64Reg Rd, ARM64Reg Rn, RoundingMode round, @@ -2433,8 +2365,6 @@ void ARM64FloatEmitter::EmitConvertScalarToInt(ARM64Reg Rd, ARM64Reg Rn, Roundin // Use the encoding that transfers the result to a GPR. const bool sf = Is64Bit(Rd); const int type = IsDouble(Rn) ? 1 : 0; - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); int opcode = (sign ? 1 : 0); int rmode = 0; switch (round) @@ -2462,8 +2392,6 @@ void ARM64FloatEmitter::EmitConvertScalarToInt(ARM64Reg Rd, ARM64Reg Rn, Roundin { // Use the encoding (vector, single) that keeps the result in the fp register. int sz = IsDouble(Rn); - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); int opcode = 0; switch (round) { @@ -2486,7 +2414,7 @@ void ARM64FloatEmitter::EmitConvertScalarToInt(ARM64Reg Rd, ARM64Reg Rn, Roundin break; } Write32((0x5E << 24) | (sign << 29) | (sz << 22) | (1 << 21) | (opcode << 12) | (2 << 10) | - (Rn << 5) | Rd); + (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } } @@ -2503,11 +2431,8 @@ void ARM64FloatEmitter::FCVTU(ARM64Reg Rd, ARM64Reg Rn, RoundingMode round) void ARM64FloatEmitter::EmitConversion2(bool sf, bool S, bool direction, u32 type, u32 rmode, u32 opcode, int scale, ARM64Reg Rd, ARM64Reg Rn) { - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); - Write32((sf << 31) | (S << 29) | (0xF0 << 21) | (direction << 21) | (type << 22) | (rmode << 19) | - (opcode << 16) | (scale << 10) | (Rn << 5) | Rd); + (opcode << 16) | (scale << 10) | (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64FloatEmitter::EmitCompare(bool M, bool S, u32 op, u32 opcode2, ARM64Reg Rn, ARM64Reg Rm) @@ -2515,11 +2440,8 @@ void ARM64FloatEmitter::EmitCompare(bool M, bool S, u32 op, u32 opcode2, ARM64Re ASSERT_MSG(DYNA_REC, !IsQuad(Rn), "%s doesn't support vector!", __func__); bool is_double = IsDouble(Rn); - Rn = DecodeReg(Rn); - Rm = DecodeReg(Rm); - - Write32((M << 31) | (S << 29) | (0xF1 << 21) | (is_double << 22) | (Rm << 16) | (op << 14) | - (1 << 13) | (Rn << 5) | opcode2); + Write32((M << 31) | (S << 29) | (0xF1 << 21) | (is_double << 22) | (DecodeReg(Rm) << 16) | + (op << 14) | (1 << 13) | (DecodeReg(Rn) << 5) | opcode2); } void ARM64FloatEmitter::EmitCondSelect(bool M, bool S, CCFlags cond, ARM64Reg Rd, ARM64Reg Rn, @@ -2528,12 +2450,8 @@ void ARM64FloatEmitter::EmitCondSelect(bool M, bool S, CCFlags cond, ARM64Reg Rd ASSERT_MSG(DYNA_REC, !IsQuad(Rd), "%s doesn't support vector!", __func__); bool is_double = IsDouble(Rd); - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); - Rm = DecodeReg(Rm); - - Write32((M << 31) | (S << 29) | (0xF1 << 21) | (is_double << 22) | (Rm << 16) | (cond << 12) | - (3 << 10) | (Rn << 5) | Rd); + Write32((M << 31) | (S << 29) | (0xF1 << 21) | (is_double << 22) | (DecodeReg(Rm) << 16) | + (cond << 12) | (3 << 10) | (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64FloatEmitter::EmitPermute(u32 size, u32 op, ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm) @@ -2550,12 +2468,8 @@ void ARM64FloatEmitter::EmitPermute(u32 size, u32 op, ARM64Reg Rd, ARM64Reg Rn, else if (size == 64) encoded_size = 3; - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); - Rm = DecodeReg(Rm); - - Write32((quad << 30) | (7 << 25) | (encoded_size << 22) | (Rm << 16) | (op << 12) | (1 << 11) | - (Rn << 5) | Rd); + Write32((quad << 30) | (7 << 25) | (encoded_size << 22) | (DecodeReg(Rm) << 16) | (op << 12) | + (1 << 11) | (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64FloatEmitter::EmitScalarImm(bool M, bool S, u32 type, u32 imm5, ARM64Reg Rd, u32 imm8) @@ -2564,10 +2478,8 @@ void ARM64FloatEmitter::EmitScalarImm(bool M, bool S, u32 type, u32 imm5, ARM64R bool is_double = !IsSingle(Rd); - Rd = DecodeReg(Rd); - Write32((M << 31) | (S << 29) | (0xF1 << 21) | (is_double << 22) | (type << 22) | (imm8 << 13) | - (1 << 12) | (imm5 << 5) | Rd); + (1 << 12) | (imm5 << 5) | DecodeReg(Rd)); } void ARM64FloatEmitter::EmitShiftImm(bool Q, bool U, u32 immh, u32 immb, u32 opcode, ARM64Reg Rd, @@ -2575,21 +2487,15 @@ void ARM64FloatEmitter::EmitShiftImm(bool Q, bool U, u32 immh, u32 immb, u32 opc { ASSERT_MSG(DYNA_REC, immh, "%s bad encoding! Can't have zero immh", __func__); - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); - Write32((Q << 30) | (U << 29) | (0xF << 24) | (immh << 19) | (immb << 16) | (opcode << 11) | - (1 << 10) | (Rn << 5) | Rd); + (1 << 10) | (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64FloatEmitter::EmitScalarShiftImm(bool U, u32 immh, u32 immb, u32 opcode, ARM64Reg Rd, ARM64Reg Rn) { - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); - Write32((2 << 30) | (U << 29) | (0x3E << 23) | (immh << 19) | (immb << 16) | (opcode << 11) | - (1 << 10) | (Rn << 5) | Rd); + (1 << 10) | (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64FloatEmitter::EmitLoadStoreMultipleStructure(u32 size, bool L, u32 opcode, ARM64Reg Rt, @@ -2605,11 +2511,8 @@ void ARM64FloatEmitter::EmitLoadStoreMultipleStructure(u32 size, bool L, u32 opc else if (size == 64) encoded_size = 3; - Rt = DecodeReg(Rt); - Rn = DecodeReg(Rn); - - Write32((quad << 30) | (3 << 26) | (L << 22) | (opcode << 12) | (encoded_size << 10) | (Rn << 5) | - Rt); + Write32((quad << 30) | (3 << 26) | (L << 22) | (opcode << 12) | (encoded_size << 10) | + (DecodeReg(Rn) << 5) | DecodeReg(Rt)); } void ARM64FloatEmitter::EmitLoadStoreMultipleStructurePost(u32 size, bool L, u32 opcode, @@ -2625,12 +2528,8 @@ void ARM64FloatEmitter::EmitLoadStoreMultipleStructurePost(u32 size, bool L, u32 else if (size == 64) encoded_size = 3; - Rt = DecodeReg(Rt); - Rn = DecodeReg(Rn); - Rm = DecodeReg(Rm); - - Write32((quad << 30) | (0b11001 << 23) | (L << 22) | (Rm << 16) | (opcode << 12) | - (encoded_size << 10) | (Rn << 5) | Rt); + Write32((quad << 30) | (0b11001 << 23) | (L << 22) | (DecodeReg(Rm) << 16) | (opcode << 12) | + (encoded_size << 10) | (DecodeReg(Rn) << 5) | DecodeReg(Rt)); } void ARM64FloatEmitter::EmitScalar1Source(bool M, bool S, u32 type, u32 opcode, ARM64Reg Rd, @@ -2638,11 +2537,8 @@ void ARM64FloatEmitter::EmitScalar1Source(bool M, bool S, u32 type, u32 opcode, { ASSERT_MSG(DYNA_REC, !IsQuad(Rd), "%s doesn't support vector!", __func__); - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); - Write32((M << 31) | (S << 29) | (0xF1 << 21) | (type << 22) | (opcode << 15) | (1 << 14) | - (Rn << 5) | Rd); + (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } void ARM64FloatEmitter::EmitVectorxElement(bool U, u32 size, bool L, u32 opcode, bool H, @@ -2650,22 +2546,18 @@ void ARM64FloatEmitter::EmitVectorxElement(bool U, u32 size, bool L, u32 opcode, { bool quad = IsQuad(Rd); - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); - Rm = DecodeReg(Rm); - - Write32((quad << 30) | (U << 29) | (0xF << 24) | (size << 22) | (L << 21) | (Rm << 16) | - (opcode << 12) | (H << 11) | (Rn << 5) | Rd); + Write32((quad << 30) | (U << 29) | (0xF << 24) | (size << 22) | (L << 21) | + (DecodeReg(Rm) << 16) | (opcode << 12) | (H << 11) | (DecodeReg(Rn) << 5) | + DecodeReg(Rd)); } void ARM64FloatEmitter::EmitLoadStoreUnscaled(u32 size, u32 op, ARM64Reg Rt, ARM64Reg Rn, s32 imm) { ASSERT_MSG(DYNA_REC, !(imm < -256 || imm > 255), "%s received too large offset: %d", __func__, imm); - Rt = DecodeReg(Rt); - Rn = DecodeReg(Rn); - Write32((size << 30) | (0xF << 26) | (op << 22) | ((imm & 0x1FF) << 12) | (Rn << 5) | Rt); + Write32((size << 30) | (0xF << 26) | (op << 22) | ((imm & 0x1FF) << 12) | (DecodeReg(Rn) << 5) | + DecodeReg(Rt)); } void ARM64FloatEmitter::EncodeLoadStorePair(u32 size, bool load, IndexType type, ARM64Reg Rt, @@ -2709,14 +2601,10 @@ void ARM64FloatEmitter::EncodeLoadStorePair(u32 size, bool load, IndexType type, imm >>= 2; } - Rt = DecodeReg(Rt); - Rt2 = DecodeReg(Rt2); - Rn = DecodeReg(Rn); - ASSERT_MSG(DYNA_REC, imm >= -64 && imm < 64, "imm too large for load/store pair!"); Write32((opc << 30) | (0b1011 << 26) | (type_encode << 23) | (load << 22) | ((imm & 0x7F) << 15) | - (Rt2 << 10) | (Rn << 5) | Rt); + (DecodeReg(Rt2) << 10) | (DecodeReg(Rn) << 5) | DecodeReg(Rt)); } void ARM64FloatEmitter::EncodeLoadStoreRegisterOffset(u32 size, bool load, ARM64Reg Rt, ARM64Reg Rn, @@ -2756,12 +2644,10 @@ void ARM64FloatEmitter::EncodeLoadStoreRegisterOffset(u32 size, bool load, ARM64 if (load) encoded_op |= 1; - Rt = DecodeReg(Rt); - Rn = DecodeReg(Rn); - ARM64Reg decoded_Rm = DecodeReg(Rm.GetReg()); + const int decoded_Rm = DecodeReg(Rm.GetReg()); Write32((encoded_size << 30) | (encoded_op << 22) | (0b111100001 << 21) | (decoded_Rm << 16) | - Rm.GetData() | (1 << 11) | (Rn << 5) | Rt); + Rm.GetData() | (1 << 11) | (DecodeReg(Rn) << 5) | DecodeReg(Rt)); } void ARM64FloatEmitter::EncodeModImm(bool Q, u8 op, u8 cmode, u8 o2, ARM64Reg Rd, u8 abcdefgh) @@ -2776,9 +2662,8 @@ void ARM64FloatEmitter::EncodeModImm(bool Q, u8 op, u8 cmode, u8 o2, ARM64Reg Rd }; } v; v.hex = abcdefgh; - Rd = DecodeReg(Rd); Write32((Q << 30) | (op << 29) | (0xF << 24) | (v.abc << 16) | (cmode << 12) | (o2 << 11) | - (1 << 10) | (v.defgh << 5) | Rd); + (1 << 10) | (v.defgh << 5) | DecodeReg(Rd)); } void ARM64FloatEmitter::LDR(u8 size, IndexType type, ARM64Reg Rt, ARM64Reg Rn, s32 imm) @@ -2864,7 +2749,7 @@ void ARM64FloatEmitter::LD1(u8 size, ARM64Reg Rt, u8 index, ARM64Reg Rn) bool S = 0; u32 opcode = 0; u32 encoded_size = 0; - ARM64Reg encoded_reg = INVALID_REG; + ARM64Reg encoded_reg = ARM64Reg::INVALID_REG; if (size == 8) { @@ -2915,7 +2800,7 @@ void ARM64FloatEmitter::LD1(u8 size, ARM64Reg Rt, u8 index, ARM64Reg Rn, ARM64Re bool S = 0; u32 opcode = 0; u32 encoded_size = 0; - ARM64Reg encoded_reg = INVALID_REG; + ARM64Reg encoded_reg = ARM64Reg::INVALID_REG; if (size == 8) { @@ -2983,7 +2868,7 @@ void ARM64FloatEmitter::ST1(u8 size, ARM64Reg Rt, u8 index, ARM64Reg Rn) bool S = 0; u32 opcode = 0; u32 encoded_size = 0; - ARM64Reg encoded_reg = INVALID_REG; + ARM64Reg encoded_reg = ARM64Reg::INVALID_REG; if (size == 8) { @@ -3034,7 +2919,7 @@ void ARM64FloatEmitter::ST1(u8 size, ARM64Reg Rt, u8 index, ARM64Reg Rn, ARM64Re bool S = 0; u32 opcode = 0; u32 encoded_size = 0; - ARM64Reg encoded_reg = INVALID_REG; + ARM64Reg encoded_reg = ARM64Reg::INVALID_REG; if (size == 8) { @@ -3175,9 +3060,8 @@ void ARM64FloatEmitter::FMOV(ARM64Reg Rd, ARM64Reg Rn, bool top) // TODO ASSERT_MSG(DYNA_REC, 0, "FMOV: Unhandled case"); } - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); - Write32((sf << 31) | (0x1e2 << 20) | (rmode << 19) | (opcode << 16) | (Rn << 5) | Rd); + Write32((sf << 31) | (0x1e2 << 20) | (rmode << 19) | (opcode << 16) | (DecodeReg(Rn) << 5) | + DecodeReg(Rd)); } } @@ -3275,14 +3159,10 @@ void ARM64FloatEmitter::EmitScalar3Source(bool isDouble, ARM64Reg Rd, ARM64Reg R ARM64Reg Ra, int opcode) { int type = isDouble ? 1 : 0; - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); - Rm = DecodeReg(Rm); - Ra = DecodeReg(Ra); int o1 = opcode >> 1; int o0 = opcode & 1; - m_emit->Write32((0x1F << 24) | (type << 22) | (o1 << 21) | (Rm << 16) | (o0 << 15) | (Ra << 10) | - (Rn << 5) | Rd); + m_emit->Write32((0x1F << 24) | (type << 22) | (o1 << 21) | (DecodeReg(Rm) << 16) | (o0 << 15) | + (DecodeReg(Ra) << 10) | (DecodeReg(Rn) << 5) | DecodeReg(Rd)); } // Scalar floating point immediate @@ -3536,7 +3416,7 @@ void ARM64FloatEmitter::INS(u8 size, ARM64Reg Rd, u8 index1, ARM64Reg Rn, u8 ind void ARM64FloatEmitter::UMOV(u8 size, ARM64Reg Rd, ARM64Reg Rn, u8 index) { bool b64Bit = Is64Bit(Rd); - ASSERT_MSG(DYNA_REC, Rd < SP, "%s destination must be a GPR!", __func__); + ASSERT_MSG(DYNA_REC, Rd < ARM64Reg::SP, "%s destination must be a GPR!", __func__); ASSERT_MSG(DYNA_REC, !(b64Bit && size != 64), "%s must have a size of 64 when destination is 64bit!", __func__); u32 imm5 = 0; @@ -3567,7 +3447,7 @@ void ARM64FloatEmitter::UMOV(u8 size, ARM64Reg Rd, ARM64Reg Rn, u8 index) void ARM64FloatEmitter::SMOV(u8 size, ARM64Reg Rd, ARM64Reg Rn, u8 index) { bool b64Bit = Is64Bit(Rd); - ASSERT_MSG(DYNA_REC, Rd < SP, "%s destination must be a GPR!", __func__); + ASSERT_MSG(DYNA_REC, Rd < ARM64Reg::SP, "%s destination must be a GPR!", __func__); ASSERT_MSG(DYNA_REC, size != 64, "%s doesn't support 64bit destination. Use UMOV!", __func__); u32 imm5 = 0; @@ -3619,10 +3499,9 @@ void ARM64FloatEmitter::SCVTF(ARM64Reg Rd, ARM64Reg Rn) { // Source is in FP register (like destination!). We must use a vector encoding. bool sign = false; - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); int sz = IsDouble(Rn); - Write32((0x5e << 24) | (sign << 29) | (sz << 22) | (0x876 << 10) | (Rn << 5) | Rd); + Write32((0x5e << 24) | (sign << 29) | (sz << 22) | (0x876 << 10) | (DecodeReg(Rn) << 5) | + DecodeReg(Rd)); } else { @@ -3640,10 +3519,9 @@ void ARM64FloatEmitter::UCVTF(ARM64Reg Rd, ARM64Reg Rn) { // Source is in FP register (like destination!). We must use a vector encoding. bool sign = true; - Rd = DecodeReg(Rd); - Rn = DecodeReg(Rn); int sz = IsDouble(Rn); - Write32((0x5e << 24) | (sign << 29) | (sz << 22) | (0x876 << 10) | (Rn << 5) | Rd); + Write32((0x5e << 24) | (sign << 29) | (sz << 22) | (0x876 << 10) | (DecodeReg(Rn) << 5) | + DecodeReg(Rd)); } else { @@ -4036,11 +3914,11 @@ void ARM64FloatEmitter::ABI_PushRegisters(BitSet32 registers, ARM64Reg tmp) } } - if (bundled_loadstore && tmp != INVALID_REG) + if (bundled_loadstore && tmp != ARM64Reg::INVALID_REG) { int num_regs = registers.Count(); - m_emit->SUB(SP, SP, num_regs * 16); - m_emit->ADD(tmp, SP, 0); + m_emit->SUB(ARM64Reg::SP, ARM64Reg::SP, num_regs * 16); + m_emit->ADD(tmp, ARM64Reg::SP, 0); std::vector<ARM64Reg> island_regs; for (int i = 0; i < 32; ++i) { @@ -4059,9 +3937,9 @@ void ARM64FloatEmitter::ABI_PushRegisters(BitSet32 registers, ARM64Reg tmp) } if (count == 1) - island_regs.push_back((ARM64Reg)(Q0 + i)); + island_regs.push_back(ARM64Reg::Q0 + i); else - ST1(64, count, IndexType::Post, (ARM64Reg)(Q0 + i), tmp); + ST1(64, count, IndexType::Post, ARM64Reg::Q0 + i, tmp); i += count - 1; } @@ -4085,15 +3963,15 @@ void ARM64FloatEmitter::ABI_PushRegisters(BitSet32 registers, ARM64Reg tmp) std::vector<ARM64Reg> pair_regs; for (auto it : registers) { - pair_regs.push_back((ARM64Reg)(Q0 + it)); + pair_regs.push_back(ARM64Reg::Q0 + it); if (pair_regs.size() == 2) { - STP(128, IndexType::Pre, pair_regs[0], pair_regs[1], SP, -32); + STP(128, IndexType::Pre, pair_regs[0], pair_regs[1], ARM64Reg::SP, -32); pair_regs.clear(); } } if (pair_regs.size()) - STR(128, IndexType::Pre, pair_regs[0], SP, -16); + STR(128, IndexType::Pre, pair_regs[0], ARM64Reg::SP, -16); } } void ARM64FloatEmitter::ABI_PopRegisters(BitSet32 registers, ARM64Reg tmp) @@ -4117,7 +3995,7 @@ void ARM64FloatEmitter::ABI_PopRegisters(BitSet32 registers, ARM64Reg tmp) } } - if (bundled_loadstore && tmp != INVALID_REG) + if (bundled_loadstore && tmp != ARM64Reg::INVALID_REG) { // The temporary register is only used to indicate that we can use this code path std::vector<ARM64Reg> island_regs; @@ -4132,9 +4010,9 @@ void ARM64FloatEmitter::ABI_PopRegisters(BitSet32 registers, ARM64Reg tmp) } if (count == 1) - island_regs.push_back((ARM64Reg)(Q0 + i)); + island_regs.push_back(ARM64Reg::Q0 + i); else - LD1(64, count, IndexType::Post, (ARM64Reg)(Q0 + i), SP); + LD1(64, count, IndexType::Post, ARM64Reg::Q0 + i, ARM64Reg::SP); i += count - 1; } @@ -4146,12 +4024,12 @@ void ARM64FloatEmitter::ABI_PopRegisters(BitSet32 registers, ARM64Reg tmp) pair_regs.push_back(it); if (pair_regs.size() == 2) { - LDP(128, IndexType::Post, pair_regs[0], pair_regs[1], SP, 32); + LDP(128, IndexType::Post, pair_regs[0], pair_regs[1], ARM64Reg::SP, 32); pair_regs.clear(); } } if (pair_regs.size()) - LDR(128, IndexType::Post, pair_regs[0], SP, 16); + LDR(128, IndexType::Post, pair_regs[0], ARM64Reg::SP, 16); } else { @@ -4166,14 +4044,14 @@ void ARM64FloatEmitter::ABI_PopRegisters(BitSet32 registers, ARM64Reg tmp) { // First load must be a regular LDR if odd odd = false; - LDR(128, IndexType::Post, (ARM64Reg)(Q0 + i), SP, 16); + LDR(128, IndexType::Post, ARM64Reg::Q0 + i, ARM64Reg::SP, 16); } else { - pair_regs.push_back((ARM64Reg)(Q0 + i)); + pair_regs.push_back(ARM64Reg::Q0 + i); if (pair_regs.size() == 2) { - LDP(128, IndexType::Post, pair_regs[1], pair_regs[0], SP, 32); + LDP(128, IndexType::Post, pair_regs[1], pair_regs[0], ARM64Reg::SP, 32); pair_regs.clear(); } } @@ -4193,7 +4071,7 @@ void ARM64XEmitter::ANDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) } else { - ASSERT_MSG(DYNA_REC, scratch != INVALID_REG, + ASSERT_MSG(DYNA_REC, scratch != ARM64Reg::INVALID_REG, "ANDI2R - failed to construct logical immediate value from %08x, need scratch", (u32)imm); MOVI2R(scratch, imm); @@ -4210,7 +4088,7 @@ void ARM64XEmitter::ORRI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) } else { - ASSERT_MSG(DYNA_REC, scratch != INVALID_REG, + ASSERT_MSG(DYNA_REC, scratch != ARM64Reg::INVALID_REG, "ORRI2R - failed to construct logical immediate value from %08x, need scratch", (u32)imm); MOVI2R(scratch, imm); @@ -4227,7 +4105,7 @@ void ARM64XEmitter::EORI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) } else { - ASSERT_MSG(DYNA_REC, scratch != INVALID_REG, + ASSERT_MSG(DYNA_REC, scratch != ARM64Reg::INVALID_REG, "EORI2R - failed to construct logical immediate value from %08x, need scratch", (u32)imm); MOVI2R(scratch, imm); @@ -4244,7 +4122,7 @@ void ARM64XEmitter::ANDSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) } else { - ASSERT_MSG(DYNA_REC, scratch != INVALID_REG, + ASSERT_MSG(DYNA_REC, scratch != ARM64Reg::INVALID_REG, "ANDSI2R - failed to construct logical immediate value from %08x, need scratch", (u32)imm); MOVI2R(scratch, imm); @@ -4274,7 +4152,7 @@ void ARM64XEmitter::AddImmediate(ARM64Reg Rd, ARM64Reg Rn, u64 imm, bool shift, void ARM64XEmitter::ADDI2R_internal(ARM64Reg Rd, ARM64Reg Rn, u64 imm, bool negative, bool flags, ARM64Reg scratch) { - bool has_scratch = scratch != INVALID_REG; + bool has_scratch = scratch != ARM64Reg::INVALID_REG; u64 imm_neg = Is64Bit(Rd) ? u64(-s64(imm)) : u64(-s64(imm)) & 0xFFFFFFFFuLL; bool neg_neg = negative ? false : true; @@ -4360,7 +4238,7 @@ void ARM64XEmitter::SUBSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch) void ARM64XEmitter::CMPI2R(ARM64Reg Rn, u64 imm, ARM64Reg scratch) { - ADDI2R_internal(Is64Bit(Rn) ? ZR : WZR, Rn, imm, true, true, scratch); + ADDI2R_internal(Is64Bit(Rn) ? ARM64Reg::ZR : ARM64Reg::WZR, Rn, imm, true, true, scratch); } bool ARM64XEmitter::TryADDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm) @@ -4441,7 +4319,7 @@ void ARM64FloatEmitter::MOVI2F(ARM64Reg Rd, float value, ARM64Reg scratch, bool if (value == 0.0f) { - FMOV(Rd, IsDouble(Rd) ? ZR : WZR); + FMOV(Rd, IsDouble(Rd) ? ARM64Reg::ZR : ARM64Reg::WZR); if (negate) FNEG(Rd, Rd); // TODO: There are some other values we could generate with the float-imm instruction, like @@ -4453,7 +4331,7 @@ void ARM64FloatEmitter::MOVI2F(ARM64Reg Rd, float value, ARM64Reg scratch, bool } else { - ASSERT_MSG(DYNA_REC, scratch != INVALID_REG, + ASSERT_MSG(DYNA_REC, scratch != ARM64Reg::INVALID_REG, "Failed to find a way to generate FP immediate %f without scratch", value); if (negate) value = -value; @@ -4469,7 +4347,7 @@ void ARM64FloatEmitter::MOVI2FDUP(ARM64Reg Rd, float value, ARM64Reg scratch) { // TODO: Make it work with more element sizes // TODO: Optimize - there are shorter solution for many values - ARM64Reg s = (ARM64Reg)(S0 + DecodeReg(Rd)); + ARM64Reg s = ARM64Reg::S0 + DecodeReg(Rd); MOVI2F(s, value, scratch); DUP(32, Rd, Rd, 0); } diff --git a/Source/Core/Common/Arm64Emitter.h b/Source/Core/Common/Arm64Emitter.h index 874f1d2fed..06c632537b 100644 --- a/Source/Core/Common/Arm64Emitter.h +++ b/Source/Core/Common/Arm64Emitter.h @@ -23,7 +23,7 @@ namespace Arm64Gen // 010 - VFP single precision // 100 - VFP double precision // 110 - VFP quad precision -enum ARM64Reg +enum class ARM64Reg { // 32bit registers W0 = 0, @@ -224,9 +224,21 @@ enum ARM64Reg WZR = WSP, ZR = SP, - INVALID_REG = 0xFFFFFFFF + INVALID_REG = -1, }; +constexpr int operator&(const ARM64Reg& reg, const int mask) +{ + return static_cast<int>(reg) & mask; +} +constexpr int operator|(const ARM64Reg& reg, const int mask) +{ + return static_cast<int>(reg) | mask; +} +constexpr ARM64Reg operator+(const ARM64Reg& reg, const int addend) +{ + return static_cast<ARM64Reg>(static_cast<int>(reg) + addend); +} constexpr bool Is64Bit(ARM64Reg reg) { return (reg & 0x20) != 0; @@ -256,9 +268,13 @@ constexpr bool IsGPR(ARM64Reg reg) return static_cast<int>(reg) < 0x40; } -constexpr ARM64Reg DecodeReg(ARM64Reg reg) +constexpr int DecodeReg(ARM64Reg reg) +{ + return reg & 0x1F; +} +constexpr ARM64Reg EncodeRegTo32(ARM64Reg reg) { - return static_cast<ARM64Reg>(reg & 0x1F); + return static_cast<ARM64Reg>(DecodeReg(reg)); } constexpr ARM64Reg EncodeRegTo64(ARM64Reg reg) { @@ -266,7 +282,7 @@ constexpr ARM64Reg EncodeRegTo64(ARM64Reg reg) } constexpr ARM64Reg EncodeRegToSingle(ARM64Reg reg) { - return static_cast<ARM64Reg>(DecodeReg(reg) + S0); + return static_cast<ARM64Reg>(ARM64Reg::S0 | DecodeReg(reg)); } constexpr ARM64Reg EncodeRegToDouble(ARM64Reg reg) { @@ -578,7 +594,7 @@ public: // Unconditional Branch (register) void BR(ARM64Reg Rn); void BLR(ARM64Reg Rn); - void RET(ARM64Reg Rn = X30); + void RET(ARM64Reg Rn = ARM64Reg::X30); void ERET(); void DRPS(); @@ -648,15 +664,15 @@ public: // Aliases void CSET(ARM64Reg Rd, CCFlags cond) { - ARM64Reg zr = Is64Bit(Rd) ? ZR : WZR; + ARM64Reg zr = Is64Bit(Rd) ? ARM64Reg::ZR : ARM64Reg::WZR; CSINC(Rd, zr, zr, (CCFlags)((u32)cond ^ 1)); } void CSETM(ARM64Reg Rd, CCFlags cond) { - ARM64Reg zr = Is64Bit(Rd) ? ZR : WZR; + ARM64Reg zr = Is64Bit(Rd) ? ARM64Reg::ZR : ARM64Reg::WZR; CSINV(Rd, zr, zr, (CCFlags)((u32)cond ^ 1)); } - void NEG(ARM64Reg Rd, ARM64Reg Rs) { SUB(Rd, Is64Bit(Rd) ? ZR : WZR, Rs); } + void NEG(ARM64Reg Rd, ARM64Reg Rs) { SUB(Rd, Is64Bit(Rd) ? ARM64Reg::ZR : ARM64Reg::WZR, Rs); } // Data-Processing 1 source void RBIT(ARM64Reg Rd, ARM64Reg Rn); void REV16(ARM64Reg Rd, ARM64Reg Rn); @@ -704,10 +720,10 @@ public: void EON(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ArithOption Shift); void ANDS(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ArithOption Shift); void BICS(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ArithOption Shift); - void TST(ARM64Reg Rn, ARM64Reg Rm) { ANDS(Is64Bit(Rn) ? ZR : WZR, Rn, Rm); } + void TST(ARM64Reg Rn, ARM64Reg Rm) { ANDS(Is64Bit(Rn) ? ARM64Reg::ZR : ARM64Reg::WZR, Rn, Rm); } void TST(ARM64Reg Rn, ARM64Reg Rm, ArithOption Shift) { - ANDS(Is64Bit(Rn) ? ZR : WZR, Rn, Rm, Shift); + ANDS(Is64Bit(Rn) ? ARM64Reg::ZR : ARM64Reg::WZR, Rn, Rm, Shift); } // Wrap the above for saner syntax @@ -879,22 +895,22 @@ public: // Wrapper around AND x, y, imm etc. If you are sure the imm will work, no need to pass a scratch // register. - void ANDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch = INVALID_REG); - void ANDSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch = INVALID_REG); - void TSTI2R(ARM64Reg Rn, u64 imm, ARM64Reg scratch = INVALID_REG) + void ANDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch = ARM64Reg::INVALID_REG); + void ANDSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch = ARM64Reg::INVALID_REG); + void TSTI2R(ARM64Reg Rn, u64 imm, ARM64Reg scratch = ARM64Reg::INVALID_REG) { - ANDSI2R(Is64Bit(Rn) ? ZR : WZR, Rn, imm, scratch); + ANDSI2R(Is64Bit(Rn) ? ARM64Reg::ZR : ARM64Reg::WZR, Rn, imm, scratch); } - void ORRI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch = INVALID_REG); - void EORI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch = INVALID_REG); - void CMPI2R(ARM64Reg Rn, u64 imm, ARM64Reg scratch = INVALID_REG); + void ORRI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch = ARM64Reg::INVALID_REG); + void EORI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch = ARM64Reg::INVALID_REG); + void CMPI2R(ARM64Reg Rn, u64 imm, ARM64Reg scratch = ARM64Reg::INVALID_REG); void ADDI2R_internal(ARM64Reg Rd, ARM64Reg Rn, u64 imm, bool negative, bool flags, ARM64Reg scratch); - void ADDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch = INVALID_REG); - void ADDSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch = INVALID_REG); - void SUBI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch = INVALID_REG); - void SUBSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch = INVALID_REG); + void ADDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch = ARM64Reg::INVALID_REG); + void ADDSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch = ARM64Reg::INVALID_REG); + void SUBI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch = ARM64Reg::INVALID_REG); + void SUBSI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm, ARM64Reg scratch = ARM64Reg::INVALID_REG); bool TryADDI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm); bool TrySUBI2R(ARM64Reg Rd, ARM64Reg Rn, u64 imm); @@ -925,9 +941,9 @@ public: ARM64Reg ABI_SetupLambda(const std::function<T(Args...)>* f) { auto trampoline = &ARM64XEmitter::CallLambdaTrampoline<T, Args...>; - MOVP2R(X8, trampoline); - MOVP2R(X0, const_cast<void*>((const void*)f)); - return X8; + MOVP2R(ARM64Reg::X8, trampoline); + MOVP2R(ARM64Reg::X0, const_cast<void*>((const void*)f)); + return ARM64Reg::X8; } // Plain function call @@ -962,9 +978,9 @@ public: // Loadstore multiple structure void LD1(u8 size, u8 count, ARM64Reg Rt, ARM64Reg Rn); - void LD1(u8 size, u8 count, IndexType type, ARM64Reg Rt, ARM64Reg Rn, ARM64Reg Rm = SP); + void LD1(u8 size, u8 count, IndexType type, ARM64Reg Rt, ARM64Reg Rn, ARM64Reg Rm = ARM64Reg::SP); void ST1(u8 size, u8 count, ARM64Reg Rt, ARM64Reg Rn); - void ST1(u8 size, u8 count, IndexType type, ARM64Reg Rt, ARM64Reg Rn, ARM64Reg Rm = SP); + void ST1(u8 size, u8 count, IndexType type, ARM64Reg Rt, ARM64Reg Rn, ARM64Reg Rm = ARM64Reg::SP); // Loadstore paired void LDP(u8 size, IndexType type, ARM64Reg Rt, ARM64Reg Rt2, ARM64Reg Rn, s32 imm); @@ -1109,12 +1125,13 @@ public: void MOVI(u8 size, ARM64Reg Rd, u64 imm, u8 shift = 0); void BIC(u8 size, ARM64Reg Rd, u8 imm, u8 shift = 0); - void MOVI2F(ARM64Reg Rd, float value, ARM64Reg scratch = INVALID_REG, bool negate = false); - void MOVI2FDUP(ARM64Reg Rd, float value, ARM64Reg scratch = INVALID_REG); + void MOVI2F(ARM64Reg Rd, float value, ARM64Reg scratch = ARM64Reg::INVALID_REG, + bool negate = false); + void MOVI2FDUP(ARM64Reg Rd, float value, ARM64Reg scratch = ARM64Reg::INVALID_REG); // ABI related - void ABI_PushRegisters(BitSet32 registers, ARM64Reg tmp = INVALID_REG); - void ABI_PopRegisters(BitSet32 registers, ARM64Reg tmp = INVALID_REG); + void ABI_PushRegisters(BitSet32 registers, ARM64Reg tmp = ARM64Reg::INVALID_REG); + void ABI_PopRegisters(BitSet32 registers, ARM64Reg tmp = ARM64Reg::INVALID_REG); private: ARM64XEmitter* m_emit; |
