src/arm/decoder-arm.c (view raw)
1/* Copyright (c) 2013-2014 Jeffrey Pfau
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6#include <mgba/internal/arm/decoder.h>
7
8#include <mgba/internal/arm/decoder-inlines.h>
9#include <mgba/internal/arm/emitter-arm.h>
10#include <mgba/internal/arm/isa-inlines.h>
11
12#define ADDR_MODE_1_SHIFT(OP) \
13 info->op3.reg = opcode & 0x0000000F; \
14 info->op3.shifterOp = ARM_SHIFT_ ## OP; \
15 info->operandFormat |= ARM_OPERAND_REGISTER_3; \
16 if (opcode & 0x00000010) { \
17 info->op3.shifterReg = (opcode >> 8) & 0xF; \
18 ++info->iCycles; \
19 info->operandFormat |= ARM_OPERAND_SHIFT_REGISTER_3; \
20 } else { \
21 info->op3.shifterImm = (opcode >> 7) & 0x1F; \
22 info->operandFormat |= ARM_OPERAND_SHIFT_IMMEDIATE_3; \
23 }
24
25#define ADDR_MODE_1_LSL \
26 ADDR_MODE_1_SHIFT(LSL) \
27 if (!info->op3.shifterImm) { \
28 info->operandFormat &= ~ARM_OPERAND_SHIFT_IMMEDIATE_3; \
29 info->op3.shifterOp = ARM_SHIFT_NONE; \
30 }
31
32#define ADDR_MODE_1_LSR ADDR_MODE_1_SHIFT(LSR)
33#define ADDR_MODE_1_ASR ADDR_MODE_1_SHIFT(ASR)
34#define ADDR_MODE_1_ROR \
35 ADDR_MODE_1_SHIFT(ROR) \
36 if (!info->op3.shifterImm) { \
37 info->op3.shifterOp = ARM_SHIFT_RRX; \
38 }
39
40#define ADDR_MODE_1_IMM \
41 int rotate = (opcode & 0x00000F00) >> 7; \
42 int immediate = opcode & 0x000000FF; \
43 info->op3.immediate = ROR(immediate, rotate); \
44 info->operandFormat |= ARM_OPERAND_IMMEDIATE_3;
45
46#define ADDR_MODE_2_SHIFT(OP) \
47 info->memory.format |= ARM_MEMORY_REGISTER_OFFSET | ARM_MEMORY_SHIFTED_OFFSET; \
48 info->memory.offset.shifterOp = ARM_SHIFT_ ## OP; \
49 info->memory.offset.shifterImm = (opcode >> 7) & 0x1F; \
50 info->memory.offset.reg = opcode & 0x0000000F;
51
52#define ADDR_MODE_2_LSL \
53 ADDR_MODE_2_SHIFT(LSL) \
54 if (!info->memory.offset.shifterImm) { \
55 info->memory.format &= ~ARM_MEMORY_SHIFTED_OFFSET; \
56 info->memory.offset.shifterOp = ARM_SHIFT_NONE; \
57 }
58
59#define ADDR_MODE_2_LSR ADDR_MODE_2_SHIFT(LSR) \
60 if (!info->memory.offset.shifterImm) { \
61 info->memory.offset.shifterImm = 32; \
62 }
63
64#define ADDR_MODE_2_ASR ADDR_MODE_2_SHIFT(ASR) \
65 if (!info->memory.offset.shifterImm) { \
66 info->memory.offset.shifterImm = 32; \
67 }
68
69#define ADDR_MODE_2_ROR \
70 ADDR_MODE_2_SHIFT(ROR) \
71 if (!info->memory.offset.shifterImm) { \
72 info->memory.offset.shifterOp = ARM_SHIFT_RRX; \
73 }
74
75#define ADDR_MODE_2_IMM \
76 info->memory.format |= ARM_MEMORY_IMMEDIATE_OFFSET; \
77 info->memory.offset.immediate = opcode & 0x00000FFF;
78
79#define ADDR_MODE_3_REG \
80 info->memory.format |= ARM_MEMORY_REGISTER_OFFSET; \
81 info->memory.offset.reg = opcode & 0x0000000F;
82
83#define ADDR_MODE_3_IMM \
84 info->memory.format |= ARM_MEMORY_IMMEDIATE_OFFSET; \
85 info->memory.offset.immediate = (opcode & 0x0000000F) | ((opcode & 0x00000F00) >> 4);
86
87#define DEFINE_DECODER_ARM(NAME, MNEMONIC, BODY) \
88 static void _ARMDecode ## NAME (uint32_t opcode, struct ARMInstructionInfo* info) { \
89 UNUSED(opcode); \
90 info->mnemonic = ARM_MN_ ## MNEMONIC; \
91 BODY; \
92 }
93
94#define DEFINE_ALU_DECODER_EX_ARM(NAME, MNEMONIC, S, SHIFTER, OTHER_AFFECTED, SKIPPED) \
95 DEFINE_DECODER_ARM(NAME, MNEMONIC, \
96 info->op1.reg = (opcode >> 12) & 0xF; \
97 info->op2.reg = (opcode >> 16) & 0xF; \
98 info->operandFormat = ARM_OPERAND_REGISTER_1 | \
99 OTHER_AFFECTED | \
100 ARM_OPERAND_REGISTER_2; \
101 info->affectsCPSR = S; \
102 SHIFTER; \
103 if (SKIPPED == 1) { \
104 info->op1 = info->op2; \
105 info->op2 = info->op3; \
106 info->operandFormat >>= 8; \
107 } else if (SKIPPED == 2) { \
108 info->op2 = info->op3; \
109 info->operandFormat |= info->operandFormat >> 8; \
110 info->operandFormat &= ~ARM_OPERAND_3; \
111 } \
112 if (info->op1.reg == ARM_PC) { \
113 info->branchType = ARM_BRANCH_INDIRECT; \
114 })
115
116#define DEFINE_ALU_DECODER_ARM(NAME, SKIPPED) \
117 DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSL, NAME, 0, ADDR_MODE_1_LSL, ARM_OPERAND_AFFECTED_1, SKIPPED) \
118 DEFINE_ALU_DECODER_EX_ARM(NAME ## S_LSL, NAME, 1, ADDR_MODE_1_LSL, ARM_OPERAND_AFFECTED_1, SKIPPED) \
119 DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSR, NAME, 0, ADDR_MODE_1_LSR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
120 DEFINE_ALU_DECODER_EX_ARM(NAME ## S_LSR, NAME, 1, ADDR_MODE_1_LSR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
121 DEFINE_ALU_DECODER_EX_ARM(NAME ## _ASR, NAME, 0, ADDR_MODE_1_ASR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
122 DEFINE_ALU_DECODER_EX_ARM(NAME ## S_ASR, NAME, 1, ADDR_MODE_1_ASR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
123 DEFINE_ALU_DECODER_EX_ARM(NAME ## _ROR, NAME, 0, ADDR_MODE_1_ROR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
124 DEFINE_ALU_DECODER_EX_ARM(NAME ## S_ROR, NAME, 1, ADDR_MODE_1_ROR, ARM_OPERAND_AFFECTED_1, SKIPPED) \
125 DEFINE_ALU_DECODER_EX_ARM(NAME ## I, NAME, 0, ADDR_MODE_1_IMM, ARM_OPERAND_AFFECTED_1, SKIPPED) \
126 DEFINE_ALU_DECODER_EX_ARM(NAME ## SI, NAME, 1, ADDR_MODE_1_IMM, ARM_OPERAND_AFFECTED_1, SKIPPED)
127
128#define DEFINE_ALU_DECODER_S_ONLY_ARM(NAME) \
129 DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSL, NAME, 1, ADDR_MODE_1_LSL, ARM_OPERAND_NONE, 1) \
130 DEFINE_ALU_DECODER_EX_ARM(NAME ## _LSR, NAME, 1, ADDR_MODE_1_LSR, ARM_OPERAND_NONE, 1) \
131 DEFINE_ALU_DECODER_EX_ARM(NAME ## _ASR, NAME, 1, ADDR_MODE_1_ASR, ARM_OPERAND_NONE, 1) \
132 DEFINE_ALU_DECODER_EX_ARM(NAME ## _ROR, NAME, 1, ADDR_MODE_1_ROR, ARM_OPERAND_NONE, 1) \
133 DEFINE_ALU_DECODER_EX_ARM(NAME ## I, NAME, 1, ADDR_MODE_1_IMM, ARM_OPERAND_NONE, 1)
134
135#define DEFINE_MULTIPLY_DECODER_EX_ARM(NAME, MNEMONIC, S, OTHER_AFFECTED) \
136 DEFINE_DECODER_ARM(NAME, MNEMONIC, \
137 info->op1.reg = (opcode >> 16) & 0xF; \
138 info->op2.reg = opcode & 0xF; \
139 info->op3.reg = (opcode >> 8) & 0xF; \
140 info->op4.reg = (opcode >> 12) & 0xF; \
141 info->operandFormat = ARM_OPERAND_REGISTER_1 | \
142 ARM_OPERAND_AFFECTED_1 | \
143 ARM_OPERAND_REGISTER_2 | \
144 ARM_OPERAND_REGISTER_3 | \
145 OTHER_AFFECTED; \
146 info->affectsCPSR = S; \
147 if (info->op1.reg == ARM_PC) { \
148 info->branchType = ARM_BRANCH_INDIRECT; \
149 })
150
151#define DEFINE_LONG_MULTIPLY_DECODER_EX_ARM(NAME, MNEMONIC, S) \
152 DEFINE_DECODER_ARM(NAME, MNEMONIC, \
153 info->op1.reg = (opcode >> 12) & 0xF; \
154 info->op2.reg = (opcode >> 16) & 0xF; \
155 info->op3.reg = opcode & 0xF; \
156 info->op4.reg = (opcode >> 8) & 0xF; \
157 info->operandFormat = ARM_OPERAND_REGISTER_1 | \
158 ARM_OPERAND_AFFECTED_1 | \
159 ARM_OPERAND_REGISTER_2 | \
160 ARM_OPERAND_AFFECTED_2 | \
161 ARM_OPERAND_REGISTER_3 | \
162 ARM_OPERAND_REGISTER_4; \
163 info->affectsCPSR = S; \
164 if (info->op1.reg == ARM_PC) { \
165 info->branchType = ARM_BRANCH_INDIRECT; \
166 })
167
168#define DEFINE_MULTIPLY_DECODER_ARM(NAME, OTHER_AFFECTED) \
169 DEFINE_MULTIPLY_DECODER_EX_ARM(NAME, NAME, 0, OTHER_AFFECTED) \
170 DEFINE_MULTIPLY_DECODER_EX_ARM(NAME ## S, NAME, 1, OTHER_AFFECTED)
171
172#define DEFINE_LONG_MULTIPLY_DECODER_ARM(NAME) \
173 DEFINE_LONG_MULTIPLY_DECODER_EX_ARM(NAME, NAME, 0) \
174 DEFINE_LONG_MULTIPLY_DECODER_EX_ARM(NAME ## S, NAME, 1)
175
176#define DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME, MNEMONIC, ADDRESSING_MODE, ADDRESSING_DECODING, CYCLES, TYPE) \
177 DEFINE_DECODER_ARM(NAME, MNEMONIC, \
178 info->op1.reg = (opcode >> 12) & 0xF; \
179 info->memory.baseReg = (opcode >> 16) & 0xF; \
180 info->memory.width = TYPE; \
181 info->operandFormat = ARM_OPERAND_REGISTER_1 | \
182 ARM_OPERAND_AFFECTED_1 | /* TODO: Remove this for STR */ \
183 ARM_OPERAND_MEMORY_2; \
184 info->memory.format = ARM_MEMORY_REGISTER_BASE | ADDRESSING_MODE; \
185 ADDRESSING_DECODING; \
186 CYCLES;)
187
188#define DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME, MNEMONIC, ADDRESSING_MODE, CYCLES, TYPE) \
189 DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME, MNEMONIC, \
190 ARM_MEMORY_POST_INCREMENT | \
191 ARM_MEMORY_WRITEBACK | \
192 ARM_MEMORY_OFFSET_SUBTRACT, \
193 ADDRESSING_MODE, CYCLES, TYPE) \
194 DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## U, MNEMONIC, \
195 ARM_MEMORY_POST_INCREMENT | \
196 ARM_MEMORY_WRITEBACK, \
197 ADDRESSING_MODE, CYCLES, TYPE) \
198 DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## P, MNEMONIC, \
199 ARM_MEMORY_OFFSET_SUBTRACT, \
200 ADDRESSING_MODE, CYCLES, TYPE) \
201 DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## PW, MNEMONIC, \
202 ARM_MEMORY_PRE_INCREMENT | \
203 ARM_MEMORY_WRITEBACK | \
204 ARM_MEMORY_OFFSET_SUBTRACT, \
205 ADDRESSING_MODE, CYCLES, TYPE) \
206 DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## PU, MNEMONIC, \
207 0, \
208 ADDRESSING_MODE, CYCLES, TYPE) \
209 DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## PUW, MNEMONIC, \
210 ARM_MEMORY_WRITEBACK, \
211 ADDRESSING_MODE, CYCLES, TYPE)
212
213#define DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE) \
214 DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _LSL_, MNEMONIC, ADDR_MODE_2_LSL, CYCLES, TYPE) \
215 DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _LSR_, MNEMONIC, ADDR_MODE_2_LSR, CYCLES, TYPE) \
216 DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _ASR_, MNEMONIC, ADDR_MODE_2_ASR, CYCLES, TYPE) \
217 DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _ROR_, MNEMONIC, ADDR_MODE_2_ROR, CYCLES, TYPE) \
218 DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_2_IMM, CYCLES, TYPE)
219
220#define DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE) \
221 DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME, MNEMONIC, ADDR_MODE_3_REG, CYCLES, TYPE) \
222 DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_3_IMM, CYCLES, TYPE)
223
224#define DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME, MNEMONIC, ADDRESSING_MODE, CYCLES, TYPE) \
225 DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME, MNEMONIC, \
226 ARM_MEMORY_POST_INCREMENT | \
227 ARM_MEMORY_WRITEBACK | \
228 ARM_MEMORY_OFFSET_SUBTRACT, \
229 ADDRESSING_MODE, CYCLES, TYPE) \
230 DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## U, MNEMONIC, \
231 ARM_MEMORY_POST_INCREMENT | \
232 ARM_MEMORY_WRITEBACK, \
233 ADDRESSING_MODE, CYCLES, TYPE)
234
235#define DEFINE_LOAD_STORE_T_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE) \
236 DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _LSL_, MNEMONIC, ADDR_MODE_2_LSL, CYCLES, TYPE) \
237 DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _LSR_, MNEMONIC, ADDR_MODE_2_LSR, CYCLES, TYPE) \
238 DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _ASR_, MNEMONIC, ADDR_MODE_2_ASR, CYCLES, TYPE) \
239 DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _ROR_, MNEMONIC, ADDR_MODE_2_ROR, CYCLES, TYPE) \
240 DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_2_IMM, CYCLES, TYPE)
241
242#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME, MNEMONIC, DIRECTION, WRITEBACK) \
243 DEFINE_DECODER_ARM(NAME, MNEMONIC, \
244 info->memory.baseReg = (opcode >> 16) & 0xF; \
245 info->op1.immediate = opcode & 0x0000FFFF; \
246 if (info->op1.immediate & (1 << ARM_PC)) { \
247 info->branchType = ARM_BRANCH_INDIRECT; \
248 } \
249 info->operandFormat = ARM_OPERAND_MEMORY_1; \
250 info->memory.format = ARM_MEMORY_REGISTER_BASE | \
251 WRITEBACK | \
252 ARM_MEMORY_ ## DIRECTION;)
253
254
255#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM_NO_S(NAME, SUFFIX) \
256 DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DA, NAME, DECREMENT_AFTER, 0) \
257 DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DAW, NAME, DECREMENT_AFTER, ARM_MEMORY_WRITEBACK) \
258 DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DB, NAME, DECREMENT_BEFORE, 0) \
259 DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DBW, NAME, DECREMENT_BEFORE, ARM_MEMORY_WRITEBACK) \
260 DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IA, NAME, INCREMENT_AFTER, 0) \
261 DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IAW, NAME, INCREMENT_AFTER, ARM_MEMORY_WRITEBACK) \
262 DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IB, NAME, INCREMENT_BEFORE, 0) \
263 DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IBW, NAME, INCREMENT_BEFORE, ARM_MEMORY_WRITEBACK) \
264
265#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(NAME) \
266 DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM_NO_S(NAME, ) \
267 DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDA, NAME, DECREMENT_AFTER, ARM_MEMORY_SPSR_SWAP) \
268 DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDAW, NAME, DECREMENT_AFTER, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP) \
269 DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDB, NAME, DECREMENT_BEFORE, ARM_MEMORY_SPSR_SWAP) \
270 DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDBW, NAME, DECREMENT_BEFORE, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP) \
271 DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIA, NAME, INCREMENT_AFTER, ARM_MEMORY_SPSR_SWAP) \
272 DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIAW, NAME, INCREMENT_AFTER, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP) \
273 DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIB, NAME, INCREMENT_BEFORE, ARM_MEMORY_SPSR_SWAP) \
274 DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIBW, NAME, INCREMENT_BEFORE, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP)
275
276#define DEFINE_SWP_DECODER_ARM(NAME, TYPE) \
277 DEFINE_DECODER_ARM(NAME, SWP, \
278 info->memory.baseReg = (opcode >> 16) & 0xF; \
279 info->op1.reg = (opcode >> 12) & 0xF; \
280 info->op2.reg = opcode & 0xF; \
281 info->operandFormat = ARM_OPERAND_REGISTER_1 | \
282 ARM_OPERAND_AFFECTED_1 | \
283 ARM_OPERAND_REGISTER_2 | \
284 ARM_OPERAND_MEMORY_3; \
285 info->memory.format = ARM_MEMORY_REGISTER_BASE; \
286 info->memory.width = TYPE;)
287
288DEFINE_ALU_DECODER_ARM(ADD, 0)
289DEFINE_ALU_DECODER_ARM(ADC, 0)
290DEFINE_ALU_DECODER_ARM(AND, 0)
291DEFINE_ALU_DECODER_ARM(BIC, 0)
292DEFINE_ALU_DECODER_S_ONLY_ARM(CMN)
293DEFINE_ALU_DECODER_S_ONLY_ARM(CMP)
294DEFINE_ALU_DECODER_ARM(EOR, 0)
295DEFINE_ALU_DECODER_ARM(MOV, 2)
296DEFINE_ALU_DECODER_ARM(MVN, 2)
297DEFINE_ALU_DECODER_ARM(ORR, 0)
298DEFINE_ALU_DECODER_ARM(RSB, 0)
299DEFINE_ALU_DECODER_ARM(RSC, 0)
300DEFINE_ALU_DECODER_ARM(SBC, 0)
301DEFINE_ALU_DECODER_ARM(SUB, 0)
302DEFINE_ALU_DECODER_S_ONLY_ARM(TEQ)
303DEFINE_ALU_DECODER_S_ONLY_ARM(TST)
304
305// TOOD: Estimate cycles
306DEFINE_MULTIPLY_DECODER_ARM(MLA, ARM_OPERAND_REGISTER_4)
307DEFINE_MULTIPLY_DECODER_ARM(MUL, ARM_OPERAND_NONE)
308
309DEFINE_LONG_MULTIPLY_DECODER_ARM(SMLAL)
310DEFINE_LONG_MULTIPLY_DECODER_ARM(SMULL)
311DEFINE_LONG_MULTIPLY_DECODER_ARM(UMLAL)
312DEFINE_LONG_MULTIPLY_DECODER_ARM(UMULL)
313
314// Begin load/store definitions
315
316DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDR, LDR, LOAD_CYCLES, ARM_ACCESS_WORD)
317DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDRB, LDR, LOAD_CYCLES, ARM_ACCESS_BYTE)
318DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRH, LDR, LOAD_CYCLES, ARM_ACCESS_HALFWORD)
319DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRSB, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_BYTE)
320DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRSH, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_HALFWORD)
321DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(STR, STR, STORE_CYCLES, ARM_ACCESS_WORD)
322DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(STRB, STR, STORE_CYCLES, ARM_ACCESS_BYTE)
323DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(STRH, STR, STORE_CYCLES, ARM_ACCESS_HALFWORD)
324
325DEFINE_LOAD_STORE_T_DECODER_ARM(LDRBT, LDR, LOAD_CYCLES, ARM_ACCESS_TRANSLATED_BYTE)
326DEFINE_LOAD_STORE_T_DECODER_ARM(LDRT, LDR, LOAD_CYCLES, ARM_ACCESS_TRANSLATED_WORD)
327DEFINE_LOAD_STORE_T_DECODER_ARM(STRBT, STR, STORE_CYCLES, ARM_ACCESS_TRANSLATED_BYTE)
328DEFINE_LOAD_STORE_T_DECODER_ARM(STRT, STR, STORE_CYCLES, ARM_ACCESS_TRANSLATED_WORD)
329
330DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(LDM)
331DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM_NO_S(LDM, v5)
332DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(STM)
333
334DEFINE_SWP_DECODER_ARM(SWP, ARM_ACCESS_WORD)
335DEFINE_SWP_DECODER_ARM(SWPB, ARM_ACCESS_BYTE)
336
337// End load/store definitions
338
339// Begin branch definitions
340
341DEFINE_DECODER_ARM(B, B,
342 int32_t offset = opcode << 8;
343 info->op1.immediate = offset >> 6;
344 info->operandFormat = ARM_OPERAND_IMMEDIATE_1;
345 info->branchType = ARM_BRANCH;)
346
347DEFINE_DECODER_ARM(BL, BL,
348 int32_t offset = opcode << 8;
349 info->op1.immediate = offset >> 6;
350 info->operandFormat = ARM_OPERAND_IMMEDIATE_1;
351 info->branchType = ARM_BRANCH_LINKED;)
352
353DEFINE_DECODER_ARM(BX, BX,
354 info->op1.reg = opcode & 0x0000000F;
355 info->operandFormat = ARM_OPERAND_REGISTER_1;
356 info->branchType = ARM_BRANCH_INDIRECT;)
357
358DEFINE_DECODER_ARM(BLX2, BLX,
359 info->op1.reg = opcode & 0x0000000F;
360 info->operandFormat = ARM_OPERAND_REGISTER_1;
361 info->branchType = ARM_BRANCH_LINKED | ARM_BRANCH_INDIRECT;)
362
363// End branch definitions
364
365// Begin coprocessor definitions
366
367#define DEFINE_DECODER_COPROCESSOR(NAME, FORMAT) \
368 DEFINE_DECODER_ARM(NAME, NAME, \
369 info->cp.op1 = (opcode >> 21) & 7; \
370 info->cp.op2 = (opcode >> 5) & 7; \
371 info->op1.reg = (opcode >> 12) & 0xF; \
372 info->cp.cp = (opcode >> 8) & 0xF; \
373 info->op2.reg = (opcode >> 16) & 0xF; \
374 info->op3.reg = opcode & 0xF; \
375 info->operandFormat = ARM_OPERAND_REGISTER_1 |\
376 ARM_OPERAND_COPROCESSOR_REG_2 | \
377 ARM_OPERAND_COPROCESSOR_REG_3 | \
378 (FORMAT);)
379
380DEFINE_DECODER_ARM(CDP, CDP, info->operandFormat = ARM_OPERAND_NONE;)
381DEFINE_DECODER_ARM(LDC, LDC, info->operandFormat = ARM_OPERAND_NONE;)
382DEFINE_DECODER_ARM(STC, STC, info->operandFormat = ARM_OPERAND_NONE;)
383DEFINE_DECODER_COPROCESSOR(MCR, ARM_OPERAND_AFFECTED_2 | ARM_OPERAND_AFFECTED_3)
384DEFINE_DECODER_COPROCESSOR(MRC, ARM_OPERAND_AFFECTED_1)
385
386// Begin miscellaneous definitions
387
388DEFINE_DECODER_ARM(BKPT, BKPT,
389 info->operandFormat = ARM_OPERAND_NONE;
390 info->traps = 1;) // Not strictly in ARMv4T, but here for convenience
391DEFINE_DECODER_ARM(ILL, ILL,
392 info->operandFormat = ARM_OPERAND_NONE;
393 info->traps = 1;) // Illegal opcode
394
395DEFINE_DECODER_ARM(CLZ, CLZ,
396 info->op1.reg = (opcode >> 12) & 0xF;
397 info->op2.reg = opcode & 0xF;
398 info->operandFormat = ARM_OPERAND_REGISTER_1 |
399 ARM_OPERAND_AFFECTED_1 |
400 ARM_OPERAND_REGISTER_2;)
401
402DEFINE_DECODER_ARM(MSR, MSR,
403 info->affectsCPSR = 1;
404 info->op1.reg = ARM_CPSR;
405 info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
406 info->op2.reg = opcode & 0x0000000F;
407 info->operandFormat = ARM_OPERAND_REGISTER_1 |
408 ARM_OPERAND_AFFECTED_1 |
409 ARM_OPERAND_REGISTER_2;)
410
411DEFINE_DECODER_ARM(MSRR, MSR,
412 info->op1.reg = ARM_SPSR;
413 info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
414 info->op2.reg = opcode & 0x0000000F;
415 info->operandFormat = ARM_OPERAND_REGISTER_1 |
416 ARM_OPERAND_AFFECTED_1 |
417 ARM_OPERAND_REGISTER_2;)
418
419DEFINE_DECODER_ARM(MRS, MRS,
420 info->affectsCPSR = 1;
421 info->op1.reg = (opcode >> 12) & 0xF;
422 info->op2.reg = ARM_CPSR;
423 info->op2.psrBits = 0;
424 info->operandFormat = ARM_OPERAND_REGISTER_1 |
425 ARM_OPERAND_AFFECTED_1 |
426 ARM_OPERAND_REGISTER_2;)
427
428DEFINE_DECODER_ARM(MRSR, MRS,
429 info->op1.reg = (opcode >> 12) & 0xF;
430 info->op2.reg = ARM_SPSR;
431 info->op2.psrBits = 0;
432 info->operandFormat = ARM_OPERAND_REGISTER_1 |
433 ARM_OPERAND_AFFECTED_1 |
434 ARM_OPERAND_REGISTER_2;)
435
436DEFINE_DECODER_ARM(MSRI, MSR,
437 int rotate = (opcode & 0x00000F00) >> 7;
438 int32_t operand = ROR(opcode & 0x000000FF, rotate);
439 info->affectsCPSR = 1;
440 info->op1.reg = ARM_CPSR;
441 info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
442 info->op2.immediate = operand;
443 info->operandFormat = ARM_OPERAND_REGISTER_1 |
444 ARM_OPERAND_AFFECTED_1 |
445 ARM_OPERAND_IMMEDIATE_2;)
446
447DEFINE_DECODER_ARM(MSRRI, MSR,
448 int rotate = (opcode & 0x00000F00) >> 7;
449 int32_t operand = ROR(opcode & 0x000000FF, rotate);
450 info->op1.reg = ARM_SPSR;
451 info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
452 info->op2.immediate = operand;
453 info->operandFormat = ARM_OPERAND_REGISTER_1 |
454 ARM_OPERAND_AFFECTED_1 |
455 ARM_OPERAND_IMMEDIATE_2;)
456
457DEFINE_DECODER_ARM(SWI, SWI,
458 info->op1.immediate = opcode & 0xFFFFFF;
459 info->operandFormat = ARM_OPERAND_IMMEDIATE_1;
460 info->traps = 1;)
461
462typedef void (*ARMDecoder)(uint32_t opcode, struct ARMInstructionInfo* info);
463
464static const ARMDecoder _armDecoderTable[0x1000] = {
465 DECLARE_ARM_EMITTER_BLOCK(_ARMDecode, 5)
466};
467
468void ARMDecodeARM(uint32_t opcode, struct ARMInstructionInfo* info) {
469 memset(info, 0, sizeof(*info));
470 info->execMode = MODE_ARM;
471 info->opcode = opcode;
472 info->branchType = ARM_BRANCH_NONE;
473 info->condition = opcode >> 28;
474 info->sInstructionCycles = 1;
475 ARMDecoder decoder = _armDecoderTable[((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x00F)];
476 decoder(opcode, info);
477}