blob: 772bd4d99147191ff73a365cdaf9470d1e3ec415 [file] [log] [blame]
Johnny Chen4baf2e32011-01-24 18:24:53 +00001//===-- lldb_ARMUtils.h -----------------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef lldb_ARMUtils_h_
11#define lldb_ARMUtils_h_
12
Johnny Chenc3b5bc32011-01-24 19:50:30 +000013// Common utilities for the ARM/Thumb Instruction Set Architecture.
Johnny Chen4baf2e32011-01-24 18:24:53 +000014
15namespace lldb_private {
16
Johnny Chenc3b5bc32011-01-24 19:50:30 +000017// ARM conditions
18#define COND_EQ 0x0
19#define COND_NE 0x1
20#define COND_CS 0x2
21#define COND_HS 0x2
22#define COND_CC 0x3
23#define COND_LO 0x3
24#define COND_MI 0x4
25#define COND_PL 0x5
26#define COND_VS 0x6
27#define COND_VC 0x7
28#define COND_HI 0x8
29#define COND_LS 0x9
30#define COND_GE 0xA
31#define COND_LT 0xB
32#define COND_GT 0xC
33#define COND_LE 0xD
34#define COND_AL 0xE
35#define COND_UNCOND 0xF
36
37// Masks for CPSR
38#define MASK_CPSR_MODE_MASK (0x0000001fu)
39#define MASK_CPSR_T (1u << 5)
40#define MASK_CPSR_F (1u << 6)
41#define MASK_CPSR_I (1u << 7)
42#define MASK_CPSR_A (1u << 8)
43#define MASK_CPSR_E (1u << 9)
44#define MASK_CPSR_GE_MASK (0x000f0000u)
45#define MASK_CPSR_J (1u << 24)
46#define MASK_CPSR_Q (1u << 27)
47#define MASK_CPSR_V (1u << 28)
48#define MASK_CPSR_C (1u << 29)
49#define MASK_CPSR_Z (1u << 30)
50#define MASK_CPSR_N (1u << 31)
51
52
Johnny Chen4c0e0bc2011-01-25 22:45:28 +000053static inline uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
54{
55 assert(msbit < 32 && lsbit <= msbit);
56 return (val >> lsbit) & ((1u << (msbit - lsbit + 1)) - 1);
57}
58
59static inline uint32_t bit(const uint32_t val, const uint32_t msbit)
60{
61 return bits(val, msbit, msbit);
62}
63
Johnny Chen60c0d622011-01-25 23:49:39 +000064static uint32_t ror(uint32_t val, uint32_t N, uint32_t shift)
Johnny Chen4c0e0bc2011-01-25 22:45:28 +000065{
Johnny Chen60c0d622011-01-25 23:49:39 +000066 uint32_t m = shift % N;
67 return (val >> m) | (val << (N - m));
68}
69
70static inline uint32_t ARMExpandImm(uint32_t val)
71{
72 uint32_t imm = bits(val, 7, 0); // immediate value
73 uint32_t rot = 2 * bits(val, 11, 8); // rotate amount
Johnny Chen4c0e0bc2011-01-25 22:45:28 +000074 return (imm >> rot) | (imm << (32 - rot));
75}
76
Johnny Chen60c0d622011-01-25 23:49:39 +000077static inline uint32_t ThumbExpandImm(uint32_t val)
Johnny Chen4c0e0bc2011-01-25 22:45:28 +000078{
Johnny Chen60c0d622011-01-25 23:49:39 +000079 uint32_t imm32 = 0;
80 const uint32_t i = bit(val, 26);
81 const uint32_t imm3 = bits(val, 14, 12);
82 const uint32_t abcdefgh = bits(val, 7, 0);
83 const uint32_t imm12 = i << 11 | imm3 << 8 | abcdefgh;
84
85 if (bits(imm12, 10, 11) == 0)
86 {
87 switch (bits(imm12, 8, 9)) {
88 case 0:
89 imm32 = abcdefgh;
90 break;
91
92 case 1:
93 imm32 = abcdefgh << 16 | abcdefgh;
94 break;
95
96 case 2:
97 imm32 = abcdefgh << 24 | abcdefgh << 8;
98 break;
99
100 case 3:
101 imm32 = abcdefgh << 24 | abcdefgh << 16 | abcdefgh << 8 | abcdefgh;
102 break;
103 }
104 }
105 else
106 {
107 const uint32_t unrotated_value = 0x80 | bits(imm12, 0, 6);
108 imm32 = ror(unrotated_value, 32, bits(imm12, 7, 11));
109 }
110 return imm32;
111}
112
113// imm32 = ZeroExtend(i:imm3:imm8, 32)
114static inline uint32_t ThumbImm12(uint32_t val)
115{
116 const uint32_t i = bit(val, 26);
117 const uint32_t imm3 = bits(val, 14, 12);
118 const uint32_t imm8 = bits(val, 7, 0);
119 const uint32_t imm12 = i << 11 | imm3 << 8 | imm8;
120 return imm12;
Johnny Chen4c0e0bc2011-01-25 22:45:28 +0000121}
122
Johnny Chene4455022011-01-26 00:08:59 +0000123// imm32 = ZeroExtend(imm7:'00', 32)
124static inline uint32_t ThumbImmScaled(uint32_t val)
125{
126 const uint32_t imm7 = bits(val, 6, 0);
127 return imm7 * 4;
128}
129
Johnny Chen4baf2e32011-01-24 18:24:53 +0000130// This function performs the check for the register numbers 13 and 15 that are
131// not permitted for many Thumb register specifiers.
132static inline bool BadReg(uint32_t n) { return n == 13 || n == 15; }
133
Johnny Chen7dc60e12011-01-24 19:46:32 +0000134// Returns an integer result equal to the number of bits of x that are ones.
135static inline uint32_t BitCount(uint32_t x)
136{
137 // c accumulates the total bits set in x
138 uint32_t c;
139 for (c = 0; x; ++c)
140 {
141 x &= x - 1; // clear the least significant bit set
142 }
143 return c;
144}
145
Johnny Chen4baf2e32011-01-24 18:24:53 +0000146} // namespace lldb_private
147
148#endif // lldb_ARMUtils_h_