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