From 87fe9345482edc1cb506262848499e6962304451 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Fri, 6 Oct 2023 01:06:50 -0400 Subject: [PATCH] Add subi mnemonics & use capstone-style CR bits --- Cargo.toml | 1 + disasm/src/generated.rs | 72 +++++++++++++++++++++++++++++++++++++ disasm/src/lib.rs | 4 +-- disasm/tests/test_disasm.rs | 32 ++++++++--------- isa.yaml | 16 +++++++++ 5 files changed, 107 insertions(+), 18 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 71aa117..92a14d8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,4 +1,5 @@ [workspace] +resolver = "2" members = [ "disasm", "disasm-py", diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index 8900b3a..794974c 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -4860,6 +4860,61 @@ impl Ins { ins: self, }; } + if ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) < 0 + && ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) != -0x8000 + { + return SimplifiedIns { + mnemonic: "subi", + suffix: String::new(), + args: vec![ + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::Simm(Simm( + (-((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32)) + as _, + )), + ], + ins: self, + }; + } + } + Opcode::Addic => { + if ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) < 0 + && ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) != -0x8000 + { + return SimplifiedIns { + mnemonic: "subic", + suffix: String::new(), + args: vec![ + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::Simm(Simm( + (-((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32)) + as _, + )), + ], + ins: self, + }; + } + } + Opcode::Addic_ => { + if ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) < 0 + && ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) != -0x8000 + { + return SimplifiedIns { + mnemonic: "subic.", + suffix: String::new(), + args: vec![ + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::Simm(Simm( + (-((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32)) + as _, + )), + ], + ins: self, + }; + } } Opcode::Addis => { if ((self.code >> 16u8) & 0x1f) == 0 { @@ -4873,6 +4928,23 @@ impl Ins { ins: self, }; } + if ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) < 0 + && ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) != -0x8000 + { + return SimplifiedIns { + mnemonic: "subis", + suffix: String::new(), + args: vec![ + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::Simm(Simm( + (-((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32)) + as _, + )), + ], + ins: self, + }; + } } Opcode::Bc => { if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 0 diff --git a/disasm/src/lib.rs b/disasm/src/lib.rs index f47b868..e46950d 100644 --- a/disasm/src/lib.rs +++ b/disasm/src/lib.rs @@ -189,9 +189,9 @@ impl Display for CRBit { let cr = self.0 >> 2; let cc = self.0 & 3; if cr != 0 { - write!(f, "4*{}+", CRField(cr))?; + write!(f, "{}", CRField(cr))?; } - const CR_NAMES: [&str; 4] = ["lt", "gt", "eq", "so"]; + const CR_NAMES: [&str; 4] = ["lt", "gt", "eq", "un"]; f.write_str(CR_NAMES[cc as usize]) } } diff --git a/disasm/tests/test_disasm.rs b/disasm/tests/test_disasm.rs index 3d2bbf8..dd669f1 100644 --- a/disasm/tests/test_disasm.rs +++ b/disasm/tests/test_disasm.rs @@ -34,7 +34,7 @@ fn test_ins_addi() { assert_asm!(0x38010010, "addi r0, r1, 0x10"); assert_asm!(0x38010018, "addi r0, r1, 0x18"); assert_asm!(0x38010140, "addi r0, r1, 0x140"); - assert_asm!(0x38049000, "addi r0, r4, -0x7000"); + assert_asm!(0x38049000, "subi r0, r4, 0x7000"); assert_asm!(0x38a00000, "li r5, 0x0"); } @@ -45,12 +45,12 @@ fn test_ins_adde() { #[test] fn test_ins_addic() { - assert_asm!(0x3060ffff, "addic r3, r0, -0x1"); + assert_asm!(0x3060ffff, "subic r3, r0, 0x1"); assert_asm!(0x30840800, "addic r4, r4, 0x800"); assert_asm!(0x30a50008, "addic r5, r5, 0x8"); assert_asm!(0x37DF001C, "addic. r30, r31, 0x1c"); assert_asm!(0x37E06278, "addic. r31, r0, 0x6278"); - assert_asm!(0x37E3FFFF, "addic. r31, r3, -0x1"); + assert_asm!(0x37E3FFFF, "subic. r31, r3, 0x1"); } #[test] @@ -126,8 +126,8 @@ fn test_ins_bc() { assert_asm!(0x4200F560, "bdnz -0xaa0"); assert_asm!(0x40010014, "bdnzf gt, 0x14"); assert_asm!(0x40410035, "bdzfl gt, 0x34"); - assert_asm!(0x41430023, "bdztla so, 0x20"); - assert_asm!(0x4108FFE3, "bdnztla 4*cr2+lt, -0x20"); + assert_asm!(0x41430023, "bdztla un, 0x20"); + assert_asm!(0x4108FFE3, "bdnztla cr2lt, -0x20"); assert_asm!(0x40A20008, "bne+ 0x8"); } @@ -155,7 +155,7 @@ fn test_ins_bclr() { assert_asm!(0x4E800020, "blr"); assert_asm!(0x4E800021, "blrl"); assert_asm!(0x4D000020, "bdnztlr lt"); - assert_asm!(0x4C1F0021, "bdnzflrl 4*cr7+so"); + assert_asm!(0x4C1F0021, "bdnzflrl cr7un"); } #[test] @@ -187,44 +187,44 @@ fn test_ins_cntlzw() { #[test] fn test_ins_crand() { - assert_asm!(0x4C853202, "crand 4*cr1+lt, 4*cr1+gt, 4*cr1+eq"); + assert_asm!(0x4C853202, "crand cr1lt, cr1gt, cr1eq"); } #[test] fn test_ins_crandc() { - assert_asm!(0x4C642902, "crandc so, 4*cr1+lt, 4*cr1+gt"); + assert_asm!(0x4C642902, "crandc un, cr1lt, cr1gt"); } #[test] fn test_ins_creqv() { - assert_asm!(0x4CE00A42, "creqv 4*cr1+so, lt, gt"); + assert_asm!(0x4CE00A42, "creqv cr1un, lt, gt"); } #[test] fn test_ins_crnand() { - assert_asm!(0x4C2219C2, "crnand gt, eq, so"); + assert_asm!(0x4C2219C2, "crnand gt, eq, un"); } #[test] fn test_ins_cror() { assert_asm!(0x4C411382, "cror eq, gt, eq"); - assert_asm!(0x4CA63B82, "cror 4*cr1+gt, 4*cr1+eq, 4*cr1+so"); + assert_asm!(0x4CA63B82, "cror cr1gt, cr1eq, cr1un"); } #[test] fn test_ins_crorc() { - assert_asm!(0x4C432342, "crorc eq, so, 4*cr1+lt"); + assert_asm!(0x4C432342, "crorc eq, un, cr1lt"); } #[test] fn test_ins_crnor() { assert_asm!(0x4C011042, "crnor lt, gt, eq"); - assert_asm!(0x4CA63042, "crnot 4*cr1+gt, 4*cr1+eq"); + assert_asm!(0x4CA63042, "crnot cr1gt, cr1eq"); } #[test] fn test_ins_crxor() { - assert_asm!(0x4CC70182, "crxor 4*cr1+eq, 4*cr1+so, lt"); + assert_asm!(0x4CC70182, "crxor cr1eq, cr1un, lt"); } #[test] @@ -585,12 +585,12 @@ fn test_ins_mtcrf() { #[test] fn test_ins_mtfsb0() { - assert_asm!(0xFFA0008C, "mtfsb0 4*cr7+gt") + assert_asm!(0xFFA0008C, "mtfsb0 cr7gt") } #[test] fn test_ins_mtfsb1() { - assert_asm!(0xFFA0004C, "mtfsb1 4*cr7+gt"); + assert_asm!(0xFFA0004C, "mtfsb1 cr7gt"); } #[test] diff --git a/isa.yaml b/isa.yaml index 6b10729..eb878d8 100644 --- a/isa.yaml +++ b/isa.yaml @@ -1973,10 +1973,26 @@ mnemonics: opcode: addis args: [ rD, uimm ] condition: rA == 0 + - name: subis + opcode: addis + args: [ rD, rA, simm=-simm ] + condition: simm < 0 && simm != -0x8000 - name: li opcode: addi args: [ rD, simm ] condition: rA == 0 + - name: subi + opcode: addi + args: [ rD, rA, simm=-simm ] + condition: simm < 0 && simm != -0x8000 + - name: subic + opcode: addic + args: [ rD, rA, simm=-simm ] + condition: simm < 0 && simm != -0x8000 + - name: subic. + opcode: addic. + args: [ rD, rA, simm=-simm ] + condition: simm < 0 && simm != -0x8000 - name: mr opcode: or args: [ rA, rS ]