From 9fd7546916993c7af65d4f5aeb5706b3bdd24bf7 Mon Sep 17 00:00:00 2001 From: InusualZ Date: Tue, 31 May 2022 17:47:00 -0400 Subject: [PATCH 01/13] disasm: improve branch ins helpers `branch_dest`: Support absolute destinations `is_branch`: Use `matches!` to improve readability `is_direct_branch`: Added helper to better match direct branches Co-authored-by: Richard Patel --- disasm/src/lib.rs | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/disasm/src/lib.rs b/disasm/src/lib.rs index 5ba3526..aa55169 100644 --- a/disasm/src/lib.rs +++ b/disasm/src/lib.rs @@ -229,6 +229,8 @@ pub struct Ins { } impl Ins { + const BLR: u32 = 0x4e800020; + /// Constructs an instruction from the given machine code and address. pub fn new(code: u32, addr: u32) -> Self { Self { @@ -283,19 +285,24 @@ impl Ins { pub fn branch_dest(&self) -> Option { self.branch_offset().and_then(|offset| { - if offset < 0 { - self.addr.checked_sub((-offset) as u32) + if self.field_AA() { + Some(offset as u32) } else { - self.addr.checked_add(offset as u32) + if offset < 0 { + self.addr.checked_sub((-offset) as u32) + } else { + self.addr.checked_add(offset as u32) + } } }) } pub fn is_branch(&self) -> bool { - match self.op { - Opcode::B | Opcode::Bc | Opcode::Bcctr | Opcode::Bclr => true, - _ => false, - } + matches!(self.op, Opcode::B | Opcode::Bc | Opcode::Bcctr | Opcode::Bclr) + } + + pub fn is_direct_branch(&self) -> bool { + matches!(self.op, Opcode::B | Opcode::Bc) } pub fn is_unconditional_branch(&self) -> bool { @@ -312,9 +319,10 @@ impl Ins { self.is_branch() && !self.is_unconditional_branch() } + #[inline] pub fn is_blr(&self) -> bool { // self.op == Opcode::Bclr && self.is_unconditional_branch() && !self.field_LK() - self.code == 0x4e800020 + self.code == Ins::BLR } } From d03a713a2b9624393014a92589e7c84f960db78a Mon Sep 17 00:00:00 2001 From: InusualZ Date: Tue, 31 May 2022 17:56:11 -0400 Subject: [PATCH 02/13] genisa: cast unmasked signed value Co-authored-by: Richard Patel --- disasm/src/generated.rs | 201 ++++++++++++++++++++++------------------ genisa/src/main.rs | 2 +- 2 files changed, 114 insertions(+), 89 deletions(-) diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index 86cbc1c..657cfc8 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -1277,21 +1277,21 @@ impl Ins { Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::simm(Simm( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) 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 & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) 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 & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), ], Opcode::Addis => vec![ @@ -1328,13 +1328,15 @@ impl Ins { Field::uimm(Uimm((self.code & 0xffff) as _)), ], Opcode::B => vec![Field::LI(BranchDest( - (((((self.code >> 2u8) & 0xffffff) ^ 0x800000).wrapping_sub(0x800000)) << 2u8) as _, + ((((((self.code >> 2u8) & 0xffffff) ^ 0x800000).wrapping_sub(0x800000)) as i32) + << 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) ^ 0x2000).wrapping_sub(0x2000)) << 2u8) as _, + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) + << 2u8) as _, )), ], Opcode::Bcctr => vec![ @@ -1354,7 +1356,7 @@ impl Ins { Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::simm(Simm( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), ], Opcode::Cmpl => vec![ @@ -1621,14 +1623,14 @@ impl Ins { Opcode::Lbz => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) 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 & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], @@ -1645,14 +1647,14 @@ impl Ins { Opcode::Lfd => vec![ Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) 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 & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], @@ -1669,14 +1671,14 @@ impl Ins { Opcode::Lfs => vec![ Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) 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 & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], @@ -1693,14 +1695,14 @@ impl Ins { Opcode::Lha => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) 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 & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], @@ -1722,14 +1724,14 @@ impl Ins { Opcode::Lhz => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) 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 & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], @@ -1746,7 +1748,7 @@ impl Ins { Opcode::Lmw => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], @@ -1773,14 +1775,14 @@ impl Ins { Opcode::Lwz => vec![ Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) 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 & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], @@ -1875,7 +1877,7 @@ impl Ins { Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::simm(Simm( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), ], Opcode::Mullw => vec![ @@ -1920,7 +1922,7 @@ impl Ins { Opcode::PsqL => vec![ Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), Field::ps_offset(Offset( - (((self.code & 0xfff) ^ 0x800).wrapping_sub(0x800)) as _, + ((((self.code & 0xfff) ^ 0x800).wrapping_sub(0x800)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::ps_W(OpaqueU(((self.code >> 15u8) & 0x1) as _)), @@ -1929,7 +1931,7 @@ impl Ins { Opcode::PsqLu => vec![ Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), Field::ps_offset(Offset( - (((self.code & 0xfff) ^ 0x800).wrapping_sub(0x800)) as _, + ((((self.code & 0xfff) ^ 0x800).wrapping_sub(0x800)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::ps_W(OpaqueU(((self.code >> 15u8) & 0x1) as _)), @@ -1952,7 +1954,7 @@ impl Ins { Opcode::PsqSt => vec![ Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), Field::ps_offset(Offset( - (((self.code & 0xfff) ^ 0x800).wrapping_sub(0x800)) as _, + ((((self.code & 0xfff) ^ 0x800).wrapping_sub(0x800)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::ps_W(OpaqueU(((self.code >> 15u8) & 0x1) as _)), @@ -1961,7 +1963,7 @@ impl Ins { Opcode::PsqStu => vec![ Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), Field::ps_offset(Offset( - (((self.code & 0xfff) ^ 0x800).wrapping_sub(0x800)) as _, + ((((self.code & 0xfff) ^ 0x800).wrapping_sub(0x800)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::ps_W(OpaqueU(((self.code >> 15u8) & 0x1) as _)), @@ -2176,14 +2178,14 @@ impl Ins { Opcode::Stb => vec![ Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) 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 & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], @@ -2200,14 +2202,14 @@ impl Ins { Opcode::Stfd => vec![ Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) 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 & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], @@ -2229,14 +2231,14 @@ impl Ins { Opcode::Stfs => vec![ Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) 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 & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], @@ -2253,7 +2255,7 @@ impl Ins { Opcode::Sth => vec![ Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], @@ -2265,7 +2267,7 @@ impl Ins { Opcode::Sthu => vec![ Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], @@ -2282,7 +2284,7 @@ impl Ins { Opcode::Stmw => vec![ Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], @@ -2299,7 +2301,7 @@ impl Ins { Opcode::Stw => vec![ Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], @@ -2316,7 +2318,7 @@ impl Ins { Opcode::Stwu => vec![ Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ], @@ -2349,7 +2351,7 @@ impl Ins { Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::simm(Simm( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), ], Opcode::Subfme => vec![ @@ -2372,7 +2374,7 @@ impl Ins { Field::TO(OpaqueU(((self.code >> 21u8) & 0x1f) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::simm(Simm( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), ], Opcode::Xor => vec![ @@ -3128,7 +3130,7 @@ impl Ins { } Opcode::Lbz => { let mut uses = vec![Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, ))]; if ((self.code >> 16u8) & 0x1f) != 0 { uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); @@ -3138,7 +3140,7 @@ impl Ins { Opcode::Lbzu => { let mut uses = vec![ Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ]; @@ -3160,7 +3162,7 @@ impl Ins { } Opcode::Lfd => { let mut uses = vec![Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, ))]; if ((self.code >> 16u8) & 0x1f) != 0 { uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); @@ -3170,7 +3172,7 @@ impl Ins { Opcode::Lfdu => { let mut uses = vec![ Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ]; @@ -3192,7 +3194,7 @@ impl Ins { } Opcode::Lfs => { let mut uses = vec![Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, ))]; if ((self.code >> 16u8) & 0x1f) != 0 { uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); @@ -3202,7 +3204,7 @@ impl Ins { Opcode::Lfsu => { let mut uses = vec![ Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ]; @@ -3224,7 +3226,7 @@ impl Ins { } Opcode::Lha => { let mut uses = vec![Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, ))]; if ((self.code >> 16u8) & 0x1f) != 0 { uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); @@ -3234,7 +3236,7 @@ impl Ins { Opcode::Lhau => { let mut uses = vec![ Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ]; @@ -3263,7 +3265,7 @@ impl Ins { } Opcode::Lhz => { let mut uses = vec![Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, ))]; if ((self.code >> 16u8) & 0x1f) != 0 { uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); @@ -3273,7 +3275,7 @@ impl Ins { Opcode::Lhzu => { let mut uses = vec![ Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ]; @@ -3295,7 +3297,7 @@ impl Ins { } Opcode::Lmw => { let mut uses = vec![Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, ))]; if ((self.code >> 16u8) & 0x1f) != 0 { uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); @@ -3332,7 +3334,7 @@ impl Ins { } Opcode::Lwz => { let mut uses = vec![Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, ))]; if ((self.code >> 16u8) & 0x1f) != 0 { uses.push(Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _))); @@ -3342,7 +3344,7 @@ impl Ins { Opcode::Lwzu => { let mut uses = vec![ Field::offset(Offset( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), ]; @@ -4963,7 +4965,8 @@ impl Ins { args: vec![ Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), Argument::Simm(Simm( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) + as _, )), ], ins: self, @@ -4997,8 +5000,9 @@ impl Ins { return SimplifiedIns { mnemonic: "blt", args: vec![Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) << 2u8) - as _, + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) + << 2u8) as _, ))], ins: self, }; @@ -5010,7 +5014,8 @@ impl Ins { args: vec![ Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) << 2u8) as _, )), ], @@ -5024,8 +5029,9 @@ impl Ins { return SimplifiedIns { mnemonic: "ble", args: vec![Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) << 2u8) - as _, + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) + << 2u8) as _, ))], ins: self, }; @@ -5037,7 +5043,8 @@ impl Ins { args: vec![ Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) << 2u8) as _, )), ], @@ -5051,8 +5058,9 @@ impl Ins { return SimplifiedIns { mnemonic: "beq", args: vec![Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) << 2u8) - as _, + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) + << 2u8) as _, ))], ins: self, }; @@ -5064,7 +5072,8 @@ impl Ins { args: vec![ Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) << 2u8) as _, )), ], @@ -5078,8 +5087,9 @@ impl Ins { return SimplifiedIns { mnemonic: "bge", args: vec![Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) << 2u8) - as _, + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) + << 2u8) as _, ))], ins: self, }; @@ -5091,7 +5101,8 @@ impl Ins { args: vec![ Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) << 2u8) as _, )), ], @@ -5105,8 +5116,9 @@ impl Ins { return SimplifiedIns { mnemonic: "bgt", args: vec![Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) << 2u8) - as _, + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) + << 2u8) as _, ))], ins: self, }; @@ -5118,7 +5130,8 @@ impl Ins { args: vec![ Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) << 2u8) as _, )), ], @@ -5132,8 +5145,9 @@ impl Ins { return SimplifiedIns { mnemonic: "bne", args: vec![Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) << 2u8) - as _, + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) + << 2u8) as _, ))], ins: self, }; @@ -5145,7 +5159,8 @@ impl Ins { args: vec![ Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) << 2u8) as _, )), ], @@ -5159,8 +5174,9 @@ impl Ins { return SimplifiedIns { mnemonic: "bso", args: vec![Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) << 2u8) - as _, + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) + << 2u8) as _, ))], ins: self, }; @@ -5172,7 +5188,8 @@ impl Ins { args: vec![ Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) << 2u8) as _, )), ], @@ -5186,8 +5203,9 @@ impl Ins { return SimplifiedIns { mnemonic: "bns", args: vec![Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) << 2u8) - as _, + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) + << 2u8) as _, ))], ins: self, }; @@ -5199,7 +5217,8 @@ impl Ins { args: vec![ Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) << 2u8) as _, )), ], @@ -5210,8 +5229,9 @@ impl Ins { return SimplifiedIns { mnemonic: "bdnz", args: vec![Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) << 2u8) - as _, + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) + << 2u8) as _, ))], ins: self, }; @@ -5220,8 +5240,9 @@ impl Ins { return SimplifiedIns { mnemonic: "bdz", args: vec![Argument::BranchDest(BranchDest( - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) << 2u8) - as _, + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) + << 2u8) as _, ))], ins: self, }; @@ -5552,7 +5573,8 @@ impl Ins { args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::Simm(Simm( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) + as _, )), ], ins: self, @@ -5565,7 +5587,8 @@ impl Ins { Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::Simm(Simm( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) + as _, )), ], ins: self, @@ -5872,7 +5895,8 @@ impl Ins { args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::Simm(Simm( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) + as _, )), ], ins: self, @@ -5884,7 +5908,8 @@ impl Ins { args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::Simm(Simm( - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _, + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) + as _, )), ], ins: self, @@ -5900,7 +5925,7 @@ impl Ins { impl Ins { #[inline(always)] pub fn field_simm(&self) -> isize { - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _ + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _ } #[inline(always)] pub fn field_uimm(&self) -> usize { @@ -5908,11 +5933,11 @@ impl Ins { } #[inline(always)] pub fn field_offset(&self) -> isize { - (((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as _ + ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _ } #[inline(always)] pub fn field_ps_offset(&self) -> isize { - (((self.code & 0xfff) ^ 0x800).wrapping_sub(0x800)) as _ + ((((self.code & 0xfff) ^ 0x800).wrapping_sub(0x800)) as i32) as _ } #[inline(always)] pub fn field_BO(&self) -> usize { @@ -5924,11 +5949,11 @@ impl Ins { } #[inline(always)] pub fn field_BD(&self) -> isize { - (((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) << 2u8) as _ + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) << 2u8) as _ } #[inline(always)] pub fn field_LI(&self) -> isize { - (((((self.code >> 2u8) & 0xffffff) ^ 0x800000).wrapping_sub(0x800000)) << 2u8) as _ + ((((((self.code >> 2u8) & 0xffffff) ^ 0x800000).wrapping_sub(0x800000)) as i32) << 2u8) as _ } #[inline(always)] pub fn field_SH(&self) -> usize { diff --git a/genisa/src/main.rs b/genisa/src/main.rs index aaf807f..c15abde 100644 --- a/genisa/src/main.rs +++ b/genisa/src/main.rs @@ -136,7 +136,7 @@ impl Field { 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))) + val = quote!((((#val ^ #mask2).wrapping_sub(#mask2)) as i32)) } let val_shift = self.shift_left; From b90b46ef8e0e45e30d11253db11fd723f3ef5cfd Mon Sep 17 00:00:00 2001 From: InusualZ Date: Tue, 31 May 2022 18:07:17 -0400 Subject: [PATCH 03/13] isa: Add missing argument to `bcctr` and `bclr` --- disasm/src/generated.rs | 9 +++++++++ isa.yaml | 7 +++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index 657cfc8..bedd15f 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -1133,6 +1133,7 @@ pub enum Field { ps_offset(Offset), BO(OpaqueU), BI(OpaqueU), + BH(OpaqueU), BD(BranchDest), LI(BranchDest), SH(OpaqueU), @@ -1176,6 +1177,7 @@ impl Field { Field::ps_offset(x) => Some(Argument::Offset(*x)), Field::BO(x) => Some(Argument::OpaqueU(*x)), Field::BI(x) => Some(Argument::OpaqueU(*x)), + Field::BH(x) => Some(Argument::OpaqueU(*x)), Field::BD(x) => Some(Argument::BranchDest(*x)), Field::LI(x) => Some(Argument::BranchDest(*x)), Field::SH(x) => Some(Argument::OpaqueU(*x)), @@ -1217,6 +1219,7 @@ impl Field { Field::ps_offset(_) => "ps_offset", Field::BO(_) => "BO", Field::BI(_) => "BI", + Field::BH(_) => "BH", Field::BD(_) => "BD", Field::LI(_) => "LI", Field::SH(_) => "SH", @@ -1342,10 +1345,12 @@ impl Ins { Opcode::Bcctr => vec![ Field::BO(OpaqueU(((self.code >> 21u8) & 0x1f) as _)), Field::BI(OpaqueU(((self.code >> 16u8) & 0x1f) as _)), + Field::BH(OpaqueU(((self.code >> 11u8) & 0x3) as _)), ], Opcode::Bclr => vec![ Field::BO(OpaqueU(((self.code >> 21u8) & 0x1f) as _)), Field::BI(OpaqueU(((self.code >> 16u8) & 0x1f) as _)), + Field::BH(OpaqueU(((self.code >> 11u8) & 0x3) as _)), ], Opcode::Cmp => vec![ Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), @@ -5948,6 +5953,10 @@ impl Ins { ((self.code >> 16u8) & 0x1f) as _ } #[inline(always)] + pub fn field_BH(&self) -> usize { + ((self.code >> 11u8) & 0x3) as _ + } + #[inline(always)] pub fn field_BD(&self) -> isize { ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) << 2u8) as _ } diff --git a/isa.yaml b/isa.yaml index b5680d5..83ae774 100644 --- a/isa.yaml +++ b/isa.yaml @@ -22,6 +22,9 @@ fields: - name: BI arg: OpaqueU bits: 11..16 + - name: BH + arg: OpaqueU + bits: 19..21 - name: BD arg: BranchDest bits: 16..30 @@ -289,7 +292,7 @@ opcodes: bitmask: 0xfc007ffe pattern: 0x4c000420 modifiers: [ LK ] - args: [ BO, BI ] + args: [ BO, BI, BH ] uses: [ ctr ] - name: bclr @@ -297,7 +300,7 @@ opcodes: bitmask: 0xfc007ffe pattern: 0x4c000020 modifiers: [ LK ] - args: [ BO, BI ] + args: [ BO, BI, BH ] uses: [ lr ] - name: cmp From ad1ec7aaa9ea27391677557edcd7f0fb43dd6b8b Mon Sep 17 00:00:00 2001 From: InusualZ Date: Tue, 31 May 2022 18:28:58 -0400 Subject: [PATCH 04/13] isa: fix paired single instruction arguments Argument specific to this instruction were re/named to a more dolphin aligned name --- disasm-py/src/lib.rs | 12 ++++++++-- disasm/src/generated.rs | 46 ++++++++++++++++++++++++------------- disasm/tests/test_disasm.rs | 4 ++-- isa.yaml | 24 +++++++++++-------- 4 files changed, 57 insertions(+), 29 deletions(-) diff --git a/disasm-py/src/lib.rs b/disasm-py/src/lib.rs index efcd9aa..a1ebb48 100644 --- a/disasm-py/src/lib.rs +++ b/disasm-py/src/lib.rs @@ -161,14 +161,22 @@ impl Ins { self.0.field_crm() as i64 } #[getter] - fn ps_l(&self) -> i64 { - self.0.field_ps_l() as i64 + fn ps_I(&self) -> i64 { + self.0.field_ps_I() as i64 + } + #[getter] + fn ps_IX(&self) -> i64 { + self.0.field_ps_IX() as i64 } #[getter] fn ps_W(&self) -> i64 { self.0.field_ps_W() as i64 } #[getter] + fn ps_WX(&self) -> i64 { + self.0.field_ps_WX() as i64 + } + #[getter] fn ps_NB(&self) -> i64 { self.0.field_NB() as i64 } diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index bedd15f..884ee38 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -1157,8 +1157,10 @@ pub enum Field { crfD(CRField), crfS(CRField), crm(OpaqueU), - ps_l(GQR), + ps_I(GQR), + ps_IX(GQR), ps_W(OpaqueU), + ps_WX(OpaqueU), NB(OpaqueU), tbr(OpaqueU), mtfsf_FM(OpaqueU), @@ -1201,8 +1203,10 @@ impl Field { Field::crfD(x) => Some(Argument::CRField(*x)), Field::crfS(x) => Some(Argument::CRField(*x)), Field::crm(x) => Some(Argument::OpaqueU(*x)), - Field::ps_l(x) => Some(Argument::GQR(*x)), + Field::ps_I(x) => Some(Argument::GQR(*x)), + Field::ps_IX(x) => Some(Argument::GQR(*x)), Field::ps_W(x) => Some(Argument::OpaqueU(*x)), + Field::ps_WX(x) => Some(Argument::OpaqueU(*x)), Field::NB(x) => Some(Argument::OpaqueU(*x)), Field::tbr(x) => Some(Argument::OpaqueU(*x)), Field::mtfsf_FM(x) => Some(Argument::OpaqueU(*x)), @@ -1243,8 +1247,10 @@ impl Field { Field::crfD(_) => "crfD", Field::crfS(_) => "crfS", Field::crm(_) => "crm", - Field::ps_l(_) => "ps_l", + Field::ps_I(_) => "ps_I", + Field::ps_IX(_) => "ps_IX", Field::ps_W(_) => "ps_W", + Field::ps_WX(_) => "ps_WX", Field::NB(_) => "NB", Field::tbr(_) => "tbr", Field::mtfsf_FM(_) => "mtfsf_FM", @@ -1931,7 +1937,7 @@ impl Ins { )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::ps_W(OpaqueU(((self.code >> 15u8) & 0x1) as _)), - Field::ps_l(GQR(((self.code >> 12u8) & 0x7) as _)), + Field::ps_I(GQR(((self.code >> 12u8) & 0x7) as _)), ], Opcode::PsqLu => vec![ Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), @@ -1940,21 +1946,21 @@ impl Ins { )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::ps_W(OpaqueU(((self.code >> 15u8) & 0x1) as _)), - Field::ps_l(GQR(((self.code >> 12u8) & 0x7) as _)), + Field::ps_I(GQR(((self.code >> 12u8) & 0x7) as _)), ], Opcode::PsqLux => vec![ Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - Field::ps_W(OpaqueU(((self.code >> 15u8) & 0x1) as _)), - Field::ps_l(GQR(((self.code >> 12u8) & 0x7) as _)), + Field::ps_WX(OpaqueU(((self.code >> 10u8) & 0x1) as _)), + Field::ps_IX(GQR(((self.code >> 7u8) & 0x7) as _)), ], Opcode::PsqLx => vec![ Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - Field::ps_W(OpaqueU(((self.code >> 15u8) & 0x1) as _)), - Field::ps_l(GQR(((self.code >> 12u8) & 0x7) as _)), + Field::ps_WX(OpaqueU(((self.code >> 10u8) & 0x1) as _)), + Field::ps_IX(GQR(((self.code >> 7u8) & 0x7) as _)), ], Opcode::PsqSt => vec![ Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), @@ -1963,7 +1969,7 @@ impl Ins { )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::ps_W(OpaqueU(((self.code >> 15u8) & 0x1) as _)), - Field::ps_l(GQR(((self.code >> 12u8) & 0x7) as _)), + Field::ps_I(GQR(((self.code >> 12u8) & 0x7) as _)), ], Opcode::PsqStu => vec![ Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), @@ -1972,21 +1978,21 @@ impl Ins { )), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::ps_W(OpaqueU(((self.code >> 15u8) & 0x1) as _)), - Field::ps_l(GQR(((self.code >> 12u8) & 0x7) as _)), + Field::ps_I(GQR(((self.code >> 12u8) & 0x7) as _)), ], Opcode::PsqStux => vec![ Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - Field::ps_W(OpaqueU(((self.code >> 15u8) & 0x1) as _)), - Field::ps_l(GQR(((self.code >> 12u8) & 0x7) as _)), + Field::ps_WX(OpaqueU(((self.code >> 10u8) & 0x1) as _)), + Field::ps_IX(GQR(((self.code >> 7u8) & 0x7) as _)), ], Opcode::PsqStx => vec![ Field::frS(FPR(((self.code >> 21u8) & 0x1f) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), - Field::ps_W(OpaqueU(((self.code >> 15u8) & 0x1) as _)), - Field::ps_l(GQR(((self.code >> 12u8) & 0x7) as _)), + Field::ps_WX(OpaqueU(((self.code >> 10u8) & 0x1) as _)), + Field::ps_IX(GQR(((self.code >> 7u8) & 0x7) as _)), ], Opcode::PsAbs => vec![ Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), @@ -6050,14 +6056,22 @@ impl Ins { ((self.code >> 12u8) & 0xff) as _ } #[inline(always)] - pub fn field_ps_l(&self) -> usize { + pub fn field_ps_I(&self) -> usize { ((self.code >> 12u8) & 0x7) as _ } #[inline(always)] + pub fn field_ps_IX(&self) -> usize { + ((self.code >> 7u8) & 0x7) as _ + } + #[inline(always)] pub fn field_ps_W(&self) -> usize { ((self.code >> 15u8) & 0x1) as _ } #[inline(always)] + pub fn field_ps_WX(&self) -> usize { + ((self.code >> 10u8) & 0x1) as _ + } + #[inline(always)] pub fn field_NB(&self) -> usize { ((self.code >> 11u8) & 0x1f) as _ } diff --git a/disasm/tests/test_disasm.rs b/disasm/tests/test_disasm.rs index 31291ea..b96545b 100644 --- a/disasm/tests/test_disasm.rs +++ b/disasm/tests/test_disasm.rs @@ -622,8 +622,8 @@ fn test_ins_psq_lx() { frD(FPR(0)), rA(GPR(0)), rB(GPR(0)), - ps_W(OpaqueU(0)), - ps_l(GQR(0)) + ps_WX(OpaqueU(0)), + ps_IX(GQR(0)) ] ); assert_eq!(ins.defs(), vec![frD(FPR(0))]); diff --git a/isa.yaml b/isa.yaml index 83ae774..c75accd 100644 --- a/isa.yaml +++ b/isa.yaml @@ -112,12 +112,18 @@ fields: arg: OpaqueU bits: 12..20 # Paired single fields - - name: ps_l + - name: ps_I arg: GQR bits: 17..20 + - name: ps_IX + arg: GQR + bits: 22..25 - name: ps_W arg: OpaqueU bits: 16..17 + - name: ps_WX + arg: OpaqueU + bits: 21..22 # Misc - name: NB arg: OpaqueU @@ -1268,7 +1274,7 @@ opcodes: desc: Paired Single Quantized Load bitmask: 0xfc000000 pattern: 0xe0000000 - args: [ frD, ps_offset, rA, ps_W, ps_l ] + args: [ frD, ps_offset, rA, ps_W, ps_I ] defs: [ frD ] uses: [ rA.nz ] @@ -1276,7 +1282,7 @@ opcodes: desc: Paired Single Quantized Load with Update bitmask: 0xfc000000 pattern: 0xe4000000 - args: [ frD, ps_offset, rA, ps_W, ps_l ] + args: [ frD, ps_offset, rA, ps_W, ps_I ] defs: [ frD, rA ] uses: [ rA ] @@ -1284,7 +1290,7 @@ opcodes: desc: Paired Single Quantized Load with Update Indexed bitmask: 0xfc00007f pattern: 0x1000004c - args: [ frD, rA, rB, ps_W, ps_l ] + args: [ frD, rA, rB, ps_WX, ps_IX ] defs: [ frD, rA ] uses: [ rA, rB ] @@ -1292,7 +1298,7 @@ opcodes: desc: Paired Single Quantized Load Indexed bitmask: 0xfc00007f pattern: 0x1000000c - args: [ frD, rA, rB, ps_W, ps_l ] + args: [ frD, rA, rB, ps_WX, ps_IX ] defs: [ frD ] uses: [ rA.nz, rB ] @@ -1300,14 +1306,14 @@ opcodes: desc: Paired Single Quantized Store bitmask: 0xfc000000 pattern: 0xf0000000 - args: [ frS, ps_offset, rA, ps_W, ps_l ] + args: [ frS, ps_offset, rA, ps_W, ps_I ] uses: [ frS, rA.nz ] - name: psq_stu desc: Paired Single Quantized Store with Update bitmask: 0xfc000000 pattern: 0xf4000000 - args: [ frS, ps_offset, rA, ps_W, ps_l ] + args: [ frS, ps_offset, rA, ps_W, ps_I ] defs: [ rA ] uses: [ frS, rA ] @@ -1315,7 +1321,7 @@ opcodes: desc: Paired Single Quantized Store with Update Indexed bitmask: 0xfc00007f pattern: 0x1000004e - args: [ frS, rA, rB, ps_W, ps_l ] + args: [ frS, rA, rB, ps_WX, ps_IX ] defs: [ rA ] uses: [ frS, rA, rB ] @@ -1323,7 +1329,7 @@ opcodes: desc: Paired Single Quantized Store Indexed bitmask: 0xfc00007f pattern: 0x1000000e - args: [ frS, rA, rB, ps_W, ps_l ] + args: [ frS, rA, rB, ps_WX, ps_IX ] uses: [ frS, rA.nz, rB ] - name: ps_abs From f4389e5edd17855eb730822fb16e9eaf86eaafcb Mon Sep 17 00:00:00 2001 From: InusualZ Date: Tue, 31 May 2022 18:51:54 -0400 Subject: [PATCH 05/13] isa: add missing `L` arg to the `cmp` instruction family Also fix the mnemonics for said instruction family --- disasm/src/generated.rs | 135 ++++++++++++++++++++++++++++++++++++++-- isa.yaml | 86 ++++++++++++++++++------- 2 files changed, 192 insertions(+), 29 deletions(-) diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index 884ee38..71489e5 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -1166,6 +1166,7 @@ pub enum Field { mtfsf_FM(OpaqueU), mtfsf_IMM(OpaqueU), TO(OpaqueU), + L(OpaqueU), xer, ctr, lr, @@ -1212,6 +1213,7 @@ impl Field { Field::mtfsf_FM(x) => Some(Argument::OpaqueU(*x)), Field::mtfsf_IMM(x) => Some(Argument::OpaqueU(*x)), Field::TO(x) => Some(Argument::OpaqueU(*x)), + Field::L(x) => Some(Argument::OpaqueU(*x)), _ => None, } } @@ -1256,6 +1258,7 @@ impl Field { Field::mtfsf_FM(_) => "mtfsf_FM", Field::mtfsf_IMM(_) => "mtfsf_IMM", Field::TO(_) => "TO", + Field::L(_) => "L", Field::xer => "xer", Field::ctr => "ctr", Field::lr => "lr", @@ -1360,11 +1363,13 @@ impl Ins { ], Opcode::Cmp => vec![ Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), + Field::L(OpaqueU(((self.code >> 21u8) & 0x1) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), ], Opcode::Cmpi => vec![ Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), + Field::L(OpaqueU(((self.code >> 21u8) & 0x1) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::simm(Simm( ((((self.code & 0xffff) ^ 0x8000).wrapping_sub(0x8000)) as i32) as _, @@ -1372,11 +1377,13 @@ impl Ins { ], Opcode::Cmpl => vec![ Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), + Field::L(OpaqueU(((self.code >> 21u8) & 0x1) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), ], Opcode::Cmpli => vec![ Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), + Field::L(OpaqueU(((self.code >> 21u8) & 0x1) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), Field::uimm(Uimm((self.code & 0xffff) as _)), ], @@ -5566,7 +5573,7 @@ impl Ins { } } Opcode::Cmp => { - if ((self.code >> 23u8) & 0x7) == 0 { + if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 0 { return SimplifiedIns { mnemonic: "cmpw", args: vec![ @@ -5576,9 +5583,41 @@ impl Ins { ins: self, }; } + if ((self.code >> 21u8) & 0x1) == 0 { + return SimplifiedIns { + mnemonic: "cmpw", + args: vec![ + Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), + ], + ins: self, + }; + } + if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 1 { + return SimplifiedIns { + mnemonic: "cmpd", + args: vec![ + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), + ], + ins: self, + }; + } + if ((self.code >> 21u8) & 0x1) == 1 { + return SimplifiedIns { + mnemonic: "cmpd", + args: vec![ + Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), + ], + ins: self, + }; + } } Opcode::Cmpi => { - if ((self.code >> 23u8) & 0x7) == 0 { + if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 0 { return SimplifiedIns { mnemonic: "cmpwi", args: vec![ @@ -5591,7 +5630,7 @@ impl Ins { ins: self, }; } - if ((self.code >> 23u8) & 0x7) == 0 { + if ((self.code >> 21u8) & 0x1) == 0 { return SimplifiedIns { mnemonic: "cmpwi", args: vec![ @@ -5605,9 +5644,36 @@ impl Ins { ins: self, }; } + if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 1 { + return SimplifiedIns { + mnemonic: "cmpdi", + 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, + }; + } + if ((self.code >> 21u8) & 0x1) == 1 { + return SimplifiedIns { + mnemonic: "cmpdi", + args: vec![ + Argument::CRField(CRField(((self.code >> 23u8) & 0x7) 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::Cmpl => { - if ((self.code >> 23u8) & 0x7) == 0 { + if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 0 { return SimplifiedIns { mnemonic: "cmplw", args: vec![ @@ -5617,9 +5683,41 @@ impl Ins { ins: self, }; } + if ((self.code >> 21u8) & 0x1) == 0 { + return SimplifiedIns { + mnemonic: "cmplw", + args: vec![ + Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), + ], + ins: self, + }; + } + if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 1 { + return SimplifiedIns { + mnemonic: "cmpld", + args: vec![ + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), + ], + ins: self, + }; + } + if ((self.code >> 21u8) & 0x1) == 1 { + return SimplifiedIns { + mnemonic: "cmpld", + args: vec![ + Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), + ], + ins: self, + }; + } } Opcode::Cmpli => { - if ((self.code >> 23u8) & 0x7) == 0 { + if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 0 { return SimplifiedIns { mnemonic: "cmplwi", args: vec![ @@ -5629,7 +5727,7 @@ impl Ins { ins: self, }; } - if ((self.code >> 23u8) & 0x7) == 0 { + if ((self.code >> 21u8) & 0x1) == 0 { return SimplifiedIns { mnemonic: "cmplwi", args: vec![ @@ -5640,6 +5738,27 @@ impl Ins { ins: self, }; } + if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 1 { + return SimplifiedIns { + mnemonic: "cmpldi", + args: vec![ + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::Uimm(Uimm((self.code & 0xffff) as _)), + ], + ins: self, + }; + } + if ((self.code >> 21u8) & 0x1) == 1 { + return SimplifiedIns { + mnemonic: "cmpldi", + args: vec![ + Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::Uimm(Uimm((self.code & 0xffff) as _)), + ], + ins: self, + }; + } } Opcode::Creqv => { if ((self.code >> 21u8) & 0x1f) == ((self.code >> 16u8) & 0x1f) @@ -6093,6 +6212,10 @@ impl Ins { ((self.code >> 21u8) & 0x1f) as _ } #[inline(always)] + pub fn field_L(&self) -> usize { + ((self.code >> 21u8) & 0x1) as _ + } + #[inline(always)] pub fn field_OE(&self) -> bool { self.bit(21usize) } diff --git a/isa.yaml b/isa.yaml index c75accd..cb6f708 100644 --- a/isa.yaml +++ b/isa.yaml @@ -145,6 +145,10 @@ fields: arg: OpaqueU desc: Bitset for tw and twi bits: 6..11 + - name: L + arg: OpaqueU + desc: Bitset for cmp, cmpi, cmpl, cmpli + bits: 10..11 - name: xer - name: ctr - name: lr @@ -313,7 +317,7 @@ opcodes: desc: Compare bitmask: 0xfc4007ff pattern: 0x7c000000 - args: [ crfD, rA, rB ] + args: [ crfD, L, rA, rB ] defs: [ crfD ] uses: [ rA, rB ] @@ -321,7 +325,7 @@ opcodes: desc: Compare Immediate bitmask: 0xfc400000 pattern: 0x2c000000 - args: [ crfD, rA, simm ] + args: [ crfD, L, rA, simm ] defs: [ crfD ] uses: [ rA ] @@ -329,7 +333,7 @@ opcodes: desc: Compare Logical bitmask: 0xfc4007ff pattern: 0x7c000040 - args: [ crfD, rA, rB ] + args: [ crfD, L, rA, rB ] defs: [ crfD ] uses: [ rA, rB ] @@ -337,7 +341,7 @@ opcodes: desc: Compare Logical Immediate bitmask: 0xfc400000 pattern: 0x28000000 - args: [ crfD, rA, uimm ] + args: [ crfD, L, rA, uimm ] defs: [ crfD ] uses: [ rA ] @@ -2005,37 +2009,73 @@ mnemonics: args: [ rA, rS, MB ] condition: ME == 31 && 32 - MB == SH - # Compares - - name: cmpw - opcode: cmp - args: [ rA, rB ] - condition: crfD == 0 - - name: cmpw - opcode: cmp - args: [ crfD, rA, rB ] - - name: cmplw - opcode: cmpl - args: [ rA, rB ] - condition: crfD == 0 - - name: cmplw - opcode: cmpl - args: [ crfD, rA, rB ] + # Compares Word - name: cmpwi opcode: cmpi args: [ rA, simm ] - condition: crfD == 0 + condition: crfD == 0 && L == 0 - name: cmpwi opcode: cmpi args: [ crfD, rA, simm ] - condition: crfD == 0 + condition: L == 0 + - name: cmpw + opcode: cmp + args: [ rA, rB ] + condition: crfD == 0 && L == 0 + - name: cmpw + opcode: cmp + args: [ crfD, rA, rB ] + condition: L == 0 - name: cmplwi opcode: cmpli args: [ rA, uimm ] - condition: crfD == 0 + condition: crfD == 0 && L == 0 - name: cmplwi opcode: cmpli args: [ crfD, rA, uimm ] - condition: crfD == 0 + condition: L == 0 + - name: cmplw + opcode: cmpl + args: [ rA, rB ] + condition: crfD == 0 && L == 0 + - name: cmplw + opcode: cmpl + args: [ crfD, rA, rB ] + condition: L == 0 + + # Compares Doubleword + - name: cmpdi + opcode: cmpi + args: [ rA, simm ] + condition: crfD == 0 && L == 1 + - name: cmpdi + opcode: cmpi + args: [ crfD, rA, simm ] + condition: L == 1 + - name: cmpd + opcode: cmp + args: [ rA, rB ] + condition: crfD == 0 && L == 1 + - name: cmpd + opcode: cmp + args: [ crfD, rA, rB ] + condition: L == 1 + - name: cmpldi + opcode: cmpli + args: [ rA, uimm ] + condition: crfD == 0 && L == 1 + - name: cmpldi + opcode: cmpli + args: [ crfD, rA, uimm ] + condition: L == 1 + - name: cmpld + opcode: cmpl + args: [ rA, rB ] + condition: crfD == 0 && L == 1 + - name: cmpld + opcode: cmpl + args: [ crfD, rA, rB ] + condition: L == 1 # Condition Register Logical - name: crset From 65b0966a97ec150bf1af695d0492c9d2021a48d0 Mon Sep 17 00:00:00 2001 From: InusualZ Date: Tue, 31 May 2022 19:05:40 -0400 Subject: [PATCH 06/13] isa: `b` and `bc` change modifiers order Previously they were `modifiers: [ AA, LK ]` and this caused problems, because the modifiers add a char to the instruction mnemonics, but this char is position dependant. --- disasm/src/generated.rs | 12 +++++------ disasm/tests/test_disasm.rs | 1 + isa.yaml | 42 ++++++++++++++++++------------------- 3 files changed, 28 insertions(+), 27 deletions(-) diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index 71489e5..828a060 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -4204,22 +4204,22 @@ impl Ins { Opcode::Andis_ => String::new(), Opcode::B => { let mut s = String::with_capacity(4); - if self.bit(30usize) { - s.push('a'); - } if self.bit(31usize) { s.push('l'); } + if self.bit(30usize) { + s.push('a'); + } s } Opcode::Bc => { let mut s = String::with_capacity(4); - if self.bit(30usize) { - s.push('a'); - } if self.bit(31usize) { s.push('l'); } + if self.bit(30usize) { + s.push('a'); + } s } Opcode::Bcctr => { diff --git a/disasm/tests/test_disasm.rs b/disasm/tests/test_disasm.rs index b96545b..96bb7cc 100644 --- a/disasm/tests/test_disasm.rs +++ b/disasm/tests/test_disasm.rs @@ -94,6 +94,7 @@ fn test_ins_b() { assert_asm!(0x4823B4D9, "bl 0x23b4d8"); assert_asm!(0x4BE03C99, "bl -0x1fc368"); assert_asm!(0x4BDC1A59, "bl -0x23e5a8"); + assert_asm!(0x48000063, "bla 0x60"); } #[test] diff --git a/isa.yaml b/isa.yaml index cb6f708..f2cac8b 100644 --- a/isa.yaml +++ b/isa.yaml @@ -287,14 +287,14 @@ opcodes: desc: Branch bitmask: 0xfc000000 pattern: 0x48000000 - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ LI ] - name: bc desc: Branch Conditional bitmask: 0xfc000000 pattern: 0x40000000 - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ BO, BI, BD ] - name: bcctr @@ -2164,105 +2164,105 @@ mnemonics: # bc branch always - name: b opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] condition: BO == 20 && BI == 0 # bc branch if negative - name: blt opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ BD ] condition: BO == 12 && BI & 0b11 == 0b00 && crfS == 0 - name: blt opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ crfS, BD ] condition: BO == 12 && BI & 0b11 == 0b00 # bc branch if not positive - name: ble opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ BD ] condition: BO == 4 && BI & 0b11 == 0b01 && crfS == 0 - name: ble opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ crfS, BD ] condition: BO == 4 && BI & 0b11 == 0b01 # bc branch if zero - name: beq opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ BD ] condition: BO == 12 && BI & 0b11 == 0b10 && crfS == 0 - name: beq opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ crfS, BD ] condition: BO == 12 && BI & 0b11 == 0b10 # bc branch if not negative - name: bge opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ BD ] condition: BO == 4 && BI & 0b11 == 0b00 && crfS == 0 - name: bge opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ crfS, BD ] condition: BO == 4 && BI & 0b11 == 0b00 # bc branch if positive - name: bgt opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ BD ] condition: BO == 12 && BI & 0b11 == 0b01 && crfS == 0 - name: bgt opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ crfS, BD ] condition: BO == 12 && BI & 0b11 == 0b01 # bc branch if not zero - name: bne opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ BD ] condition: BO == 4 && BI & 0b11 == 0b10 && crfS == 0 - name: bne opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ crfS, BD ] condition: BO == 4 && BI & 0b11 == 0b10 # bc branch if summary overflow - name: bso opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ BD ] condition: BO == 12 && BI & 0b11 == 0b11 && crfS == 0 - name: bso opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ crfS, BD ] condition: BO == 12 && BI & 0b11 == 0b11 # bc branch if not summary overflow - name: bns opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ BD ] condition: BO == 4 && BI & 0b11 == 0b11 && crfS == 0 - name: bns opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ crfS, BD ] condition: BO == 4 && BI & 0b11 == 0b11 - name: bdnz opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ BD ] condition: BO == 16 && BI == 0 - name: bdz opcode: bc - modifiers: [ AA, LK ] + modifiers: [ LK, AA ] args: [ BD ] condition: BO == 18 && BI == 0 # TODO support conditional bd... From 7167807402a703ed9b7568acef4d7c249da57f87 Mon Sep 17 00:00:00 2001 From: InusualZ Date: Tue, 31 May 2022 19:17:42 -0400 Subject: [PATCH 07/13] isa: fix `mfcr` argument --- disasm/src/generated.rs | 4 ++-- disasm/tests/test_disasm.rs | 2 +- isa.yaml | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index 828a060..24b5064 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -1823,7 +1823,7 @@ impl Ins { Field::crfS(CRField(((self.code >> 18u8) & 0x7) as _)), ], Opcode::Mcrxr => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], - Opcode::Mfcr => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], + Opcode::Mfcr => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], Opcode::Mffs => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], Opcode::Mfmsr => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], Opcode::Mfspr => vec![ @@ -2562,7 +2562,7 @@ impl Ins { Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _)), Field::xer, ], - Opcode::Mfcr => vec![Field::crfD(CRField(((self.code >> 23u8) & 0x7) as _))], + Opcode::Mfcr => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], Opcode::Mffs => vec![Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _))], Opcode::Mfmsr => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], Opcode::Mfspr => vec![Field::rD(GPR(((self.code >> 21u8) & 0x1f) as _))], diff --git a/disasm/tests/test_disasm.rs b/disasm/tests/test_disasm.rs index 96bb7cc..95b5e92 100644 --- a/disasm/tests/test_disasm.rs +++ b/disasm/tests/test_disasm.rs @@ -483,7 +483,7 @@ fn test_ins_lwzx() { #[test] fn test_ins_mfcr() { - assert_asm!(0x7C000026, "mfcr cr0"); + assert_asm!(0x7C000026, "mfcr r0"); } #[test] diff --git a/isa.yaml b/isa.yaml index f2cac8b..37b067f 100644 --- a/isa.yaml +++ b/isa.yaml @@ -1063,8 +1063,8 @@ opcodes: desc: Move from Condition Register bitmask: 0xfc1fffff pattern: 0x7c000026 - args: [ crfD ] - defs: [ crfD ] + args: [ rD ] + defs: [ rD ] - name: mffs desc: Move from FPSCR From 2364d17751c9e21044df435a450ad653c6f2a293 Mon Sep 17 00:00:00 2001 From: InusualZ Date: Tue, 31 May 2022 19:26:13 -0400 Subject: [PATCH 08/13] isa: remove `RC` modifier from a bunch of instruction This modifier is not part of those instruction --- disasm/src/generated.rs | 216 +++++----------------------------------- isa.yaml | 27 ----- 2 files changed, 27 insertions(+), 216 deletions(-) diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index 24b5064..cd0b10e 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -4532,13 +4532,7 @@ impl Ins { Opcode::Mcrfs => String::new(), Opcode::Mcrxr => String::new(), Opcode::Mfcr => String::new(), - Opcode::Mffs => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } + Opcode::Mffs => String::new(), Opcode::Mfmsr => String::new(), Opcode::Mfspr => String::new(), Opcode::Mfsr => String::new(), @@ -4591,13 +4585,7 @@ impl Ins { } s } - Opcode::Mulli => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } + Opcode::Mulli => String::new(), Opcode::Mullw => { let mut s = String::with_capacity(4); if self.bit(21usize) { @@ -4656,185 +4644,35 @@ impl Ins { Opcode::PsqStu => String::new(), Opcode::PsqStux => String::new(), Opcode::PsqStx => String::new(), - Opcode::PsAbs => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsAdd => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } + Opcode::PsAbs => String::new(), + Opcode::PsAdd => String::new(), Opcode::PsCmpo0 => String::new(), Opcode::PsCmpo1 => String::new(), Opcode::PsCmpu0 => String::new(), Opcode::PsCmpu1 => String::new(), - Opcode::PsDiv => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMadd => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMadds0 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMadds1 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMerge00 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMerge01 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMerge10 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMerge11 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMr => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMsub => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMul => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMuls0 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsMuls1 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsNabs => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsNeg => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsNmadd => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsNmsub => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsRes => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsRsqrte => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsSel => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsSub => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsSum0 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } - Opcode::PsSum1 => { - let mut s = String::with_capacity(4); - if self.bit(31usize) { - s.push('.'); - } - s - } + Opcode::PsDiv => String::new(), + Opcode::PsMadd => String::new(), + Opcode::PsMadds0 => String::new(), + Opcode::PsMadds1 => String::new(), + Opcode::PsMerge00 => String::new(), + Opcode::PsMerge01 => String::new(), + Opcode::PsMerge10 => String::new(), + Opcode::PsMerge11 => String::new(), + Opcode::PsMr => String::new(), + Opcode::PsMsub => String::new(), + Opcode::PsMul => String::new(), + Opcode::PsMuls0 => String::new(), + Opcode::PsMuls1 => String::new(), + Opcode::PsNabs => String::new(), + Opcode::PsNeg => String::new(), + Opcode::PsNmadd => String::new(), + Opcode::PsNmsub => String::new(), + Opcode::PsRes => String::new(), + Opcode::PsRsqrte => String::new(), + Opcode::PsSel => String::new(), + Opcode::PsSub => String::new(), + Opcode::PsSum0 => String::new(), + Opcode::PsSum1 => String::new(), Opcode::Rfi => String::new(), Opcode::Rlwimi => { let mut s = String::with_capacity(4); diff --git a/isa.yaml b/isa.yaml index 37b067f..9247f09 100644 --- a/isa.yaml +++ b/isa.yaml @@ -1070,7 +1070,6 @@ opcodes: desc: Move from FPSCR bitmask: 0xfc1ffffe pattern: 0xfc00048e - modifiers: [ Rc ] args: [ frD ] defs: [ frD ] @@ -1199,7 +1198,6 @@ opcodes: desc: Multiply Low Immediate bitmask: 0xfc000000 pattern: 0x1c000000 - modifiers: [ Rc ] args: [ rD, rA, simm ] defs: [ rD ] uses: [ rA ] @@ -1340,7 +1338,6 @@ opcodes: desc: Paired Single Absolute Value bitmask: 0xfc1f07fe pattern: 0x10000210 - modifiers: [ Rc ] args: [ frD, frB ] defs: [ frD ] uses: [ frB ] @@ -1349,7 +1346,6 @@ opcodes: desc: Paired Single Add bitmask: 0xfc0007fe pattern: 0x1000002a - modifiers: [ Rc ] args: [ frD, frA, frB ] defs: [ frD ] uses: [ frA, frB ] @@ -1390,7 +1386,6 @@ opcodes: desc: Paired Single Divide bitmask: 0xfc0007fe pattern: 0x10000024 - modifiers: [ Rc ] args: [ frD, frA, frB ] defs: [ frD ] uses: [ frA, frB ] @@ -1399,7 +1394,6 @@ opcodes: desc: Paired Single Multiply-Add bitmask: 0xfc00003e pattern: 0x1000003a - modifiers: [ Rc ] args: [ frD, frA, frC, frB ] defs: [ frD ] uses: [ frA, frC, frB ] @@ -1408,7 +1402,6 @@ opcodes: desc: Paired Single Multiply-Add Scalar high bitmask: 0xfc00003e pattern: 0x1000001c - modifiers: [ Rc ] args: [ frD, frA, frC, frB ] defs: [ frD ] uses: [ frA, frC, frB ] @@ -1417,7 +1410,6 @@ opcodes: desc: Paired Single Multiply-Add Scalar low bitmask: 0xfc00003e pattern: 0x1000001e - modifiers: [ Rc ] args: [ frD, frA, frC, frB ] defs: [ frD ] uses: [ frA, frC, frB ] @@ -1426,7 +1418,6 @@ opcodes: desc: Paired Single MERGE high bitmask: 0xfc0007fe pattern: 0x10000420 - modifiers: [ Rc ] args: [ frD, frA, frB ] defs: [ frD ] uses: [ frA, frB ] @@ -1435,7 +1426,6 @@ opcodes: desc: Paired Single MERGE direct bitmask: 0xfc0007fe pattern: 0x10000460 - modifiers: [ Rc ] args: [ frD, frA, frB ] defs: [ frD ] uses: [ frA, frB ] @@ -1444,7 +1434,6 @@ opcodes: desc: Paired Single MERGE swapped bitmask: 0xfc0007fe pattern: 0x100004a0 - modifiers: [ Rc ] args: [ frD, frA, frB ] defs: [ frD ] uses: [ frA, frB ] @@ -1453,7 +1442,6 @@ opcodes: desc: Paired Single MERGE low bitmask: 0xfc0007fe pattern: 0x100004e0 - modifiers: [ Rc ] args: [ frD, frA, frB ] defs: [ frD ] uses: [ frA, frB ] @@ -1462,7 +1450,6 @@ opcodes: desc: Paired Single Move Register bitmask: 0xfc1f07fe pattern: 0x10000090 - modifiers: [ Rc ] args: [ frD, frA, frB ] defs: [ frD ] uses: [ frB ] @@ -1471,7 +1458,6 @@ opcodes: desc: Paired Single Multiply-Subtract bitmask: 0xfc00003e pattern: 0x10000038 - modifiers: [ Rc ] args: [ frD, frA, frC, frB ] defs: [ frD ] uses: [ frA, frC, frB ] @@ -1480,7 +1466,6 @@ opcodes: desc: Paired Single Multiply bitmask: 0xfc00f83e pattern: 0x10000032 - modifiers: [ Rc ] args: [ frD, frA, frC ] defs: [ frD ] uses: [ frA, frC ] @@ -1489,7 +1474,6 @@ opcodes: desc: Paired Single Multiply Scalar high bitmask: 0xfc00f83e pattern: 0x10000018 - modifiers: [ Rc ] args: [ frD, frA, frC ] defs: [ frD ] uses: [ frA, frC ] @@ -1498,7 +1482,6 @@ opcodes: desc: Paired Single Multiply Scalar low bitmask: 0xfc00f83e pattern: 0x1000001a - modifiers: [ Rc ] args: [ frD, frA, frC ] defs: [ frD ] uses: [ frA, frC ] @@ -1507,7 +1490,6 @@ opcodes: desc: Paired Single Negative Absolute Value bitmask: 0xfc1f07fe pattern: 0x10000110 - modifiers: [ Rc ] args: [ frD, frB ] defs: [ frD ] uses: [ frB ] @@ -1516,7 +1498,6 @@ opcodes: desc: Paired Single Negate bitmask: 0xfc1f07fe pattern: 0x10000050 - modifiers: [ Rc ] args: [ frD, frB ] defs: [ frD ] uses: [ frB ] @@ -1525,7 +1506,6 @@ opcodes: desc: Paired Single Negative Multiply-Add bitmask: 0xfc00003e pattern: 0x1000003e - modifiers: [ Rc ] args: [ frD, frA, frC, frB ] defs: [ frD ] uses: [ frA, frC, frB ] @@ -1534,7 +1514,6 @@ opcodes: desc: Paired Single Negative Multiply-Subtract bitmask: 0xfc00003e pattern: 0x1000003c - modifiers: [ Rc ] args: [ frD, frA, frC, frB ] defs: [ frD ] uses: [ frA, frC, frB ] @@ -1543,7 +1522,6 @@ opcodes: desc: Paired Single Reciprocal Estimate bitmask: 0xfc1f07fe pattern: 0x10000030 - modifiers: [ Rc ] args: [ frD, frB ] defs: [ frD ] uses: [ frB ] @@ -1552,7 +1530,6 @@ opcodes: desc: Paired Single Reciprocal Square Root Estimate bitmask: 0xfc1f07fe pattern: 0x10000034 - modifiers: [ Rc ] args: [ frD, frB ] defs: [ frD ] uses: [ frB ] @@ -1561,7 +1538,6 @@ opcodes: desc: Paired Single Select bitmask: 0xfc00003e pattern: 0x1000002e - modifiers: [ Rc ] args: [ frD, frA, frC, frB ] defs: [ frD ] uses: [ frA, frC, frB ] @@ -1570,7 +1546,6 @@ opcodes: desc: Paired Single Subtract bitmask: 0xfc0007fe pattern: 0x10000028 - modifiers: [ Rc ] args: [ frD, frA, frB ] defs: [ frD ] uses: [ frA, frB ] @@ -1579,7 +1554,6 @@ opcodes: desc: Paired Single vector SUM high bitmask: 0xfc00003e pattern: 0x10000014 - modifiers: [ Rc ] args: [ frD, frA, frC, frB ] defs: [ frD ] uses: [ frA, frC, frB ] @@ -1588,7 +1562,6 @@ opcodes: desc: Paired Single vector SUM low bitmask: 0xfc00003e pattern: 0x10000016 - modifiers: [ Rc ] args: [ frD, frA, frC, frB ] defs: [ frD ] uses: [ frA, frC, frB ] From 49673468fc2b1d3cff9ccd7fac85818e00200c84 Mon Sep 17 00:00:00 2001 From: InusualZ Date: Tue, 31 May 2022 19:30:33 -0400 Subject: [PATCH 09/13] isa: fix `srw` argument order --- disasm/src/generated.rs | 2 +- disasm/tests/test_disasm.rs | 1 + isa.yaml | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index cd0b10e..71fd1cb 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -2189,8 +2189,8 @@ impl Ins { Field::SH(OpaqueU(((self.code >> 11u8) & 0x1f) as _)), ], Opcode::Srw => vec![ - Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::rA(GPR(((self.code >> 16u8) & 0x1f) as _)), + Field::rS(GPR(((self.code >> 21u8) & 0x1f) as _)), Field::rB(GPR(((self.code >> 11u8) & 0x1f) as _)), ], Opcode::Stb => vec![ diff --git a/disasm/tests/test_disasm.rs b/disasm/tests/test_disasm.rs index 95b5e92..f19980a 100644 --- a/disasm/tests/test_disasm.rs +++ b/disasm/tests/test_disasm.rs @@ -816,6 +816,7 @@ fn test_ins_srawi() { #[test] fn test_ins_srw() { assert_asm!(0x7C001C30, "srw r0, r0, r3"); + assert_asm!(0x7C600430, "srw r0, r3, r0"); } #[test] diff --git a/isa.yaml b/isa.yaml index 9247f09..49ba4f2 100644 --- a/isa.yaml +++ b/isa.yaml @@ -1635,7 +1635,7 @@ opcodes: bitmask: 0xfc0007fe pattern: 0x7c000430 modifiers: [ Rc ] - args: [ rS, rA, rB ] + args: [ rA, rS, rB ] defs: [ rA ] uses: [ rA, rB ] From a9ae0cb8a151b99f0cbea61531201bd834f26fb6 Mon Sep 17 00:00:00 2001 From: InusualZ Date: Tue, 31 May 2022 19:36:21 -0400 Subject: [PATCH 10/13] isa: add `RC` modifier to the `xor` instruction --- disasm/src/generated.rs | 8 +++++++- disasm/tests/test_disasm.rs | 1 + isa.yaml | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index 71fd1cb..40ab7ef 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -4807,7 +4807,13 @@ impl Ins { Opcode::Tlbsync => String::new(), Opcode::Tw => String::new(), Opcode::Twi => String::new(), - Opcode::Xor => String::new(), + Opcode::Xor => { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('.'); + } + s + } Opcode::Xori => String::new(), Opcode::Xoris => String::new(), } diff --git a/disasm/tests/test_disasm.rs b/disasm/tests/test_disasm.rs index f19980a..574be34 100644 --- a/disasm/tests/test_disasm.rs +++ b/disasm/tests/test_disasm.rs @@ -959,6 +959,7 @@ fn test_ins_sync() { #[test] fn test_ins_xor() { assert_asm!(0x7C052A78, "xor r5, r0, r5"); + assert_asm!(0x7D275279, "xor. r7, r9, r10"); } #[test] diff --git a/isa.yaml b/isa.yaml index 49ba4f2..3866a18 100644 --- a/isa.yaml +++ b/isa.yaml @@ -1926,6 +1926,7 @@ opcodes: desc: XOR bitmask: 0xfc0007fe pattern: 0x7c000278 + modifiers: [ Rc ] args: [ rA, rS, rB ] defs: [ rA ] uses: [ rS, rB ] From 86e081fdb2095b28c106a3c25a88c15afae7a996 Mon Sep 17 00:00:00 2001 From: InusualZ Date: Tue, 31 May 2022 19:44:21 -0400 Subject: [PATCH 11/13] isa: fix `rlwinm`'s mnemonic `slwi` using `ME` instead of `SH` as arg --- disasm/src/generated.rs | 2 +- disasm/tests/test_disasm.rs | 3 +++ isa.yaml | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index 40ab7ef..395afa6 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -5843,7 +5843,7 @@ impl Ins { args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), - Argument::OpaqueU(OpaqueU(((self.code >> 1u8) & 0x1f) as _)), + Argument::OpaqueU(OpaqueU(((self.code >> 11u8) & 0x1f) as _)), ], ins: self, }; diff --git a/disasm/tests/test_disasm.rs b/disasm/tests/test_disasm.rs index 574be34..02dc22c 100644 --- a/disasm/tests/test_disasm.rs +++ b/disasm/tests/test_disasm.rs @@ -784,6 +784,9 @@ fn test_ins_rlwimi() { fn test_ins_rlwinm() { assert_asm!(0x54000423, "rlwinm. r0, r0, 0, 16, 17"); assert_asm!(0x54000432, "rlwinm r0, r0, 0, 16, 25"); + + // mnemonics + assert_asm!(0x57E5103A, "slwi r5, r31, 2"); } #[test] diff --git a/isa.yaml b/isa.yaml index 3866a18..c70de96 100644 --- a/isa.yaml +++ b/isa.yaml @@ -1976,7 +1976,7 @@ mnemonics: condition: MB == 0 && ME == 31 - name: slwi opcode: rlwinm - args: [ rA, rS, ME ] + args: [ rA, rS, SH ] condition: MB == 0 && 31 - SH == ME - name: srwi opcode: rlwinm From 3c0656ee3c754967664edbf2c571ffc963e3e70f Mon Sep 17 00:00:00 2001 From: InusualZ Date: Tue, 31 May 2022 19:54:51 -0400 Subject: [PATCH 12/13] isa: remove `mfspr`'s `mftdu` and `mttdu` mnemonics since there are not recognized by the metrowerks assembler --- disasm/src/generated.rs | 22 ---------------------- isa.yaml | 8 -------- 2 files changed, 30 deletions(-) diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index 395afa6..4006744 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -5708,17 +5708,6 @@ impl Ins { ins: self, }; } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 571 - { - return SimplifiedIns { - mnemonic: "mftdu", - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } } Opcode::Mtspr => { if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) @@ -5776,17 +5765,6 @@ impl Ins { ins: self, }; } - if (((((self.code >> 11u8) & 0x3ff) & 0b11111_00000u32) >> 5u32) - | ((((self.code >> 11u8) & 0x3ff) & 0b00000_11111u32) << 5u32)) - as u32 - == 571 - { - return SimplifiedIns { - mnemonic: "mttdu", - args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], - ins: self, - }; - } } Opcode::Or => { if ((self.code >> 21u8) & 0x1f) == ((self.code >> 11u8) & 0x1f) { diff --git a/isa.yaml b/isa.yaml index c70de96..00a459c 100644 --- a/isa.yaml +++ b/isa.yaml @@ -2103,10 +2103,6 @@ mnemonics: opcode: mtspr args: [ rS ] condition: spr == 397 - - name: mttdu - opcode: mtspr - args: [ rS ] - condition: spr == 571 # Move from special-purpose register - name: mfxer @@ -2129,10 +2125,6 @@ mnemonics: opcode: mfspr args: [ rD ] condition: spr == 397 - - name: mftdu - opcode: mfspr - args: [ rD ] - condition: spr == 571 # Branch Conditional # bc branch always From d1c809b3f676256a732e91e264ae287dcfc7aac9 Mon Sep 17 00:00:00 2001 From: InusualZ Date: Tue, 31 May 2022 20:12:48 -0400 Subject: [PATCH 13/13] isa: fix `ps_mr` having `frA` as argument --- disasm/src/generated.rs | 1 - disasm/tests/test_disasm.rs | 5 +++++ isa.yaml | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index 4006744..5becd08 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -2075,7 +2075,6 @@ impl Ins { ], Opcode::PsMr => vec![ Field::frD(FPR(((self.code >> 21u8) & 0x1f) as _)), - Field::frA(FPR(((self.code >> 16u8) & 0x1f) as _)), Field::frB(FPR(((self.code >> 11u8) & 0x1f) as _)), ], Opcode::PsMsub => vec![ diff --git a/disasm/tests/test_disasm.rs b/disasm/tests/test_disasm.rs index 02dc22c..e0df349 100644 --- a/disasm/tests/test_disasm.rs +++ b/disasm/tests/test_disasm.rs @@ -709,6 +709,11 @@ fn test_ins_ps_merge11() { assert_asm!(0x10AA14E0, "ps_merge11 f5, f10, f2"); } +#[test] +fn test_ins_ps_mr() { + assert_asm!(0x10200090, "ps_mr f1, f0"); +} + #[test] fn test_ins_ps_msub() { assert_asm!(0x10A53778, "ps_msub f5, f5, f29, f6"); diff --git a/isa.yaml b/isa.yaml index 00a459c..c39f470 100644 --- a/isa.yaml +++ b/isa.yaml @@ -1450,7 +1450,7 @@ opcodes: desc: Paired Single Move Register bitmask: 0xfc1f07fe pattern: 0x10000090 - args: [ frD, frA, frB ] + args: [ frD, frB ] defs: [ frD ] uses: [ frB ]