1use crate::{
4 conditions::Condition,
5 registers::{Register, SpecialRegister},
6};
7
8#[derive(Debug)]
10pub struct Instruction {
11 pub width: InstructionWidth,
12 pub operation: Operation,
13}
14
15#[derive(Debug)]
17pub enum InstructionWidth {
18 Bit32,
19 Bit16,
20}
21
22impl Instruction {
23 pub fn is_16bit(&self) -> bool {
25 matches!(self.width, InstructionWidth::Bit16)
26 }
27
28 pub fn is_32bit(&self) -> bool {
30 matches!(self.width, InstructionWidth::Bit32)
31 }
32}
33
34#[derive(Debug)]
36pub enum Operation {
37 ADCReg {
38 m: Register,
39 n: Register,
40 d: Register,
41 },
42 ADDImm {
43 imm: u32,
44 n: Register,
45 d: Register,
46 },
47 ADDReg {
48 m: Register,
49 n: Register,
50 d: Register,
51 },
52 ADDImmSP {
53 d: Register,
54 imm: u32,
55 },
56 ADDRegSP {
57 d: Register,
58 m: Register,
59 },
60 ADR {
61 d: Register,
62 imm: u32,
63 },
64 ANDReg {
65 m: Register,
66 dn: Register,
67 },
68 ASRImm {
69 imm: u32,
70 m: Register,
71 d: Register,
72 },
73 ASRReg {
74 m: Register,
75 dn: Register,
76 },
77 B {
78 cond: Condition,
79 imm: u32,
80 },
81 BICReg {
82 m: Register,
83 dn: Register,
84 },
85 BKPT {
86 imm: u32,
87 },
88 BL {
89 imm: u32,
90 },
91 BLXReg {
92 m: Register,
93 },
94 BX {
95 m: Register,
96 },
97 CMNReg {
98 m: Register,
99 n: Register,
100 },
101 CMPImm {
102 n: Register,
103 imm: u32,
104 },
105 CMPReg {
106 m: Register,
107 n: Register,
108 },
109 CPS {
110 im: bool,
111 },
112 CPY,
113 DMB {
114 option: u8,
115 },
116 DSB {
117 option: u8,
118 },
119 EORReg {
120 m: Register,
121 dn: Register,
122 },
123 ISB {
124 option: u8,
125 },
126 LDM {
127 n: Register,
128 reg_list: Vec<Register>,
129 },
130 LDRImm {
131 imm: u32,
132 n: Register,
133 t: Register,
134 },
135 LDRLiteral {
136 t: Register,
137 imm: u32,
138 },
139 LDRReg {
140 m: Register,
141 n: Register,
142 t: Register,
143 },
144 LDRBImm {
145 imm: u32,
146 n: Register,
147 t: Register,
148 },
149 LDRBReg {
150 m: Register,
151 n: Register,
152 t: Register,
153 },
154 LDRHImm {
155 imm: u32,
156 n: Register,
157 t: Register,
158 },
159 LDRHReg {
160 m: Register,
161 n: Register,
162 t: Register,
163 },
164 LDRSBReg {
165 m: Register,
166 n: Register,
167 t: Register,
168 },
169 LDRSH {
170 m: Register,
171 n: Register,
172 t: Register,
173 },
174 LSLImm {
175 imm: u32,
176 m: Register,
177 d: Register,
178 },
179 LSLReg {
180 m: Register,
181 dn: Register,
182 },
183 LSRImm {
184 imm: u32,
185 m: Register,
186 d: Register,
187 },
188 LSRReg {
189 m: Register,
190 dn: Register,
191 },
192 MOVImm {
193 d: Register,
194 imm: u32,
195 },
196 MOVReg {
197 m: Register,
198 d: Register,
199 set_flags: bool,
200 },
201 MRS {
202 d: Register,
203 sysm: SpecialRegister,
204 },
205 MSRReg {
206 n: Register,
207 sysm: SpecialRegister,
208 },
209 MUL {
210 n: Register,
211 dm: Register,
212 },
213 MVNReg {
214 m: Register,
215 d: Register,
216 },
217 NOP,
218 ORRReg {
219 m: Register,
220 dn: Register,
221 },
222 POP {
223 reg_list: Vec<Register>,
224 },
225 PUSH {
226 reg_list: Vec<Register>,
227 },
228 REV {
229 m: Register,
230 d: Register,
231 },
232 REV16 {
233 m: Register,
234 d: Register,
235 },
236 REVSH {
237 m: Register,
238 d: Register,
239 },
240 RORReg {
241 m: Register,
242 dn: Register,
243 },
244 RSBImm {
245 n: Register,
246 d: Register,
247 },
248 SBCReg {
249 m: Register,
250 dn: Register,
251 },
252 SEV,
253 STM {
254 n: Register,
255 reg_list: Vec<Register>,
256 },
257 STRImm {
258 imm: u32,
259 n: Register,
260 t: Register,
261 },
262 STRReg {
263 m: Register,
264 n: Register,
265 t: Register,
266 },
267 STRBImm {
268 imm: u32,
269 n: Register,
270 t: Register,
271 },
272 STRBReg {
273 m: Register,
274 n: Register,
275 t: Register,
276 },
277 STRHImm {
278 imm: u32,
279 n: Register,
280 t: Register,
281 },
282 STRHReg {
283 m: Register,
284 n: Register,
285 t: Register,
286 },
287 SUBImm {
288 imm: u32,
289 n: Register,
290 d: Register,
291 },
292 SUBReg {
293 m: Register,
294 n: Register,
295 d: Register,
296 },
297 SUBImmSP {
298 imm: u32,
299 },
300 SVC {
301 imm: u32,
302 },
303 SXTB {
304 m: Register,
305 d: Register,
306 },
307 SXTH {
308 m: Register,
309 d: Register,
310 },
311 TSTReg {
312 m: Register,
313 n: Register,
314 },
315 UDF {
316 imm: u32,
317 },
318 UXTB {
319 m: Register,
320 d: Register,
321 },
322 UXTH {
323 m: Register,
324 d: Register,
325 },
326 WFE,
327 WFI,
328 YIELD,
329}
330
331#[cfg(test)]
332mod test {
333 use super::*;
334
335 #[test]
336 fn instruction_size() {
337 let instruction_32 = Instruction {
338 width: InstructionWidth::Bit32,
339 operation: Operation::NOP,
340 };
341 assert_eq!(instruction_32.is_32bit(), true);
342 assert_eq!(instruction_32.is_16bit(), false);
343
344 let instruction_16 = Instruction {
345 width: InstructionWidth::Bit16,
346 operation: Operation::NOP,
347 };
348 assert_eq!(instruction_16.is_32bit(), false);
349 assert_eq!(instruction_16.is_16bit(), true);
350 }
351}