all repos — mgba @ 000b49e45b30ec9c856b7b2e8cf8baee21daa56d

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 <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_WRITEBACK, \
218		ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
219
220#define DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE, OTHER_AFFECTED) \
221	DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _LSL_, MNEMONIC, ADDR_MODE_2_LSL, CYCLES, TYPE, OTHER_AFFECTED) \
222	DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _LSR_, MNEMONIC, ADDR_MODE_2_LSR, CYCLES, TYPE, OTHER_AFFECTED) \
223	DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _ASR_, MNEMONIC, ADDR_MODE_2_ASR, CYCLES, TYPE, OTHER_AFFECTED) \
224	DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _ROR_, MNEMONIC, ADDR_MODE_2_ROR, CYCLES, TYPE, OTHER_AFFECTED) \
225	DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_2_IMM, CYCLES, TYPE, OTHER_AFFECTED)
226
227#define DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE, OTHER_AFFECTED) \
228	DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME, MNEMONIC, ADDR_MODE_3_REG, CYCLES, TYPE, OTHER_AFFECTED) \
229	DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_3_IMM, CYCLES, TYPE, OTHER_AFFECTED)
230
231#define DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME, MNEMONIC, ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
232	DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME, MNEMONIC, \
233		ARM_MEMORY_POST_INCREMENT | \
234		ARM_MEMORY_WRITEBACK | \
235		ARM_MEMORY_OFFSET_SUBTRACT, \
236		ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
237	DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## U, MNEMONIC, \
238		ARM_MEMORY_POST_INCREMENT | \
239		ARM_MEMORY_WRITEBACK, \
240		ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED)
241
242#define DEFINE_LOAD_STORE_T_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE, OTHER_AFFECTED) \
243	DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _LSL_, MNEMONIC, ADDR_MODE_2_LSL, CYCLES, TYPE, OTHER_AFFECTED) \
244	DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _LSR_, MNEMONIC, ADDR_MODE_2_LSR, CYCLES, TYPE, OTHER_AFFECTED) \
245	DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _ASR_, MNEMONIC, ADDR_MODE_2_ASR, CYCLES, TYPE, OTHER_AFFECTED) \
246	DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _ROR_, MNEMONIC, ADDR_MODE_2_ROR, CYCLES, TYPE, OTHER_AFFECTED) \
247	DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_2_IMM, CYCLES, TYPE, OTHER_AFFECTED)
248
249#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME, MNEMONIC, DIRECTION, WRITEBACK) \
250	DEFINE_DECODER_ARM(NAME, MNEMONIC, \
251		info->memory.baseReg = (opcode >> 16) & 0xF; \
252		info->op1.immediate = opcode & 0x0000FFFF; \
253		if (info->op1.immediate & (1 << ARM_PC)) { \
254			info->branchType = ARM_BRANCH_INDIRECT; \
255		} \
256		info->operandFormat = ARM_OPERAND_MEMORY_1; \
257		info->memory.format = ARM_MEMORY_REGISTER_BASE | \
258			WRITEBACK | \
259			ARM_MEMORY_ ## DIRECTION;)
260
261
262#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM_NO_S(NAME, SUFFIX) \
263	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DA,   NAME, DECREMENT_AFTER, 0) \
264	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DAW,  NAME, DECREMENT_AFTER, ARM_MEMORY_WRITEBACK) \
265	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DB,   NAME, DECREMENT_BEFORE, 0) \
266	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DBW,  NAME, DECREMENT_BEFORE, ARM_MEMORY_WRITEBACK) \
267	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IA,   NAME, INCREMENT_AFTER, 0) \
268	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IAW,  NAME, INCREMENT_AFTER, ARM_MEMORY_WRITEBACK) \
269	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IB,   NAME, INCREMENT_BEFORE, 0) \
270	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IBW,  NAME, INCREMENT_BEFORE, ARM_MEMORY_WRITEBACK) \
271
272#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(NAME) \
273	DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM_NO_S(NAME, ) \
274	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDA,  NAME, DECREMENT_AFTER, ARM_MEMORY_SPSR_SWAP) \
275	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDAW, NAME, DECREMENT_AFTER, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP) \
276	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDB,  NAME, DECREMENT_BEFORE, ARM_MEMORY_SPSR_SWAP) \
277	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDBW, NAME, DECREMENT_BEFORE, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP) \
278	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIA,  NAME, INCREMENT_AFTER, ARM_MEMORY_SPSR_SWAP) \
279	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIAW, NAME, INCREMENT_AFTER, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP) \
280	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIB,  NAME, INCREMENT_BEFORE, ARM_MEMORY_SPSR_SWAP) \
281	DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIBW, NAME, INCREMENT_BEFORE, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP)
282
283#define DEFINE_SWP_DECODER_ARM(NAME, TYPE) \
284	DEFINE_DECODER_ARM(NAME, SWP, \
285		info->memory.baseReg = (opcode >> 16) & 0xF; \
286		info->op1.reg = (opcode >> 12) & 0xF; \
287		info->op2.reg = opcode & 0xF; \
288		info->operandFormat = ARM_OPERAND_REGISTER_1 | \
289			ARM_OPERAND_AFFECTED_1 | \
290			ARM_OPERAND_REGISTER_2 | \
291			ARM_OPERAND_MEMORY_3; \
292		info->memory.format = ARM_MEMORY_REGISTER_BASE; \
293		info->memory.width = TYPE;)
294
295DEFINE_ALU_DECODER_ARM(ADD, 0)
296DEFINE_ALU_DECODER_ARM(ADC, 0)
297DEFINE_ALU_DECODER_ARM(AND, 0)
298DEFINE_ALU_DECODER_ARM(BIC, 0)
299DEFINE_ALU_DECODER_S_ONLY_ARM(CMN)
300DEFINE_ALU_DECODER_S_ONLY_ARM(CMP)
301DEFINE_ALU_DECODER_ARM(EOR, 0)
302DEFINE_ALU_DECODER_ARM(MOV, 2)
303DEFINE_ALU_DECODER_ARM(MVN, 2)
304DEFINE_ALU_DECODER_ARM(ORR, 0)
305DEFINE_ALU_DECODER_ARM(RSB, 0)
306DEFINE_ALU_DECODER_ARM(RSC, 0)
307DEFINE_ALU_DECODER_ARM(SBC, 0)
308DEFINE_ALU_DECODER_ARM(SUB, 0)
309DEFINE_ALU_DECODER_S_ONLY_ARM(TEQ)
310DEFINE_ALU_DECODER_S_ONLY_ARM(TST)
311
312// TOOD: Estimate cycles
313DEFINE_MULTIPLY_DECODER_ARM(MLA, ARM_OPERAND_REGISTER_4)
314DEFINE_MULTIPLY_DECODER_ARM(MUL, ARM_OPERAND_NONE)
315
316DEFINE_LONG_MULTIPLY_DECODER_ARM(SMLAL)
317DEFINE_LONG_MULTIPLY_DECODER_ARM(SMULL)
318DEFINE_LONG_MULTIPLY_DECODER_ARM(UMLAL)
319DEFINE_LONG_MULTIPLY_DECODER_ARM(UMULL)
320
321DEFINE_MULTIPLY_DECODER_EX_ARM(SMLABB, SMLABB, 0, ARM_OPERAND_REGISTER_4)
322DEFINE_MULTIPLY_DECODER_EX_ARM(SMLABT, SMLABT, 0, ARM_OPERAND_REGISTER_4)
323DEFINE_MULTIPLY_DECODER_EX_ARM(SMLATB, SMLATB, 0, ARM_OPERAND_REGISTER_4)
324DEFINE_MULTIPLY_DECODER_EX_ARM(SMLATT, SMLATT, 0, ARM_OPERAND_REGISTER_4)
325DEFINE_MULTIPLY_DECODER_EX_ARM(SMULBB, SMULBB, 0, 0)
326DEFINE_MULTIPLY_DECODER_EX_ARM(SMULBT, SMULBT, 0, 0)
327DEFINE_MULTIPLY_DECODER_EX_ARM(SMULTB, SMULTB, 0, 0)
328DEFINE_MULTIPLY_DECODER_EX_ARM(SMULTT, SMULTT, 0, 0)
329
330DEFINE_MULTIPLY_DECODER_EX_ARM(SMLAWB, SMLAWB, 0, ARM_OPERAND_REGISTER_4)
331DEFINE_MULTIPLY_DECODER_EX_ARM(SMLAWT, SMLAWT, 0, ARM_OPERAND_REGISTER_4)
332DEFINE_MULTIPLY_DECODER_EX_ARM(SMULWB, SMULWB, 0, 0)
333DEFINE_MULTIPLY_DECODER_EX_ARM(SMULWT, SMULWT, 0, 0)
334
335// Begin load/store definitions
336
337DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDR, LDR, LOAD_CYCLES, ARM_ACCESS_WORD, ARM_OPERAND_AFFECTED_1)
338DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDRv5, LDR, LOAD_CYCLES, ARM_ACCESS_WORD, ARM_OPERAND_AFFECTED_1)
339DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDRB, LDR, LOAD_CYCLES, ARM_ACCESS_BYTE, ARM_OPERAND_AFFECTED_1)
340DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRD, LDR, LOAD_CYCLES, ARM_ACCESS_DUALWORD, ARM_OPERAND_AFFECTED_1)
341DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRH, LDR, LOAD_CYCLES, ARM_ACCESS_HALFWORD, ARM_OPERAND_AFFECTED_1)
342DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRSB, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_BYTE, ARM_OPERAND_AFFECTED_1)
343DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRSH, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_HALFWORD, ARM_OPERAND_AFFECTED_1)
344DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(STR, STR, STORE_CYCLES, ARM_ACCESS_WORD, ARM_OPERAND_NONE)
345DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(STRB, STR, STORE_CYCLES, ARM_ACCESS_BYTE, ARM_OPERAND_NONE)
346DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(STRD, STR, STORE_CYCLES, ARM_ACCESS_DUALWORD, ARM_OPERAND_NONE)
347DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(STRH, STR, STORE_CYCLES, ARM_ACCESS_HALFWORD, ARM_OPERAND_NONE)
348
349DEFINE_LOAD_STORE_T_DECODER_ARM(LDRBT, LDR, LOAD_CYCLES, ARM_ACCESS_TRANSLATED_BYTE, ARM_OPERAND_AFFECTED_1)
350DEFINE_LOAD_STORE_T_DECODER_ARM(LDRT, LDR, LOAD_CYCLES, ARM_ACCESS_TRANSLATED_WORD, ARM_OPERAND_AFFECTED_1)
351DEFINE_LOAD_STORE_T_DECODER_ARM(STRBT, STR, STORE_CYCLES, ARM_ACCESS_TRANSLATED_BYTE, ARM_OPERAND_NONE)
352DEFINE_LOAD_STORE_T_DECODER_ARM(STRT, STR, STORE_CYCLES, ARM_ACCESS_TRANSLATED_WORD, ARM_OPERAND_NONE)
353
354DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(LDM)
355DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM_NO_S(LDM, v5)
356DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(STM)
357
358DEFINE_SWP_DECODER_ARM(SWP, ARM_ACCESS_WORD)
359DEFINE_SWP_DECODER_ARM(SWPB, ARM_ACCESS_BYTE)
360
361// End load/store definitions
362
363// Begin branch definitions
364
365DEFINE_DECODER_ARM(B, B,
366	int32_t offset = opcode << 8;
367	info->op1.immediate = offset >> 6;
368	info->operandFormat = ARM_OPERAND_IMMEDIATE_1;
369	info->branchType = ARM_BRANCH;)
370
371DEFINE_DECODER_ARM(BL, BL,
372	int32_t offset = opcode << 8;
373	info->op1.immediate = offset >> 6;
374	info->operandFormat = ARM_OPERAND_IMMEDIATE_1;
375	info->branchType = ARM_BRANCH_LINKED;)
376
377DEFINE_DECODER_ARM(BX, BX,
378	info->op1.reg = opcode & 0x0000000F;
379	info->operandFormat = ARM_OPERAND_REGISTER_1;
380	info->branchType = ARM_BRANCH_INDIRECT;)
381
382DEFINE_DECODER_ARM(BLX, BLX,
383	int32_t offset = opcode << 8;
384	info->op1.immediate = offset >> 6;
385	info->operandFormat = ARM_OPERAND_IMMEDIATE_1;
386	info->branchType = ARM_BRANCH_LINKED;)
387
388DEFINE_DECODER_ARM(BLX2, BLX,
389	info->op1.reg = opcode & 0x0000000F;
390	info->operandFormat = ARM_OPERAND_REGISTER_1;
391	info->branchType = ARM_BRANCH_LINKED | ARM_BRANCH_INDIRECT;)
392
393// End branch definitions
394
395// Begin coprocessor definitions
396
397#define DEFINE_DECODER_COPROCESSOR(NAME, FORMAT) \
398	DEFINE_DECODER_ARM(NAME, NAME, \
399		info->cp.op1 = (opcode >> 21) & 7; \
400		info->cp.op2 = (opcode >> 5) & 7; \
401		info->op1.reg = (opcode >> 12) & 0xF; \
402		info->cp.cp = (opcode >> 8) & 0xF; \
403		info->op2.reg = (opcode >> 16) & 0xF; \
404		info->op3.reg = opcode & 0xF; \
405		info->operandFormat = ARM_OPERAND_REGISTER_1 |\
406		                      ARM_OPERAND_COPROCESSOR_REG_2 | \
407		                      ARM_OPERAND_COPROCESSOR_REG_3 | \
408		                      (FORMAT);)
409
410DEFINE_DECODER_ARM(CDP, CDP, info->operandFormat = ARM_OPERAND_NONE;)
411DEFINE_DECODER_ARM(LDC, LDC, info->operandFormat = ARM_OPERAND_NONE;)
412DEFINE_DECODER_ARM(STC, STC, info->operandFormat = ARM_OPERAND_NONE;)
413DEFINE_DECODER_COPROCESSOR(MCR, ARM_OPERAND_AFFECTED_2 | ARM_OPERAND_AFFECTED_3)
414DEFINE_DECODER_COPROCESSOR(MRC, ARM_OPERAND_AFFECTED_1)
415
416// Begin miscellaneous definitions
417
418DEFINE_DECODER_ARM(BKPT, BKPT,
419	info->operandFormat = ARM_OPERAND_NONE;
420	info->traps = 1;) // Not strictly in ARMv4T, but here for convenience
421DEFINE_DECODER_ARM(ILL, ILL,
422	info->operandFormat = ARM_OPERAND_NONE;
423	info->traps = 1;) // Illegal opcode
424
425DEFINE_DECODER_ARM(CLZ, CLZ,
426	info->op1.reg = (opcode >> 12) & 0xF;
427	info->op2.reg = opcode & 0xF;
428	info->operandFormat = ARM_OPERAND_REGISTER_1 |
429		ARM_OPERAND_AFFECTED_1 |
430		ARM_OPERAND_REGISTER_2;)
431
432DEFINE_DECODER_ARM(MSR, MSR,
433	info->affectsCPSR = 1;
434	info->op1.reg = ARM_CPSR;
435	info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
436	info->op2.reg = opcode & 0x0000000F;
437	info->operandFormat = ARM_OPERAND_REGISTER_1 |
438		ARM_OPERAND_AFFECTED_1 |
439		ARM_OPERAND_REGISTER_2;)
440
441DEFINE_DECODER_ARM(MSRR, MSR,
442	info->op1.reg = ARM_SPSR;
443	info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
444	info->op2.reg = opcode & 0x0000000F;
445	info->operandFormat = ARM_OPERAND_REGISTER_1 |
446		ARM_OPERAND_AFFECTED_1 |
447		ARM_OPERAND_REGISTER_2;)
448
449DEFINE_DECODER_ARM(MRS, MRS,
450	info->affectsCPSR = 1;
451	info->op1.reg = (opcode >> 12) & 0xF;
452	info->op2.reg = ARM_CPSR;
453	info->op2.psrBits = 0;
454	info->operandFormat = ARM_OPERAND_REGISTER_1 |
455		ARM_OPERAND_AFFECTED_1 |
456		ARM_OPERAND_REGISTER_2;)
457
458DEFINE_DECODER_ARM(MRSR, MRS,
459	info->op1.reg = (opcode >> 12) & 0xF;
460	info->op2.reg = ARM_SPSR;
461	info->op2.psrBits = 0;
462	info->operandFormat = ARM_OPERAND_REGISTER_1 |
463		ARM_OPERAND_AFFECTED_1 |
464		ARM_OPERAND_REGISTER_2;)
465
466DEFINE_DECODER_ARM(MSRI, MSR,
467	int rotate = (opcode & 0x00000F00) >> 7;
468	int32_t operand = ROR(opcode & 0x000000FF, rotate);
469	info->affectsCPSR = 1;
470	info->op1.reg = ARM_CPSR;
471	info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
472	info->op2.immediate = operand;
473	info->operandFormat = ARM_OPERAND_REGISTER_1 |
474		ARM_OPERAND_AFFECTED_1 |
475		ARM_OPERAND_IMMEDIATE_2;)
476
477DEFINE_DECODER_ARM(MSRRI, MSR,
478	int rotate = (opcode & 0x00000F00) >> 7;
479	int32_t operand = ROR(opcode & 0x000000FF, rotate);
480	info->op1.reg = ARM_SPSR;
481	info->op1.psrBits = (opcode >> 16) & ARM_PSR_MASK;
482	info->op2.immediate = operand;
483	info->operandFormat = ARM_OPERAND_REGISTER_1 |
484		ARM_OPERAND_AFFECTED_1 |
485		ARM_OPERAND_IMMEDIATE_2;)
486
487DEFINE_DECODER_ARM(SWI, SWI,
488	info->op1.immediate = opcode & 0xFFFFFF;
489	info->operandFormat = ARM_OPERAND_IMMEDIATE_1;
490	info->traps = 1;)
491
492typedef void (*ARMDecoder)(uint32_t opcode, struct ARMInstructionInfo* info);
493
494static const ARMDecoder _armDecoderTable[0x1000] = {
495	DECLARE_ARM_EMITTER_BLOCK(_ARMDecode, 5)
496};
497
498static const ARMDecoder _armDecoderFTable[0x1000] = {
499	DECLARE_ARM_F_EMITTER_BLOCK(_ARMDecode, 5)
500};
501
502void ARMDecodeARM(uint32_t opcode, struct ARMInstructionInfo* info) {
503	memset(info, 0, sizeof(*info));
504	info->execMode = MODE_ARM;
505	info->opcode = opcode;
506	info->branchType = ARM_BRANCH_NONE;
507	info->condition = opcode >> 28;
508	info->sInstructionCycles = 1;
509	ARMDecoder decoder;
510	if (info->condition == ARM_CONDITION_NV) {
511		decoder = _armDecoderFTable[((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x00F)];
512		info->condition = ARM_CONDITION_AL;
513	} else {
514		decoder = _armDecoderTable[((opcode >> 16) & 0xFF0) | ((opcode >> 4) & 0x00F)];
515	}
516	decoder(opcode, info);
517}