blob: e81de10b905a925fef3e7e0f1e347b3751f41741 [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 Chen108d5aa2011-01-26 01:00:55 +000013#include "InstructionUtils.h"
14
Johnny Chenc3b5bc32011-01-24 19:50:30 +000015// Common utilities for the ARM/Thumb Instruction Set Architecture.
Johnny Chen4baf2e32011-01-24 18:24:53 +000016
17namespace lldb_private {
18
Johnny Chen4c0e0bc2011-01-25 22:45:28 +000019static inline uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
20{
Johnny Chen108d5aa2011-01-26 01:00:55 +000021 return Bits32(val, msbit, lsbit);
Johnny Chen4c0e0bc2011-01-25 22:45:28 +000022}
23
24static inline uint32_t bit(const uint32_t val, const uint32_t msbit)
25{
26 return bits(val, msbit, msbit);
27}
28
Johnny Chen60c0d622011-01-25 23:49:39 +000029static uint32_t ror(uint32_t val, uint32_t N, uint32_t shift)
Johnny Chen4c0e0bc2011-01-25 22:45:28 +000030{
Johnny Chen60c0d622011-01-25 23:49:39 +000031 uint32_t m = shift % N;
32 return (val >> m) | (val << (N - m));
33}
34
35static inline uint32_t ARMExpandImm(uint32_t val)
36{
37 uint32_t imm = bits(val, 7, 0); // immediate value
38 uint32_t rot = 2 * bits(val, 11, 8); // rotate amount
Johnny Chen4c0e0bc2011-01-25 22:45:28 +000039 return (imm >> rot) | (imm << (32 - rot));
40}
41
Johnny Chen60c0d622011-01-25 23:49:39 +000042static inline uint32_t ThumbExpandImm(uint32_t val)
Johnny Chen4c0e0bc2011-01-25 22:45:28 +000043{
Johnny Chen60c0d622011-01-25 23:49:39 +000044 uint32_t imm32 = 0;
45 const uint32_t i = bit(val, 26);
46 const uint32_t imm3 = bits(val, 14, 12);
47 const uint32_t abcdefgh = bits(val, 7, 0);
48 const uint32_t imm12 = i << 11 | imm3 << 8 | abcdefgh;
49
50 if (bits(imm12, 10, 11) == 0)
51 {
52 switch (bits(imm12, 8, 9)) {
53 case 0:
54 imm32 = abcdefgh;
55 break;
56
57 case 1:
58 imm32 = abcdefgh << 16 | abcdefgh;
59 break;
60
61 case 2:
62 imm32 = abcdefgh << 24 | abcdefgh << 8;
63 break;
64
65 case 3:
66 imm32 = abcdefgh << 24 | abcdefgh << 16 | abcdefgh << 8 | abcdefgh;
67 break;
68 }
69 }
70 else
71 {
72 const uint32_t unrotated_value = 0x80 | bits(imm12, 0, 6);
73 imm32 = ror(unrotated_value, 32, bits(imm12, 7, 11));
74 }
75 return imm32;
76}
77
78// imm32 = ZeroExtend(i:imm3:imm8, 32)
79static inline uint32_t ThumbImm12(uint32_t val)
80{
81 const uint32_t i = bit(val, 26);
82 const uint32_t imm3 = bits(val, 14, 12);
83 const uint32_t imm8 = bits(val, 7, 0);
84 const uint32_t imm12 = i << 11 | imm3 << 8 | imm8;
85 return imm12;
Johnny Chen4c0e0bc2011-01-25 22:45:28 +000086}
87
Johnny Chene4455022011-01-26 00:08:59 +000088// imm32 = ZeroExtend(imm7:'00', 32)
89static inline uint32_t ThumbImmScaled(uint32_t val)
90{
91 const uint32_t imm7 = bits(val, 6, 0);
92 return imm7 * 4;
93}
94
Johnny Chen4baf2e32011-01-24 18:24:53 +000095// This function performs the check for the register numbers 13 and 15 that are
96// not permitted for many Thumb register specifiers.
97static inline bool BadReg(uint32_t n) { return n == 13 || n == 15; }
98
Johnny Chen4baf2e32011-01-24 18:24:53 +000099} // namespace lldb_private
100
101#endif // lldb_ARMUtils_h_