1 // Copyright 2006 The Android Open Source Project
2
3 #ifndef OPCODE_H
4 #define OPCODE_H
5
6 #include <inttypes.h>
7
8 // Note: this list of opcodes must match the list used to initialize
9 // the opflags[] array in opcode.cpp.
10 enum Opcode {
11 OP_INVALID,
12 OP_UNDEFINED,
13 OP_ADC,
14 OP_ADD,
15 OP_AND,
16 OP_B,
17 OP_BL,
18 OP_BIC,
19 OP_BKPT,
20 OP_BLX,
21 OP_BX,
22 OP_CDP,
23 OP_CLZ,
24 OP_CMN,
25 OP_CMP,
26 OP_EOR,
27 OP_LDC,
28 OP_LDM,
29 OP_LDR,
30 OP_LDRB,
31 OP_LDRBT,
32 OP_LDRH,
33 OP_LDRSB,
34 OP_LDRSH,
35 OP_LDRT,
36 OP_MCR,
37 OP_MLA,
38 OP_MOV,
39 OP_MRC,
40 OP_MRS,
41 OP_MSR,
42 OP_MUL,
43 OP_MVN,
44 OP_ORR,
45 OP_PLD,
46 OP_RSB,
47 OP_RSC,
48 OP_SBC,
49 OP_SMLAL,
50 OP_SMULL,
51 OP_STC,
52 OP_STM,
53 OP_STR,
54 OP_STRB,
55 OP_STRBT,
56 OP_STRH,
57 OP_STRT,
58 OP_SUB,
59 OP_SWI,
60 OP_SWP,
61 OP_SWPB,
62 OP_TEQ,
63 OP_TST,
64 OP_UMLAL,
65 OP_UMULL,
66
67 // Define thumb opcodes
68 OP_THUMB_UNDEFINED,
69 OP_THUMB_ADC,
70 OP_THUMB_ADD,
71 OP_THUMB_AND,
72 OP_THUMB_ASR,
73 OP_THUMB_B,
74 OP_THUMB_BIC,
75 OP_THUMB_BKPT,
76 OP_THUMB_BL,
77 OP_THUMB_BLX,
78 OP_THUMB_BX,
79 OP_THUMB_CMN,
80 OP_THUMB_CMP,
81 OP_THUMB_EOR,
82 OP_THUMB_LDMIA,
83 OP_THUMB_LDR,
84 OP_THUMB_LDRB,
85 OP_THUMB_LDRH,
86 OP_THUMB_LDRSB,
87 OP_THUMB_LDRSH,
88 OP_THUMB_LSL,
89 OP_THUMB_LSR,
90 OP_THUMB_MOV,
91 OP_THUMB_MUL,
92 OP_THUMB_MVN,
93 OP_THUMB_NEG,
94 OP_THUMB_ORR,
95 OP_THUMB_POP,
96 OP_THUMB_PUSH,
97 OP_THUMB_ROR,
98 OP_THUMB_SBC,
99 OP_THUMB_STMIA,
100 OP_THUMB_STR,
101 OP_THUMB_STRB,
102 OP_THUMB_STRH,
103 OP_THUMB_SUB,
104 OP_THUMB_SWI,
105 OP_THUMB_TST,
106
107 OP_END // must be last
108 };
109
110 extern uint32_t opcode_flags[];
111 extern const char *opcode_names[];
112
113 // Define bit flags for the opcode categories
114 static const uint32_t kCatByte = 0x0001;
115 static const uint32_t kCatHalf = 0x0002;
116 static const uint32_t kCatWord = 0x0004;
117 static const uint32_t kCatLong = 0x0008;
118 static const uint32_t kCatNumBytes = (kCatByte | kCatHalf | kCatWord | kCatLong);
119 static const uint32_t kCatMultiple = 0x0010;
120 static const uint32_t kCatSigned = 0x0020;
121 static const uint32_t kCatLoad = 0x0040;
122 static const uint32_t kCatStore = 0x0080;
123 static const uint32_t kCatMemoryRef = (kCatLoad | kCatStore);
124 static const uint32_t kCatAlu = 0x0100;
125 static const uint32_t kCatBranch = 0x0200;
126 static const uint32_t kCatBranchLink = 0x0400;
127 static const uint32_t kCatBranchExch = 0x0800;
128 static const uint32_t kCatCoproc = 0x1000;
129 static const uint32_t kCatLoadMultiple = (kCatLoad | kCatMultiple);
130 static const uint32_t kCatStoreMultiple = (kCatStore | kCatMultiple);
131
isALU(Opcode op)132 inline bool isALU(Opcode op) { return (opcode_flags[op] & kCatAlu) != 0; }
isBranch(Opcode op)133 inline bool isBranch(Opcode op) { return (opcode_flags[op] & kCatBranch) != 0; }
isBranchLink(Opcode op)134 inline bool isBranchLink(Opcode op) {
135 return (opcode_flags[op] & kCatBranchLink) != 0;
136 }
isBranchExch(Opcode op)137 inline bool isBranchExch(Opcode op) {
138 return (opcode_flags[op] & kCatBranchExch) != 0;
139 }
isLoad(Opcode op)140 inline bool isLoad(Opcode op) { return (opcode_flags[op] & kCatLoad) != 0; }
isLoadMultiple(Opcode op)141 inline bool isLoadMultiple(Opcode op) {
142 return (opcode_flags[op] & kCatLoadMultiple) == kCatLoadMultiple;
143 }
isStoreMultiple(Opcode op)144 inline bool isStoreMultiple(Opcode op) {
145 return (opcode_flags[op] & kCatStoreMultiple) == kCatStoreMultiple;
146 }
isStore(Opcode op)147 inline bool isStore(Opcode op) { return (opcode_flags[op] & kCatStore) != 0; }
isSigned(Opcode op)148 inline bool isSigned(Opcode op) { return (opcode_flags[op] & kCatSigned) != 0; }
isMemoryRef(Opcode op)149 inline bool isMemoryRef(Opcode op) {
150 return (opcode_flags[op] & kCatMemoryRef) != 0;
151 }
getAccessSize(Opcode op)152 inline int getAccessSize(Opcode op) { return opcode_flags[op] & kCatNumBytes; }
isCoproc(Opcode op)153 inline bool isCoproc(Opcode op) { return (opcode_flags[op] & kCatCoproc) != 0; }
getNumAccesses(Opcode op,uint32_t binary)154 inline int getNumAccesses(Opcode op, uint32_t binary) {
155 extern int num_one_bits[];
156 int num_accesses = 0;
157 if (opcode_flags[op] & kCatNumBytes)
158 num_accesses = 1;
159 else if (opcode_flags[op] & kCatMultiple) {
160 num_accesses = num_one_bits[(binary >> 8) & 0xff]
161 + num_one_bits[binary & 0xff];
162 }
163 return num_accesses;
164 }
165
166 #endif // OPCODE_H
167