From 5f6e991bf495388c4104f188d2e90c79da9f78de Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sun, 11 Dec 2022 23:47:35 -0500 Subject: [PATCH] Fix mcrf, mcrfs, mcrxr, twi, twui --- disasm/src/generated.rs | 57 ++++++++++++++++++++++++++++++++++--- disasm/tests/test_disasm.rs | 42 +++++++++++++++++++++++++++ isa.yaml | 20 ++++++++++--- 3 files changed, 111 insertions(+), 8 deletions(-) diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index c24c5be..8900b3a 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -770,13 +770,13 @@ impl Opcode { if code & 0xfc0007ff == 0x7c00002e { return Opcode::Lwzx; } - if code & 0xfc300fff == 0x4c000000 { + if code & 0xfc63ffff == 0x4c000000 { return Opcode::Mcrf; } - if code & 0xfc30ffff == 0xfc000080 { + if code & 0xfc63ffff == 0xfc000080 { return Opcode::Mcrfs; } - if code & 0xfc30ffff == 0x7c000400 { + if code & 0xfc7fffff == 0x7c000400 { return Opcode::Mcrxr; } if code & 0xfc1fffff == 0x7c000026 { @@ -1109,7 +1109,7 @@ impl Opcode { if code & 0xfc0007ff == 0x7c000008 { return Opcode::Tw; } - if code & 0xfc000000 == 0xc0000000 { + if code & 0xfc000000 == 0xc000000 { return Opcode::Twi; } if code & 0xfc0007fe == 0x7c000278 { @@ -7593,6 +7593,41 @@ impl Ins { }; } } + Opcode::Tw => { + if ((self.code >> 21u8) & 0x1f) == 4 { + return SimplifiedIns { + mnemonic: "tweq", + suffix: String::new(), + args: vec![ + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), + ], + ins: self, + }; + } + if ((self.code >> 21u8) & 0x1f) == 5 { + return SimplifiedIns { + mnemonic: "twlge", + suffix: String::new(), + args: vec![ + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), + ], + ins: self, + }; + } + if ((self.code >> 21u8) & 0x1f) == 31 + && ((self.code >> 16u8) & 0x1f) == 0 + && ((self.code >> 11u8) & 0x1f) == 0 + { + return SimplifiedIns { + mnemonic: "trap", + suffix: String::new(), + args: vec![], + ins: self, + }; + } + } Opcode::Twi => { if ((self.code >> 21u8) & 0x1f) == 8 { return SimplifiedIns { @@ -7622,6 +7657,20 @@ impl Ins { ins: self, }; } + if ((self.code >> 21u8) & 0x1f) == 31 { + return SimplifiedIns { + mnemonic: "twui", + suffix: String::new(), + args: vec![ + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::Simm(Simm( + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) + as _, + )), + ], + ins: self, + }; + } } _ => {} } diff --git a/disasm/tests/test_disasm.rs b/disasm/tests/test_disasm.rs index 783f623..3d2bbf8 100644 --- a/disasm/tests/test_disasm.rs +++ b/disasm/tests/test_disasm.rs @@ -530,6 +530,21 @@ fn test_ins_lwzx() { assert_asm!(0x7C03002E, "lwzx r0, r3, r0"); } +#[test] +fn test_ins_mcrf() { + assert_asm!(0x4E1C0000, "mcrf cr4, cr7"); +} + +#[test] +fn test_ins_mcrfs() { + assert_asm!(0xFE1C0080, "mcrfs cr4, cr7"); +} + +#[test] +fn test_ins_mcrxr() { + assert_asm!(0x7F800400, "mcrxr cr7"); +} + #[test] fn test_ins_mfcr() { assert_asm!(0x7C000026, "mfcr r0"); @@ -844,6 +859,7 @@ fn test_ins_rfi() { fn test_ins_rlwimi() { assert_asm!(0x500306FE, "rlwimi r3, r0, 0, 27, 31"); assert_asm!(0x50032D74, "rlwimi r3, r0, 5, 21, 26"); + assert_asm!(0x5400003F, "clrrwi. r0, r0, 0"); } #[test] @@ -1037,6 +1053,32 @@ fn test_ins_sync() { assert_asm!(0x7C0004AC, "sync"); } +#[test] +fn test_tlbie() { + assert_asm!(0x7C001A64, "tlbie r3"); +} + +#[test] +fn test_tlbsync() { + assert_asm!(0x7C00046C, "tlbsync"); +} + +#[test] +fn test_tw() { + assert_asm!(0x7C063808, "tw 0, r6, r7"); + assert_asm!(0x7C842808, "tweq r4, r5"); + assert_asm!(0x7CA42808, "twlge r4, r5"); + assert_asm!(0x7FE00008, "trap"); +} + +#[test] +fn test_twi() { + assert_asm!(0x0C000000, "twi 0, r0, 0x0"); + assert_asm!(0x0D07FFFF, "twgti r7, -0x1"); + assert_asm!(0x0CC4FF01, "twllei r4, -0xff"); + assert_asm!(0x0FE40003, "twui r4, 0x3"); +} + #[test] fn test_ins_xor() { assert_asm!(0x7C052A78, "xor r5, r0, r5"); diff --git a/isa.yaml b/isa.yaml index 93715ca..6b10729 100644 --- a/isa.yaml +++ b/isa.yaml @@ -1058,7 +1058,7 @@ opcodes: - name: mcrf desc: Move Condition Register Field - bitmask: 0xfc300fff + bitmask: 0xfc63ffff pattern: 0x4c000000 args: [ crfD, crfS ] defs: [ crfD ] @@ -1066,7 +1066,7 @@ opcodes: - name: mcrfs desc: Move to Condition Register from FPSCR - bitmask: 0xfc30ffff + bitmask: 0xfc63ffff pattern: 0xfc000080 args: [ crfD, crfS ] defs: [ crfD ] @@ -1074,7 +1074,7 @@ opcodes: - name: mcrxr desc: Move to Condition Register from XER - bitmask: 0xfc30ffff + bitmask: 0xfc7fffff pattern: 0x7c000400 args: [ crfD ] defs: [ crfD, xer ] @@ -1938,7 +1938,7 @@ opcodes: - name: twi desc: Trap Word Immediate bitmask: 0xfc000000 - pattern: 0xc0000000 + pattern: 0x0c000000 args: [ TO, rA, simm ] uses: [ rA ] @@ -2118,6 +2118,17 @@ mnemonics: condition: crbA == crbB # Misc + - name: tweq + opcode: tw + args: [ rA, rB ] + condition: TO == 4 + - name: twlge + opcode: tw + args: [ rA, rB ] + condition: TO == 5 + - name: trap + opcode: tw + condition: TO == 31 && rA == 0 && rB == 0 - name: twgti opcode: twi args: [ rA, simm ] @@ -2127,6 +2138,7 @@ mnemonics: args: [ rA, simm ] condition: TO == 6 - name: twui + opcode: twi args: [ rA, simm ] condition: TO == 31