From b8199e678c4e5447f2ef0c6a15dfe94f7faa0f49 Mon Sep 17 00:00:00 2001 From: Richard Patel Date: Thu, 7 Apr 2022 04:07:15 +0200 Subject: [PATCH] fix signed fields --- disasm/src/generated.rs | 483 ++++++++++++++++++++++++++++-------- disasm/src/lib.rs | 20 ++ disasm/tests/test_disasm.rs | 3 +- flow-graph/Cargo.toml | 4 +- flow-graph/src/flow.rs | 7 +- flow-graph/src/slices.rs | 4 +- genisa/src/main.rs | 78 +++++- isa.yaml | 2 + 8 files changed, 486 insertions(+), 115 deletions(-) diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index e3141ae..2c61756 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -1166,7 +1166,7 @@ pub enum Field { ctr, lr, } -#[allow(clippy::all)] +#[allow(clippy::all, unused_mut)] impl Ins { pub(crate) fn _fields(&self) -> Vec { match self.op { @@ -1189,22 +1189,28 @@ impl Ins { Opcode::Addi => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::simm(Simm(((self.code >> 0u8) & 0xffff) as _)), + Field::simm(Simm( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), ], Opcode::Addic => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::simm(Simm(((self.code >> 0u8) & 0xffff) as _)), + Field::simm(Simm( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), ], Opcode::Addic_ => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::simm(Simm(((self.code >> 0u8) & 0xffff) as _)), + Field::simm(Simm( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), ], Opcode::Addis => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::uimm(Uimm(((self.code >> 0u8) & 0xffff) as _)), + Field::uimm(Uimm((self.code & 0xffff) as _)), ], Opcode::Addme => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), @@ -1227,18 +1233,22 @@ impl Ins { Opcode::Andi_ => vec![ Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::uimm(Uimm(((self.code >> 0u8) & 0xffff) as _)), + Field::uimm(Uimm((self.code & 0xffff) as _)), ], Opcode::Andis_ => vec![ Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::uimm(Uimm(((self.code >> 0u8) & 0xffff) as _)), + Field::uimm(Uimm((self.code & 0xffff) as _)), ], - Opcode::B => vec![Field::LI(BranchDest(((self.code >> 2u8) & 0xffffff) as _))], + Opcode::B => vec![Field::LI(BranchDest( + (((((self.code >> 2u8) & 0xffffff) ^ 0x800000).wrapping_sub(0x800000)) << 2u8) as _, + ))], Opcode::Bc => vec![ Field::BO(OpaqueU(((self.code >> 21u8) & 0x1f) as _)), Field::BI(OpaqueU(((self.code >> 16u8) & 0x1f) as _)), - Field::BD(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Field::BD(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) << 2u8) as _, + )), ], Opcode::Bcctr => vec![ Field::BO(OpaqueU(((self.code >> 21u8) & 0x1f) as _)), @@ -1256,7 +1266,9 @@ impl Ins { Opcode::Cmpi => vec![ Field::crfD(CRBit(((self.code >> 23u8) & 0x7) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::simm(Simm(((self.code >> 0u8) & 0xffff) as _)), + Field::simm(Simm( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), ], Opcode::Cmpl => vec![ Field::crfD(CRBit(((self.code >> 23u8) & 0x7) as _)), @@ -1266,7 +1278,7 @@ impl Ins { Opcode::Cmpli => vec![ Field::crfD(CRBit(((self.code >> 23u8) & 0x7) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::uimm(Uimm(((self.code >> 0u8) & 0xffff) as _)), + Field::uimm(Uimm((self.code & 0xffff) as _)), ], Opcode::Cntlzw => vec![ Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), @@ -1521,12 +1533,16 @@ impl Ins { Opcode::Isync => vec![], Opcode::Lbz => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Lbzu => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Lbzux => vec![ @@ -1541,12 +1557,16 @@ impl Ins { ], Opcode::Lfd => vec![ Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Lfdu => vec![ Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Lfdux => vec![ @@ -1561,12 +1581,16 @@ impl Ins { ], Opcode::Lfs => vec![ Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Lfsu => vec![ Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Lfsux => vec![ @@ -1581,12 +1605,16 @@ impl Ins { ], Opcode::Lha => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Lhau => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Lhaux => vec![ @@ -1606,12 +1634,16 @@ impl Ins { ], Opcode::Lhz => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Lhzu => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Lhzux => vec![ @@ -1626,7 +1658,9 @@ impl Ins { ], Opcode::Lmw => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Lswi => vec![ @@ -1651,12 +1685,16 @@ impl Ins { ], Opcode::Lwz => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Lwzu => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Lwzux => vec![ @@ -1737,7 +1775,9 @@ impl Ins { Opcode::Mulli => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::simm(Simm(((self.code >> 0u8) & 0xffff) as _)), + Field::simm(Simm( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), ], Opcode::Mullw => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), @@ -1771,23 +1811,27 @@ impl Ins { Opcode::Ori => vec![ Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::uimm(Uimm(((self.code >> 0u8) & 0xffff) as _)), + Field::uimm(Uimm((self.code & 0xffff) as _)), ], Opcode::Oris => vec![ Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::uimm(Uimm(((self.code >> 0u8) & 0xffff) as _)), + Field::uimm(Uimm((self.code & 0xffff) as _)), ], Opcode::PsqL => vec![ Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::ps_W(OpaqueU(((self.code >> 16u8) & 0x0) as _)), Field::ps_l(GQR(((self.code >> 12u8) & 0x7) as _)), ], Opcode::PsqLu => vec![ Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::ps_W(OpaqueU(((self.code >> 16u8) & 0x0) as _)), Field::ps_l(GQR(((self.code >> 12u8) & 0x7) as _)), @@ -1808,14 +1852,18 @@ impl Ins { ], Opcode::PsqSt => vec![ Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::ps_W(OpaqueU(((self.code >> 16u8) & 0x0) as _)), Field::ps_l(GQR(((self.code >> 12u8) & 0x7) as _)), ], Opcode::PsqStu => vec![ Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::ps_W(OpaqueU(((self.code >> 16u8) & 0x0) as _)), Field::ps_l(GQR(((self.code >> 12u8) & 0x7) as _)), @@ -2028,12 +2076,16 @@ impl Ins { ], Opcode::Stb => vec![ Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Stbu => vec![ Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Stbux => vec![ @@ -2048,12 +2100,16 @@ impl Ins { ], Opcode::Stfd => vec![ Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Stfdu => vec![ Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Stfdux => vec![ @@ -2073,12 +2129,16 @@ impl Ins { ], Opcode::Stfs => vec![ Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Stfsu => vec![ Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Stfsux => vec![ @@ -2093,7 +2153,9 @@ impl Ins { ], Opcode::Sth => vec![ Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Sthbrx => vec![ @@ -2103,7 +2165,9 @@ impl Ins { ], Opcode::Sthu => vec![ Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Sthux => vec![ @@ -2118,7 +2182,9 @@ impl Ins { ], Opcode::Stmw => vec![ Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Stswi => vec![ @@ -2133,7 +2199,9 @@ impl Ins { ], Opcode::Stw => vec![ Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Stwbrx => vec![ @@ -2148,7 +2216,9 @@ impl Ins { ], Opcode::Stwu => vec![ Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], Opcode::Stwux => vec![ @@ -2179,7 +2249,9 @@ impl Ins { Opcode::Subfic => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::simm(Simm(((self.code >> 0u8) & 0xffff) as _)), + Field::simm(Simm( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), ], Opcode::Subfme => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), @@ -2200,7 +2272,9 @@ impl Ins { Opcode::Twi => vec![ Field::TO(OpaqueU(((self.code >> 21u8) & 0x1f) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), - Field::simm(Simm(((self.code >> 0u8) & 0xffff) as _)), + Field::simm(Simm( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), ], Opcode::Xor => vec![ Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), @@ -2210,16 +2284,15 @@ impl Ins { Opcode::Xori => vec![ Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::uimm(Uimm(((self.code >> 0u8) & 0xffff) as _)), + Field::uimm(Uimm((self.code & 0xffff) as _)), ], Opcode::Xoris => vec![ Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), - Field::uimm(Uimm(((self.code >> 0u8) & 0xffff) as _)), + Field::uimm(Uimm((self.code & 0xffff) as _)), ], } } - #[allow(unused_mut)] pub(crate) fn _defs(&self) -> Vec { match self.op { Opcode::Illegal => vec![], @@ -2492,7 +2565,6 @@ impl Ins { Opcode::Xoris => vec![Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))], } } - #[allow(unused_mut)] pub(crate) fn _uses(&self) -> Vec { match self.op { Opcode::Illegal => vec![], @@ -2956,7 +3028,9 @@ impl Ins { uses } Opcode::Lbz => { - let mut uses = vec![Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _))]; + let mut uses = vec![Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ))]; if ((self.code >> 16u8) & 0x1f) != 0 { uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); } @@ -2964,7 +3038,9 @@ impl Ins { } Opcode::Lbzu => { let mut uses = vec![ - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ]; uses @@ -2984,7 +3060,9 @@ impl Ins { uses } Opcode::Lfd => { - let mut uses = vec![Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _))]; + let mut uses = vec![Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ))]; if ((self.code >> 16u8) & 0x1f) != 0 { uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); } @@ -2992,7 +3070,9 @@ impl Ins { } Opcode::Lfdu => { let mut uses = vec![ - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ]; uses @@ -3012,7 +3092,9 @@ impl Ins { uses } Opcode::Lfs => { - let mut uses = vec![Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _))]; + let mut uses = vec![Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ))]; if ((self.code >> 16u8) & 0x1f) != 0 { uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); } @@ -3020,7 +3102,9 @@ impl Ins { } Opcode::Lfsu => { let mut uses = vec![ - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ]; uses @@ -3040,7 +3124,9 @@ impl Ins { uses } Opcode::Lha => { - let mut uses = vec![Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _))]; + let mut uses = vec![Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ))]; if ((self.code >> 16u8) & 0x1f) != 0 { uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); } @@ -3048,7 +3134,9 @@ impl Ins { } Opcode::Lhau => { let mut uses = vec![ - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ]; uses @@ -3075,7 +3163,9 @@ impl Ins { uses } Opcode::Lhz => { - let mut uses = vec![Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _))]; + let mut uses = vec![Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ))]; if ((self.code >> 16u8) & 0x1f) != 0 { uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); } @@ -3083,7 +3173,9 @@ impl Ins { } Opcode::Lhzu => { let mut uses = vec![ - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ]; uses @@ -3103,7 +3195,9 @@ impl Ins { uses } Opcode::Lmw => { - let mut uses = vec![Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _))]; + let mut uses = vec![Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ))]; if ((self.code >> 16u8) & 0x1f) != 0 { uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); } @@ -3138,7 +3232,9 @@ impl Ins { uses } Opcode::Lwz => { - let mut uses = vec![Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _))]; + let mut uses = vec![Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ))]; if ((self.code >> 16u8) & 0x1f) != 0 { uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); } @@ -3146,7 +3242,9 @@ impl Ins { } Opcode::Lwzu => { let mut uses = vec![ - Field::offset(Offset(((self.code >> 0u8) & 0xffff) as _)), + Field::offset(Offset( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ]; uses @@ -3912,7 +4010,6 @@ impl Ins { } } } - #[allow(unused_mut)] pub(crate) fn _modifiers(&self) -> Modifiers { match self.op { Opcode::Illegal => Modifiers::default(), @@ -4557,7 +4654,9 @@ impl Ins { modifiers: Modifiers::default(), args: vec![ Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::Simm(Simm(((self.code >> 0u8) & 0xffff) as _)), + Argument::Simm(Simm( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), ], ins: self, }; @@ -4570,7 +4669,7 @@ impl Ins { modifiers: Modifiers::default(), args: vec![ Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::Uimm(Uimm(((self.code >> 0u8) & 0xffff) as _)), + Argument::Uimm(Uimm((self.code & 0xffff) as _)), ], ins: self, }; @@ -4588,7 +4687,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4604,7 +4706,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4620,7 +4725,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4636,7 +4744,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4652,7 +4763,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4668,7 +4782,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4684,7 +4801,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4700,7 +4820,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4715,7 +4838,8 @@ impl Ins { m }, args: vec![Argument::BranchDest(BranchDest( - ((self.code >> 2u8) & 0x3fff) as _, + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) << 2u8) + as _, ))], ins: self, }; @@ -4730,7 +4854,8 @@ impl Ins { m }, args: vec![Argument::BranchDest(BranchDest( - ((self.code >> 2u8) & 0x3fff) as _, + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) << 2u8) + as _, ))], ins: self, }; @@ -4747,7 +4872,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4762,7 +4890,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4777,7 +4908,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4792,7 +4926,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4807,7 +4944,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4822,7 +4962,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4837,7 +4980,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4852,7 +4998,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4877,7 +5026,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4892,7 +5044,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4907,7 +5062,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4922,7 +5080,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4937,7 +5098,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4952,7 +5116,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4967,7 +5134,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -4982,7 +5152,10 @@ impl Ins { }, args: vec![ Argument::CRBit(CRBit(((self.code >> 18u8) & 0x7) as _)), - Argument::BranchDest(BranchDest(((self.code >> 2u8) & 0x3fff) as _)), + Argument::BranchDest(BranchDest( + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + << 2u8) as _, + )), ], ins: self, }; @@ -5008,7 +5181,9 @@ impl Ins { modifiers: Modifiers::default(), args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Simm(Simm(((self.code >> 0u8) & 0xffff) as _)), + Argument::Simm(Simm( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), ], ins: self, }; @@ -5020,7 +5195,9 @@ impl Ins { args: vec![ Argument::CRBit(CRBit(((self.code >> 23u8) & 0x7) as _)), Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Simm(Simm(((self.code >> 0u8) & 0xffff) as _)), + Argument::Simm(Simm( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), ], ins: self, }; @@ -5046,7 +5223,7 @@ impl Ins { modifiers: Modifiers::default(), args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Uimm(Uimm(((self.code >> 0u8) & 0xffff) as _)), + Argument::Uimm(Uimm((self.code & 0xffff) as _)), ], ins: self, }; @@ -5058,7 +5235,7 @@ impl Ins { args: vec![ Argument::CRBit(CRBit(((self.code >> 23u8) & 0x7) as _)), Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Uimm(Uimm(((self.code >> 0u8) & 0xffff) as _)), + Argument::Uimm(Uimm((self.code & 0xffff) as _)), ], ins: self, }; @@ -5180,7 +5357,7 @@ impl Ins { Opcode::Ori => { if ((self.code >> 16u8) & 0x1f) == 0 && ((self.code >> 21u8) & 0x1f) == 0 - && ((self.code >> 0u8) & 0xffff) == 0 + && (self.code & 0xffff) == 0 { return SimplifiedIns { mnemonic: "nop", @@ -5251,7 +5428,9 @@ impl Ins { modifiers: Modifiers::default(), args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Simm(Simm(((self.code >> 0u8) & 0xffff) as _)), + Argument::Simm(Simm( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), ], ins: self, }; @@ -5262,7 +5441,9 @@ impl Ins { modifiers: Modifiers::default(), args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), - Argument::Simm(Simm(((self.code >> 0u8) & 0xffff) as _)), + Argument::Simm(Simm( + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + )), ], ins: self, }; @@ -5273,3 +5454,111 @@ impl Ins { SimplifiedIns::basic_form(self) } } +#[allow(clippy::all, non_snake_case)] +impl Ins { + pub fn field_simm(&self) -> isize { + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _ + } + pub fn field_uimm(&self) -> usize { + (self.code & 0xffff) as _ + } + pub fn field_offset(&self) -> isize { + (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _ + } + pub fn field_BO(&self) -> usize { + ((self.code >> 21u8) & 0x1f) as _ + } + pub fn field_BI(&self) -> usize { + ((self.code >> 16u8) & 0x1f) as _ + } + pub fn field_BD(&self) -> isize { + (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) << 2u8) as _ + } + pub fn field_LI(&self) -> isize { + (((((self.code >> 2u8) & 0xffffff) ^ 0x800000).wrapping_sub(0x800000)) << 2u8) as _ + } + pub fn field_SH(&self) -> usize { + ((self.code >> 11u8) & 0x1f) as _ + } + pub fn field_MB(&self) -> usize { + ((self.code >> 6u8) & 0x1f) as _ + } + pub fn field_ME(&self) -> usize { + ((self.code >> 1u8) & 0x1f) as _ + } + pub fn field_rS(&self) -> usize { + ((self.code >> 21u8) & 0x1f) as _ + } + pub fn field_rD(&self) -> usize { + ((self.code >> 21u8) & 0x1f) as _ + } + pub fn field_rA(&self) -> usize { + ((self.code >> 16u8) & 0x1f) as _ + } + pub fn field_rB(&self) -> usize { + ((self.code >> 11u8) & 0x1f) as _ + } + pub fn field_rC(&self) -> usize { + ((self.code >> 6u8) & 0x1f) as _ + } + pub fn field_sr(&self) -> usize { + ((self.code >> 16u8) & 0xf) as _ + } + pub fn field_spr(&self) -> usize { + ((self.code >> 11u8) & 0x3ff) as _ + } + pub fn field_frS(&self) -> usize { + ((self.code >> 21u8) & 0x1f) as _ + } + pub fn field_frD(&self) -> usize { + ((self.code >> 21u8) & 0x1f) as _ + } + pub fn field_frA(&self) -> usize { + ((self.code >> 16u8) & 0x1f) as _ + } + pub fn field_frB(&self) -> usize { + ((self.code >> 11u8) & 0x1f) as _ + } + pub fn field_frC(&self) -> usize { + ((self.code >> 6u8) & 0x1f) as _ + } + pub fn field_crbD(&self) -> usize { + ((self.code >> 21u8) & 0x1f) as _ + } + pub fn field_crbA(&self) -> usize { + ((self.code >> 16u8) & 0x1f) as _ + } + pub fn field_crbB(&self) -> usize { + ((self.code >> 11u8) & 0x1f) as _ + } + pub fn field_crfD(&self) -> usize { + ((self.code >> 23u8) & 0x7) as _ + } + pub fn field_crfS(&self) -> usize { + ((self.code >> 18u8) & 0x7) as _ + } + pub fn field_crm(&self) -> usize { + ((self.code >> 12u8) & 0xff) as _ + } + pub fn field_ps_l(&self) -> usize { + ((self.code >> 12u8) & 0x7) as _ + } + pub fn field_ps_W(&self) -> usize { + ((self.code >> 16u8) & 0x0) as _ + } + pub fn field_NB(&self) -> usize { + ((self.code >> 11u8) & 0x1f) as _ + } + pub fn field_tbr(&self) -> usize { + ((self.code >> 11u8) & 0x3ff) as _ + } + pub fn field_mtfsf_FM(&self) -> usize { + ((self.code >> 17u8) & 0xff) as _ + } + pub fn field_mtfsf_IMM(&self) -> usize { + ((self.code >> 12u8) & 0xf) as _ + } + pub fn field_TO(&self) -> usize { + ((self.code >> 21u8) & 0x1f) as _ + } +} diff --git a/disasm/src/lib.rs b/disasm/src/lib.rs index 89c7575..a09d433 100644 --- a/disasm/src/lib.rs +++ b/disasm/src/lib.rs @@ -313,6 +313,26 @@ impl Ins { pub fn bits(&self, range: Range) -> u32 { bits(self.code, range) } + + /* + pub fn branch_offset(&self) -> Option { + match self.op { + Opcode::B => Some(self.li()), + Opcode::Bc | Opcode::Bcctr | Opcode::Bclr => Some(self.field_BD() as i32), + _ => None, + } + } + + pub fn branch_dest(&self) -> Option { + self.branch_offset().and_then(|offset| { + if offset < 0 { + self.addr.checked_sub((-offset) as u32) + } else { + self.addr.checked_add(offset as u32) + } + }) + } + */ } /// A simplified PowerPC 750CL instruction. diff --git a/disasm/tests/test_disasm.rs b/disasm/tests/test_disasm.rs index cb12e7c..11a4527 100644 --- a/disasm/tests/test_disasm.rs +++ b/disasm/tests/test_disasm.rs @@ -85,7 +85,7 @@ fn test_ins_andi_() { fn test_ins_andis_() { assert_asm!(0x77c802ff, "andis. r8, r30, 0x2ff"); } -/* + #[test] fn test_ins_b() { assert_asm!(0x48000000, "b 0x0"); @@ -96,6 +96,7 @@ fn test_ins_b() { assert_asm!(0x4BDC1A59, "bl -0x23e5a8"); } +/* #[test] fn test_ins_bc() { assert_asm!(0x40800008, "bge 0x8"); diff --git a/flow-graph/Cargo.toml b/flow-graph/Cargo.toml index 18d12bd..a5fc135 100644 --- a/flow-graph/Cargo.toml +++ b/flow-graph/Cargo.toml @@ -8,9 +8,9 @@ description = "Control flow graph analysis for PowerPC 750CL" repository = "https://github.com/terorie/ppc750cl" [dependencies] -clap = "2.33" +clap = "3" dol = { version = "0.1.0", path = "../dol" } itertools = "0.10" -parse_int = "0.5" +parse_int = "0.6" petgraph = "0.6" ppc750cl = { version = "0.1.1", path = "../disasm" } diff --git a/flow-graph/src/flow.rs b/flow-graph/src/flow.rs index 1c4d81b..4eb7d15 100644 --- a/flow-graph/src/flow.rs +++ b/flow-graph/src/flow.rs @@ -55,14 +55,17 @@ impl<'a> BasicBlock<'a> { Opcode::Addis => { if ins.a() == 0 { // lis - defs.insert(ins.d(), ins.uimm()); + defs.insert(ins.d(), ins.field_uimm() as u16); } else { defs.remove(&ins.d()); } } Opcode::Addi => { if let Some(hi) = defs.get(&ins.a()) { - data_refs.insert(ins.addr / 4, ((*hi as u32) << 16) + (ins.uimm() as u32)); + data_refs.insert( + ins.addr / 4, + ((*hi as u32) << 16) + (ins.field_uimm() as u32), + ); } defs.remove(&ins.d()); } diff --git a/flow-graph/src/slices.rs b/flow-graph/src/slices.rs index 368ae2b..2529ec9 100644 --- a/flow-graph/src/slices.rs +++ b/flow-graph/src/slices.rs @@ -33,7 +33,7 @@ impl BasicSlices { continue; } // We encountered some kind of control flow instruction. - if ins.code != Opcode::BLR { + if ins.field_BO() == 20 && ins.field_BI() == 0 { // There's a possibility that branch can be taken. // Branch destinations are always the first instruction of a block. // Thus, we also found the end of another block. @@ -58,5 +58,5 @@ fn is_conditional_branch(ins: &Ins) -> bool { _ => return false, }; // Check whether bits "branch always". - ins.bo() & 0b10100 != 0b10100 + ins.field_BO() & 0b10100 != 0b10100 } diff --git a/genisa/src/main.rs b/genisa/src/main.rs index 8d585a9..7fc4e04 100644 --- a/genisa/src/main.rs +++ b/genisa/src/main.rs @@ -97,24 +97,49 @@ pub(crate) struct Field { signed: bool, split: bool, arg: Option, + shift_left: u8, } impl Field { fn variant_identifier(&self) -> Option { + self.identifier("") + } + + fn identifier(&self, prefix: &str) -> Option { if self.name.strip_suffix(".nz").is_none() { - Some(to_rust_ident(&self.name)) + Some(to_rust_ident(prefix, &self.name)) } else { None } } fn express_value(&self, code: TokenStream) -> TokenStream { + let mut val = quote!(#code); + let shift = 32 - self.bits.0.end; - let mask = (1u32 << self.bits.0.len()) - 1; - let mask = LitInt::new(&format!("0x{:x}", mask), Span::call_site()); - quote! { - ((#code >> #shift) & #mask) + if shift > 0 { + val = quote!((#val >> #shift)); } + + let mask = (1u32 << self.bits.0.len()) - 1; + if mask != 0xFFFF_FFFF { + let mask = LitInt::new(&format!("0x{:x}", mask), Span::call_site()); + val = quote!((#val & #mask)); + } + + // https://graphics.stanford.edu/~seander/bithacks.html#VariableSignExtend + if self.signed { + let mask2 = 1u32 << (self.bits.0.len() - 1); + let mask2 = LitInt::new(&format!("0x{:x}", mask2), Span::call_site()); + val = quote!(((#val ^ #mask2).wrapping_sub(#mask2))) + } + + let val_shift = self.shift_left; + if val_shift > 0 { + val = quote!((#val << #val_shift)); + } + + val } fn express_value_self(&self) -> TokenStream { @@ -153,6 +178,27 @@ impl Field { fn construct_variant_self(&self) -> TokenStream { self.construct_variant(quote!(self.code)) } + + fn construct_accessor(&self) -> TokenStream { + let field_variant = match self.identifier("field_") { + Some(v) => v, + None => return TokenStream::new(), + }; + if self.arg.is_none() { + return TokenStream::new(); + } + let value = self.express_value_self(); + let ret_type = if self.signed { + quote!(isize) + } else { + quote!(usize) + }; + quote! { + pub fn #field_variant(&self) -> #ret_type { + #value as _ + } + } + } } #[derive(Deserialize, Default)] @@ -475,9 +521,15 @@ impl Isa { let use_match_arms = token_stream!(use_match_arms); let modifier_match_arms = token_stream!(modifier_match_arms); let simplified_ins_match_arms = token_stream!(simplified_ins_match_arms); + let field_accessors = self + .fields + .iter() + .map(|field| field.construct_accessor()) + .collect::>(); + let field_accessors = token_stream!(field_accessors); // Generate final fields function. let ins_impl = quote! { - #[allow(clippy::all)] + #[allow(clippy::all, unused_mut)] impl Ins { pub(crate) fn _fields(&self) -> Vec { match self.op { @@ -486,7 +538,6 @@ impl Isa { } } - #[allow(unused_mut)] pub(crate) fn _defs(&self) -> Vec { match self.op { Opcode::Illegal => vec![], @@ -494,7 +545,6 @@ impl Isa { } } - #[allow(unused_mut)] pub(crate) fn _uses(&self) -> Vec { match self.op { Opcode::Illegal => vec![], @@ -502,7 +552,6 @@ impl Isa { } } - #[allow(unused_mut)] pub(crate) fn _modifiers(&self) -> Modifiers { match self.op { Opcode::Illegal => Modifiers::default(), @@ -518,14 +567,21 @@ impl Isa { SimplifiedIns::basic_form(self) } } + #[allow(clippy::all, non_snake_case)] + impl Ins { + #field_accessors + } }; Ok(ins_impl) } } /// Converts the given key into an identifier. -fn to_rust_ident(key: &str) -> TokenTree { - TokenTree::Ident(Ident::new(&key.replace('.', "_"), Span::call_site())) +fn to_rust_ident(prefix: &str, key: &str) -> TokenTree { + TokenTree::Ident(Ident::new( + &(prefix.to_owned() + &key.replace('.', "_")), + Span::call_site(), + )) } /// Converts the given key into an enum variant key. diff --git a/isa.yaml b/isa.yaml index 7ab30df..c4eb52a 100644 --- a/isa.yaml +++ b/isa.yaml @@ -22,9 +22,11 @@ fields: arg: BranchDest bits: 16..30 shift_left: 2 + signed: true - name: LI arg: BranchDest bits: 6..30 + signed: true shift_left: 2 # Shift/rotate type fields - name: SH