all repos — mgba @ aefa5f0ab8511dd2f72d3ded479327268072e536

mGBA Game Boy Advance Emulator

src/arm/decoder.h (view raw)

  1#ifndef ARM_DECODER_H
  2#define ARM_DECODER_H
  3
  4#include "arm.h"
  5
  6#include <stdint.h>
  7
  8// Bit 0: a register is involved with this operand
  9// Bit 1: an immediate is invovled with this operand
 10// Bit 2: a memory access is invovled with this operand
 11// Bit 3: the destination of this operand is affected by this opcode
 12// Bit 4: this operand is shifted by a register
 13// Bit 5: this operand is shifted by an immediate
 14enum ARMOperandFormat {
 15	ARM_OPERAND_NONE =               0x00000000,
 16	ARM_OPERAND_REGISTER_1 =         0x00000001,
 17	ARM_OPERAND_IMMEDIATE_1 =        0x00000002,
 18	ARM_OPERAND_MEMORY_1 =           0x00000004,
 19	ARM_OPERAND_AFFECTED_1 =         0x00000008,
 20	ARM_OPERAND_SHIFT_REGISTER_1 =   0x00000010,
 21	ARM_OPERAND_SHIFT_IMMEDIATE_1 =  0x00000020,
 22	ARM_OPERAND_1 =                  0x000000FF,
 23
 24	ARM_OPERAND_REGISTER_2 =         0x00000100,
 25	ARM_OPERAND_IMMEDIATE_2 =        0x00000200,
 26	ARM_OPERAND_MEMORY_2 =           0x00000400,
 27	ARM_OPERAND_AFFECTED_2 =         0x00000800,
 28	ARM_OPERAND_SHIFT_REGISTER_2 =   0x00001000,
 29	ARM_OPERAND_SHIFT_IMMEDIATE_2 =  0x00002000,
 30	ARM_OPERAND_2 =                  0x0000FF00,
 31
 32	ARM_OPERAND_REGISTER_3 =         0x00010000,
 33	ARM_OPERAND_IMMEDIATE_3 =        0x00020000,
 34	ARM_OPERAND_MEMORY_3 =           0x00040000,
 35	ARM_OPERAND_AFFECTED_3 =         0x00080000,
 36	ARM_OPERAND_SHIFT_REGISTER_3 =   0x00100000,
 37	ARM_OPERAND_SHIFT_IMMEDIATE_3 =  0x00200000,
 38	ARM_OPERAND_3 =                  0x00FF0000,
 39
 40	ARM_OPERAND_REGISTER_4 =         0x01000000,
 41	ARM_OPERAND_IMMEDIATE_4 =        0x02000000,
 42	ARM_OPERAND_MEMORY_4 =           0x04000000,
 43	ARM_OPERAND_AFFECTED_4 =         0x08000000,
 44	ARM_OPERAND_SHIFT_REGISTER_4 =   0x10000000,
 45	ARM_OPERAND_SHIFT_IMMEDIATE_4 =  0x20000000,
 46	ARM_OPERAND_4 =                  0xFF000000
 47};
 48
 49enum ARMMemoryFormat {
 50	ARM_MEMORY_REGISTER_BASE =    0x0001,
 51	ARM_MEMORY_IMMEDIATE_OFFSET = 0x0002,
 52	ARM_MEMORY_REGISTER_OFFSET  = 0x0004,
 53	ARM_MEMORY_SHIFTED_OFFSET =   0x0008,
 54	ARM_MEMORY_PRE_INCREMENT =    0x0010,
 55	ARM_MEMORY_POST_INCREMENT =   0x0020,
 56	ARM_MEMORY_OFFSET_SUBTRACT =  0x0040,
 57	ARM_MEMORY_WRITEBACK =        0x0080,
 58	ARM_MEMORY_DECREMENT_AFTER =  0x0000,
 59	ARM_MEMORY_INCREMENT_AFTER =  0x0100,
 60	ARM_MEMORY_DECREMENT_BEFORE = 0x0200,
 61	ARM_MEMORY_INCREMENT_BEFORE = 0x0300,
 62};
 63
 64#define MEMORY_FORMAT_TO_DIRECTION(F) (((F) >> 8) & 0x7)
 65
 66enum ARMCondition {
 67	ARM_CONDITION_EQ = 0x0,
 68	ARM_CONDITION_NE = 0x1,
 69	ARM_CONDITION_CS = 0x2,
 70	ARM_CONDITION_CC = 0x3,
 71	ARM_CONDITION_MI = 0x4,
 72	ARM_CONDITION_PL = 0x5,
 73	ARM_CONDITION_VS = 0x6,
 74	ARM_CONDITION_VC = 0x7,
 75	ARM_CONDITION_HI = 0x8,
 76	ARM_CONDITION_LS = 0x9,
 77	ARM_CONDITION_GE = 0xA,
 78	ARM_CONDITION_LT = 0xB,
 79	ARM_CONDITION_GT = 0xC,
 80	ARM_CONDITION_LE = 0xD,
 81	ARM_CONDITION_AL = 0xE,
 82	ARM_CONDITION_NV = 0xF
 83};
 84
 85enum ARMShifterOperation {
 86	ARM_SHIFT_NONE = 0,
 87	ARM_SHIFT_LSL,
 88	ARM_SHIFT_LSR,
 89	ARM_SHIFT_ASR,
 90	ARM_SHIFT_ROR,
 91	ARM_SHIFT_RRX
 92};
 93
 94union ARMOperand {
 95	struct {
 96		uint8_t reg;
 97		enum ARMShifterOperation shifterOp;
 98		union {
 99			uint8_t shifterReg;
100			uint8_t shifterImm;
101		};
102	};
103	int32_t immediate;
104};
105
106enum ARMMemoryAccessType {
107	ARM_ACCESS_WORD = 4,
108	ARM_ACCESS_HALFWORD = 2,
109	ARM_ACCESS_SIGNED_HALFWORD = 10,
110	ARM_ACCESS_BYTE = 1,
111	ARM_ACCESS_SIGNED_BYTE = 9,
112	ARM_ACCESS_TRANSLATED_WORD = 20,
113	ARM_ACCESS_TRANSLATED_BYTE = 17
114};
115
116struct ARMMemoryAccess {
117	uint8_t baseReg;
118	uint16_t format;
119	union ARMOperand offset;
120	enum ARMMemoryAccessType width;
121};
122
123enum ARMMnemonic {
124	ARM_MN_ILL = 0,
125	ARM_MN_ADC,
126	ARM_MN_ADD,
127	ARM_MN_AND,
128	ARM_MN_ASR,
129	ARM_MN_B,
130	ARM_MN_BIC,
131	ARM_MN_BKPT,
132	ARM_MN_BL,
133	ARM_MN_BLH,
134	ARM_MN_BX,
135	ARM_MN_CMN,
136	ARM_MN_CMP,
137	ARM_MN_EOR,
138	ARM_MN_LDM,
139	ARM_MN_LDR,
140	ARM_MN_LSL,
141	ARM_MN_LSR,
142	ARM_MN_MLA,
143	ARM_MN_MOV,
144	ARM_MN_MRS,
145	ARM_MN_MSR,
146	ARM_MN_MUL,
147	ARM_MN_MVN,
148	ARM_MN_NEG,
149	ARM_MN_ORR,
150	ARM_MN_ROR,
151	ARM_MN_RSB,
152	ARM_MN_RSC,
153	ARM_MN_SBC,
154	ARM_MN_SMLAL,
155	ARM_MN_SMULL,
156	ARM_MN_STM,
157	ARM_MN_STR,
158	ARM_MN_SUB,
159	ARM_MN_SWI,
160	ARM_MN_SWP,
161	ARM_MN_TEQ,
162	ARM_MN_TST,
163	ARM_MN_UMLAL,
164	ARM_MN_UMULL,
165
166	ARM_MN_MAX
167};
168
169enum {
170	ARM_CPSR = 16,
171	ARM_SPSR = 17
172};
173
174struct ARMInstructionInfo {
175	enum ExecutionMode execMode;
176	uint32_t opcode;
177	enum ARMMnemonic mnemonic;
178	union ARMOperand op1;
179	union ARMOperand op2;
180	union ARMOperand op3;
181	union ARMOperand op4;
182	struct ARMMemoryAccess memory;
183	int operandFormat;
184	int branches;
185	int traps;
186	int affectsCPSR;
187	int condition;
188	int sDataCycles;
189	int nDataCycles;
190	int sInstructionCycles;
191	int nInstructionCycles;
192	int iCycles;
193	int cCycles;
194};
195
196void ARMDecodeARM(uint32_t opcode, struct ARMInstructionInfo* info);
197void ARMDecodeThumb(uint16_t opcode, struct ARMInstructionInfo* info);
198int ARMDisassemble(struct ARMInstructionInfo* info, uint32_t pc, char* buffer, int blen);
199
200#endif