all repos — mgba @ 64cc5ada8684b93a0e1835c8e63d0a018aa430d5

mGBA Game Boy Advance Emulator

src/arm/decoder.h (view raw)

  1#ifndef ARM_DECODER_H
  2#define ARM_DECODER_H
  3
  4#include <stdint.h>
  5
  6// Bit 0: a register is involved with this operand
  7// Bit 1: an immediate is invovled with this operand
  8// Bit 2: a memory access is invovled with this operand
  9// Bit 3: the destination of this operand is affected by this opcode
 10// Bit 4: this operand is shifted by a register
 11// Bit 5: this operand is shifted by an immediate
 12enum ARMOperandFormat {
 13	ARM_OPERAND_NONE =               0x00000000,
 14	ARM_OPERAND_REGISTER_1 =         0x00000001,
 15	ARM_OPERAND_IMMEDIATE_1 =        0x00000002,
 16	ARM_OPERAND_MEMORY_1 =           0x00000004,
 17	ARM_OPERAND_AFFECTED_1 =         0x00000008,
 18	ARM_OPERAND_SHIFT_REGISTER_1 =   0x00000010,
 19	ARM_OPERAND_SHIFT_IMMEDIATE_1 =  0x00000020,
 20	ARM_OPERAND_1 =                  0x000000FF,
 21
 22	ARM_OPERAND_REGISTER_2 =         0x00000100,
 23	ARM_OPERAND_IMMEDIATE_2 =        0x00000200,
 24	ARM_OPERAND_MEMORY_2 =           0x00000400,
 25	ARM_OPERAND_AFFECTED_2 =         0x00000800,
 26	ARM_OPERAND_SHIFT_REGISTER_2 =   0x00001000,
 27	ARM_OPERAND_SHIFT_IMMEDIATE_2 =  0x00002000,
 28	ARM_OPERAND_2 =                  0x0000FF00,
 29
 30	ARM_OPERAND_REGISTER_3 =         0x00010000,
 31	ARM_OPERAND_IMMEDIATE_3 =        0x00020000,
 32	ARM_OPERAND_MEMORY_3 =           0x00040000,
 33	ARM_OPERAND_AFFECTED_3 =         0x00080000,
 34	ARM_OPERAND_SHIFT_REGISTER_3 =   0x00100000,
 35	ARM_OPERAND_SHIFT_IMMEDIATE_3 =  0x00200000,
 36	ARM_OPERAND_3 =                  0x00FF0000
 37};
 38
 39enum ARMMemoryFormat {
 40	ARM_MEMORY_REGISTER_BASE =    0x0001,
 41	ARM_MEMORY_IMMEDIATE_OFFSET = 0x0002,
 42	ARM_MEMORY_REGISTER_OFFSET  = 0x0004,
 43	ARM_MEMORY_SHIFTED_OFFSET =   0x0008,
 44	ARM_MEMORY_PRE_INCREMENT =    0x0010,
 45	ARM_MEMORY_POST_INCREMENT =   0x0020,
 46	ARM_MEMORY_OFFSET_SUBTRACT =  0x0040
 47};
 48
 49enum ARMCondition {
 50	ARM_CONDITION_EQ = 0x0,
 51	ARM_CONDITION_NE = 0x1,
 52	ARM_CONDITION_CS = 0x2,
 53	ARM_CONDITION_CC = 0x3,
 54	ARM_CONDITION_MI = 0x4,
 55	ARM_CONDITION_PL = 0x5,
 56	ARM_CONDITION_VS = 0x6,
 57	ARM_CONDITION_VC = 0x7,
 58	ARM_CONDITION_HI = 0x8,
 59	ARM_CONDITION_LS = 0x9,
 60	ARM_CONDITION_GE = 0xA,
 61	ARM_CONDITION_LT = 0xB,
 62	ARM_CONDITION_GT = 0xC,
 63	ARM_CONDITION_LE = 0xD,
 64	ARM_CONDITION_AL = 0xE,
 65	ARM_CONDITION_NV = 0xF
 66};
 67
 68union ARMOperand {
 69	struct {
 70		uint8_t reg;
 71		uint8_t shifterOp;
 72		union {
 73			uint8_t shifterReg;
 74			uint8_t shifterImm;
 75		};
 76	};
 77	int32_t immediate;
 78};
 79
 80enum ARMMultipleDirection {
 81	ARM_DECREMENT_AFTER = 0,
 82	ARM_INCREMENT_AFTER = 1,
 83	ARM_DECREMENT_BEFORE = 2,
 84	ARM_INCREMENT_BEFORE = 3,
 85};
 86
 87enum ARMMemoryAccessType {
 88	ARM_ACCESS_WORD = 4,
 89	ARM_ACCESS_HALFWORD = 2,
 90	ARM_ACCESS_SIGNED_HALFWORD = 10,
 91	ARM_ACCESS_BYTE = 1,
 92	ARM_ACCESS_SIGNED_BYTE = 9
 93};
 94
 95struct ARMMemoryAccess {
 96	uint8_t baseReg;
 97	uint16_t format;
 98	union ARMOperand offset;
 99	union {
100		enum ARMMultipleDirection direction;
101		enum ARMMemoryAccessType width;
102	};
103};
104
105enum ARMMnemonic {
106	ARM_MN_ILL = 0,
107	ARM_MN_ADC,
108	ARM_MN_ADD,
109	ARM_MN_AND,
110	ARM_MN_ASR,
111	ARM_MN_B,
112	ARM_MN_BIC,
113	ARM_MN_BKPT,
114	ARM_MN_BL,
115	ARM_MN_BLH,
116	ARM_MN_BX,
117	ARM_MN_CMN,
118	ARM_MN_CMP,
119	ARM_MN_EOR,
120	ARM_MN_LDM,
121	ARM_MN_LDR,
122	ARM_MN_LSL,
123	ARM_MN_LSR,
124	ARM_MN_MOV,
125	ARM_MN_MUL,
126	ARM_MN_MVN,
127	ARM_MN_NEG,
128	ARM_MN_ORR,
129	ARM_MN_ROR,
130	ARM_MN_SBC,
131	ARM_MN_STM,
132	ARM_MN_STR,
133	ARM_MN_SUB,
134	ARM_MN_SWI,
135	ARM_MN_TST,
136
137	ARM_MN_MAX
138};
139
140struct ARMInstructionInfo {
141	uint32_t opcode;
142	enum ARMMnemonic mnemonic;
143	union ARMOperand op1;
144	union ARMOperand op2;
145	union ARMOperand op3;
146	struct ARMMemoryAccess memory;
147	int operandFormat;
148	int branches;
149	int traps;
150	int affectsCPSR;
151	int condition;
152	int sDataCycles;
153	int nDataCycles;
154	int sInstructionCycles;
155	int nInstructionCycles;
156	int iCycles;
157	int cCycles;
158};
159
160void ARMDecodeThumb(uint16_t opcode, struct ARMInstructionInfo* info);
161int ARMDisassembleThumb(uint16_t opcode, uint32_t pc, char* buffer, int blen);
162
163#endif