diff options
Diffstat (limited to 'lldb/source/Plugins/Process/Utility/ARMUtils.h')
-rw-r--r-- | lldb/source/Plugins/Process/Utility/ARMUtils.h | 567 |
1 files changed, 274 insertions, 293 deletions
diff --git a/lldb/source/Plugins/Process/Utility/ARMUtils.h b/lldb/source/Plugins/Process/Utility/ARMUtils.h index b6ba3fea692..2bbd519b246 100644 --- a/lldb/source/Plugins/Process/Utility/ARMUtils.h +++ b/lldb/source/Plugins/Process/Utility/ARMUtils.h @@ -18,352 +18,335 @@ namespace lldb_private { -static inline uint32_t Align(uint32_t val, uint32_t alignment) -{ - return alignment * (val / alignment); +static inline uint32_t Align(uint32_t val, uint32_t alignment) { + return alignment * (val / alignment); } -static inline uint32_t DecodeImmShift(const uint32_t type, const uint32_t imm5, ARM_ShifterType &shift_t) -{ - switch (type) - { - default: - //assert(0 && "Invalid shift type"); - case 0: - shift_t = SRType_LSL; - return imm5; - case 1: - shift_t = SRType_LSR; - return (imm5 == 0 ? 32 : imm5); - case 2: - shift_t = SRType_ASR; - return (imm5 == 0 ? 32 : imm5); - case 3: - if (imm5 == 0) - { - shift_t = SRType_RRX; - return 1; - } - else - { - shift_t = SRType_ROR; - return imm5; - } +static inline uint32_t DecodeImmShift(const uint32_t type, const uint32_t imm5, + ARM_ShifterType &shift_t) { + switch (type) { + default: + // assert(0 && "Invalid shift type"); + case 0: + shift_t = SRType_LSL; + return imm5; + case 1: + shift_t = SRType_LSR; + return (imm5 == 0 ? 32 : imm5); + case 2: + shift_t = SRType_ASR; + return (imm5 == 0 ? 32 : imm5); + case 3: + if (imm5 == 0) { + shift_t = SRType_RRX; + return 1; + } else { + shift_t = SRType_ROR; + return imm5; } - shift_t = SRType_Invalid; - return UINT32_MAX; - + } + shift_t = SRType_Invalid; + return UINT32_MAX; } // A8.6.35 CMP (register) -- Encoding T3 // Convenience function. -static inline uint32_t DecodeImmShiftThumb(const uint32_t opcode, ARM_ShifterType &shift_t) -{ - return DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t); +static inline uint32_t DecodeImmShiftThumb(const uint32_t opcode, + ARM_ShifterType &shift_t) { + return DecodeImmShift(Bits32(opcode, 5, 4), + Bits32(opcode, 14, 12) << 2 | Bits32(opcode, 7, 6), + shift_t); } // A8.6.35 CMP (register) -- Encoding A1 // Convenience function. -static inline uint32_t DecodeImmShiftARM(const uint32_t opcode, ARM_ShifterType &shift_t) -{ - return DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t); +static inline uint32_t DecodeImmShiftARM(const uint32_t opcode, + ARM_ShifterType &shift_t) { + return DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t); } -static inline uint32_t DecodeImmShift(const ARM_ShifterType shift_t, const uint32_t imm5) -{ - ARM_ShifterType dont_care; - return DecodeImmShift(shift_t, imm5, dont_care); +static inline uint32_t DecodeImmShift(const ARM_ShifterType shift_t, + const uint32_t imm5) { + ARM_ShifterType dont_care; + return DecodeImmShift(shift_t, imm5, dont_care); } -static inline ARM_ShifterType DecodeRegShift(const uint32_t type) -{ - switch (type) { - default: - //assert(0 && "Invalid shift type"); - return SRType_Invalid; - case 0: - return SRType_LSL; - case 1: - return SRType_LSR; - case 2: - return SRType_ASR; - case 3: - return SRType_ROR; - } +static inline ARM_ShifterType DecodeRegShift(const uint32_t type) { + switch (type) { + default: + // assert(0 && "Invalid shift type"); + return SRType_Invalid; + case 0: + return SRType_LSL; + case 1: + return SRType_LSR; + case 2: + return SRType_ASR; + case 3: + return SRType_ROR; + } } -static inline uint32_t LSL_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success) -{ - if (amount == 0) { - *success = false; - return 0; - } - *success = true; - carry_out = amount <= 32 ? Bit32(value, 32 - amount) : 0; - return value << amount; +static inline uint32_t LSL_C(const uint32_t value, const uint32_t amount, + uint32_t &carry_out, bool *success) { + if (amount == 0) { + *success = false; + return 0; + } + *success = true; + carry_out = amount <= 32 ? Bit32(value, 32 - amount) : 0; + return value << amount; } -static inline uint32_t LSL(const uint32_t value, const uint32_t amount, bool *success) -{ - *success = true; - if (amount == 0) - return value; - uint32_t dont_care; - uint32_t result = LSL_C(value, amount, dont_care, success); - if (*success) - return result; - else - return 0; -} - -static inline uint32_t LSR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success) -{ - if (amount == 0) { - *success = false; - return 0; - } - *success = true; - carry_out = amount <= 32 ? Bit32(value, amount - 1) : 0; - return value >> amount; +static inline uint32_t LSL(const uint32_t value, const uint32_t amount, + bool *success) { + *success = true; + if (amount == 0) + return value; + uint32_t dont_care; + uint32_t result = LSL_C(value, amount, dont_care, success); + if (*success) + return result; + else + return 0; } -static inline uint32_t LSR(const uint32_t value, const uint32_t amount, bool *success) -{ - *success = true; - if (amount == 0) - return value; - uint32_t dont_care; - uint32_t result = LSR_C(value, amount, dont_care, success); - if (*success) - return result; - else - return 0; +static inline uint32_t LSR_C(const uint32_t value, const uint32_t amount, + uint32_t &carry_out, bool *success) { + if (amount == 0) { + *success = false; + return 0; + } + *success = true; + carry_out = amount <= 32 ? Bit32(value, amount - 1) : 0; + return value >> amount; } -static inline uint32_t ASR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success) -{ - if (amount == 0 || amount > 32) { - *success = false; - return 0; - } - *success = true; - bool negative = BitIsSet(value, 31); - if (amount <= 32) - { - carry_out = Bit32(value, amount - 1); - int64_t extended = llvm::SignExtend64<32>(value); - return UnsignedBits(extended, amount + 31, amount); - } - else - { - carry_out = (negative ? 1 : 0); - return (negative ? 0xffffffff : 0); - } +static inline uint32_t LSR(const uint32_t value, const uint32_t amount, + bool *success) { + *success = true; + if (amount == 0) + return value; + uint32_t dont_care; + uint32_t result = LSR_C(value, amount, dont_care, success); + if (*success) + return result; + else + return 0; } -static inline uint32_t ASR(const uint32_t value, const uint32_t amount, bool *success) -{ - *success = true; - if (amount == 0) - return value; - uint32_t dont_care; - uint32_t result = ASR_C(value, amount, dont_care, success); - if (*success) - return result; - else - return 0; +static inline uint32_t ASR_C(const uint32_t value, const uint32_t amount, + uint32_t &carry_out, bool *success) { + if (amount == 0 || amount > 32) { + *success = false; + return 0; + } + *success = true; + bool negative = BitIsSet(value, 31); + if (amount <= 32) { + carry_out = Bit32(value, amount - 1); + int64_t extended = llvm::SignExtend64<32>(value); + return UnsignedBits(extended, amount + 31, amount); + } else { + carry_out = (negative ? 1 : 0); + return (negative ? 0xffffffff : 0); + } } -static inline uint32_t ROR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success) -{ - if (amount == 0) { - *success = false; - return 0; - } - *success = true; - uint32_t amt = amount % 32; - uint32_t result = Rotr32(value, amt); - carry_out = Bit32(value, 31); +static inline uint32_t ASR(const uint32_t value, const uint32_t amount, + bool *success) { + *success = true; + if (amount == 0) + return value; + uint32_t dont_care; + uint32_t result = ASR_C(value, amount, dont_care, success); + if (*success) return result; + else + return 0; } -static inline uint32_t ROR(const uint32_t value, const uint32_t amount, bool *success) -{ - *success = true; - if (amount == 0) - return value; - uint32_t dont_care; - uint32_t result = ROR_C(value, amount, dont_care, success); - if (*success) - return result; - else - return 0; +static inline uint32_t ROR_C(const uint32_t value, const uint32_t amount, + uint32_t &carry_out, bool *success) { + if (amount == 0) { + *success = false; + return 0; + } + *success = true; + uint32_t amt = amount % 32; + uint32_t result = Rotr32(value, amt); + carry_out = Bit32(value, 31); + return result; } -static inline uint32_t RRX_C(const uint32_t value, const uint32_t carry_in, uint32_t &carry_out, bool *success) -{ - *success = true; - carry_out = Bit32(value, 0); - return Bit32(carry_in, 0) << 31 | Bits32(value, 31, 1); +static inline uint32_t ROR(const uint32_t value, const uint32_t amount, + bool *success) { + *success = true; + if (amount == 0) + return value; + uint32_t dont_care; + uint32_t result = ROR_C(value, amount, dont_care, success); + if (*success) + return result; + else + return 0; } -static inline uint32_t RRX(const uint32_t value, const uint32_t carry_in, bool *success) -{ - *success = true; - uint32_t dont_care; - uint32_t result = RRX_C(value, carry_in, dont_care, success); - if (*success) - return result; - else - return 0; +static inline uint32_t RRX_C(const uint32_t value, const uint32_t carry_in, + uint32_t &carry_out, bool *success) { + *success = true; + carry_out = Bit32(value, 0); + return Bit32(carry_in, 0) << 31 | Bits32(value, 31, 1); } -static inline uint32_t Shift_C(const uint32_t value, ARM_ShifterType type, const uint32_t amount, - const uint32_t carry_in, uint32_t &carry_out, bool *success) -{ - if (type == SRType_RRX && amount != 1) { - *success = false; - return 0; - } - *success = true; +static inline uint32_t RRX(const uint32_t value, const uint32_t carry_in, + bool *success) { + *success = true; + uint32_t dont_care; + uint32_t result = RRX_C(value, carry_in, dont_care, success); + if (*success) + return result; + else + return 0; +} - if (amount == 0) { - carry_out = carry_in; - return value; - } - uint32_t result; - switch (type) { - case SRType_LSL: - result = LSL_C(value, amount, carry_out, success); - break; - case SRType_LSR: - result = LSR_C(value, amount, carry_out, success); - break; - case SRType_ASR: - result = ASR_C(value, amount, carry_out, success); - break; - case SRType_ROR: - result = ROR_C(value, amount, carry_out, success); - break; - case SRType_RRX: - result = RRX_C(value, carry_in, carry_out, success); - break; - default: - *success = false; - break; - } - if (*success) - return result; - else - return 0; +static inline uint32_t Shift_C(const uint32_t value, ARM_ShifterType type, + const uint32_t amount, const uint32_t carry_in, + uint32_t &carry_out, bool *success) { + if (type == SRType_RRX && amount != 1) { + *success = false; + return 0; + } + *success = true; + + if (amount == 0) { + carry_out = carry_in; + return value; + } + uint32_t result; + switch (type) { + case SRType_LSL: + result = LSL_C(value, amount, carry_out, success); + break; + case SRType_LSR: + result = LSR_C(value, amount, carry_out, success); + break; + case SRType_ASR: + result = ASR_C(value, amount, carry_out, success); + break; + case SRType_ROR: + result = ROR_C(value, amount, carry_out, success); + break; + case SRType_RRX: + result = RRX_C(value, carry_in, carry_out, success); + break; + default: + *success = false; + break; + } + if (*success) + return result; + else + return 0; } -static inline uint32_t Shift(const uint32_t value, ARM_ShifterType type, const uint32_t amount, - const uint32_t carry_in, bool *success) -{ - // Don't care about carry out in this case. - uint32_t dont_care; - uint32_t result = Shift_C(value, type, amount, carry_in, dont_care, success); - if (*success) - return result; - else - return 0; +static inline uint32_t Shift(const uint32_t value, ARM_ShifterType type, + const uint32_t amount, const uint32_t carry_in, + bool *success) { + // Don't care about carry out in this case. + uint32_t dont_care; + uint32_t result = Shift_C(value, type, amount, carry_in, dont_care, success); + if (*success) + return result; + else + return 0; } -static inline uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit) -{ - return Bits32(val, msbit, lsbit); +static inline uint32_t bits(const uint32_t val, const uint32_t msbit, + const uint32_t lsbit) { + return Bits32(val, msbit, lsbit); } -static inline uint32_t bit(const uint32_t val, const uint32_t msbit) -{ - return bits(val, msbit, msbit); +static inline uint32_t bit(const uint32_t val, const uint32_t msbit) { + return bits(val, msbit, msbit); } -static uint32_t ror(uint32_t val, uint32_t N, uint32_t shift) -{ - uint32_t m = shift % N; - return (val >> m) | (val << (N - m)); +static uint32_t ror(uint32_t val, uint32_t N, uint32_t shift) { + uint32_t m = shift % N; + return (val >> m) | (val << (N - m)); } // (imm32, carry_out) = ARMExpandImm_C(imm12, carry_in) -static inline uint32_t ARMExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t &carry_out) -{ - uint32_t imm32; // the expanded result - uint32_t imm = bits(opcode, 7, 0); // immediate value - uint32_t amt = 2 * bits(opcode, 11, 8); // rotate amount - if (amt == 0) - { - imm32 = imm; - carry_out = carry_in; - } - else - { - imm32 = ror(imm, 32, amt); - carry_out = Bit32(imm32, 31); - } - return imm32; +static inline uint32_t ARMExpandImm_C(uint32_t opcode, uint32_t carry_in, + uint32_t &carry_out) { + uint32_t imm32; // the expanded result + uint32_t imm = bits(opcode, 7, 0); // immediate value + uint32_t amt = 2 * bits(opcode, 11, 8); // rotate amount + if (amt == 0) { + imm32 = imm; + carry_out = carry_in; + } else { + imm32 = ror(imm, 32, amt); + carry_out = Bit32(imm32, 31); + } + return imm32; } -static inline uint32_t ARMExpandImm(uint32_t opcode) -{ - // 'carry_in' argument to following function call does not affect the imm32 result. - uint32_t carry_in = 0; - uint32_t carry_out; - return ARMExpandImm_C(opcode, carry_in, carry_out); +static inline uint32_t ARMExpandImm(uint32_t opcode) { + // 'carry_in' argument to following function call does not affect the imm32 + // result. + uint32_t carry_in = 0; + uint32_t carry_out; + return ARMExpandImm_C(opcode, carry_in, carry_out); } // (imm32, carry_out) = ThumbExpandImm_C(imm12, carry_in) -static inline uint32_t ThumbExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t &carry_out) -{ - uint32_t imm32; // the expanded result - const uint32_t i = bit(opcode, 26); - const uint32_t imm3 = bits(opcode, 14, 12); - const uint32_t abcdefgh = bits(opcode, 7, 0); - const uint32_t imm12 = i << 11 | imm3 << 8 | abcdefgh; - - if (bits(imm12, 11, 10) == 0) - { - switch (bits(imm12, 9, 8)) { - default: // Keep static analyzer happy with a default case - case 0: - imm32 = abcdefgh; - break; - - case 1: - imm32 = abcdefgh << 16 | abcdefgh; - break; - - case 2: - imm32 = abcdefgh << 24 | abcdefgh << 8; - break; - - case 3: - imm32 = abcdefgh << 24 | abcdefgh << 16 | abcdefgh << 8 | abcdefgh; - break; - } - carry_out = carry_in; - } - else - { - const uint32_t unrotated_value = 0x80 | bits(imm12, 6, 0); - imm32 = ror(unrotated_value, 32, bits(imm12, 11, 7)); - carry_out = Bit32(imm32, 31); +static inline uint32_t ThumbExpandImm_C(uint32_t opcode, uint32_t carry_in, + uint32_t &carry_out) { + uint32_t imm32; // the expanded result + const uint32_t i = bit(opcode, 26); + const uint32_t imm3 = bits(opcode, 14, 12); + const uint32_t abcdefgh = bits(opcode, 7, 0); + const uint32_t imm12 = i << 11 | imm3 << 8 | abcdefgh; + + if (bits(imm12, 11, 10) == 0) { + switch (bits(imm12, 9, 8)) { + default: // Keep static analyzer happy with a default case + case 0: + imm32 = abcdefgh; + break; + + case 1: + imm32 = abcdefgh << 16 | abcdefgh; + break; + + case 2: + imm32 = abcdefgh << 24 | abcdefgh << 8; + break; + + case 3: + imm32 = abcdefgh << 24 | abcdefgh << 16 | abcdefgh << 8 | abcdefgh; + break; } - return imm32; + carry_out = carry_in; + } else { + const uint32_t unrotated_value = 0x80 | bits(imm12, 6, 0); + imm32 = ror(unrotated_value, 32, bits(imm12, 11, 7)); + carry_out = Bit32(imm32, 31); + } + return imm32; } -static inline uint32_t ThumbExpandImm(uint32_t opcode) -{ - // 'carry_in' argument to following function call does not affect the imm32 result. - uint32_t carry_in = 0; - uint32_t carry_out; - return ThumbExpandImm_C(opcode, carry_in, carry_out); +static inline uint32_t ThumbExpandImm(uint32_t opcode) { + // 'carry_in' argument to following function call does not affect the imm32 + // result. + uint32_t carry_in = 0; + uint32_t carry_out; + return ThumbExpandImm_C(opcode, carry_in, carry_out); } // imm32 = ZeroExtend(i:imm3:imm8, 32) -static inline uint32_t ThumbImm12(uint32_t opcode) -{ +static inline uint32_t ThumbImm12(uint32_t opcode) { const uint32_t i = bit(opcode, 26); const uint32_t imm3 = bits(opcode, 14, 12); const uint32_t imm8 = bits(opcode, 7, 0); @@ -372,15 +355,13 @@ static inline uint32_t ThumbImm12(uint32_t opcode) } // imm32 = ZeroExtend(imm7:'00', 32) -static inline uint32_t ThumbImm7Scaled(uint32_t opcode) -{ +static inline uint32_t ThumbImm7Scaled(uint32_t opcode) { const uint32_t imm7 = bits(opcode, 6, 0); return imm7 * 4; } // imm32 = ZeroExtend(imm8:'00', 32) -static inline uint32_t ThumbImm8Scaled(uint32_t opcode) -{ +static inline uint32_t ThumbImm8Scaled(uint32_t opcode) { const uint32_t imm8 = bits(opcode, 7, 0); return imm8 * 4; } @@ -389,6 +370,6 @@ static inline uint32_t ThumbImm8Scaled(uint32_t opcode) // not permitted for many Thumb register specifiers. static inline bool BadReg(uint32_t n) { return n == 13 || n == 15; } -} // namespace lldb_private +} // namespace lldb_private -#endif // lldb_ARMUtils_h_ +#endif // lldb_ARMUtils_h_ |