all repos — mgba @ e30674d05301e40ad386fd4ed32341a8bb533d95

mGBA Game Boy Advance Emulator

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