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 && (OTHER_AFFECTED & ARM_OPERAND_AFFECTED_1)) { \
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, OTHER_AFFECTED) \
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 			OTHER_AFFECTED | \
183 			ARM_OPERAND_MEMORY_2; \
184 		info->memory.format = ARM_MEMORY_REGISTER_BASE | ADDRESSING_MODE; \
185 		ADDRESSING_DECODING; \
186 		if (info->op1.reg == ARM_PC && (OTHER_AFFECTED & ARM_OPERAND_AFFECTED_1)) { \
187 			info->branchType = ARM_BRANCH_INDIRECT; \
188 		} \
189 		if ((info->memory.format & (ARM_MEMORY_WRITEBACK | ARM_MEMORY_REGISTER_OFFSET)) == (ARM_MEMORY_WRITEBACK | ARM_MEMORY_REGISTER_OFFSET) && \
190 		    info->memory.offset.reg == ARM_PC) { \
191 			info->branchType = ARM_BRANCH_INDIRECT; \
192 		} \
193 		CYCLES;)
194 
195 #define DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME, MNEMONIC, ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
196 	DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME, MNEMONIC, \
197 		ARM_MEMORY_POST_INCREMENT | \
198 		ARM_MEMORY_WRITEBACK | \
199 		ARM_MEMORY_OFFSET_SUBTRACT, \
200 		ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
201 	DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## U, MNEMONIC, \
202 		ARM_MEMORY_POST_INCREMENT | \
203 		ARM_MEMORY_WRITEBACK, \
204 		ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
205 	DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## P, MNEMONIC, \
206 		ARM_MEMORY_OFFSET_SUBTRACT, \
207 		ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
208 	DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## PW, MNEMONIC, \
209 		ARM_MEMORY_PRE_INCREMENT | \
210 		ARM_MEMORY_WRITEBACK | \
211 		ARM_MEMORY_OFFSET_SUBTRACT, \
212 		ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
213 	DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## PU, MNEMONIC, \
214 		0, \
215 		ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
216 	DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## PUW, MNEMONIC, \
217 		ARM_MEMORY_PRE_INCREMENT | \
218 		ARM_MEMORY_WRITEBACK, \
219 		ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
220 
221 #define DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE, OTHER_AFFECTED) \
222 	DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _LSL_, MNEMONIC, ADDR_MODE_2_LSL, CYCLES, TYPE, OTHER_AFFECTED) \
223 	DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _LSR_, MNEMONIC, ADDR_MODE_2_LSR, CYCLES, TYPE, OTHER_AFFECTED) \
224 	DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _ASR_, MNEMONIC, ADDR_MODE_2_ASR, CYCLES, TYPE, OTHER_AFFECTED) \
225 	DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _ROR_, MNEMONIC, ADDR_MODE_2_ROR, CYCLES, TYPE, OTHER_AFFECTED) \
226 	DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_2_IMM, CYCLES, TYPE, OTHER_AFFECTED)
227 
228 #define DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE, OTHER_AFFECTED) \
229 	DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME, MNEMONIC, ADDR_MODE_3_REG, CYCLES, TYPE, OTHER_AFFECTED) \
230 	DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_3_IMM, CYCLES, TYPE, OTHER_AFFECTED)
231 
232 #define DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME, MNEMONIC, ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
233 	DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME, MNEMONIC, \
234 		ARM_MEMORY_POST_INCREMENT | \
235 		ARM_MEMORY_WRITEBACK | \
236 		ARM_MEMORY_OFFSET_SUBTRACT, \
237 		ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
238 	DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## U, MNEMONIC, \
239 		ARM_MEMORY_POST_INCREMENT | \
240 		ARM_MEMORY_WRITEBACK, \
241 		ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED)
242 
243 #define DEFINE_LOAD_STORE_T_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE, OTHER_AFFECTED) \
244 	DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _LSL_, MNEMONIC, ADDR_MODE_2_LSL, CYCLES, TYPE, OTHER_AFFECTED) \
245 	DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _LSR_, MNEMONIC, ADDR_MODE_2_LSR, CYCLES, TYPE, OTHER_AFFECTED) \
246 	DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _ASR_, MNEMONIC, ADDR_MODE_2_ASR, CYCLES, TYPE, OTHER_AFFECTED) \
247 	DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _ROR_, MNEMONIC, ADDR_MODE_2_ROR, CYCLES, TYPE, OTHER_AFFECTED) \
248 	DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_2_IMM, CYCLES, TYPE, OTHER_AFFECTED)
249 
250 #define DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME, MNEMONIC, DIRECTION, WRITEBACK) \
251 	DEFINE_DECODER_ARM(NAME, MNEMONIC, \
252 		info->memory.baseReg = (opcode >> 16) & 0xF; \
253 		info->op1.immediate = opcode & 0x0000FFFF; \
254 		if (info->op1.immediate & (1 << ARM_PC)) { \
255 			info->branchType = ARM_BRANCH_INDIRECT; \
256 		} \
257 		info->operandFormat = ARM_OPERAND_MEMORY_1; \
258 		info->memory.format = ARM_MEMORY_REGISTER_BASE | \
259 			WRITEBACK | \
260 			ARM_MEMORY_ ## DIRECTION;)
261 
262 
263 #define DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(NAME) \
264 	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## DA,   NAME, DECREMENT_AFTER, 0) \
265 	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## DAW,  NAME, DECREMENT_AFTER, ARM_MEMORY_WRITEBACK) \
266 	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## DB,   NAME, DECREMENT_BEFORE, 0) \
267 	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## DBW,  NAME, DECREMENT_BEFORE, ARM_MEMORY_WRITEBACK) \
268 	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## IA,   NAME, INCREMENT_AFTER, 0) \
269 	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## IAW,  NAME, INCREMENT_AFTER, ARM_MEMORY_WRITEBACK) \
270 	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## IB,   NAME, INCREMENT_BEFORE, 0) \
271 	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## IBW,  NAME, INCREMENT_BEFORE, ARM_MEMORY_WRITEBACK) \
272 	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDA,  NAME, DECREMENT_AFTER, ARM_MEMORY_SPSR_SWAP) \
273 	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDAW, NAME, DECREMENT_AFTER, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP) \
274 	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDB,  NAME, DECREMENT_BEFORE, ARM_MEMORY_SPSR_SWAP) \
275 	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDBW, NAME, DECREMENT_BEFORE, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP) \
276 	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIA,  NAME, INCREMENT_AFTER, ARM_MEMORY_SPSR_SWAP) \
277 	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIAW, NAME, INCREMENT_AFTER, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP) \
278 	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIB,  NAME, INCREMENT_BEFORE, ARM_MEMORY_SPSR_SWAP) \
279 	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIBW, NAME, INCREMENT_BEFORE, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP)
280 
281 #define DEFINE_SWP_DECODER_ARM(NAME, TYPE) \
282 	DEFINE_DECODER_ARM(NAME, SWP, \
283 		info->memory.baseReg = (opcode >> 16) & 0xF; \
284 		info->op1.reg = (opcode >> 12) & 0xF; \
285 		info->op2.reg = opcode & 0xF; \
286 		info->operandFormat = ARM_OPERAND_REGISTER_1 | \
287 			ARM_OPERAND_AFFECTED_1 | \
288 			ARM_OPERAND_REGISTER_2 | \
289 			ARM_OPERAND_MEMORY_3; \
290 		info->memory.format = ARM_MEMORY_REGISTER_BASE; \
291 		info->memory.width = TYPE;)
292 
293 DEFINE_ALU_DECODER_ARM(ADD, 0)
294 DEFINE_ALU_DECODER_ARM(ADC, 0)
295 DEFINE_ALU_DECODER_ARM(AND, 0)
296 DEFINE_ALU_DECODER_ARM(BIC, 0)
297 DEFINE_ALU_DECODER_S_ONLY_ARM(CMN)
298 DEFINE_ALU_DECODER_S_ONLY_ARM(CMP)
299 DEFINE_ALU_DECODER_ARM(EOR, 0)
300 DEFINE_ALU_DECODER_ARM(MOV, 2)
301 DEFINE_ALU_DECODER_ARM(MVN, 2)
302 DEFINE_ALU_DECODER_ARM(ORR, 0)
303 DEFINE_ALU_DECODER_ARM(RSB, 0)
304 DEFINE_ALU_DECODER_ARM(RSC, 0)
305 DEFINE_ALU_DECODER_ARM(SBC, 0)
306 DEFINE_ALU_DECODER_ARM(SUB, 0)
307 DEFINE_ALU_DECODER_S_ONLY_ARM(TEQ)
308 DEFINE_ALU_DECODER_S_ONLY_ARM(TST)
309 
310 // TOOD: Estimate cycles
311 DEFINE_MULTIPLY_DECODER_ARM(MLA, ARM_OPERAND_REGISTER_4)
312 DEFINE_MULTIPLY_DECODER_ARM(MUL, ARM_OPERAND_NONE)
313 
314 DEFINE_LONG_MULTIPLY_DECODER_ARM(SMLAL)
315 DEFINE_LONG_MULTIPLY_DECODER_ARM(SMULL)
316 DEFINE_LONG_MULTIPLY_DECODER_ARM(UMLAL)
317 DEFINE_LONG_MULTIPLY_DECODER_ARM(UMULL)
318 
319 // Begin load/store definitions
320 
321 DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDR, LDR, LOAD_CYCLES, ARM_ACCESS_WORD, ARM_OPERAND_AFFECTED_1)
322 DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDRB, LDR, LOAD_CYCLES, ARM_ACCESS_BYTE, ARM_OPERAND_AFFECTED_1)
323 DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRH, LDR, LOAD_CYCLES, ARM_ACCESS_HALFWORD, ARM_OPERAND_AFFECTED_1)
324 DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRSB, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_BYTE, ARM_OPERAND_AFFECTED_1)
325 DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRSH, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_HALFWORD, ARM_OPERAND_AFFECTED_1)
326 DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(STR, STR, STORE_CYCLES, ARM_ACCESS_WORD, ARM_OPERAND_NONE)
327 DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(STRB, STR, STORE_CYCLES, ARM_ACCESS_BYTE, ARM_OPERAND_NONE)
328 DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(STRH, STR, STORE_CYCLES, ARM_ACCESS_HALFWORD, ARM_OPERAND_NONE)
329 
330 DEFINE_LOAD_STORE_T_DECODER_ARM(LDRBT, LDR, LOAD_CYCLES, ARM_ACCESS_TRANSLATED_BYTE, ARM_OPERAND_AFFECTED_1)
331 DEFINE_LOAD_STORE_T_DECODER_ARM(LDRT, LDR, LOAD_CYCLES, ARM_ACCESS_TRANSLATED_WORD, ARM_OPERAND_AFFECTED_1)
332 DEFINE_LOAD_STORE_T_DECODER_ARM(STRBT, STR, STORE_CYCLES, ARM_ACCESS_TRANSLATED_BYTE, ARM_OPERAND_NONE)
333 DEFINE_LOAD_STORE_T_DECODER_ARM(STRT, STR, STORE_CYCLES, ARM_ACCESS_TRANSLATED_WORD, ARM_OPERAND_NONE)
334 
335 DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(LDM)
336 DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(STM)
337 
338 DEFINE_SWP_DECODER_ARM(SWP, ARM_ACCESS_WORD)
339 DEFINE_SWP_DECODER_ARM(SWPB, ARM_ACCESS_BYTE)
340 
341 // End load/store definitions
342 
343 // Begin branch definitions
344 
345 DEFINE_DECODER_ARM(B, B,
346 	int32_t offset = opcode << 8;
347 	info->op1.immediate = offset >> 6;
348 	info->operandFormat = ARM_OPERAND_IMMEDIATE_1;
349 	info->branchType = ARM_BRANCH;)
350 
351 DEFINE_DECODER_ARM(BL, BL,
352 	int32_t offset = opcode << 8;
353 	info->op1.immediate = offset >> 6;
354 	info->operandFormat = ARM_OPERAND_IMMEDIATE_1;
355 	info->branchType = ARM_BRANCH_LINKED;)
356 
357 DEFINE_DECODER_ARM(BX, BX,
358 	info->op1.reg = opcode & 0x0000000F;
359 	info->operandFormat = ARM_OPERAND_REGISTER_1;
360 	info->branchType = ARM_BRANCH_INDIRECT;)
361 
362 // End branch definitions
363 
364 // Begin coprocessor definitions
365 
366 DEFINE_DECODER_ARM(CDP, ILL, info->operandFormat = ARM_OPERAND_NONE;)
367 DEFINE_DECODER_ARM(LDC, ILL, info->operandFormat = ARM_OPERAND_NONE;)
368 DEFINE_DECODER_ARM(STC, ILL, info->operandFormat = ARM_OPERAND_NONE;)
369 DEFINE_DECODER_ARM(MCR, ILL, info->operandFormat = ARM_OPERAND_NONE;)
370 DEFINE_DECODER_ARM(MRC, ILL, info->operandFormat = ARM_OPERAND_NONE;)
371 
372 // Begin miscellaneous definitions
373 
374 DEFINE_DECODER_ARM(BKPT, BKPT,
375 	info->operandFormat = ARM_OPERAND_NONE;
376 	info->traps = 1;) // Not strictly in ARMv4T, but here for convenience
377 DEFINE_DECODER_ARM(ILL, ILL,
378 	info->operandFormat = ARM_OPERAND_NONE;
379 	info->traps = 1;) // Illegal opcode
380 
381 DEFINE_DECODER_ARM(MSR, MSR,
382 	info->affectsCPSR = 1;
383 	info->op1.reg = ARM_CPSR;
384 	info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
385 	info->op2.reg = opcode & 0x0000000F;
386 	info->operandFormat = ARM_OPERAND_REGISTER_1 |
387 		ARM_OPERAND_AFFECTED_1 |
388 		ARM_OPERAND_REGISTER_2;)
389 
390 DEFINE_DECODER_ARM(MSRR, MSR,
391 	info->op1.reg = ARM_SPSR;
392 	info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
393 	info->op2.reg = opcode & 0x0000000F;
394 	info->operandFormat = ARM_OPERAND_REGISTER_1 |
395 		ARM_OPERAND_AFFECTED_1 |
396 		ARM_OPERAND_REGISTER_2;)
397 
398 DEFINE_DECODER_ARM(MRS, MRS,
399 	info->affectsCPSR = 1;
400 	info->op1.reg = (opcode >> 12) & 0xF;
401 	info->op2.reg = ARM_CPSR;
402 	info->op2.psrBits = 0;
403 	info->operandFormat = ARM_OPERAND_REGISTER_1 |
404 		ARM_OPERAND_AFFECTED_1 |
405 		ARM_OPERAND_REGISTER_2;)
406 
407 DEFINE_DECODER_ARM(MRSR, MRS,
408 	info->op1.reg = (opcode >> 12) & 0xF;
409 	info->op2.reg = ARM_SPSR;
410 	info->op2.psrBits = 0;
411 	info->operandFormat = ARM_OPERAND_REGISTER_1 |
412 		ARM_OPERAND_AFFECTED_1 |
413 		ARM_OPERAND_REGISTER_2;)
414 
415 DEFINE_DECODER_ARM(MSRI, MSR,
416 	int rotate = (opcode & 0x00000F00) >> 7;
417 	int32_t operand = ROR(opcode & 0x000000FF, rotate);
418 	info->affectsCPSR = 1;
419 	info->op1.reg = ARM_CPSR;
420 	info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
421 	info->op2.immediate = operand;
422 	info->operandFormat = ARM_OPERAND_REGISTER_1 |
423 		ARM_OPERAND_AFFECTED_1 |
424 		ARM_OPERAND_IMMEDIATE_2;)
425 
426 DEFINE_DECODER_ARM(MSRRI, MSR,
427 	int rotate = (opcode & 0x00000F00) >> 7;
428 	int32_t operand = ROR(opcode & 0x000000FF, rotate);
429 	info->op1.reg = ARM_SPSR;
430 	info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
431 	info->op2.immediate = operand;
432 	info->operandFormat = ARM_OPERAND_REGISTER_1 |
433 		ARM_OPERAND_AFFECTED_1 |
434 		ARM_OPERAND_IMMEDIATE_2;)
435 
436 DEFINE_DECODER_ARM(SWI, SWI,
437 	info->op1.immediate = opcode & 0xFFFFFF;
438 	info->operandFormat = ARM_OPERAND_IMMEDIATE_1;
439 	info->traps = 1;)
440 
441 typedef void (*ARMDecoder)(uint32_t opcode, struct ARMInstructionInfo* info);
442 
443 static const ARMDecoder _armDecoderTable[0x1000] = {
444 	DECLARE_ARM_EMITTER_BLOCK(_ARMDecode)
445 };
446 
ARMDecodeARM(uint32_t opcode,struct ARMInstructionInfo * info)447 void ARMDecodeARM(uint32_t opcode, struct ARMInstructionInfo* info) {
448 	memset(info, 0, sizeof(*info));
449 	info->execMode = MODE_ARM;
450 	info->opcode = opcode;
451 	info->branchType = ARM_BRANCH_NONE;
452 	info->condition = opcode >> 28;
453 	info->sInstructionCycles = 1;
454 	ARMDecoder decoder = _armDecoderTable[((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x00F)];
455 	decoder(opcode, info);
456 }
457