1pub mod conditions;
18pub mod instructons;
19pub mod registers;
20
21use conditions::Condition;
22use instructons::*;
23use registers::*;
24use tracing::debug;
25
26pub fn parse(input: &[u8]) -> Result<Instruction, &str> {
29 if input.len() < 2 {
30 return Err("input not long enough for a instruction");
31 }
32 let mut instruction_bytes1: [u8; 2] = [0; 2];
33 instruction_bytes1.copy_from_slice(&input[0..2]);
34 let instruction_bits1 = u16::from_le_bytes(instruction_bytes1);
35
36 match (instruction_bits1 >> 11) & 0x1f {
37 0b11101 | 0b11110 | 0b11111 => {
38 if input.len() < 4 {
40 return Err("32 bit instruction not long enough");
41 };
42 let mut instruction_bytes2: [u8; 2] = [0; 2];
43 instruction_bytes2.copy_from_slice(&input[2..4]);
44 let instruction_bits2 = u16::from_le_bytes(instruction_bytes2);
45 let instruction_bits: u32 = (instruction_bits1 as u32) << 16 | instruction_bits2 as u32;
46 debug!("instruction bits: {:#034b}", instruction_bits);
47 Ok(Instruction {
48 width: InstructionWidth::Bit32,
49 operation: parse_32bit_operation(instruction_bits)?,
50 })
51 }
52 _ => {
53 debug!("instruction bits: {:#018b}", instruction_bits1);
54 Ok(Instruction {
55 width: InstructionWidth::Bit16,
56 operation: parse_16bit_operation(instruction_bits1)?,
57 })
58 }
59 }
60}
61
62fn parse_32bit_operation(input: u32) -> Result<Operation, &'static str> {
63 let op1 = (input >> 27) & 0x3;
64 let op = (input >> 15) & 0x1;
65
66 match (op1, op) {
67 (0b10, 0b1) => {
68 parse_branch_misc_ctrl(input)
70 }
71 (_, _) => Err("opcode not matching valid 32 bit instruction"),
72 }
73}
74
75fn parse_branch_misc_ctrl(input: u32) -> Result<Operation, &'static str> {
76 let op1 = (input >> 20) & 0x7f;
77 let op2 = (input >> 12) & 0x7;
78
79 match (op2, op1) {
80 (0b000 | 0b010, 0b0111000..=0b0111001) => {
81 let rn = (((input >> 16) & 0xf) as u8).try_into().unwrap();
83 let sysm = ((input & 0xff) as u8).try_into()?; Ok(Operation::MSRReg { n: rn, sysm: sysm })
85 }
86 (0b000 | 0b010, 0b0111011) => {
87 parse_misc_ctrl(input)
89 }
90 (0b000 | 0b010, 0b0111110..=0b0111111) => {
91 let rd = (((input >> 8) & 0xf) as u8).try_into().unwrap();
93 let sysm = ((input & 0xff) as u8).try_into()?;
94 Ok(Operation::MRS { d: rd, sysm: sysm })
95 }
96 (0b010, 0b1111111) => {
97 let imm = ((input & 0xf0000) >> 4) | (input & 0xfff);
98 Ok(Operation::UDF { imm: imm })
99 }
100 (0b101 | 0b111, _) => {
101 let s = (input >> 26) & 0x1;
103 let j1 = (input >> 13) & 0x1;
104 let j2 = (input >> 11) & 0x1;
105 let i1 = !(j1 ^ s) & 0x1;
106 let i2 = !(j2 ^ s) & 0x1;
107 let imm10 = (input >> 16) & 0x3ff;
108 let imm11 = input & 0x7ff;
109 let imm = ((s << 24) | (i1 << 23) | (i2 << 22) | (imm10 << 12) | (imm11 << 1))
110 .sign_extend(25);
111
112 Ok(Operation::BL { imm: imm })
113 }
114 _ => Err("opcode not matching valid 32 bit instruction"),
115 }
116}
117
118fn parse_misc_ctrl(input: u32) -> Result<Operation, &'static str> {
119 let op = (input >> 4) & 0xf;
120
121 match op {
122 0b0100 => {
123 let option = input & 0xf;
124 Ok(Operation::DSB {
125 option: option as u8,
126 })
127 }
128 0b0101 => {
129 let option = input & 0xf;
130 Ok(Operation::DMB {
131 option: option as u8,
132 })
133 }
134 0b0110 => {
135 let option = input & 0xf;
136 Ok(Operation::ISB {
137 option: option as u8,
138 })
139 }
140 _ => Err("Not a valid op code"),
141 }
142}
143
144fn parse_16bit_operation(input: u16) -> Result<Operation, &'static str> {
145 let opcode = (input >> 10) & 0x3f;
146 match opcode {
147 0b000000..=0b001111 => {
148 parse_arith_instructions(input) }
150 0b010000 => {
151 parse_data_processing_instruction(input) }
153 0b010001 => {
154 parse_special_data_branch_exchange_instruction(input) }
156 0b010010..=0b010011 => {
157 let rt: Register = (((input >> 8) & 0x7) as u8).try_into().unwrap();
160 let imm = ((input & 0xff) << 2) as u32;
161 Ok(Operation::LDRLiteral { t: rt, imm: imm })
162 }
163 0b010100..=0b100111 => {
164 parse_load_store_instruction(input)
166 }
167 0b101000..=0b101001 => {
168 let rd: Register = (((input >> 8) & 0x7) as u8).try_into().unwrap();
170 let imm = ((input & 0xff) << 2) as u32;
171 Ok(Operation::ADR { d: rd, imm: imm })
172 }
173 0b101010..=0b101011 => {
174 let rd: Register = (((input >> 8) & 0x7) as u8).try_into().unwrap();
176 let imm = ((input & 0xff) << 2) as u32;
177 Ok(Operation::ADDImmSP { d: rd, imm: imm })
178 }
179 0b101100..=0b101111 => {
180 parse_misc_16_bit(input) }
182 0b110000..=0b110001 => {
183 let rn: Register = (((input >> 8) & 0x7) as u8).try_into().unwrap();
185 let reg_list_bits = input & 0xff;
186 let reg_list = register_list_from_bit_array(reg_list_bits);
187 Ok(Operation::STM {
188 n: rn,
189 reg_list: reg_list,
190 })
191 }
192 0b110010..=0b110011 => {
193 let rn: Register = (((input >> 8) & 0x7) as u8).try_into().unwrap();
195 let reg_list_bits = input & 0xff;
196 let reg_list = register_list_from_bit_array(reg_list_bits);
197 Ok(Operation::LDM {
198 n: rn,
199 reg_list: reg_list,
200 })
201 }
202 0b110100..=0b110111 => {
203 parse_conditional_branch(input)
205 }
206 0b111000..=0b111001 => {
207 let imm = ((input & 0x7ff) << 1).sign_extend(12);
210 Ok(Operation::B {
211 cond: Condition::None,
212 imm: imm,
213 })
214 }
215 _ => Err("not a valid opcode"),
216 }
217}
218
219fn parse_conditional_branch(input: u16) -> Result<Operation, &'static str> {
220 let opcode = (input >> 8) & 0xf;
221
222 match opcode {
223 0b1110 => {
224 let imm = (input & 0xff) as u32;
227 Ok(Operation::UDF { imm })
228 },
229 0b1111 => {
230 let imm = (input & 0xff) as u32;
232 Ok(Operation::SVC { imm: imm })
233 }
234 _ => {
235 let imm = ((input & 0xff) << 1).sign_extend(9);
237 let cond: Condition = (((input >> 8) & 0xf) as u8).try_into()?;
238 Ok(Operation::B {
239 cond: cond,
240 imm: imm,
241 })
242 }
243 }
244}
245
246fn parse_load_store_instruction(input: u16) -> Result<Operation, &'static str> {
247 let op_a = (input >> 12) & 0xf;
248 let op_b = (input >> 9) & 0x7;
249
250 match (op_a, op_b) {
251 (0b0101, op_b) => match op_b {
252 0b000 => {
253 let rm: Register = (((input >> 6) & 0x7) as u8).try_into().unwrap();
255 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
256 let rt: Register = ((input & 0x7) as u8).try_into().unwrap();
257 Ok(Operation::STRReg {
258 m: rm,
259 n: rn,
260 t: rt,
261 })
262 }
263 0b001 => {
264 let rm: Register = (((input >> 6) & 0x7) as u8).try_into().unwrap();
266 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
267 let rt: Register = ((input & 0x7) as u8).try_into().unwrap();
268 Ok(Operation::STRHReg {
269 m: rm,
270 n: rn,
271 t: rt,
272 })
273 }
274 0b010 => {
275 let rm: Register = (((input >> 6) & 0x7) as u8).try_into().unwrap();
277 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
278 let rt: Register = ((input & 0x7) as u8).try_into().unwrap();
279 Ok(Operation::STRBReg {
280 m: rm,
281 n: rn,
282 t: rt,
283 })
284 }
285 0b011 => {
286 let rm: Register = (((input >> 6) & 0x7) as u8).try_into().unwrap();
288 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
289 let rt: Register = ((input & 0x7) as u8).try_into().unwrap();
290 Ok(Operation::LDRSBReg {
291 m: rm,
292 n: rn,
293 t: rt,
294 })
295 }
296 0b100 => {
297 let rm: Register = (((input >> 6) & 0x7) as u8).try_into().unwrap();
299 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
300 let rt: Register = ((input & 0x7) as u8).try_into().unwrap();
301 Ok(Operation::LDRReg {
302 m: rm,
303 n: rn,
304 t: rt,
305 })
306 }
307 0b101 => {
308 let rm: Register = (((input >> 6) & 0x7) as u8).try_into().unwrap();
310 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
311 let rt: Register = ((input & 0x7) as u8).try_into().unwrap();
312 Ok(Operation::LDRHReg {
313 m: rm,
314 n: rn,
315 t: rt,
316 })
317 }
318 0b110 => {
319 let rm: Register = (((input >> 6) & 0x7) as u8).try_into().unwrap();
321 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
322 let rt: Register = ((input & 0x7) as u8).try_into().unwrap();
323 Ok(Operation::LDRBReg {
324 m: rm,
325 n: rn,
326 t: rt,
327 })
328 }
329 0b111 => {
330 let rm: Register = (((input >> 6) & 0x7) as u8).try_into().unwrap();
332 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
333 let rt: Register = ((input & 0x7) as u8).try_into().unwrap();
334 Ok(Operation::LDRSH {
335 m: rm,
336 n: rn,
337 t: rt,
338 })
339 }
340 _ => Err("Invalid opcode"),
341 },
342 (0b0110, op_b) => match op_b {
343 0b000..=0b011 => {
344 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
346 let rt: Register = ((input & 0x7) as u8).try_into().unwrap();
347 let imm = ((input & 0x7c0) >> 4) as u32;
348 Ok(Operation::STRImm {
349 imm: imm,
350 n: rn,
351 t: rt,
352 })
353 }
354 0b100..=0b111 => {
355 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
357 let rt: Register = ((input & 0x7) as u8).try_into().unwrap();
358 let imm = ((input & 0x7c0) >> 4) as u32;
359 Ok(Operation::LDRImm {
360 imm: imm,
361 n: rn,
362 t: rt,
363 })
364 }
365 _ => Err("Invalid opcode"),
366 },
367 (0b0111, op_b) => match op_b {
368 0b000..=0b011 => {
369 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
371 let rt: Register = ((input & 0x7) as u8).try_into().unwrap();
372 let imm = ((input & 0x7c0) >> 6) as u32;
373 Ok(Operation::STRBImm {
374 imm: imm,
375 n: rn,
376 t: rt,
377 })
378 }
379 0b100..=0b111 => {
380 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
382 let rt: Register = ((input & 0x7) as u8).try_into().unwrap();
383 let imm = ((input & 0x7c0) >> 6) as u32;
384 Ok(Operation::LDRBImm {
385 imm: imm,
386 n: rn,
387 t: rt,
388 })
389 }
390 _ => Err("Invalid opcode"),
391 },
392 (0b1000, op_b) => match op_b {
393 0b000..=0b011 => {
394 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
396 let rt: Register = ((input & 0x7) as u8).try_into().unwrap();
397 let imm = ((input & 0x7c0) >> 5) as u32;
398 Ok(Operation::STRHImm {
399 imm: imm,
400 n: rn,
401 t: rt,
402 })
403 }
404 0b100..=0b111 => {
405 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
407 let rt: Register = ((input & 0x7) as u8).try_into().unwrap();
408 let imm = ((input & 0x7c0) >> 5) as u32;
409 Ok(Operation::LDRHImm {
410 imm: imm,
411 n: rn,
412 t: rt,
413 })
414 }
415 _ => Err("Invalid opcode"),
416 },
417 (0b1001, op_b) => match op_b {
418 0b000..=0b011 => {
419 let rt: Register = (((input >> 8) & 0x7) as u8).try_into().unwrap();
421 let imm = ((input & 0xff) << 2) as u32;
422 Ok(Operation::STRImm {
423 n: Register::SP,
424 t: rt,
425 imm: imm,
426 })
427 }
428 0b100..=0b111 => {
429 let rt: Register = (((input >> 8) & 0x7) as u8).try_into().unwrap();
431 let imm = ((input & 0xff) << 2) as u32;
432 Ok(Operation::LDRImm {
433 n: Register::SP,
434 t: rt,
435 imm: imm,
436 })
437 }
438 _ => Err("Invalid opcode"),
439 },
440 (_, _) => Err("Invalid opcode"),
441 }
442}
443
444fn parse_special_data_branch_exchange_instruction(input: u16) -> Result<Operation, &'static str> {
445 let opcode = (input >> 6) & 0xf;
446 match opcode {
447 0b0000..=0b0011 => {
448 let rm: Register = (((input >> 3) & 0xf) as u8).try_into().unwrap();
450 let rdn: Register = (((input & 0x7) | ((input >> 4) & 0b1000)) as u8)
451 .try_into()
452 .unwrap();
453 if rdn == Register::SP || rm == Register::SP {
454 if rm == Register::SP {
455 Ok(Operation::ADDRegSP { d: rdn, m: rdn })
457 } else {
458 Ok(Operation::ADDRegSP {
460 d: Register::SP,
461 m: rm,
462 })
463 }
464 } else {
465 Ok(Operation::ADDReg {
467 m: rm,
468 n: rdn,
469 d: rdn,
470 })
471 }
472 }
473 0b0100 => Err("unpredictable"), 0b0101 | 0b0110..=0b0111 => {
475 let rm: Register = (((input >> 3) & 0xf) as u8).try_into().unwrap();
476 let rn: Register = (((input & 0x7) | ((input >> 4) & 0b1000)) as u8)
477 .try_into()
478 .unwrap();
479 Ok(Operation::CMPReg { m: rm, n: rn })
480 }
481 0b1000..=0b1011 => {
482 let rm: Register = (((input >> 3) & 0xf) as u8).try_into().unwrap();
483 let rd: Register = (((input & 0x7) | ((input >> 4) & 0b1000)) as u8)
484 .try_into()
485 .unwrap();
486 Ok(Operation::MOVReg {
487 set_flags: false,
488 m: rm,
489 d: rd,
490 })
491 }
492 0b1100..=0b1101 => {
493 let rm: Register = (((input >> 3) & 0xf) as u8).try_into().unwrap();
494 Ok(Operation::BX { m: rm })
495 }
496 0b1110..=0b1111 => {
497 let rm: Register = (((input >> 3) & 0xf) as u8).try_into().unwrap();
498 Ok(Operation::BLXReg { m: rm })
499 }
500 _ => Err("invalid opcode"),
501 }
502}
503
504fn parse_data_processing_instruction(input: u16) -> Result<Operation, &'static str> {
505 let opcode = (input >> 6) & 0xf;
506 match opcode {
507 0b0000 => {
508 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
509 let rdn: Register = ((input & 0x7) as u8).try_into().unwrap();
510 Ok(Operation::ANDReg { m: rm, dn: rdn })
511 }
512 0b0001 => {
513 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
514 let rdn: Register = ((input & 0x7) as u8).try_into().unwrap();
515 Ok(Operation::EORReg { m: rm, dn: rdn })
516 }
517 0b0010 => {
518 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
519 let rdn: Register = ((input & 0x7) as u8).try_into().unwrap();
520 Ok(Operation::LSLReg { m: rm, dn: rdn })
521 }
522 0b0011 => {
523 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
524 let rdn: Register = ((input & 0x7) as u8).try_into().unwrap();
525 Ok(Operation::LSRReg { m: rm, dn: rdn })
526 }
527 0b0100 => {
528 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
529 let rdn: Register = ((input & 0x7) as u8).try_into().unwrap();
530 Ok(Operation::ASRReg { m: rm, dn: rdn })
531 }
532 0b0101 => {
533 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
534 let rdn: Register = ((input & 0x7) as u8).try_into().unwrap();
535 Ok(Operation::ADCReg {
536 m: rm,
537 n: rdn,
538 d: rdn,
539 })
540 }
541 0b0110 => {
542 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
543 let rdn: Register = ((input & 0x7) as u8).try_into().unwrap();
544 Ok(Operation::SBCReg { m: rm, dn: rdn })
545 }
546 0b0111 => {
547 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
548 let rdn: Register = ((input & 0x7) as u8).try_into().unwrap();
549 Ok(Operation::RORReg { m: rm, dn: rdn })
550 }
551 0b1000 => {
552 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
553 let rn: Register = ((input & 0x7) as u8).try_into().unwrap();
554 Ok(Operation::TSTReg { m: rm, n: rn })
555 }
556 0b1001 => {
557 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
558 let rd: Register = ((input & 0x7) as u8).try_into().unwrap();
559 Ok(Operation::RSBImm { n: rn, d: rd })
560 }
561 0b1010 => {
562 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
563 let rn: Register = ((input & 0x7) as u8).try_into().unwrap();
564 Ok(Operation::CMPReg { m: rm, n: rn })
565 }
566 0b1011 => {
567 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
568 let rn: Register = ((input & 0x7) as u8).try_into().unwrap();
569 Ok(Operation::CMNReg { m: rm, n: rn })
570 }
571 0b1100 => {
572 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
573 let rdn: Register = ((input & 0x7) as u8).try_into().unwrap();
574 Ok(Operation::ORRReg { m: rm, dn: rdn })
575 }
576 0b1101 => {
577 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
578 let rdm: Register = ((input & 0x7) as u8).try_into().unwrap();
579 Ok(Operation::MUL { n: rn, dm: rdm })
580 }
581 0b1110 => {
582 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
583 let rdn: Register = ((input & 0x7) as u8).try_into().unwrap();
584 Ok(Operation::BICReg { m: rm, dn: rdn })
585 }
586 0b1111 => {
587 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
588 let rd: Register = ((input & 0x7) as u8).try_into().unwrap();
589 Ok(Operation::MVNReg { m: rm, d: rd })
590 }
591 _ => Err("invalid opcode"),
592 }
593}
594
595fn parse_arith_instructions(input: u16) -> Result<Operation, &'static str> {
596 let opcode = (input >> 9) & 0x1f;
598 match opcode {
599 0b00000..=0b00011 => {
600 let imm = (input >> 6) & 0x1f;
602 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
603 let rd: Register = ((input & 0x7) as u8).try_into().unwrap();
604 if imm > 0 {
605 Ok(Operation::LSLImm {
606 imm: imm as u32,
607 m: rm,
608 d: rd,
609 })
610 } else {
611 Ok(Operation::MOVReg {
612 set_flags: true,
613 m: rm,
614 d: rd,
615 })
616 }
617 }
618 0b00100..=0b00111 => {
619 let imm = (input >> 6) & 0x1f;
621 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
622 let rd: Register = ((input & 0x7) as u8).try_into().unwrap();
623 Ok(Operation::LSRImm {
624 imm: imm as u32,
625 m: rm,
626 d: rd,
627 })
628 }
629 0b01000..=0b01011 => {
630 let imm = (input >> 6) & 0x1f;
632 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
633 let rd: Register = ((input & 0x7) as u8).try_into().unwrap();
634 Ok(Operation::ASRImm {
635 imm: imm as u32,
636 m: rm,
637 d: rd,
638 })
639 }
640 0b01100 => {
641 let rm: Register = (((input >> 6) & 0x7) as u8).try_into().unwrap();
643 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
644 let rd: Register = ((input & 0x7) as u8).try_into().unwrap();
645 Ok(Operation::ADDReg {
646 m: rm,
647 n: rn,
648 d: rd,
649 })
650 }
651 0b01101 => {
652 let rm: Register = (((input >> 6) & 0x7) as u8).try_into().unwrap();
654 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
655 let rd: Register = ((input & 0x7) as u8).try_into().unwrap();
656 Ok(Operation::SUBReg {
657 m: rm,
658 n: rn,
659 d: rd,
660 })
661 }
662 0b01110 => {
663 let imm = (input >> 6) & 0x7;
665 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
666 let rd: Register = ((input & 0x7) as u8).try_into().unwrap();
667 Ok(Operation::ADDImm {
668 imm: imm as u32,
669 n: rn,
670 d: rd,
671 })
672 }
673 0b01111 => {
674 let imm: Register = (((input >> 6) & 0x7) as u8).try_into().unwrap();
676 let rn: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
677 let rd: Register = ((input & 0x7) as u8).try_into().unwrap();
678 Ok(Operation::SUBImm {
679 imm: imm as u32,
680 n: rn,
681 d: rd,
682 })
683 }
684 0b10000..=0b10011 => {
685 let imm = input & 0xff;
687 let rd: Register = (((input >> 8) & 0x7) as u8).try_into().unwrap();
688 Ok(Operation::MOVImm {
689 d: rd,
690 imm: imm as u32,
691 })
692 }
693 0b10100..=0b10111 => {
694 let imm = input & 0xff;
696 let rn: Register = (((input >> 8) & 0x7) as u8).try_into().unwrap();
697 Ok(Operation::CMPImm {
698 n: rn,
699 imm: imm as u32,
700 })
701 }
702 0b11000..=0b11011 => {
703 let imm = input & 0xff;
705 let rdn: Register = (((input >> 8) & 0x7) as u8).try_into().unwrap();
706 Ok(Operation::ADDImm {
707 imm: imm as u32,
708 n: rdn,
709 d: rdn,
710 })
711 }
712 0b11100..=0b11111 => {
713 let imm = input & 0xff;
715 let rdn: Register = (((input >> 8) & 0x7) as u8).try_into().unwrap();
716 Ok(Operation::SUBImm {
717 n: rdn,
718 d: rdn,
719 imm: imm as u32,
720 })
721 }
722 _ => Err("Not a valid opcode"),
723 }
724}
725
726fn parse_misc_16_bit(input: u16) -> Result<Operation, &'static str> {
727 let opcode = (input >> 5) & 0x7f;
728 match opcode {
729 0b0000000..=0b0000011 => {
730 let imm = (input & 0x7f) << 2;
733 Ok(Operation::ADDImmSP {
734 d: Register::SP,
735 imm: imm as u32,
736 })
737 }
738 0b0000100..=0b0000111 => {
739 let imm = (input & 0x7f) << 2;
742 Ok(Operation::SUBImmSP { imm: imm as u32 })
743 }
744 0b0010000..=0b0010001 => {
745 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
748 let rd: Register = ((input & 0x7) as u8).try_into().unwrap();
749
750 Ok(Operation::SXTH { m: rm, d: rd })
751 }
752 0b0010010..=0b0010011 => {
753 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
756 let rd: Register = ((input & 0x7) as u8).try_into().unwrap();
757
758 Ok(Operation::SXTB { m: rm, d: rd })
759 }
760 0b0010100..=0b0010101 => {
761 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
764 let rd: Register = ((input & 0x7) as u8).try_into().unwrap();
765
766 Ok(Operation::UXTH { m: rm, d: rd })
767 }
768 0b0010110..=0b0010111 => {
769 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
772 let rd: Register = ((input & 0x7) as u8).try_into().unwrap();
773
774 Ok(Operation::UXTB { m: rm, d: rd })
775 }
776 0b0100000..=0b0101111 => {
777 let reg_list_bits = (((input >> 8) & 0b1) << 14) | (input & 0xff);
780 let reg_list = register_list_from_bit_array(reg_list_bits);
781 Ok(Operation::PUSH { reg_list: reg_list })
782 }
783 0b0110011 => {
784 let im = ((input >> 4) & 0b1) == 1;
787 Ok(Operation::CPS { im: im })
788 }
789 0b1010000..=0b1010001 => {
790 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
793 let rd: Register = ((input & 0x7) as u8).try_into().unwrap();
794
795 Ok(Operation::REV { m: rm, d: rd })
796 }
797 0b1010010..=0b1010011 => {
798 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
801 let rd: Register = ((input & 0x7) as u8).try_into().unwrap();
802
803 Ok(Operation::REV16 { m: rm, d: rd })
804 }
805 0b1010110..=0b1010111 => {
806 let rm: Register = (((input >> 3) & 0x7) as u8).try_into().unwrap();
809 let rd: Register = ((input & 0x7) as u8).try_into().unwrap();
810
811 Ok(Operation::REVSH { m: rm, d: rd })
812 }
813 0b1100000..=0b1101111 => {
814 let reg_list_bits = (((input >> 8) & 0b1) << 15) | (input & 0xff);
817 let reg_list = register_list_from_bit_array(reg_list_bits);
818 Ok(Operation::POP { reg_list: reg_list })
819 }
820 0b1110000..=0b1110111 => {
821 let imm = input & 0xff;
824 Ok(Operation::BKPT { imm: imm as u32 })
825 }
826 0b1111000..=0b1111111 => {
827 parse_hint_instruction(input)
830 }
831 _ => Err("invalid opcode"),
832 }
833}
834
835fn parse_hint_instruction(input: u16) -> Result<Operation, &'static str> {
836 let op_a = (input >> 4) & 0xf;
838 let op_b = input & 0xf;
839
840 if op_b > 0 {
841 return Err("invalid opcode");
842 }
843
844 match op_a {
845 0b0000 => Ok(Operation::NOP),
846 0b0001 => Ok(Operation::YIELD),
847 0b0010 => Ok(Operation::WFE),
848 0b0011 => Ok(Operation::WFE),
849 0b0100 => Ok(Operation::SEV),
850 _ => Err("invalid opcode"),
851 }
852}
853
854trait SignExtend {
855 fn sign_extend(&self, valid_bits: usize) -> u32;
856}
857
858impl SignExtend for u16 {
859 fn sign_extend(&self, valid_bits: usize) -> u32 {
860 let shift = 16 - valid_bits;
861 ((((self << shift) as i16) >> shift) as i32) as u32
862 }
863}
864
865impl SignExtend for u32 {
866 fn sign_extend(&self, valid_bits: usize) -> u32 {
867 let shift = 32 - valid_bits;
868 (((self << shift) as i32) >> shift) as u32
869 }
870}
871
872#[cfg(test)]
873mod test {
874 use super::*;
875
876 #[test]
877 fn sign_extend_u16() {
878 assert_eq!(0xffffffff, 0x1u16.sign_extend(1));
879 assert_eq!(0x1, 0x1u16.sign_extend(2));
880 assert_eq!(0xfffffff9, 0x9u16.sign_extend(4));
881 assert_eq!(0x00000009, 0x9u16.sign_extend(5));
882 }
883
884 #[test]
885 fn sign_extend_u32() {
886 assert_eq!(0xffffffff, 0x1u32.sign_extend(1));
887 assert_eq!(0x1, 0x1u32.sign_extend(2));
888 assert_eq!(0xfffffff9, 0x9u32.sign_extend(4));
889 assert_eq!(0x00000009, 0x9u32.sign_extend(5));
890 }
891}