all repos — mgba @ f7b1cee66ee5438db8d483911b48acacd8ebefd9

mGBA Game Boy Advance Emulator

src/arm/decoder-arm.c (view raw)

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