all repos — mgba @ 293831e3bf85da749dea26ab0382cd8c866d5a41

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