1use crate::error::*;
4
5#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
11pub enum Operand {
12 None,
13 MnemonicCondition(MnemonicCondition),
14 AddressMode(AddressMode),
15 Condition(Condition),
16 ConditionalInstruction(ConditionalInstruction),
17 ItCondition(ItCondition),
18 Register(Register),
19 SpecialRegister(SpecialRegister),
20 BankedRegister(BankedRegister),
21 RegisterList(RegisterList),
22 SignedImmediate(i32),
23 UnsignedImmediate(u32),
24 ModifiedImmediate(ModifiedImmediate),
25 Label(Label),
26 Shift(Shift),
27 ShiftType(ShiftType),
28 Iflags(Iflags),
29 BarrierOperation(BarrierOperation),
30 PlusMinus(PlusMinus),
31 WriteBack(WriteBack),
32 SysRegEncodingSpace(SysRegEncodingSpace),
33 SysRegRegister(SysRegRegister),
34 ApsrNzcv,
35 Endianness(Endianness),
36}
37
38impl Operand {
39 pub fn is_none(&self) -> bool {
40 if let Operand::None = self {
41 return true;
42 }
43 false
44 }
45
46 pub fn as_mnemonic_condition(&self) -> Result<&MnemonicCondition> {
47 if let Operand::MnemonicCondition(value) = self {
48 return Ok(value);
49 }
50 todo!()
51 }
52
53 pub fn as_address_mode(&self) -> Result<&AddressMode> {
54 if let Operand::AddressMode(value) = self {
55 return Ok(value);
56 }
57 todo!()
58 }
59
60 pub fn as_condition(&self) -> Result<&Condition> {
61 if let Operand::Condition(value) = self {
62 return Ok(value);
63 }
64 todo!()
65 }
66
67 pub fn as_it_condition(&self) -> Result<&ItCondition> {
68 if let Operand::ItCondition(value) = self {
69 return Ok(value);
70 }
71 todo!()
72 }
73
74 pub fn as_register(&self) -> Result<&Register> {
75 if let Operand::Register(value) = self {
76 return Ok(value);
77 }
78 todo!()
79 }
80
81 pub fn as_special_register(&self) -> Result<&SpecialRegister> {
82 if let Operand::SpecialRegister(value) = self {
83 return Ok(value);
84 }
85 todo!()
86 }
87
88 pub fn as_banked_register(&self) -> Result<&BankedRegister> {
89 if let Operand::BankedRegister(value) = self {
90 return Ok(value);
91 }
92 todo!()
93 }
94
95 pub fn as_register_list(&self) -> Result<&RegisterList> {
96 if let Operand::RegisterList(value) = self {
97 return Ok(value);
98 }
99 todo!()
100 }
101
102 pub fn as_signed_immediate(&self) -> Result<i32> {
103 if let Operand::SignedImmediate(value) = self {
104 return Ok(*value);
105 }
106 todo!()
107 }
108
109 pub fn as_unsigned_immediate(&self) -> Result<u32> {
110 if let Operand::UnsignedImmediate(uimm) = self {
111 return Ok(*uimm);
112 }
113 if let Operand::SignedImmediate(uimm) = self {
114 return Ok(*uimm as u32);
115 }
116 todo!()
117 }
118
119 pub fn as_label(&self) -> Result<&Label> {
120 if let Operand::Label(value) = self {
121 return Ok(value);
122 }
123 todo!()
124 }
125
126 pub fn as_modified_immediate(&self) -> Result<&ModifiedImmediate> {
127 if let Operand::ModifiedImmediate(value) = self {
128 return Ok(value);
129 }
130 todo!()
131 }
132
133 pub fn as_shift(&self) -> Result<&Shift> {
134 if let Operand::Shift(value) = self {
135 return Ok(value);
136 }
137 todo!()
138 }
139
140 pub fn as_shift_type(&self) -> Result<&ShiftType> {
141 if let Operand::ShiftType(value) = self {
142 return Ok(value);
143 }
144 todo!()
145 }
146
147 pub fn as_iflags(&self) -> Result<&Iflags> {
148 if let Operand::Iflags(value) = self {
149 return Ok(value);
150 }
151 todo!()
152 }
153
154 pub fn as_barrier_operation(&self) -> Result<&BarrierOperation> {
155 if let Operand::BarrierOperation(value) = self {
156 return Ok(value);
157 }
158 todo!()
159 }
160
161 pub fn as_plus_minus(&self) -> Result<&PlusMinus> {
162 if let Operand::PlusMinus(value) = self {
163 return Ok(value);
164 }
165 todo!()
166 }
167
168 pub fn as_write_back(&self) -> Result<&WriteBack> {
169 if let Operand::WriteBack(value) = self {
170 return Ok(value);
171 }
172 todo!()
173 }
174
175 pub fn as_sysreg_encoding_space(&self) -> Result<&SysRegEncodingSpace> {
176 if let Operand::SysRegEncodingSpace(value) = self {
177 return Ok(value);
178 }
179 todo!()
180 }
181
182 pub fn as_sysreg_register(&self) -> Result<&SysRegRegister> {
183 if let Operand::SysRegRegister(value) = self {
184 return Ok(value);
185 }
186 todo!()
187 }
188
189 pub fn as_endianness(&self) -> Result<&Endianness> {
190 if let Operand::Endianness(value) = self {
191 return Ok(value);
192 }
193 todo!()
194 }
195}
196
197impl Default for Operand {
198 fn default() -> Self {
199 Operand::None
200 }
201}
202
203impl From<MnemonicCondition> for Operand {
204 fn from(value: MnemonicCondition) -> Self {
205 Operand::MnemonicCondition(value)
206 }
207}
208
209impl From<AddressMode> for Operand {
210 fn from(value: AddressMode) -> Self {
211 Operand::AddressMode(value)
212 }
213}
214
215impl From<Condition> for Operand {
216 fn from(value: Condition) -> Self {
217 Operand::Condition(value)
218 }
219}
220
221impl From<ItCondition> for Operand {
222 fn from(value: ItCondition) -> Self {
223 Operand::ItCondition(value)
224 }
225}
226
227impl From<Register> for Operand {
228 fn from(value: Register) -> Self {
229 Operand::Register(value)
230 }
231}
232
233impl From<SpecialRegister> for Operand {
234 fn from(value: SpecialRegister) -> Self {
235 Operand::SpecialRegister(value)
236 }
237}
238
239impl From<BankedRegister> for Operand {
240 fn from(value: BankedRegister) -> Self {
241 Operand::BankedRegister(value)
242 }
243}
244
245impl From<RegisterList> for Operand {
246 fn from(value: RegisterList) -> Self {
247 Operand::RegisterList(value)
248 }
249}
250
251impl From<&[Register]> for Operand {
252 fn from(value: &[Register]) -> Self {
253 let value = value
254 .iter()
255 .fold(0, |acc, register| acc | (1 << *register as usize));
256 Operand::RegisterList(RegisterList::decode(value))
257 }
258}
259
260impl From<u32> for Operand {
261 fn from(value: u32) -> Self {
262 Operand::UnsignedImmediate(value)
263 }
264}
265
266impl From<i32> for Operand {
267 fn from(value: i32) -> Self {
268 Operand::SignedImmediate(value)
269 }
270}
271
272impl From<ModifiedImmediate> for Operand {
273 fn from(value: ModifiedImmediate) -> Self {
274 Operand::ModifiedImmediate(value)
275 }
276}
277
278impl From<Label> for Operand {
279 fn from(value: Label) -> Self {
280 Operand::Label(value)
281 }
282}
283
284impl From<Shift> for Operand {
285 fn from(value: Shift) -> Self {
286 Operand::Shift(value)
287 }
288}
289
290impl From<ShiftType> for Operand {
291 fn from(value: ShiftType) -> Self {
292 Operand::ShiftType(value)
293 }
294}
295
296impl From<Iflags> for Operand {
297 fn from(value: Iflags) -> Self {
298 Operand::Iflags(value)
299 }
300}
301
302impl From<BarrierOperation> for Operand {
303 fn from(value: BarrierOperation) -> Self {
304 Operand::BarrierOperation(value)
305 }
306}
307
308impl From<PlusMinus> for Operand {
309 fn from(value: PlusMinus) -> Self {
310 Operand::PlusMinus(value)
311 }
312}
313
314impl From<WriteBack> for Operand {
315 fn from(value: WriteBack) -> Self {
316 Operand::WriteBack(value)
317 }
318}
319
320impl From<SysRegEncodingSpace> for Operand {
321 fn from(value: SysRegEncodingSpace) -> Self {
322 Operand::SysRegEncodingSpace(value)
323 }
324}
325
326impl From<SysRegRegister> for Operand {
327 fn from(value: SysRegRegister) -> Self {
328 Operand::SysRegRegister(value)
329 }
330}
331
332impl From<Endianness> for Operand {
333 fn from(value: Endianness) -> Self {
334 Operand::Endianness(value)
335 }
336}
337
338#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
343pub enum MnemonicCondition {
344 Eq,
345 Ne,
346 Cs,
347 Cc,
348 Mi,
349 Pl,
350 Vs,
351 Vc,
352 Hi,
353 Ls,
354 Ge,
355 Lt,
356 Gt,
357 Le,
358 Al,
359}
360
361impl MnemonicCondition {
362 pub fn decode(value: u32) -> Result<Self> {
363 match value {
364 0b0000 => Ok(Self::Eq),
365 0b0001 => Ok(Self::Ne),
366 0b0010 => Ok(Self::Cs),
367 0b0011 => Ok(Self::Cc),
368 0b0100 => Ok(Self::Mi),
369 0b0101 => Ok(Self::Pl),
370 0b0110 => Ok(Self::Vs),
371 0b0111 => Ok(Self::Vc),
372 0b1000 => Ok(Self::Hi),
373 0b1001 => Ok(Self::Ls),
374 0b1010 => Ok(Self::Ge),
375 0b1011 => Ok(Self::Lt),
376 0b1100 => Ok(Self::Gt),
377 0b1101 => Ok(Self::Le),
378 0b1110 => Ok(Self::Al),
379 _ => Err(OperandError::MnemonicConditionOutOfRange(value))?,
380 }
381 }
382
383 pub fn encode(self) -> u32 {
384 match self {
385 Self::Eq => 0b0000,
386 Self::Ne => 0b0001,
387 Self::Cs => 0b0010,
388 Self::Cc => 0b0011,
389 Self::Mi => 0b0100,
390 Self::Pl => 0b0101,
391 Self::Vs => 0b0110,
392 Self::Vc => 0b0111,
393 Self::Hi => 0b1000,
394 Self::Ls => 0b1001,
395 Self::Ge => 0b1010,
396 Self::Lt => 0b1011,
397 Self::Gt => 0b1100,
398 Self::Le => 0b1101,
399 Self::Al => 0b1110,
400 }
401 }
402
403 pub fn as_str(&self) -> &str {
404 match self {
405 Self::Eq => "eq",
406 Self::Ne => "ne",
407 Self::Cs => "hs",
408 Self::Cc => "lo",
409 Self::Mi => "mi",
410 Self::Pl => "pl",
411 Self::Vs => "vs",
412 Self::Vc => "vc",
413 Self::Hi => "hi",
414 Self::Ls => "ls",
415 Self::Ge => "ge",
416 Self::Lt => "lt",
417 Self::Gt => "gt",
418 Self::Le => "le",
419 Self::Al => "al",
420 }
421 }
422}
423
424#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
425pub enum AddressMode {
426 DecrementAfter,
427 FullAscending,
428 DecrementBefore,
429 EmptyAscending,
430 IncrementAfter,
431 FullDescending,
432 IncrementBefore,
433 EmptyDescending,
434}
435
436#[allow(non_upper_case_globals)]
437impl AddressMode {
438 pub const DA: Self = Self::DecrementAfter;
439 pub const FA: Self = Self::FullAscending;
440 pub const DB: Self = Self::DecrementBefore;
441 pub const EA: Self = Self::EmptyAscending;
442 pub const IA: Self = Self::IncrementAfter;
443 pub const FD: Self = Self::FullDescending;
444 pub const IB: Self = Self::IncrementBefore;
445 pub const ED: Self = Self::EmptyDescending;
446
447 pub fn decode(value: u32) -> Self {
448 match (value & 2, value & 1) {
449 (0, 0) => Self::DecrementAfter,
450 (0, 1) => Self::DecrementBefore,
451 (2, 0) => Self::IncrementAfter,
452 (2, 1) => Self::IncrementBefore,
453 _ => unreachable!(),
454 }
455 }
456
457 pub fn encode(self) -> u32 {
458 match self {
459 Self::DecrementAfter => 0,
460 Self::FullAscending => 0,
461 Self::DecrementBefore => 1,
462 Self::EmptyAscending => 1,
463 Self::IncrementAfter => 2,
464 Self::FullDescending => 2,
465 Self::IncrementBefore => 3,
466 Self::EmptyDescending => 3,
467 }
468 }
469
470 pub fn as_str(self) -> &'static str {
471 match self {
472 Self::DecrementAfter => "da",
473 Self::FullAscending => "fa",
474 Self::DecrementBefore => "db",
475 Self::EmptyAscending => "ea",
476 Self::IncrementAfter => "ia",
477 Self::FullDescending => "fd",
478 Self::IncrementBefore => "ib",
479 Self::EmptyDescending => "ed",
480 }
481 }
482}
483
484#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
485pub enum AssemblerQualifier {
486 None,
487 Narrow,
488 Wide,
489}
490
491#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
492pub enum PlusMinus {
493 Plus,
494 Minus,
495}
496
497impl PlusMinus {
498 pub fn decode(value: u32) -> Self {
499 match value {
500 0 => Self::Minus,
501 _ => Self::Plus,
502 }
503 }
504
505 pub fn encode(self) -> u32 {
506 match self {
507 Self::Minus => 0,
508 Self::Plus => 1,
509 }
510 }
511}
512
513#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
514pub enum WriteBack {
515 True,
516 False,
517}
518
519impl WriteBack {
520 pub fn decode(value: u32) -> Self {
521 match value {
522 1 => Self::True,
523 _ => Self::False,
524 }
525 }
526
527 pub fn encode(self) -> u32 {
528 match self {
529 Self::False => 0,
530 Self::True => 1,
531 }
532 }
533}
534
535#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
540pub enum Register {
541 R0,
542 R1,
543 R2,
544 R3,
545 R4,
546 R5,
547 R6,
548 R7,
549 R8,
550 R9,
551 R10,
552 R11,
553 R12,
554 R13,
555 R14,
556 R15,
557}
558
559impl Register {
560 pub const SP: Self = Self::R13;
561 pub const LR: Self = Self::R14;
562 pub const PC: Self = Self::R15;
563
564 pub fn decode(value: u32) -> Result<Self> {
565 match value {
566 0 => Ok(Self::R0),
567 1 => Ok(Self::R1),
568 2 => Ok(Self::R2),
569 3 => Ok(Self::R3),
570 4 => Ok(Self::R4),
571 5 => Ok(Self::R5),
572 6 => Ok(Self::R6),
573 7 => Ok(Self::R7),
574 8 => Ok(Self::R8),
575 9 => Ok(Self::R9),
576 10 => Ok(Self::R10),
577 11 => Ok(Self::R11),
578 12 => Ok(Self::R12),
579 13 => Ok(Self::R13),
580 14 => Ok(Self::R14),
581 15 => Ok(Self::R15),
582 _ => Err(OperandError::RegisterOutOfRange(value))?,
583 }
584 }
585
586 pub fn encode(self) -> u32 {
587 match self {
588 Self::R0 => 0,
589 Self::R1 => 1,
590 Self::R2 => 2,
591 Self::R3 => 3,
592 Self::R4 => 4,
593 Self::R5 => 5,
594 Self::R6 => 6,
595 Self::R7 => 7,
596 Self::R8 => 8,
597 Self::R9 => 9,
598 Self::R10 => 10,
599 Self::R11 => 11,
600 Self::R12 => 12,
601 Self::R13 => 13,
602 Self::R14 => 14,
603 Self::R15 => 15,
604 }
605 }
606
607 pub fn as_str(&self) -> &str {
608 match self {
609 Self::R0 => "r0",
610 Self::R1 => "r1",
611 Self::R2 => "r2",
612 Self::R3 => "r3",
613 Self::R4 => "r4",
614 Self::R5 => "r5",
615 Self::R6 => "r6",
616 Self::R7 => "r7",
617 Self::R8 => "r8",
618 Self::R9 => "r9",
619 Self::R10 => "r10",
620 Self::R11 => "r11",
621 Self::R12 => "r12",
622 Self::R13 => "sp",
623 Self::R14 => "lr",
624 Self::R15 => "pc",
625 }
626 }
627}
628
629#[allow(non_camel_case_types)]
630#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
631pub enum SpecialRegister {
632 CPSR,
633 CPSR_c,
634 CPSR_x,
635 CPSR_xc,
636 CPSR_s,
637 CPSR_sc,
638 CPSR_sx,
639 CPSR_sxc,
640 CPSR_f,
641 CPSR_fc,
642 CPSR_fx,
643 CPSR_fxc,
644 CPSR_fs,
645 CPSR_fsc,
646 CPSR_fsx,
647 CPSR_fsxc,
648 SPSR,
649 SPSR_c,
650 SPSR_x,
651 SPSR_xc,
652 SPSR_s,
653 SPSR_sc,
654 SPSR_sx,
655 SPSR_sxc,
656 SPSR_f,
657 SPSR_fc,
658 SPSR_fx,
659 SPSR_fxc,
660 SPSR_fs,
661 SPSR_fsc,
662 SPSR_fsx,
663 SPSR_fsxc,
664 APSR,
665 APSR_nzcvq,
666 APSR_g,
667 APSR_nzcvqg,
668}
669
670impl SpecialRegister {
671 pub fn decode(r: u32, mask: u32, as_apsr: bool) -> Result<Self> {
672 let f = (mask >> 0) & 1;
673 let s = (mask >> 1) & 1;
674 let x = (mask >> 2) & 1;
675 let c = (mask >> 3) & 1;
676 Ok(match (r, c, x, s, f) {
677 (0, 0, 0, 0, 1) => Self::CPSR_c,
678 (0, 0, 0, 1, 0) => Self::CPSR_x,
679 (0, 0, 0, 1, 1) => Self::CPSR_xc,
680 (0, 0, 1, 0, 0) => {
681 if as_apsr {
682 Self::APSR_g
683 } else {
684 Self::CPSR_s
685 }
686 }
687 (0, 0, 1, 0, 1) => Self::CPSR_sc,
688 (0, 0, 1, 1, 0) => Self::CPSR_sx,
689 (0, 0, 1, 1, 1) => Self::CPSR_sxc,
690 (0, 1, 0, 0, 0) => {
691 if as_apsr {
692 Self::APSR_nzcvq
693 } else {
694 Self::CPSR_f
695 }
696 }
697 (0, 1, 0, 0, 1) => Self::CPSR_fc,
698 (0, 1, 0, 1, 0) => Self::CPSR_fx,
699 (0, 1, 0, 1, 1) => Self::CPSR_fxc,
700 (0, 1, 1, 0, 0) => {
701 if as_apsr {
702 Self::APSR_nzcvqg
703 } else {
704 Self::CPSR_fs
705 }
706 }
707 (0, 1, 1, 0, 1) => Self::CPSR_fsc,
708 (0, 1, 1, 1, 0) => Self::CPSR_fsx,
709 (0, 1, 1, 1, 1) => Self::CPSR_fsxc,
710 (1, 0, 0, 0, 0) => Self::SPSR,
711 (1, 0, 0, 0, 1) => Self::SPSR_c,
712 (1, 0, 0, 1, 0) => Self::SPSR_x,
713 (1, 0, 0, 1, 1) => Self::SPSR_xc,
714 (1, 0, 1, 0, 0) => Self::SPSR_s,
715 (1, 0, 1, 0, 1) => Self::SPSR_sc,
716 (1, 0, 1, 1, 0) => Self::SPSR_sx,
717 (1, 0, 1, 1, 1) => Self::SPSR_sxc,
718 (1, 1, 0, 0, 0) => Self::SPSR_f,
719 (1, 1, 0, 0, 1) => Self::SPSR_fc,
720 (1, 1, 0, 1, 0) => Self::SPSR_fx,
721 (1, 1, 0, 1, 1) => Self::SPSR_fxc,
722 (1, 1, 1, 0, 0) => Self::SPSR_fs,
723 (1, 1, 1, 0, 1) => Self::SPSR_fsc,
724 (1, 1, 1, 1, 0) => Self::SPSR_fsx,
725 (1, 1, 1, 1, 1) => Self::SPSR_fsxc,
726 x => todo!("{:#?}", x),
727 })
728 }
729
730 pub fn encode(self) -> Result<(u32, u32)> {
731 let (r, c, x, s, f) = match self {
732 Self::CPSR_c => (0, 0, 0, 0, 1),
733 Self::CPSR_x => (0, 0, 0, 1, 0),
734 Self::CPSR_xc => (0, 0, 0, 1, 1),
735 Self::CPSR_s | Self::APSR_g => (0, 0, 1, 0, 0),
736 Self::CPSR_sc => (0, 0, 1, 0, 1),
737 Self::CPSR_sx => (0, 0, 1, 1, 0),
738 Self::CPSR_sxc => (0, 0, 1, 1, 1),
739 Self::CPSR_f | Self::APSR_nzcvq => (0, 1, 0, 0, 0),
740 Self::CPSR_fc => (0, 1, 0, 0, 1),
741 Self::CPSR_fx => (0, 1, 0, 1, 0),
742 Self::CPSR_fxc => (0, 1, 0, 1, 1),
743 Self::CPSR_fs | Self::APSR_nzcvqg => (0, 1, 1, 0, 0),
744 Self::CPSR_fsc => (0, 1, 1, 0, 1),
745 Self::CPSR_fsx => (0, 1, 1, 1, 0),
746 Self::CPSR_fsxc => (0, 1, 1, 1, 1),
747 Self::SPSR => (1, 0, 0, 0, 0),
748 Self::SPSR_c => (1, 0, 0, 0, 1),
749 Self::SPSR_x => (1, 0, 0, 1, 0),
750 Self::SPSR_xc => (1, 0, 0, 1, 1),
751 Self::SPSR_s => (1, 0, 1, 0, 0),
752 Self::SPSR_sc => (1, 0, 1, 0, 1),
753 Self::SPSR_sx => (1, 0, 1, 1, 0),
754 Self::SPSR_sxc => (1, 0, 1, 1, 1),
755 Self::SPSR_f => (1, 1, 0, 0, 0),
756 Self::SPSR_fc => (1, 1, 0, 0, 1),
757 Self::SPSR_fx => (1, 1, 0, 1, 0),
758 Self::SPSR_fxc => (1, 1, 0, 1, 1),
759 Self::SPSR_fs => (1, 1, 1, 0, 0),
760 Self::SPSR_fsc => (1, 1, 1, 0, 1),
761 Self::SPSR_fsx => (1, 1, 1, 1, 0),
762 Self::SPSR_fsxc => (1, 1, 1, 1, 1),
763 x => todo!("{:#?}", x),
764 };
765 let mask = (c << 3) | (x << 2) | (s << 1) | f;
766 Ok((r, mask))
767 }
768
769 pub fn as_str(&self) -> &str {
770 match self {
771 Self::CPSR => "CPSR",
772 Self::CPSR_c => "CPSR_c",
773 Self::CPSR_x => "CPSR_x",
774 Self::CPSR_xc => "CPSR_xc",
775 Self::CPSR_s => "CPSR_s",
776 Self::CPSR_sc => "CPSR_sc",
777 Self::CPSR_sx => "CPSR_sx",
778 Self::CPSR_sxc => "CPSR_sxc",
779 Self::CPSR_f => "CPSR_f",
780 Self::CPSR_fc => "CPSR_fc",
781 Self::CPSR_fx => "CPSR_fx",
782 Self::CPSR_fxc => "CPSR_fxc",
783 Self::CPSR_fs => "CPSR_fs",
784 Self::CPSR_fsc => "CPSR_fsc",
785 Self::CPSR_fsx => "CPSR_fsx",
786 Self::CPSR_fsxc => "CPSR_fsxc",
787 Self::SPSR => "SPSR",
788 Self::SPSR_c => "SPSR_c",
789 Self::SPSR_x => "SPSR_x",
790 Self::SPSR_xc => "SPSR_xc",
791 Self::SPSR_s => "SPSR_s",
792 Self::SPSR_sc => "SPSR_sc",
793 Self::SPSR_sx => "SPSR_sx",
794 Self::SPSR_sxc => "SPSR_sxc",
795 Self::SPSR_f => "SPSR_f",
796 Self::SPSR_fc => "SPSR_fc",
797 Self::SPSR_fx => "SPSR_fx",
798 Self::SPSR_fxc => "SPSR_fxc",
799 Self::SPSR_fs => "SPSR_fs",
800 Self::SPSR_fsc => "SPSR_fsc",
801 Self::SPSR_fsx => "SPSR_fsx",
802 Self::SPSR_fsxc => "SPSR_fsxc",
803 Self::APSR => "APSR",
804 Self::APSR_nzcvq => "APSR_nzcvq",
805 Self::APSR_g => "APSR_g",
806 Self::APSR_nzcvqg => "APSR_nzcvqg",
807 }
808 }
809}
810
811#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
812pub enum BankedRegister {
813 R8Usr,
814 R9Usr,
815 R10Usr,
816 R11Usr,
817 R12Usr,
818 SpUsr,
819 LrUsr,
820 R8Fiq,
821 R9Fiq,
822 R10Fiq,
823 R11Fiq,
824 R12Fiq,
825 SpFiq,
826 LrFiq,
827 LrIrq,
828 SpIrq,
829 LrSvc,
830 SpSvc,
831 LrAbt,
832 SpAbt,
833 LrUnd,
834 SpUnd,
835 LrMon,
836 SpMon,
837 ElrHyp,
838 SpHyp,
839 SpsrFiq,
840 SpsrIrq,
841 SpsrSvc,
842 SpsrAbt,
843 SpsrUnd,
844 SpsrMon,
845 SpsrHyp,
846}
847
848impl BankedRegister {
849 pub fn as_str(&self) -> &str {
850 match self {
851 Self::R8Usr => "r8_usr",
852 Self::R9Usr => "r9_usr",
853 Self::R10Usr => "r10_usr",
854 Self::R11Usr => "r11_usr",
855 Self::R12Usr => "r12_usr",
856 Self::SpUsr => "sp_usr",
857 Self::LrUsr => "lr_usr",
858 Self::R8Fiq => "r8_fiq",
859 Self::R9Fiq => "r9_fiq",
860 Self::R10Fiq => "r10_fiq",
861 Self::R11Fiq => "r11_fiq",
862 Self::R12Fiq => "r12_fiq",
863 Self::SpFiq => "sp_fiq",
864 Self::LrFiq => "lr_fiq",
865 Self::LrIrq => "lr_irq",
866 Self::SpIrq => "sp_irq",
867 Self::LrSvc => "lr_svc",
868 Self::SpSvc => "sp_svc",
869 Self::LrAbt => "lr_abt",
870 Self::SpAbt => "sp_abt",
871 Self::LrUnd => "lr_und",
872 Self::SpUnd => "sp_und",
873 Self::LrMon => "lr_mon",
874 Self::SpMon => "sp_mon",
875 Self::ElrHyp => "elr_hyp",
876 Self::SpHyp => "sp_hyp",
877 Self::SpsrFiq => "SPSR_fiq",
878 Self::SpsrIrq => "SPSR_irq",
879 Self::SpsrSvc => "SPSR_svc",
880 Self::SpsrAbt => "SPSR_abt",
881 Self::SpsrUnd => "SPSR_und",
882 Self::SpsrMon => "SPSR_mon",
883 Self::SpsrHyp => "SPSR_hyp",
884 }
885 }
886}
887
888#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
889pub struct RegisterList(pub u16);
890
891impl RegisterList {
892 pub fn decode(value: u32) -> Self {
893 Self(value as u16)
894 }
895
896 pub fn encode(self) -> u32 {
897 self.0 as u32
898 }
899
900 pub fn value(self) -> Vec<Register> {
901 (0..16)
902 .into_iter()
903 .filter(|i| (self.0 >> i) & 1 == 1)
904 .fold(vec![], |mut acc, x| {
905 acc.push(Register::decode(x).unwrap());
908 acc
909 })
910 }
911}
912
913#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
918pub enum Condition {
919 Eq,
920 Ne,
921 Cs,
922 Cc,
923 Mi,
924 Pl,
925 Vs,
926 Vc,
927 Hi,
928 Ls,
929 Ge,
930 Lt,
931 Gt,
932 Le,
933 Al,
934}
935
936impl Condition {
937 pub fn decode(value: u32) -> Result<Self> {
938 match value {
939 0b0000 => Ok(Self::Eq),
940 0b0001 => Ok(Self::Ne),
941 0b0010 => Ok(Self::Cs),
942 0b0011 => Ok(Self::Cc),
943 0b0100 => Ok(Self::Mi),
944 0b0101 => Ok(Self::Pl),
945 0b0110 => Ok(Self::Vs),
946 0b0111 => Ok(Self::Vc),
947 0b1000 => Ok(Self::Hi),
948 0b1001 => Ok(Self::Ls),
949 0b1010 => Ok(Self::Ge),
950 0b1011 => Ok(Self::Lt),
951 0b1100 => Ok(Self::Gt),
952 0b1101 => Ok(Self::Le),
953 0b1110 => Ok(Self::Al),
954 _ => Err(OperandError::ConditionOutOfRange(value))?,
955 }
956 }
957
958 pub fn encode(self) -> u32 {
959 match self {
960 Self::Eq => 0b0000,
961 Self::Ne => 0b0001,
962 Self::Cs => 0b0010,
963 Self::Cc => 0b0011,
964 Self::Mi => 0b0100,
965 Self::Pl => 0b0101,
966 Self::Vs => 0b0110,
967 Self::Vc => 0b0111,
968 Self::Hi => 0b1000,
969 Self::Ls => 0b1001,
970 Self::Ge => 0b1010,
971 Self::Lt => 0b1011,
972 Self::Gt => 0b1100,
973 Self::Le => 0b1101,
974 Self::Al => 0b1110,
975 }
976 }
977
978 pub fn opposite(self) -> Self {
979 match self {
980 Self::Eq => Self::Ne,
981 Self::Ne => Self::Eq,
982 Self::Cs => Self::Cc,
983 Self::Cc => Self::Cs,
984 Self::Mi => Self::Pl,
985 Self::Pl => Self::Mi,
986 Self::Vs => Self::Vc,
987 Self::Vc => Self::Vs,
988 Self::Hi => Self::Ls,
989 Self::Ls => Self::Hi,
990 Self::Ge => Self::Lt,
991 Self::Lt => Self::Ge,
992 Self::Gt => Self::Le,
993 Self::Le => Self::Gt,
994 _ => todo!(),
995 }
996 }
997
998 pub fn as_str(&self) -> &str {
999 match self {
1000 Self::Eq => "eq",
1001 Self::Ne => "ne",
1002 Self::Cs => "hs",
1003 Self::Cc => "lo",
1004 Self::Mi => "mi",
1005 Self::Pl => "pl",
1006 Self::Vs => "vs",
1007 Self::Vc => "vc",
1008 Self::Hi => "hi",
1009 Self::Ls => "ls",
1010 Self::Ge => "ge",
1011 Self::Lt => "lt",
1012 Self::Gt => "gt",
1013 Self::Le => "le",
1014 Self::Al => "al",
1015 }
1016 }
1017}
1018
1019impl From<Condition> for MnemonicCondition {
1020 fn from(value: Condition) -> Self {
1021 match value {
1022 Condition::Eq => Self::Eq,
1023 Condition::Ne => Self::Ne,
1024 Condition::Cs => Self::Cs,
1025 Condition::Cc => Self::Cc,
1026 Condition::Mi => Self::Mi,
1027 Condition::Pl => Self::Pl,
1028 Condition::Vs => Self::Vs,
1029 Condition::Vc => Self::Vc,
1030 Condition::Hi => Self::Hi,
1031 Condition::Ls => Self::Ls,
1032 Condition::Ge => Self::Ge,
1033 Condition::Lt => Self::Lt,
1034 Condition::Gt => Self::Gt,
1035 Condition::Le => Self::Le,
1036 Condition::Al => Self::Al,
1037 }
1038 }
1039}
1040
1041#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
1042pub enum ItCondition {
1043 None,
1044 If,
1045 Else,
1046}
1047
1048impl ItCondition {
1049 pub fn is_none(&self) -> bool {
1050 if let ItCondition::None = self {
1051 return true;
1052 }
1053 false
1054 }
1055
1056 pub fn decode(value: u32, firstcond: u32, position: u32) -> Result<Self> {
1057 if position == 0 || position > 3 {
1060 todo!()
1061 }
1062 let shift = 4 - position;
1065 let mask = (1 << shift) - 1;
1066 if value & mask == 0 {
1067 return Ok(Self::None);
1068 } else if (value >> shift) & 1 == firstcond & 1 {
1069 return Ok(Self::If);
1070 } else {
1071 return Ok(Self::Else);
1072 }
1073 }
1074
1075 pub fn encode(self, firstcond: u32, position: u32) -> u32 {
1076 match self {
1077 Self::None => 1 << (4 - position),
1078 Self::If => (firstcond & 1) << (4 - position) | if position == 3 { 1 } else { 0 },
1079 Self::Else => {
1080 ((firstcond + 1) % 2) << (4 - position) | if position == 3 { 1 } else { 0 }
1081 }
1082 }
1083 }
1084
1085 pub fn as_str(&self) -> &str {
1086 match self {
1087 Self::None => "",
1088 Self::If => "t",
1089 Self::Else => "e",
1090 }
1091 }
1092}
1093
1094#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
1095pub enum ConditionalInstruction {
1096 None,
1097 ItBlock(Condition, ItCondition, ItCondition, ItCondition),
1098 Condition(usize, bool, bool),
1100}
1101
1102impl ConditionalInstruction {
1103 pub fn encode(self) -> (u32, u32) {
1104 match self {
1105 Self::ItBlock(cond, ic1, ic2, ic3) => {
1106 let firstcond = cond.encode();
1107 let mut mask = 0;
1108
1109 mask |= ic1.encode(firstcond, 1);
1110 if ic1.is_none() {
1111 return (firstcond, mask);
1112 }
1113 mask |= ic2.encode(firstcond, 2);
1114 if ic2.is_none() {
1115 return (firstcond, mask);
1116 }
1117 mask |= ic3.encode(firstcond, 3);
1118 return (firstcond, mask);
1119 }
1120 _ => todo!(),
1121 }
1122 }
1123}
1124
1125#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
1130pub struct ModifiedImmediate(pub u32, pub u32);
1131
1132impl ModifiedImmediate {
1133 pub fn decode(value: u32) -> Self {
1134 let rotation = (value >> 8) & 0xf;
1135 let value = value & 0xff;
1136 Self(rotation, value)
1137 }
1138
1139 pub fn encode(self) -> u32 {
1140 (self.0 << 8) | self.1
1141 }
1142
1143 pub fn value(self) -> u32 {
1144 self.1.rotate_right(self.0 * 2)
1145 }
1146}
1147
1148#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
1153pub enum Label {
1154 LabelName(u64),
1155 Label(i32),
1156 LabelModified(ModifiedImmediate),
1157 LabelModifiedNegative(ModifiedImmediate),
1158}
1159
1160impl Label {
1161 pub fn decode(value: i64, modified: bool) -> Self {
1162 if modified {
1163 if value < 0 {
1164 Self::LabelModifiedNegative(ModifiedImmediate::decode(-value as u32))
1165 } else {
1166 Self::LabelModified(ModifiedImmediate::decode(value as u32))
1167 }
1168 } else {
1169 Self::Label(value as i32)
1170 }
1171 }
1172
1173 pub fn encode(self) -> Result<u32> {
1174 match self {
1175 Self::Label(imm) => Ok(imm as u32),
1176 Self::LabelModified(imm) => Ok(imm.encode()),
1177 Self::LabelModifiedNegative(imm) => Ok(imm.encode()),
1178 Self::LabelName(_) => todo!(),
1179 }
1180 }
1181
1182 pub fn value(self) -> i64 {
1183 match self {
1184 Self::Label(imm) => imm as i64,
1185 Self::LabelModified(imm) => imm.value() as i64,
1186 Self::LabelModifiedNegative(imm) => -(imm.value() as i64),
1187 Self::LabelName(imm) => imm as i64,
1188 }
1189 }
1190}
1191
1192#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
1197pub enum Shift {
1198 LSL(u32),
1199 LSR(u32),
1200 ASR(u32),
1201 ROR(u32),
1202 RRX,
1203}
1204
1205impl Shift {
1206 pub fn value(self) -> u32 {
1207 match self {
1208 Self::LSL(imm) => imm,
1209 Self::LSR(imm) => imm,
1210 Self::ASR(imm) => imm,
1211 Self::ROR(imm) => imm,
1212 Self::RRX => 1,
1213 }
1214 }
1215
1216 pub fn as_str(&self) -> &str {
1217 match self {
1218 Self::LSL(_) => "lsl",
1219 Self::LSR(_) => "lsr",
1220 Self::ASR(_) => "asr",
1221 Self::ROR(_) => "ror",
1222 Self::RRX => "rrx",
1223 }
1224 }
1225}
1226
1227#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
1228pub enum ShiftType {
1229 LSL,
1230 LSR,
1231 ASR,
1232 ROR,
1233}
1234
1235impl ShiftType {
1236 pub fn as_str(&self) -> &str {
1237 match self {
1238 Self::LSL => "lsl",
1239 Self::LSR => "lsr",
1240 Self::ASR => "asr",
1241 Self::ROR => "ror",
1242 }
1243 }
1244}
1245
1246#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
1251pub struct Iflags {
1252 pub a: bool,
1253 pub i: bool,
1254 pub f: bool,
1255}
1256
1257impl Iflags {
1258 pub fn decode(a: u32, i: u32, f: u32) -> Self {
1259 Self {
1260 a: a != 0,
1261 i: i != 0,
1262 f: f != 0,
1263 }
1264 }
1265
1266 pub fn encode(self) -> (u32, u32, u32) {
1267 (self.a as u32, self.i as u32, self.f as u32)
1268 }
1269}
1270
1271#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
1272pub enum BarrierOperation {
1273 Ssbb,
1274 Pssbb,
1275 Sy,
1276 St,
1277 Ld,
1278 Ish,
1279 Ishst,
1280 Ishld,
1281 Nsh,
1282 Nshst,
1283 Nshld,
1284 Osh,
1285 Oshst,
1286 Oshld,
1287 Reserved(u8),
1288}
1289
1290impl BarrierOperation {
1291 pub fn decode_dsb(value: u32) -> Self {
1292 match value {
1293 0b0000 => Self::Ssbb,
1294 0b0001 => Self::Oshld,
1295 0b0010 => Self::Oshst,
1296 0b0011 => Self::Osh,
1297 0b0100 => Self::Pssbb,
1298 0b0101 => Self::Nshld,
1299 0b0110 => Self::Nshst,
1300 0b0111 => Self::Nsh,
1301 0b1001 => Self::Ishld,
1302 0b1010 => Self::Ishst,
1303 0b1011 => Self::Ish,
1304 0b1101 => Self::Ld,
1305 0b1110 => Self::St,
1306 0b1111 => Self::Sy,
1307 _ => Self::Reserved(value as u8),
1308 }
1309 }
1310
1311 pub fn decode_dmb(value: u32) -> Self {
1312 match value {
1313 0b0001 => Self::Oshld,
1314 0b0010 => Self::Oshst,
1315 0b0011 => Self::Osh,
1316 0b0101 => Self::Nshld,
1317 0b0110 => Self::Nshst,
1318 0b0111 => Self::Nsh,
1319 0b1001 => Self::Ishld,
1320 0b1010 => Self::Ishst,
1321 0b1011 => Self::Ish,
1322 0b1101 => Self::Ld,
1323 0b1110 => Self::St,
1324 0b1111 => Self::Sy,
1325 _ => Self::Reserved(value as u8),
1326 }
1327 }
1328
1329 pub fn decode_isb(value: u32) -> Self {
1330 match value {
1331 0b1111 => Self::Sy,
1332 _ => Self::Reserved(value as u8),
1333 }
1334 }
1335
1336 pub fn encode(self) -> u32 {
1337 match self {
1338 Self::Ssbb => 0b0000,
1339 Self::Oshld => 0b0001,
1340 Self::Oshst => 0b0010,
1341 Self::Osh => 0b0011,
1342 Self::Pssbb => 0b0100,
1343 Self::Nshld => 0b0101,
1344 Self::Nshst => 0b0110,
1345 Self::Nsh => 0b0111,
1346 Self::Ishld => 0b1001,
1347 Self::Ishst => 0b1010,
1348 Self::Ish => 0b1011,
1349 Self::Ld => 0b1101,
1350 Self::St => 0b1110,
1351 Self::Sy => 0b1111,
1352 Self::Reserved(x) => x as u32,
1353 }
1354 }
1355
1356 pub fn as_str(&self) -> &str {
1357 match self {
1358 Self::Ssbb => "ssbb",
1359 Self::Oshld => "oshld",
1360 Self::Oshst => "oshst",
1361 Self::Osh => "osh",
1362 Self::Pssbb => "pssbb",
1363 Self::Nshld => "nshld",
1364 Self::Nshst => "nshst",
1365 Self::Nsh => "nsh",
1366 Self::Ishld => "ishld",
1367 Self::Ishst => "ishst",
1368 Self::Ish => "ish",
1369 Self::Ld => "ld",
1370 Self::St => "st",
1371 Self::Sy => "sy",
1372 Self::Reserved(_) => "reserved",
1373 }
1374 }
1375}
1376
1377#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
1378pub enum SysRegEncodingSpace {
1379 P14,
1380 P15,
1381}
1382
1383impl SysRegEncodingSpace {
1384 pub fn decode(value: u32) -> Result<Self> {
1385 Ok(match value {
1386 0 => Self::P14,
1387 1 => Self::P15,
1388 _ => todo!(),
1389 })
1390 }
1391
1392 pub fn encode(self) -> u32 {
1393 match self {
1394 Self::P14 => 0,
1395 Self::P15 => 1,
1396 }
1397 }
1398
1399 pub fn as_str(&self) -> &str {
1400 match self {
1401 Self::P14 => "p14",
1402 Self::P15 => "p15",
1403 }
1404 }
1405}
1406
1407#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
1408pub enum SysRegRegister {
1409 C0,
1410 C1,
1411 C2,
1412 C3,
1413 C4,
1414 C5,
1415 C6,
1416 C7,
1417 C8,
1418 C9,
1419 C10,
1420 C11,
1421 C12,
1422 C13,
1423 C14,
1424 C15,
1425}
1426
1427impl SysRegRegister {
1428 pub fn decode(value: u32) -> Result<Self> {
1429 match value {
1430 0 => Ok(Self::C0),
1431 1 => Ok(Self::C1),
1432 2 => Ok(Self::C2),
1433 3 => Ok(Self::C3),
1434 4 => Ok(Self::C4),
1435 5 => Ok(Self::C5),
1436 6 => Ok(Self::C6),
1437 7 => Ok(Self::C7),
1438 8 => Ok(Self::C8),
1439 9 => Ok(Self::C9),
1440 10 => Ok(Self::C10),
1441 11 => Ok(Self::C11),
1442 12 => Ok(Self::C12),
1443 13 => Ok(Self::C13),
1444 14 => Ok(Self::C14),
1445 15 => Ok(Self::C15),
1446 _ => Err(OperandError::RegisterOutOfRange(value))?,
1447 }
1448 }
1449
1450 pub fn encode(self) -> u32 {
1451 match self {
1452 Self::C0 => 0,
1453 Self::C1 => 1,
1454 Self::C2 => 2,
1455 Self::C3 => 3,
1456 Self::C4 => 4,
1457 Self::C5 => 5,
1458 Self::C6 => 6,
1459 Self::C7 => 7,
1460 Self::C8 => 8,
1461 Self::C9 => 9,
1462 Self::C10 => 10,
1463 Self::C11 => 11,
1464 Self::C12 => 12,
1465 Self::C13 => 13,
1466 Self::C14 => 14,
1467 Self::C15 => 15,
1468 }
1469 }
1470
1471 pub fn as_str(&self) -> &str {
1472 match self {
1473 Self::C0 => "c0",
1474 Self::C1 => "c1",
1475 Self::C2 => "c2",
1476 Self::C3 => "c3",
1477 Self::C4 => "c4",
1478 Self::C5 => "c5",
1479 Self::C6 => "c6",
1480 Self::C7 => "c7",
1481 Self::C8 => "c8",
1482 Self::C9 => "c9",
1483 Self::C10 => "c10",
1484 Self::C11 => "c11",
1485 Self::C12 => "c12",
1486 Self::C13 => "c13",
1487 Self::C14 => "c14",
1488 Self::C15 => "c15",
1489 }
1490 }
1491}
1492
1493#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Debug, Hash)]
1494pub enum Endianness {
1495 Le,
1496 Be,
1497}
1498
1499impl Endianness {
1500 pub fn decode(value: u32) -> Result<Self> {
1501 match value {
1502 0 => Ok(Self::Le),
1503 1 => Ok(Self::Be),
1504 _ => todo!(),
1505 }
1506 }
1507
1508 pub fn encode(self) -> u32 {
1509 match self {
1510 Self::Le => 0,
1511 Self::Be => 1,
1512 }
1513 }
1514
1515 pub fn as_str(&self) -> &str {
1516 match self {
1517 Self::Le => "le",
1518 Self::Be => "be",
1519 }
1520 }
1521}