1254721Semaste//===-- ARMUtils.h ----------------------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#ifndef lldb_ARMUtils_h_
11254721Semaste#define lldb_ARMUtils_h_
12254721Semaste
13254721Semaste#include "ARMDefines.h"
14254721Semaste#include "InstructionUtils.h"
15254721Semaste#include "llvm/Support/MathExtras.h" // for SignExtend64 template function
16254721Semaste
17254721Semaste// Common utilities for the ARM/Thumb Instruction Set Architecture.
18254721Semaste
19254721Semastenamespace lldb_private {
20254721Semaste
21254721Semastestatic inline uint32_t Align(uint32_t val, uint32_t alignment)
22254721Semaste{
23254721Semaste    return alignment * (val / alignment);
24254721Semaste}
25254721Semaste
26254721Semastestatic inline uint32_t DecodeImmShift(const uint32_t type, const uint32_t imm5, ARM_ShifterType &shift_t)
27254721Semaste{
28254721Semaste    switch (type)
29254721Semaste    {
30254721Semaste    default:
31254721Semaste        //assert(0 && "Invalid shift type");
32254721Semaste    case 0:
33254721Semaste        shift_t = SRType_LSL;
34254721Semaste        return imm5;
35254721Semaste    case 1:
36254721Semaste        shift_t = SRType_LSR;
37254721Semaste        return (imm5 == 0 ? 32 : imm5);
38254721Semaste    case 2:
39254721Semaste        shift_t = SRType_ASR;
40254721Semaste        return (imm5 == 0 ? 32 : imm5);
41254721Semaste    case 3:
42254721Semaste        if (imm5 == 0)
43254721Semaste        {
44254721Semaste            shift_t = SRType_RRX;
45254721Semaste            return 1;
46254721Semaste        }
47254721Semaste        else
48254721Semaste        {
49254721Semaste            shift_t = SRType_ROR;
50254721Semaste            return imm5;
51254721Semaste        }
52254721Semaste    }
53254721Semaste    shift_t = SRType_Invalid;
54254721Semaste    return UINT32_MAX;
55254721Semaste
56254721Semaste}
57254721Semaste
58254721Semaste// A8.6.35 CMP (register) -- Encoding T3
59254721Semaste// Convenience function.
60254721Semastestatic inline uint32_t DecodeImmShiftThumb(const uint32_t opcode, ARM_ShifterType &shift_t)
61254721Semaste{
62254721Semaste    return DecodeImmShift(Bits32(opcode, 5, 4), Bits32(opcode, 14, 12)<<2 | Bits32(opcode, 7, 6), shift_t);
63254721Semaste}
64254721Semaste
65254721Semaste// A8.6.35 CMP (register) -- Encoding A1
66254721Semaste// Convenience function.
67254721Semastestatic inline uint32_t DecodeImmShiftARM(const uint32_t opcode, ARM_ShifterType &shift_t)
68254721Semaste{
69254721Semaste    return DecodeImmShift(Bits32(opcode, 6, 5), Bits32(opcode, 11, 7), shift_t);
70254721Semaste}
71254721Semaste
72254721Semastestatic inline uint32_t DecodeImmShift(const ARM_ShifterType shift_t, const uint32_t imm5)
73254721Semaste{
74254721Semaste    ARM_ShifterType dont_care;
75254721Semaste    return DecodeImmShift(shift_t, imm5, dont_care);
76254721Semaste}
77254721Semaste
78254721Semastestatic inline ARM_ShifterType DecodeRegShift(const uint32_t type)
79254721Semaste{
80254721Semaste    switch (type) {
81254721Semaste    default:
82254721Semaste        //assert(0 && "Invalid shift type");
83254721Semaste        return SRType_Invalid;
84254721Semaste    case 0:
85254721Semaste        return SRType_LSL;
86254721Semaste    case 1:
87254721Semaste        return SRType_LSR;
88254721Semaste    case 2:
89254721Semaste        return SRType_ASR;
90254721Semaste    case 3:
91254721Semaste        return SRType_ROR;
92254721Semaste    }
93254721Semaste}
94254721Semaste
95254721Semastestatic inline uint32_t LSL_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
96254721Semaste{
97254721Semaste    if (amount == 0) {
98254721Semaste        *success = false;
99254721Semaste        return 0;
100254721Semaste    }
101254721Semaste    *success = true;
102254721Semaste    carry_out = amount <= 32 ? Bit32(value, 32 - amount) : 0;
103254721Semaste    return value << amount;
104254721Semaste}
105254721Semaste
106254721Semastestatic inline uint32_t LSL(const uint32_t value, const uint32_t amount, bool *success)
107254721Semaste{
108254721Semaste    *success = true;
109254721Semaste    if (amount == 0)
110254721Semaste        return value;
111254721Semaste    uint32_t dont_care;
112254721Semaste    uint32_t result = LSL_C(value, amount, dont_care, success);
113254721Semaste    if (*success)
114254721Semaste        return result;
115254721Semaste    else
116254721Semaste        return 0;
117254721Semaste}
118254721Semaste
119254721Semastestatic inline uint32_t LSR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
120254721Semaste{
121254721Semaste    if (amount == 0) {
122254721Semaste        *success = false;
123254721Semaste        return 0;
124254721Semaste    }
125254721Semaste    *success = true;
126254721Semaste    carry_out = amount <= 32 ? Bit32(value, amount - 1) : 0;
127254721Semaste    return value >> amount;
128254721Semaste}
129254721Semaste
130254721Semastestatic inline uint32_t LSR(const uint32_t value, const uint32_t amount, bool *success)
131254721Semaste{
132254721Semaste    *success = true;
133254721Semaste    if (amount == 0)
134254721Semaste        return value;
135254721Semaste    uint32_t dont_care;
136254721Semaste    uint32_t result = LSR_C(value, amount, dont_care, success);
137254721Semaste    if (*success)
138254721Semaste        return result;
139254721Semaste    else
140254721Semaste        return 0;
141254721Semaste}
142254721Semaste
143254721Semastestatic inline uint32_t ASR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
144254721Semaste{
145254721Semaste    if (amount == 0 || amount > 32) {
146254721Semaste        *success = false;
147254721Semaste        return 0;
148254721Semaste    }
149254721Semaste    *success = true;
150254721Semaste    bool negative = BitIsSet(value, 31);
151254721Semaste    if (amount <= 32)
152254721Semaste    {
153254721Semaste        carry_out = Bit32(value, amount - 1);
154254721Semaste        int64_t extended = llvm::SignExtend64<32>(value);
155254721Semaste        return UnsignedBits(extended, amount + 31, amount);
156254721Semaste    }
157254721Semaste    else
158254721Semaste    {
159254721Semaste        carry_out = (negative ? 1 : 0);
160254721Semaste        return (negative ? 0xffffffff : 0);
161254721Semaste    }
162254721Semaste}
163254721Semaste
164254721Semastestatic inline uint32_t ASR(const uint32_t value, const uint32_t amount, bool *success)
165254721Semaste{
166254721Semaste    *success = true;
167254721Semaste    if (amount == 0)
168254721Semaste        return value;
169254721Semaste    uint32_t dont_care;
170254721Semaste    uint32_t result = ASR_C(value, amount, dont_care, success);
171254721Semaste    if (*success)
172254721Semaste        return result;
173254721Semaste    else
174254721Semaste        return 0;
175254721Semaste}
176254721Semaste
177254721Semastestatic inline uint32_t ROR_C(const uint32_t value, const uint32_t amount, uint32_t &carry_out, bool *success)
178254721Semaste{
179254721Semaste    if (amount == 0) {
180254721Semaste        *success = false;
181254721Semaste        return 0;
182254721Semaste    }
183254721Semaste    *success = true;
184254721Semaste    uint32_t amt = amount % 32;
185254721Semaste    uint32_t result = Rotr32(value, amt);
186254721Semaste    carry_out = Bit32(value, 31);
187254721Semaste    return result;
188254721Semaste}
189254721Semaste
190254721Semastestatic inline uint32_t ROR(const uint32_t value, const uint32_t amount, bool *success)
191254721Semaste{
192254721Semaste    *success = true;
193254721Semaste    if (amount == 0)
194254721Semaste        return value;
195254721Semaste    uint32_t dont_care;
196254721Semaste    uint32_t result = ROR_C(value, amount, dont_care, success);
197254721Semaste    if (*success)
198254721Semaste        return result;
199254721Semaste    else
200254721Semaste        return 0;
201254721Semaste}
202254721Semaste
203254721Semastestatic inline uint32_t RRX_C(const uint32_t value, const uint32_t carry_in, uint32_t &carry_out, bool *success)
204254721Semaste{
205254721Semaste    *success = true;
206254721Semaste    carry_out = Bit32(value, 0);
207254721Semaste    return Bit32(carry_in, 0) << 31 | Bits32(value, 31, 1);
208254721Semaste}
209254721Semaste
210254721Semastestatic inline uint32_t RRX(const uint32_t value, const uint32_t carry_in, bool *success)
211254721Semaste{
212254721Semaste    *success = true;
213254721Semaste    uint32_t dont_care;
214254721Semaste    uint32_t result = RRX_C(value, carry_in, dont_care, success);
215254721Semaste    if (*success)
216254721Semaste        return result;
217254721Semaste    else
218254721Semaste        return 0;
219254721Semaste}
220254721Semaste
221254721Semastestatic inline uint32_t Shift_C(const uint32_t value, ARM_ShifterType type, const uint32_t amount,
222254721Semaste                               const uint32_t carry_in, uint32_t &carry_out, bool *success)
223254721Semaste{
224254721Semaste    if (type == SRType_RRX && amount != 1) {
225254721Semaste        *success = false;
226254721Semaste        return 0;
227254721Semaste    }
228254721Semaste    *success = true;
229254721Semaste
230254721Semaste    if (amount == 0) {
231254721Semaste        carry_out = carry_in;
232254721Semaste        return value;
233254721Semaste    }
234254721Semaste    uint32_t result;
235254721Semaste    switch (type) {
236254721Semaste    case SRType_LSL:
237254721Semaste        result = LSL_C(value, amount, carry_out, success);
238254721Semaste        break;
239254721Semaste    case SRType_LSR:
240254721Semaste        result = LSR_C(value, amount, carry_out, success);
241254721Semaste        break;
242254721Semaste    case SRType_ASR:
243254721Semaste        result = ASR_C(value, amount, carry_out, success);
244254721Semaste        break;
245254721Semaste    case SRType_ROR:
246254721Semaste        result = ROR_C(value, amount, carry_out, success);
247254721Semaste        break;
248254721Semaste    case SRType_RRX:
249254721Semaste        result = RRX_C(value, carry_in, carry_out, success);
250254721Semaste        break;
251254721Semaste    default:
252254721Semaste        *success = false;
253254721Semaste        break;
254254721Semaste    }
255254721Semaste    if (*success)
256254721Semaste        return result;
257254721Semaste    else
258254721Semaste        return 0;
259254721Semaste}
260254721Semaste
261254721Semastestatic inline uint32_t Shift(const uint32_t value, ARM_ShifterType type, const uint32_t amount,
262254721Semaste                             const uint32_t carry_in, bool *success)
263254721Semaste{
264254721Semaste    // Don't care about carry out in this case.
265254721Semaste    uint32_t dont_care;
266254721Semaste    uint32_t result = Shift_C(value, type, amount, carry_in, dont_care, success);
267254721Semaste    if (*success)
268254721Semaste        return result;
269254721Semaste    else
270254721Semaste        return 0;
271254721Semaste}
272254721Semaste
273254721Semastestatic inline uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
274254721Semaste{
275254721Semaste    return Bits32(val, msbit, lsbit);
276254721Semaste}
277254721Semaste
278254721Semastestatic inline uint32_t bit(const uint32_t val, const uint32_t msbit)
279254721Semaste{
280254721Semaste    return bits(val, msbit, msbit);
281254721Semaste}
282254721Semaste
283254721Semastestatic uint32_t ror(uint32_t val, uint32_t N, uint32_t shift)
284254721Semaste{
285254721Semaste    uint32_t m = shift % N;
286254721Semaste    return (val >> m) | (val << (N - m));
287254721Semaste}
288254721Semaste
289254721Semaste// (imm32, carry_out) = ARMExpandImm_C(imm12, carry_in)
290254721Semastestatic inline uint32_t ARMExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t &carry_out)
291254721Semaste{
292254721Semaste    uint32_t imm32;                         // the expanded result
293254721Semaste    uint32_t imm = bits(opcode, 7, 0);      // immediate value
294254721Semaste    uint32_t amt = 2 * bits(opcode, 11, 8); // rotate amount
295254721Semaste    if (amt == 0)
296254721Semaste    {
297254721Semaste        imm32 = imm;
298254721Semaste        carry_out = carry_in;
299254721Semaste    }
300254721Semaste    else
301254721Semaste    {
302254721Semaste        imm32 = ror(imm, 32, amt);
303254721Semaste        carry_out = Bit32(imm32, 31);
304254721Semaste    }
305254721Semaste    return imm32;
306254721Semaste}
307254721Semaste
308254721Semastestatic inline uint32_t ARMExpandImm(uint32_t opcode)
309254721Semaste{
310254721Semaste    // 'carry_in' argument to following function call does not affect the imm32 result.
311254721Semaste    uint32_t carry_in = 0;
312254721Semaste    uint32_t carry_out;
313254721Semaste    return ARMExpandImm_C(opcode, carry_in, carry_out);
314254721Semaste}
315254721Semaste
316254721Semaste// (imm32, carry_out) = ThumbExpandImm_C(imm12, carry_in)
317254721Semastestatic inline uint32_t ThumbExpandImm_C(uint32_t opcode, uint32_t carry_in, uint32_t &carry_out)
318254721Semaste{
319254721Semaste    uint32_t imm32; // the expaned result
320254721Semaste    const uint32_t i = bit(opcode, 26);
321254721Semaste    const uint32_t imm3 = bits(opcode, 14, 12);
322254721Semaste    const uint32_t abcdefgh = bits(opcode, 7, 0);
323254721Semaste    const uint32_t imm12 = i << 11 | imm3 << 8 | abcdefgh;
324254721Semaste
325254721Semaste    if (bits(imm12, 11, 10) == 0)
326254721Semaste    {
327254721Semaste        switch (bits(imm12, 9, 8)) {
328254721Semaste        default: // Keep static analyzer happy with a default case
329254721Semaste        case 0:
330254721Semaste            imm32 = abcdefgh;
331254721Semaste            break;
332254721Semaste
333254721Semaste        case 1:
334254721Semaste            imm32 = abcdefgh << 16 | abcdefgh;
335254721Semaste            break;
336254721Semaste
337254721Semaste        case 2:
338254721Semaste            imm32 = abcdefgh << 24 | abcdefgh << 8;
339254721Semaste            break;
340254721Semaste
341254721Semaste        case 3:
342254721Semaste            imm32 = abcdefgh  << 24 | abcdefgh << 16 | abcdefgh << 8 | abcdefgh;
343254721Semaste            break;
344254721Semaste        }
345254721Semaste        carry_out = carry_in;
346254721Semaste    }
347254721Semaste    else
348254721Semaste    {
349254721Semaste        const uint32_t unrotated_value = 0x80 | bits(imm12, 6, 0);
350254721Semaste        imm32 = ror(unrotated_value, 32, bits(imm12, 11, 7));
351254721Semaste        carry_out = Bit32(imm32, 31);
352254721Semaste    }
353254721Semaste    return imm32;
354254721Semaste}
355254721Semaste
356254721Semastestatic inline uint32_t ThumbExpandImm(uint32_t opcode)
357254721Semaste{
358254721Semaste    // 'carry_in' argument to following function call does not affect the imm32 result.
359254721Semaste    uint32_t carry_in = 0;
360254721Semaste    uint32_t carry_out;
361254721Semaste    return ThumbExpandImm_C(opcode, carry_in, carry_out);
362254721Semaste}
363254721Semaste
364254721Semaste// imm32 = ZeroExtend(i:imm3:imm8, 32)
365254721Semastestatic inline uint32_t ThumbImm12(uint32_t opcode)
366254721Semaste{
367254721Semaste  const uint32_t i = bit(opcode, 26);
368254721Semaste  const uint32_t imm3 = bits(opcode, 14, 12);
369254721Semaste  const uint32_t imm8 = bits(opcode, 7, 0);
370254721Semaste  const uint32_t imm12 = i << 11 | imm3 << 8 | imm8;
371254721Semaste  return imm12;
372254721Semaste}
373254721Semaste
374254721Semaste// imm32 = ZeroExtend(imm7:'00', 32)
375254721Semastestatic inline uint32_t ThumbImm7Scaled(uint32_t opcode)
376254721Semaste{
377254721Semaste  const uint32_t imm7 = bits(opcode, 6, 0);
378254721Semaste  return imm7 * 4;
379254721Semaste}
380254721Semaste
381254721Semaste// imm32 = ZeroExtend(imm8:'00', 32)
382254721Semastestatic inline uint32_t ThumbImm8Scaled(uint32_t opcode)
383254721Semaste{
384254721Semaste  const uint32_t imm8 = bits(opcode, 7, 0);
385254721Semaste  return imm8 * 4;
386254721Semaste}
387254721Semaste
388254721Semaste// This function performs the check for the register numbers 13 and 15 that are
389254721Semaste// not permitted for many Thumb register specifiers.
390254721Semastestatic inline bool BadReg(uint32_t n) { return n == 13 || n == 15; }
391254721Semaste
392254721Semaste}   // namespace lldb_private
393254721Semaste
394254721Semaste#endif  // lldb_ARMUtils_h_
395