diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index 5becd08..3ec512b 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -1165,6 +1165,8 @@ pub enum Field { tbr(OpaqueU), mtfsf_FM(OpaqueU), mtfsf_IMM(OpaqueU), + spr_SPRG(OpaqueU), + spr_BAT(OpaqueU), TO(OpaqueU), L(OpaqueU), xer, @@ -1212,6 +1214,8 @@ impl Field { Field::tbr(x) => Some(Argument::OpaqueU(*x)), Field::mtfsf_FM(x) => Some(Argument::OpaqueU(*x)), Field::mtfsf_IMM(x) => Some(Argument::OpaqueU(*x)), + Field::spr_SPRG(x) => Some(Argument::OpaqueU(*x)), + Field::spr_BAT(x) => Some(Argument::OpaqueU(*x)), Field::TO(x) => Some(Argument::OpaqueU(*x)), Field::L(x) => Some(Argument::OpaqueU(*x)), _ => None, @@ -1257,6 +1261,8 @@ impl Field { Field::tbr(_) => "tbr", Field::mtfsf_FM(_) => "mtfsf_FM", Field::mtfsf_IMM(_) => "mtfsf_IMM", + Field::spr_SPRG(_) => "spr_SPRG", + Field::spr_BAT(_) => "spr_BAT", Field::TO(_) => "TO", Field::L(_) => "L", Field::xer => "xer", @@ -5699,11 +5705,141 @@ impl Ins { if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) as u32 - == 397 + == 19 + { + return SimplifiedIns { + mnemonic: "mfdar", + args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + == 22 + { + return SimplifiedIns { + mnemonic: "mfdec", + args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + == 25 + { + return SimplifiedIns { + mnemonic: "mfsdr1", + args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + == 26 + { + return SimplifiedIns { + mnemonic: "mfsrr0", + args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + == 27 + { + return SimplifiedIns { + mnemonic: "mfsrr1", + args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + & 0b1111111100 + == 272 + { + return SimplifiedIns { + mnemonic: "mfsprg", + args: vec![ + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + Argument::OpaqueU(OpaqueU(((self.code >> 16u8) & 0x3) as _)), + ], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + == 282 + { + return SimplifiedIns { + mnemonic: "mfear", + args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + & 0b1111111001 + == 528 + { + return SimplifiedIns { + mnemonic: "mfibatu", + args: vec![ + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), + ], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + & 0b1111111001 + == 529 + { + return SimplifiedIns { + mnemonic: "mfibatl", + args: vec![ + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), + ], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + & 0b1111111001 + == 536 { return SimplifiedIns { mnemonic: "mfdbatu", - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], + args: vec![ + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), + ], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + & 0b1111111001 + == 537 + { + return SimplifiedIns { + mnemonic: "mfdbatl", + args: vec![ + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), + ], ins: self, }; } @@ -5756,11 +5892,163 @@ impl Ins { if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) as u32 - == 397 + == 19 + { + return SimplifiedIns { + mnemonic: "mtdar", + args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + == 22 + { + return SimplifiedIns { + mnemonic: "mtdec", + args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + == 25 + { + return SimplifiedIns { + mnemonic: "mtsdr1", + args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + == 26 + { + return SimplifiedIns { + mnemonic: "mtsrr0", + args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + == 27 + { + return SimplifiedIns { + mnemonic: "mtsrr1", + args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + & 0b1111111100 + == 272 + { + return SimplifiedIns { + mnemonic: "mtsprg", + args: vec![ + Argument::OpaqueU(OpaqueU(((self.code >> 16u8) & 0x3) as _)), + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + ], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + == 282 + { + return SimplifiedIns { + mnemonic: "mtear", + args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + == 284 + { + return SimplifiedIns { + mnemonic: "mttbl", + args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + == 285 + { + return SimplifiedIns { + mnemonic: "mttbu", + args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + & 0b1111111001 + == 528 + { + return SimplifiedIns { + mnemonic: "mtibatu", + args: vec![ + Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + ], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + & 0b1111111001 + == 529 + { + return SimplifiedIns { + mnemonic: "mtibatl", + args: vec![ + Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + ], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + & 0b1111111001 + == 536 { return SimplifiedIns { mnemonic: "mtdbatu", - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], + args: vec![ + Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + ], + ins: self, + }; + } + if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) + | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) + as u32 + & 0b1111111001 + == 537 + { + return SimplifiedIns { + mnemonic: "mtdbatl", + args: vec![ + Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + ], ins: self, }; } @@ -6029,6 +6317,14 @@ impl Ins { ((self.code >> 12u8) & 0xf) as _ } #[inline(always)] + pub fn field_spr_SPRG(&self) -> usize { + ((self.code >> 16u8) & 0x3) as _ + } + #[inline(always)] + pub fn field_spr_BAT(&self) -> usize { + ((self.code >> 17u8) & 0x3) as _ + } + #[inline(always)] pub fn field_TO(&self) -> usize { ((self.code >> 21u8) & 0x1f) as _ } diff --git a/disasm/src/lib.rs b/disasm/src/lib.rs index 802cfb7..2bfeeee 100644 --- a/disasm/src/lib.rs +++ b/disasm/src/lib.rs @@ -104,7 +104,82 @@ field_arg!(FPR, u8, "f{}"); // Segment register. field_arg!(SR, u8); // Special-purpose register. -field_arg!(SPR, u16); +field_arg_no_display!(SPR, u16); +impl Display for SPR { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.write_str(match self.0 { + 1 => "XER", + 8 => "LR", + 9 => "CTR", + 18 => "DSISR", + 19 => "DAR", + 22 => "DEC", + 25 => "SDR1", + 26 => "SRR0", + 27 => "SRR1", + 272 => "SPRG0", + 273 => "SPRG1", + 274 => "SPRG2", + 275 => "SPRG3", + 282 => "EAR", + 287 => "PVR", + 528 => "IBAT0U", + 529 => "IBAT0L", + 530 => "IBAT1U", + 531 => "IBAT1L", + 532 => "IBAT2U", + 533 => "IBAT2L", + 534 => "IBAT3U", + 535 => "IBAT3L", + 536 => "DBAT0U", + 537 => "DBAT0L", + 538 => "DBAT1U", + 539 => "DBAT1L", + 540 => "DBAT2U", + 541 => "DBAT2L", + 542 => "DBAT3U", + 543 => "DBAT3L", + 912 => "GQR0", + 913 => "GQR1", + 914 => "GQR2", + 915 => "GQR3", + 916 => "GQR4", + 917 => "GQR5", + 918 => "GQR6", + 919 => "GQR7", + 920 => "HID2", + 921 => "WPAR", + 922 => "DMA_U", + 923 => "DMA_L", + 936 => "UMMCR0", + 937 => "UPMC1", + 938 => "UPMC2", + 939 => "USIA", + 940 => "UMMCR1", + 941 => "UPMC3", + 942 => "UPMC4", + 943 => "USDA", + 952 => "MMCR0", + 953 => "PMC1", + 954 => "PMC2", + 955 => "SIA", + 956 => "MMCR1", + 957 => "PMC3", + 958 => "PMC4", + 959 => "SDA", + 1008 => "HID0", + 1009 => "HID1", + 1010 => "IABR", + 1013 => "DABR", + 1017 => "L2CR", + 1019 => "ICTC", + 1020 => "THRM1", + 1021 => "THRM2", + 1022 => "THRM3", + _ => return write!(f, "{}", self.0), + }) + } +} // Condition register field. field_arg!(CRField, u8, "cr{}"); // Condition register bit (index + condition case). diff --git a/disasm/tests/test_disasm.rs b/disasm/tests/test_disasm.rs index 052ee86..5722b9f 100644 --- a/disasm/tests/test_disasm.rs +++ b/disasm/tests/test_disasm.rs @@ -496,7 +496,10 @@ fn test_ins_mfmsr() { #[test] fn test_ins_mfspr() { - assert_asm!(0x7E1A02A6, "mfspr r16, 26"); + assert_asm!(0x7E1A02A6, "mfsrr0 r16"); + assert_asm!(0x7C70FAA6, "mfspr r3, HID0"); + assert_asm!(0x7C7482A6, "mfibatu r3, 2"); + assert_asm!(0x7C7782A6, "mfibatl r3, 3"); } #[test] @@ -537,7 +540,16 @@ fn test_ins_mtmsr() { #[test] fn test_ins_mtspr() { - assert_asm!(0x7E75FBA6, "mtspr 1013, r19"); + assert_asm!(0x7E75FBA6, "mtspr DABR, r19"); + assert_asm!(0x7C70FBA6, "mtspr HID0, r3"); + assert_asm!(0x7C7603A6, "mtdec r3"); + assert_asm!(0x7C7043A6, "mtsprg 0, r3"); + assert_asm!(0x7C7143A6, "mtsprg 1, r3"); + assert_asm!(0x7C7343A6, "mtsprg 3, r3"); + assert_asm!(0x7C7083A6, "mtibatu 0, r3"); + assert_asm!(0x7C7483A6, "mtibatu 2, r3"); + assert_asm!(0x7C7783A6, "mtibatl 3, r3"); + assert_asm!(0x7C7D83A6, "mtdbatl 2, r3"); } #[test] diff --git a/isa.yaml b/isa.yaml index c39f470..25bbf68 100644 --- a/isa.yaml +++ b/isa.yaml @@ -141,6 +141,14 @@ fields: arg: OpaqueU desc: Immediate for mtfsfi bits: 16..20 + - name: spr_SPRG + arg: OpaqueU + desc: SPRG index for m[tf]sprg + bits: 14..16 + - name: spr_BAT + arg: OpaqueU + desc: IBAT/DBAT index for m[tf][id]bat[ul] + bits: 13..15 - name: TO arg: OpaqueU desc: Bitset for tw and twi @@ -2099,10 +2107,58 @@ mnemonics: opcode: mtspr args: [ rS ] condition: spr == 18 - - name: mtdbatu + - name: mtdar opcode: mtspr args: [ rS ] - condition: spr == 397 + condition: spr == 19 + - name: mtdec + opcode: mtspr + args: [ rS ] + condition: spr == 22 + - name: mtsdr1 + opcode: mtspr + args: [ rS ] + condition: spr == 25 + - name: mtsrr0 + opcode: mtspr + args: [ rS ] + condition: spr == 26 + - name: mtsrr1 + opcode: mtspr + args: [ rS ] + condition: spr == 27 + - name: mtsprg + opcode: mtspr + args: [ spr_SPRG, rS ] + condition: spr & 0b1111111100 == 272 + - name: mtear + opcode: mtspr + args: [ rS ] + condition: spr == 282 + - name: mttbl + opcode: mtspr + args: [ rS ] + condition: spr == 284 + - name: mttbu + opcode: mtspr + args: [ rS ] + condition: spr == 285 + - name: mtibatu + opcode: mtspr + args: [ spr_BAT, rS ] + condition: spr & 0b1111111001 == 528 + - name: mtibatl + opcode: mtspr + args: [ spr_BAT, rS ] + condition: spr & 0b1111111001 == 529 + - name: mtdbatu + opcode: mtspr + args: [ spr_BAT, rS ] + condition: spr & 0b1111111001 == 536 + - name: mtdbatl + opcode: mtspr + args: [ spr_BAT, rS ] + condition: spr & 0b1111111001 == 537 # Move from special-purpose register - name: mfxer @@ -2121,10 +2177,50 @@ mnemonics: opcode: mfspr args: [ rD ] condition: spr == 18 - - name: mfdbatu + - name: mfdar opcode: mfspr args: [ rD ] - condition: spr == 397 + condition: spr == 19 + - name: mfdec + opcode: mfspr + args: [ rD ] + condition: spr == 22 + - name: mfsdr1 + opcode: mfspr + args: [ rD ] + condition: spr == 25 + - name: mfsrr0 + opcode: mfspr + args: [ rD ] + condition: spr == 26 + - name: mfsrr1 + opcode: mfspr + args: [ rD ] + condition: spr == 27 + - name: mfsprg + opcode: mfspr + args: [ rD, spr_SPRG ] + condition: spr & 0b1111111100 == 272 + - name: mfear + opcode: mfspr + args: [ rD ] + condition: spr == 282 + - name: mfibatu + opcode: mfspr + args: [ rD, spr_BAT ] + condition: spr & 0b1111111001 == 528 + - name: mfibatl + opcode: mfspr + args: [ rD, spr_BAT ] + condition: spr & 0b1111111001 == 529 + - name: mfdbatu + opcode: mfspr + args: [ rD, spr_BAT ] + condition: spr & 0b1111111001 == 536 + - name: mfdbatl + opcode: mfspr + args: [ rD, spr_BAT ] + condition: spr & 0b1111111001 == 537 # Branch Conditional # bc branch always