9#ifndef LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMUTILS_H
10#define LLDB_SOURCE_PLUGINS_PROCESS_UTILITY_ARMUTILS_H
14#include "llvm/ADT/bit.h"
15#include "llvm/Support/MathExtras.h"
21static inline uint32_t
Align(uint32_t val, uint32_t alignment) {
22 return alignment * (val / alignment);
25static inline uint32_t
DecodeImmShift(
const uint32_t type,
const uint32_t imm5,
29 assert(0 &&
"Invalid shift type");
36 return (imm5 == 0 ? 32 : imm5);
39 return (imm5 == 0 ? 32 : imm5);
70 const uint32_t imm5) {
91static inline uint32_t
LSL_C(
const uint32_t value,
const uint32_t amount,
92 uint32_t &carry_out,
bool *success) {
98 carry_out = amount <= 32 ?
Bit32(value, 32 - amount) : 0;
99 return value << amount;
102static inline uint32_t
LSL(
const uint32_t value,
const uint32_t amount,
108 uint32_t result =
LSL_C(value, amount, dont_care, success);
115static inline uint32_t
LSR_C(
const uint32_t value,
const uint32_t amount,
116 uint32_t &carry_out,
bool *success) {
122 carry_out = amount <= 32 ?
Bit32(value, amount - 1) : 0;
123 return value >> amount;
126static inline uint32_t
LSR(
const uint32_t value,
const uint32_t amount,
132 uint32_t result =
LSR_C(value, amount, dont_care, success);
139static inline uint32_t
ASR_C(
const uint32_t value,
const uint32_t amount,
140 uint32_t &carry_out,
bool *success) {
141 if (amount == 0 || amount > 32) {
146 bool negative =
BitIsSet(value, 31);
148 carry_out =
Bit32(value, amount - 1);
149 int64_t extended = llvm::SignExtend64<32>(value);
152 carry_out = (negative ? 1 : 0);
153 return (negative ? 0xffffffff : 0);
157static inline uint32_t
ASR(
const uint32_t value,
const uint32_t amount,
163 uint32_t result =
ASR_C(value, amount, dont_care, success);
170static inline uint32_t
ROR_C(
const uint32_t value,
const uint32_t amount,
171 uint32_t &carry_out,
bool *success) {
177 uint32_t result = llvm::rotr<uint32_t>(value, amount);
178 carry_out =
Bit32(value, 31);
182static inline uint32_t
ROR(
const uint32_t value,
const uint32_t amount,
188 uint32_t result =
ROR_C(value, amount, dont_care, success);
195static inline uint32_t
RRX_C(
const uint32_t value,
const uint32_t carry_in,
196 uint32_t &carry_out,
bool *success) {
198 carry_out =
Bit32(value, 0);
199 return Bit32(carry_in, 0) << 31 |
Bits32(value, 31, 1);
202static inline uint32_t
RRX(
const uint32_t value,
const uint32_t carry_in,
206 uint32_t result =
RRX_C(value, carry_in, dont_care, success);
214 const uint32_t amount,
const uint32_t carry_in,
215 uint32_t &carry_out,
bool *success) {
223 carry_out = carry_in;
229 result =
LSL_C(value, amount, carry_out, success);
232 result =
LSR_C(value, amount, carry_out, success);
235 result =
ASR_C(value, amount, carry_out, success);
238 result =
ROR_C(value, amount, carry_out, success);
241 result =
RRX_C(value, carry_in, carry_out, success);
254 const uint32_t amount,
const uint32_t carry_in,
258 uint32_t result =
Shift_C(value, type, amount, carry_in, dont_care, success);
265static inline uint32_t
bits(
const uint32_t val,
const uint32_t msbit,
266 const uint32_t lsbit) {
267 return Bits32(val, msbit, lsbit);
270static inline uint32_t
bit(
const uint32_t val,
const uint32_t msbit) {
271 return bits(val, msbit, msbit);
274static uint32_t
ror(uint32_t val, uint32_t N, uint32_t shift) {
275 uint32_t m = shift % N;
276 return (val >> m) | (val << (N - m));
281 uint32_t &carry_out) {
283 uint32_t imm =
bits(opcode, 7, 0);
284 uint32_t amt = 2 *
bits(opcode, 11, 8);
287 carry_out = carry_in;
289 imm32 =
ror(imm, 32, amt);
290 carry_out =
Bit32(imm32, 31);
298 uint32_t carry_in = 0;
305 uint32_t &carry_out) {
307 const uint32_t i =
bit(opcode, 26);
308 const uint32_t imm3 =
bits(opcode, 14, 12);
309 const uint32_t abcdefgh =
bits(opcode, 7, 0);
310 const uint32_t imm12 = i << 11 | imm3 << 8 | abcdefgh;
312 if (
bits(imm12, 11, 10) == 0) {
313 switch (
bits(imm12, 9, 8)) {
322 imm32 = abcdefgh << 16 | abcdefgh;
326 imm32 = abcdefgh << 24 | abcdefgh << 8;
330 imm32 = abcdefgh << 24 | abcdefgh << 16 | abcdefgh << 8 | abcdefgh;
333 carry_out = carry_in;
335 const uint32_t unrotated_value = 0x80 |
bits(imm12, 6, 0);
336 imm32 =
ror(unrotated_value, 32,
bits(imm12, 11, 7));
337 carry_out =
Bit32(imm32, 31);
345 uint32_t carry_in = 0;
352 const uint32_t i =
bit(opcode, 26);
353 const uint32_t imm3 =
bits(opcode, 14, 12);
354 const uint32_t imm8 =
bits(opcode, 7, 0);
355 const uint32_t imm12 = i << 11 | imm3 << 8 | imm8;
361 const uint32_t imm7 =
bits(opcode, 6, 0);
367 const uint32_t imm8 =
bits(opcode, 7, 0);
373static inline bool BadReg(uint32_t n) {
return n == 13 || n == 15; }
A class that represents a running process on the host machine.
static uint32_t LSR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
static uint32_t ThumbExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t &carry_out)
static uint32_t DecodeImmShift(const uint32_t type, const uint32_t imm5, ARM_ShifterType &shift_t)
static uint32_t ARMExpandImm(uint32_t opcode)
static uint32_t ASR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
static uint32_t LSL(const uint32_t value, const uint32_t amount, bool *success)
static uint32_t LSL_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
static uint32_t DecodeImmShiftARM(const uint32_t opcode, ARM_ShifterType &shift_t)
static uint32_t ThumbExpandImm(uint32_t opcode)
static uint32_t ROR(const uint32_t value, const uint32_t amount, bool *success)
static uint32_t ThumbImm12(uint32_t opcode)
static uint32_t LSR(const uint32_t value, const uint32_t amount, bool *success)
static 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)
static uint32_t ThumbImm8Scaled(uint32_t opcode)
static uint32_t Shift(const uint32_t value, ARM_ShifterType type, const uint32_t amount, const uint32_t carry_in, bool *success)
static uint32_t ThumbImm7Scaled(uint32_t opcode)
static bool BitIsSet(const uint64_t value, const uint64_t bit)
static uint32_t ARMExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t &carry_out)
static uint32_t RRX_C(const uint32_t value, const uint32_t carry_in, uint32_t &carry_out, bool *success)
static uint32_t ROR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
static uint32_t DecodeImmShiftThumb(const uint32_t opcode, ARM_ShifterType &shift_t)
static uint32_t Align(uint32_t val, uint32_t alignment)
static bool BadReg(uint32_t n)
static uint32_t RRX(const uint32_t value, const uint32_t carry_in, bool *success)
static uint64_t UnsignedBits(const uint64_t value, const uint64_t msbit, const uint64_t lsbit)
static ARM_ShifterType DecodeRegShift(const uint32_t type)
static uint32_t ror(uint32_t val, uint32_t N, uint32_t shift)
static uint32_t Bits32(const uint32_t bits, const uint32_t msbit, const uint32_t lsbit)
static uint32_t ASR(const uint32_t value, const uint32_t amount, bool *success)
static uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
static uint32_t Bit32(const uint32_t bits, const uint32_t bit)