From 4d8e4733319312abf47cde193d7386e55744bdf8 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Mon, 10 Oct 2022 17:53:24 -0400 Subject: [PATCH] Support branch prediction bits, more bd mnemonics, more rlwinm mnemonics --- disasm/src/formatter.rs | 2 +- disasm/src/generated.rs | 1708 ++++++++++++++++++++++++++++++++--- disasm/src/lib.rs | 14 +- disasm/tests/test_disasm.rs | 63 +- dol/src/lib.rs | 9 +- genisa/src/main.rs | 84 +- isa.yaml | 261 +++--- 7 files changed, 1869 insertions(+), 272 deletions(-) diff --git a/disasm/src/formatter.rs b/disasm/src/formatter.rs index 3e2ca3c..d1322c5 100644 --- a/disasm/src/formatter.rs +++ b/disasm/src/formatter.rs @@ -7,7 +7,7 @@ pub struct FormattedIns(pub Ins); impl Display for FormattedIns { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { let simple = self.0.clone().simplified(); - write!(f, "{}{}", simple.mnemonic, simple.ins.suffix())?; + write!(f, "{}{}", simple.mnemonic, simple.suffix)?; let mut writing_offset = false; for (i, arg) in simple.args.iter().enumerate() { if i == 0 { diff --git a/disasm/src/generated.rs b/disasm/src/generated.rs index 3ec512b..851f89d 100644 --- a/disasm/src/generated.rs +++ b/disasm/src/generated.rs @@ -1132,7 +1132,7 @@ pub enum Field { offset(Offset), ps_offset(Offset), BO(OpaqueU), - BI(OpaqueU), + BI(CRBit), BH(OpaqueU), BD(BranchDest), LI(BranchDest), @@ -1181,7 +1181,7 @@ impl Field { Field::offset(x) => Some(Argument::Offset(*x)), Field::ps_offset(x) => Some(Argument::Offset(*x)), Field::BO(x) => Some(Argument::OpaqueU(*x)), - Field::BI(x) => Some(Argument::OpaqueU(*x)), + Field::BI(x) => Some(Argument::CRBit(*x)), Field::BH(x) => Some(Argument::OpaqueU(*x)), Field::BD(x) => Some(Argument::BranchDest(*x)), Field::LI(x) => Some(Argument::BranchDest(*x)), @@ -1351,7 +1351,7 @@ impl Ins { ))], Opcode::Bc => vec![ Field::BO(OpaqueU(((self.code >> 21u8) & 0x1f) as _)), - Field::BI(OpaqueU(((self.code >> 16u8) & 0x1f) as _)), + Field::BI(CRBit(((self.code >> 16u8) & 0x1f) as _)), Field::BD(BranchDest( ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) << 2u8) as _, @@ -1359,12 +1359,12 @@ impl Ins { ], Opcode::Bcctr => vec![ Field::BO(OpaqueU(((self.code >> 21u8) & 0x1f) as _)), - Field::BI(OpaqueU(((self.code >> 16u8) & 0x1f) as _)), + Field::BI(CRBit(((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::BI(CRBit(((self.code >> 16u8) & 0x1f) as _)), Field::BH(OpaqueU(((self.code >> 11u8) & 0x3) as _)), ], Opcode::Cmp => vec![ @@ -4225,6 +4225,20 @@ impl Ins { if self.bit(30usize) { s.push('a'); } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) + << 2u8) + < 0 + { + s.push('-'); + } s } Opcode::Bcctr => { @@ -4232,6 +4246,9 @@ impl Ins { if self.bit(31usize) { s.push('l'); } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } s } Opcode::Bclr => { @@ -4239,6 +4256,9 @@ impl Ins { if self.bit(31usize) { s.push('l'); } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } s } Opcode::Cmp => String::new(), @@ -4829,6 +4849,7 @@ impl Ins { if ((self.code >> 16u8) & 0x1f) == 0 { return SimplifiedIns { mnemonic: "li", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), Argument::Simm(Simm( @@ -4844,6 +4865,7 @@ impl Ins { if ((self.code >> 16u8) & 0x1f) == 0 { return SimplifiedIns { mnemonic: "lis", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), Argument::Uimm(Uimm((self.code & 0xffff) as _)), @@ -4853,19 +4875,40 @@ impl Ins { } } Opcode::Bc => { - if ((self.code >> 21u8) & 0x1f) == 20 && ((self.code >> 16u8) & 0x1f) == 0 { - return SimplifiedIns { - mnemonic: "b", - args: vec![], - ins: self, - }; - } - if ((self.code >> 21u8) & 0x1f) == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 0 { return SimplifiedIns { mnemonic: "blt", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![Argument::BranchDest(BranchDest( ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) @@ -4874,10 +4917,41 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 0 { return SimplifiedIns { mnemonic: "blt", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![ Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), Argument::BranchDest(BranchDest( @@ -4889,12 +4963,40 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 1 { return SimplifiedIns { mnemonic: "ble", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![Argument::BranchDest(BranchDest( ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) @@ -4903,10 +5005,41 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 1 { return SimplifiedIns { mnemonic: "ble", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![ Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), Argument::BranchDest(BranchDest( @@ -4918,12 +5051,40 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 2 { return SimplifiedIns { mnemonic: "beq", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![Argument::BranchDest(BranchDest( ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) @@ -4932,10 +5093,41 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 2 { return SimplifiedIns { mnemonic: "beq", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![ Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), Argument::BranchDest(BranchDest( @@ -4947,12 +5139,40 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 0 { return SimplifiedIns { mnemonic: "bge", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![Argument::BranchDest(BranchDest( ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) @@ -4961,10 +5181,41 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 0 { return SimplifiedIns { mnemonic: "bge", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![ Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), Argument::BranchDest(BranchDest( @@ -4976,12 +5227,40 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 1 { return SimplifiedIns { mnemonic: "bgt", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![Argument::BranchDest(BranchDest( ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) @@ -4990,10 +5269,41 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 1 { return SimplifiedIns { mnemonic: "bgt", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![ Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), Argument::BranchDest(BranchDest( @@ -5005,12 +5315,40 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 2 { return SimplifiedIns { mnemonic: "bne", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![Argument::BranchDest(BranchDest( ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) @@ -5019,10 +5357,41 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 2 { return SimplifiedIns { mnemonic: "bne", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![ Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), Argument::BranchDest(BranchDest( @@ -5034,12 +5403,40 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 3 { return SimplifiedIns { mnemonic: "bso", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![Argument::BranchDest(BranchDest( ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) @@ -5048,10 +5445,41 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 3 { return SimplifiedIns { mnemonic: "bso", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![ Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), Argument::BranchDest(BranchDest( @@ -5063,12 +5491,40 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 3 { return SimplifiedIns { mnemonic: "bns", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![Argument::BranchDest(BranchDest( ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) @@ -5077,10 +5533,41 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 3 { return SimplifiedIns { mnemonic: "bns", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![ Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _)), Argument::BranchDest(BranchDest( @@ -5092,9 +5579,40 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 16 && ((self.code >> 16u8) & 0x1f) == 0 { + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 16 && ((self.code >> 16u8) & 0x1f) == 0 + { return SimplifiedIns { mnemonic: "bdnz", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![Argument::BranchDest(BranchDest( ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) @@ -5103,9 +5621,128 @@ impl Ins { ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 18 && ((self.code >> 16u8) & 0x1f) == 0 { + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 8 { + return SimplifiedIns { + mnemonic: "bdnzt", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, + args: vec![ + Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _)), + Argument::BranchDest(BranchDest( + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) + << 2u8) as _, + )), + ], + ins: self, + }; + } + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 0 { + return SimplifiedIns { + mnemonic: "bdnzf", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, + args: vec![ + Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _)), + Argument::BranchDest(BranchDest( + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) + << 2u8) as _, + )), + ], + ins: self, + }; + } + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 18 && ((self.code >> 16u8) & 0x1f) == 0 + { return SimplifiedIns { mnemonic: "bdz", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, args: vec![Argument::BranchDest(BranchDest( ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) @@ -5114,155 +5751,436 @@ impl Ins { ins: self, }; } + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 10 { + return SimplifiedIns { + mnemonic: "bdzt", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, + args: vec![ + Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _)), + Argument::BranchDest(BranchDest( + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) + << 2u8) as _, + )), + ], + ins: self, + }; + } + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 2 { + return SimplifiedIns { + mnemonic: "bdzf", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if self.bit(30usize) { + s.push('a'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + >= 0 + { + s.push('+'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000) + .wrapping_sub(0x2000)) + as i32) + << 2u8) + < 0 + { + s.push('-'); + } + s + } + }, + args: vec![ + Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _)), + Argument::BranchDest(BranchDest( + ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) + as i32) + << 2u8) as _, + )), + ], + ins: self, + }; + } } Opcode::Bcctr => { if ((self.code >> 21u8) & 0x1f) == 20 && ((self.code >> 16u8) & 0x1f) == 0 { return SimplifiedIns { mnemonic: "bctr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 0 { return SimplifiedIns { mnemonic: "bltctr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 0 { return SimplifiedIns { mnemonic: "bltctr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 1 { return SimplifiedIns { mnemonic: "blectr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 1 { return SimplifiedIns { mnemonic: "blectr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 2 { return SimplifiedIns { mnemonic: "beqctr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 2 { return SimplifiedIns { mnemonic: "beqctr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 0 { return SimplifiedIns { mnemonic: "bgectr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 0 { return SimplifiedIns { mnemonic: "bgectr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 1 { return SimplifiedIns { mnemonic: "bgtctr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 1 { return SimplifiedIns { mnemonic: "bgtctr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 2 { return SimplifiedIns { mnemonic: "bnectr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 2 { return SimplifiedIns { mnemonic: "bnectr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 3 { return SimplifiedIns { mnemonic: "bsoctr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 3 { return SimplifiedIns { mnemonic: "bsoctr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 3 { return SimplifiedIns { mnemonic: "bnsctr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 3 { return SimplifiedIns { mnemonic: "bnsctr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], ins: self, }; @@ -5272,159 +6190,469 @@ impl Ins { if ((self.code >> 21u8) & 0x1f) == 20 && ((self.code >> 16u8) & 0x1f) == 0 { return SimplifiedIns { mnemonic: "blr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 0 { return SimplifiedIns { mnemonic: "bltlr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 0 { return SimplifiedIns { mnemonic: "bltlr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 1 { return SimplifiedIns { mnemonic: "blelr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 1 { return SimplifiedIns { mnemonic: "blelr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 2 { return SimplifiedIns { mnemonic: "beqlr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 2 { return SimplifiedIns { mnemonic: "beqlr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 0 { return SimplifiedIns { mnemonic: "bgelr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b00 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 0 { return SimplifiedIns { mnemonic: "bgelr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 1 { return SimplifiedIns { mnemonic: "bgtlr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b01 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 1 { return SimplifiedIns { mnemonic: "bgtlr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 2 { return SimplifiedIns { mnemonic: "bnelr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b10 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 2 { return SimplifiedIns { mnemonic: "bnelr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 && ((self.code >> 16u8) & 0x1f) == 3 { return SimplifiedIns { mnemonic: "bsolr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 12 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 12 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 3 { return SimplifiedIns { mnemonic: "bsolr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 - && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11 - && ((self.code >> 18u8) & 0x7) == 0 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 && ((self.code >> 16u8) & 0x1f) == 3 { return SimplifiedIns { mnemonic: "bnslr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![], ins: self, }; } - if ((self.code >> 21u8) & 0x1f) == 4 && ((self.code >> 16u8) & 0x1f) & 0b11 == 0b11 + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 4 + && ((self.code >> 16u8) & 0x1f) & 0b11 == 3 { return SimplifiedIns { mnemonic: "bnslr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, args: vec![Argument::CRField(CRField(((self.code >> 18u8) & 0x7) as _))], ins: self, }; } + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 16 && ((self.code >> 16u8) & 0x1f) == 0 + { + return SimplifiedIns { + mnemonic: "bdnzlr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, + args: vec![], + ins: self, + }; + } + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 8 { + return SimplifiedIns { + mnemonic: "bdnztlr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, + args: vec![Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _))], + ins: self, + }; + } + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 0 { + return SimplifiedIns { + mnemonic: "bdnzflr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, + args: vec![Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _))], + ins: self, + }; + } + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 18 && ((self.code >> 16u8) & 0x1f) == 0 + { + return SimplifiedIns { + mnemonic: "bdzlr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, + args: vec![], + ins: self, + }; + } + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 10 { + return SimplifiedIns { + mnemonic: "bdztlr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, + args: vec![Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _))], + ins: self, + }; + } + if ((self.code >> 21u8) & 0x1f) & 0b11110 == 0 { + return SimplifiedIns { + mnemonic: "bdzflr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('l'); + } + if ((self.code >> 21u8) & 0x1f) & 1 == 1 { + s.push('+'); + } + s + } + }, + args: vec![Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _))], + ins: self, + }; + } } Opcode::Cmp => { if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 0 { return SimplifiedIns { mnemonic: "cmpw", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), @@ -5435,6 +6663,7 @@ impl Ins { if ((self.code >> 21u8) & 0x1) == 0 { return SimplifiedIns { mnemonic: "cmpw", + suffix: String::new(), args: vec![ Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), @@ -5446,6 +6675,7 @@ impl Ins { if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 1 { return SimplifiedIns { mnemonic: "cmpd", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), @@ -5456,6 +6686,7 @@ impl Ins { if ((self.code >> 21u8) & 0x1) == 1 { return SimplifiedIns { mnemonic: "cmpd", + suffix: String::new(), args: vec![ Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), @@ -5469,6 +6700,7 @@ impl Ins { if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 0 { return SimplifiedIns { mnemonic: "cmpwi", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::Simm(Simm( @@ -5482,6 +6714,7 @@ impl Ins { if ((self.code >> 21u8) & 0x1) == 0 { return SimplifiedIns { mnemonic: "cmpwi", + suffix: String::new(), args: vec![ Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), @@ -5496,6 +6729,7 @@ impl Ins { if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 1 { return SimplifiedIns { mnemonic: "cmpdi", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::Simm(Simm( @@ -5509,6 +6743,7 @@ impl Ins { if ((self.code >> 21u8) & 0x1) == 1 { return SimplifiedIns { mnemonic: "cmpdi", + suffix: String::new(), args: vec![ Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), @@ -5525,6 +6760,7 @@ impl Ins { if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 0 { return SimplifiedIns { mnemonic: "cmplw", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), @@ -5535,6 +6771,7 @@ impl Ins { if ((self.code >> 21u8) & 0x1) == 0 { return SimplifiedIns { mnemonic: "cmplw", + suffix: String::new(), args: vec![ Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), @@ -5546,6 +6783,7 @@ impl Ins { if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 1 { return SimplifiedIns { mnemonic: "cmpld", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), @@ -5556,6 +6794,7 @@ impl Ins { if ((self.code >> 21u8) & 0x1) == 1 { return SimplifiedIns { mnemonic: "cmpld", + suffix: String::new(), args: vec![ Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), @@ -5569,6 +6808,7 @@ impl Ins { if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 0 { return SimplifiedIns { mnemonic: "cmplwi", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::Uimm(Uimm((self.code & 0xffff) as _)), @@ -5579,6 +6819,7 @@ impl Ins { if ((self.code >> 21u8) & 0x1) == 0 { return SimplifiedIns { mnemonic: "cmplwi", + suffix: String::new(), args: vec![ Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), @@ -5590,6 +6831,7 @@ impl Ins { if ((self.code >> 23u8) & 0x7) == 0 && ((self.code >> 21u8) & 0x1) == 1 { return SimplifiedIns { mnemonic: "cmpldi", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::Uimm(Uimm((self.code & 0xffff) as _)), @@ -5600,6 +6842,7 @@ impl Ins { if ((self.code >> 21u8) & 0x1) == 1 { return SimplifiedIns { mnemonic: "cmpldi", + suffix: String::new(), args: vec![ Argument::CRField(CRField(((self.code >> 23u8) & 0x7) as _)), Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), @@ -5615,6 +6858,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "crset", + suffix: String::new(), args: vec![Argument::CRBit(CRBit(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5624,10 +6868,10 @@ impl Ins { if ((self.code >> 16u8) & 0x1f) == ((self.code >> 11u8) & 0x1f) { return SimplifiedIns { mnemonic: "crnot", + suffix: String::new(), args: vec![ Argument::CRBit(CRBit(((self.code >> 21u8) & 0x1f) as _)), Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Argument::CRBit(CRBit(((self.code >> 11u8) & 0x1f) as _)), ], ins: self, }; @@ -5637,10 +6881,10 @@ impl Ins { if ((self.code >> 16u8) & 0x1f) == ((self.code >> 11u8) & 0x1f) { return SimplifiedIns { mnemonic: "crmove", + suffix: String::new(), args: vec![ Argument::CRBit(CRBit(((self.code >> 21u8) & 0x1f) as _)), Argument::CRBit(CRBit(((self.code >> 16u8) & 0x1f) as _)), - Argument::CRBit(CRBit(((self.code >> 11u8) & 0x1f) as _)), ], ins: self, }; @@ -5652,6 +6896,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "crclr", + suffix: String::new(), args: vec![Argument::CRBit(CRBit(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5665,6 +6910,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mfxer", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5676,6 +6922,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mflr", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5687,6 +6934,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mfctr", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5698,6 +6946,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mfdsisr", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5709,6 +6958,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mfdar", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5720,6 +6970,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mfdec", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5731,6 +6982,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mfsdr1", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5742,6 +6994,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mfsrr0", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5753,6 +7006,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mfsrr1", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5765,6 +7019,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mfsprg", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), Argument::OpaqueU(OpaqueU(((self.code >> 16u8) & 0x3) as _)), @@ -5779,6 +7034,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mfear", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5791,6 +7047,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mfibatu", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), @@ -5806,6 +7063,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mfibatl", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), @@ -5821,6 +7079,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mfdbatu", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), @@ -5836,6 +7095,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mfdbatl", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), @@ -5852,6 +7112,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mtxer", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5863,6 +7124,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mtlr", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5874,6 +7136,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mtctr", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5885,6 +7148,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mtdsisr", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5896,6 +7160,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mtdar", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5907,6 +7172,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mtdec", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5918,6 +7184,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mtsdr1", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5929,6 +7196,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mtsrr0", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5940,6 +7208,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mtsrr1", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5952,6 +7221,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mtsprg", + suffix: String::new(), args: vec![ Argument::OpaqueU(OpaqueU(((self.code >> 16u8) & 0x3) as _)), Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), @@ -5966,6 +7236,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mtear", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5977,6 +7248,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mttbl", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -5988,6 +7260,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mttbu", + suffix: String::new(), args: vec![Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _))], ins: self, }; @@ -6000,6 +7273,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mtibatu", + suffix: String::new(), args: vec![ Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), @@ -6015,6 +7289,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mtibatl", + suffix: String::new(), args: vec![ Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), @@ -6030,6 +7305,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mtdbatu", + suffix: String::new(), args: vec![ Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), @@ -6045,6 +7321,7 @@ impl Ins { { return SimplifiedIns { mnemonic: "mtdbatl", + suffix: String::new(), args: vec![ Argument::OpaqueU(OpaqueU(((self.code >> 17u8) & 0x3) as _)), Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), @@ -6057,6 +7334,15 @@ impl Ins { if ((self.code >> 21u8) & 0x1f) == ((self.code >> 11u8) & 0x1f) { return SimplifiedIns { mnemonic: "mr", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('.'); + } + s + } + }, args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), @@ -6072,15 +7358,48 @@ impl Ins { { return SimplifiedIns { mnemonic: "nop", + suffix: String::new(), args: vec![], ins: self, }; } } Opcode::Rlwinm => { + if ((self.code >> 11u8) & 0x1f) == 0 + && ((self.code >> 6u8) & 0x1f) == 0 + && ((self.code >> 1u8) & 0x1f) < 32 + { + return SimplifiedIns { + mnemonic: "clrrwi", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('.'); + } + s + } + }, + args: vec![ + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + Argument::OpaqueU(OpaqueU((31 - ((self.code >> 1u8) & 0x1f)) as _)), + ], + ins: self, + }; + } if ((self.code >> 11u8) & 0x1f) == 0 && ((self.code >> 1u8) & 0x1f) == 31 { return SimplifiedIns { mnemonic: "clrlwi", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('.'); + } + s + } + }, args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), @@ -6089,9 +7408,45 @@ impl Ins { ins: self, }; } - if ((self.code >> 6u8) & 0x1f) == 0 && ((self.code >> 1u8) & 0x1f) == 31 { + if ((self.code >> 11u8) & 0x1f) < 32 + && ((self.code >> 6u8) & 0x1f) >= ((self.code >> 11u8) & 0x1f) + && ((self.code >> 1u8) & 0x1f) == 31 - ((self.code >> 11u8) & 0x1f) + { + return SimplifiedIns { + mnemonic: "clrlslwi", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('.'); + } + s + } + }, + args: vec![ + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + Argument::OpaqueU(OpaqueU((32 - ((self.code >> 11u8) & 0x1f)) as _)), + Argument::OpaqueU(OpaqueU(((self.code >> 11u8) & 0x1f) as _)), + ], + ins: self, + }; + } + if ((self.code >> 6u8) & 0x1f) == 0 + && ((self.code >> 1u8) & 0x1f) == 31 + && ((self.code >> 11u8) & 0x1f) <= 16 + { return SimplifiedIns { mnemonic: "rotlwi", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('.'); + } + s + } + }, args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), @@ -6100,11 +7455,43 @@ impl Ins { ins: self, }; } + if ((self.code >> 6u8) & 0x1f) == 0 + && ((self.code >> 1u8) & 0x1f) == 31 + && ((self.code >> 11u8) & 0x1f) > 16 + { + return SimplifiedIns { + mnemonic: "rotrwi", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('.'); + } + s + } + }, + args: vec![ + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + Argument::OpaqueU(OpaqueU((32 - ((self.code >> 11u8) & 0x1f)) as _)), + ], + ins: self, + }; + } if ((self.code >> 6u8) & 0x1f) == 0 && 31 - ((self.code >> 11u8) & 0x1f) == ((self.code >> 1u8) & 0x1f) { return SimplifiedIns { mnemonic: "slwi", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('.'); + } + s + } + }, args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), @@ -6118,6 +7505,15 @@ impl Ins { { return SimplifiedIns { mnemonic: "srwi", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('.'); + } + s + } + }, args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), @@ -6126,11 +7522,81 @@ impl Ins { ins: self, }; } + if ((self.code >> 6u8) & 0x1f) == 0 { + return SimplifiedIns { + mnemonic: "extlwi", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('.'); + } + s + } + }, + 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) + 1) as _)), + Argument::OpaqueU(OpaqueU(((self.code >> 11u8) & 0x1f) as _)), + ], + ins: self, + }; + } + if ((self.code >> 1u8) & 0x1f) == 31 + && ((self.code >> 11u8) & 0x1f) >= 32 - ((self.code >> 6u8) & 0x1f) + { + return SimplifiedIns { + mnemonic: "extrwi", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('.'); + } + s + } + }, + args: vec![ + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + Argument::OpaqueU(OpaqueU((32 - ((self.code >> 6u8) & 0x1f)) as _)), + Argument::OpaqueU(OpaqueU( + (((self.code >> 11u8) & 0x1f) - (32 - ((self.code >> 6u8) & 0x1f))) + as _, + )), + ], + ins: self, + }; + } + } + Opcode::Rlwnm => { + if ((self.code >> 6u8) & 0x1f) == 0 && ((self.code >> 1u8) & 0x1f) == 31 { + return SimplifiedIns { + mnemonic: "rotlw", + suffix: { + { + let mut s = String::with_capacity(4); + if self.bit(31usize) { + s.push('.'); + } + s + } + }, + args: vec![ + Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 21u8) & 0x1f) as _)), + Argument::GPR(GPR(((self.code >> 11u8) & 0x1f) as _)), + ], + ins: self, + }; + } } Opcode::Twi => { if ((self.code >> 21u8) & 0x1f) == 8 { return SimplifiedIns { mnemonic: "twgti", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::Simm(Simm( @@ -6144,6 +7610,7 @@ impl Ins { if ((self.code >> 21u8) & 0x1f) == 6 { return SimplifiedIns { mnemonic: "twllei", + suffix: String::new(), args: vec![ Argument::GPR(GPR(((self.code >> 16u8) & 0x1f) as _)), Argument::Simm(Simm( @@ -6348,4 +7815,19 @@ impl Ins { pub fn field_AA(&self) -> bool { self.bit(30usize) } + #[inline(always)] + pub fn field_BP(&self) -> bool { + ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) << 2u8) + >= 0 + } + #[inline(always)] + pub fn field_BNP(&self) -> bool { + ((self.code >> 21u8) & 0x1f) & 1 == 1 + && ((((((self.code >> 2u8) & 0x3fff) ^ 0x2000).wrapping_sub(0x2000)) as i32) << 2u8) < 0 + } + #[inline(always)] + pub fn field_BP_ND(&self) -> bool { + ((self.code >> 21u8) & 0x1f) & 1 == 1 + } } diff --git a/disasm/src/lib.rs b/disasm/src/lib.rs index 2bfeeee..f47b868 100644 --- a/disasm/src/lib.rs +++ b/disasm/src/lib.rs @@ -215,8 +215,6 @@ impl Display for Bit { // Unsigned opaque argument. field_arg!(OpaqueU, u32); -const SPR_LR: usize = 16; - #[derive(Debug, Clone)] pub enum Argument { GPR(GPR), @@ -373,12 +371,10 @@ impl Ins { self.branch_offset().and_then(|offset| { if self.field_AA() { Some(offset as u32) + } else if offset < 0 { + self.addr.checked_sub((-offset) as u32) } else { - if offset < 0 { - self.addr.checked_sub((-offset) as u32) - } else { - self.addr.checked_add(offset as u32) - } + self.addr.checked_add(offset as u32) } }) } @@ -419,12 +415,13 @@ impl Ins { pub struct SimplifiedIns { pub ins: Ins, pub mnemonic: &'static str, + pub suffix: String, pub args: Vec, } impl Display for SimplifiedIns { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}{} ", self.mnemonic, self.ins.suffix())?; + write!(f, "{}{} ", self.mnemonic, self.suffix)?; let mut writing_offset = false; for (i, argument) in self.args.iter().enumerate() { write!(f, "{}", argument)?; @@ -449,6 +446,7 @@ impl SimplifiedIns { pub(crate) fn basic_form(ins: Ins) -> Self { Self { mnemonic: ins.op.mnemonic(), + suffix: ins.suffix(), args: ins .fields() .iter() diff --git a/disasm/tests/test_disasm.rs b/disasm/tests/test_disasm.rs index 5722b9f..c68c3d8 100644 --- a/disasm/tests/test_disasm.rs +++ b/disasm/tests/test_disasm.rs @@ -95,6 +95,7 @@ fn test_ins_b() { assert_asm!(0x4BE03C99, "bl -0x1fc368"); assert_asm!(0x4BDC1A59, "bl -0x23e5a8"); assert_asm!(0x48000063, "bla 0x60"); + assert_asm!(0x48000002, "ba 0x0"); } #[test] @@ -121,18 +122,29 @@ fn test_ins_bc() { assert_asm!(0x418502E4, "bgt cr1, 0x2e4"); assert_asm!(0x419A0138, "beq cr6, 0x138"); assert_asm!(0x419C0008, "blt cr7, 0x8"); + assert_asm!(0x4240FFF0, "bdz -0x10"); assert_asm!(0x4200F560, "bdnz -0xaa0"); + assert_asm!(0x40010014, "bdnzf gt, 0x14"); + assert_asm!(0x40410035, "bdzfl gt, 0x34"); + assert_asm!(0x41430023, "bdztla so, 0x20"); + assert_asm!(0x4108FFE3, "bdnztla 4*cr2+lt, -0x20"); + assert_asm!(0x40A20008, "bne+ 0x8"); } #[test] fn test_ins_bcctr() { assert_asm!(0x4E800420, "bctr"); assert_asm!(0x4E800421, "bctrl"); + assert_asm!(0x4D820420, "beqctr"); + assert_asm!(0x4D8D0421, "bgtctrl cr3"); + assert_asm!(0x4DA20420, "beqctr+"); + assert_asm!(0x4DB90421, "bgtctrl+ cr6"); } #[test] fn test_ins_bclr() { assert_asm!(0x4C800020, "bgelr"); + assert_asm!(0x4CA00020, "bgelr+"); assert_asm!(0x4C810020, "blelr"); assert_asm!(0x4C820020, "bnelr"); assert_asm!(0x4C9E0020, "bnelr cr7"); @@ -142,6 +154,8 @@ fn test_ins_bclr() { assert_asm!(0x4D860020, "beqlr cr1"); assert_asm!(0x4E800020, "blr"); assert_asm!(0x4E800021, "blrl"); + assert_asm!(0x4D000020, "bdnztlr lt"); + assert_asm!(0x4C1F0021, "bdnzflrl 4*cr7+so"); } #[test] @@ -171,9 +185,46 @@ fn test_ins_cntlzw() { assert_asm!(0x7C030034, "cntlzw r3, r0"); } +#[test] +fn test_ins_crand() { + assert_asm!(0x4C853202, "crand 4*cr1+lt, 4*cr1+gt, 4*cr1+eq"); +} + +#[test] +fn test_ins_crandc() { + assert_asm!(0x4C642902, "crandc so, 4*cr1+lt, 4*cr1+gt"); +} + +#[test] +fn test_ins_creqv() { + assert_asm!(0x4CE00A42, "creqv 4*cr1+so, lt, gt"); +} + +#[test] +fn test_ins_crnand() { + assert_asm!(0x4C2219C2, "crnand gt, eq, so"); +} + #[test] fn test_ins_cror() { assert_asm!(0x4C411382, "cror eq, gt, eq"); + assert_asm!(0x4CA63B82, "cror 4*cr1+gt, 4*cr1+eq, 4*cr1+so"); +} + +#[test] +fn test_ins_crorc() { + assert_asm!(0x4C432342, "crorc eq, so, 4*cr1+lt"); +} + +#[test] +fn test_ins_crnor() { + assert_asm!(0x4C011042, "crnor lt, gt, eq"); + assert_asm!(0x4CA63042, "crnot 4*cr1+gt, 4*cr1+eq"); +} + +#[test] +fn test_ins_crxor() { + assert_asm!(0x4CC70182, "crxor 4*cr1+eq, 4*cr1+so, lt"); } #[test] @@ -634,7 +685,7 @@ fn test_ins_psq_lx() { rA(GPR(0)), rB(GPR(0)), ps_WX(OpaqueU(0)), - ps_IX(GQR(0)) + ps_IX(GQR(0)), ] ); assert_eq!(ins.defs(), vec![frD(FPR(0))]); @@ -802,12 +853,22 @@ fn test_ins_rlwinm() { // mnemonics assert_asm!(0x57E5103A, "slwi r5, r31, 2"); + assert_asm!(0x54832026, "extlwi r3, r4, 20, 4"); + assert_asm!(0x5483AB3E, "extrwi r3, r4, 20, 1"); + assert_asm!(0x540027BE, "extrwi r0, r0, 2, 2"); + assert_asm!(0x54839B3E, "rlwinm r3, r4, 19, 12, 31"); + assert_asm!(0x5483203E, "rotlwi r3, r4, 4"); + assert_asm!(0x5483E03E, "rotrwi r3, r4, 4"); + assert_asm!(0x5464043E, "clrlwi r4, r3, 16"); + assert_asm!(0x54830036, "clrrwi r3, r4, 4"); + assert_asm!(0x54640fbc, "clrlslwi r4, r3, 31, 1"); } #[test] fn test_ins_rlwnm() { assert_asm!(0x5D6A67FE, "rlwnm r10, r11, r12, 31, 31"); assert_asm!(0x5FC52EFE, "rlwnm r5, r30, r5, 27, 31"); + assert_asm!(0x5FC5283F, "rotlw. r5, r30, r5"); } #[test] diff --git a/dol/src/lib.rs b/dol/src/lib.rs index 94059b2..a544ae8 100644 --- a/dol/src/lib.rs +++ b/dol/src/lib.rs @@ -205,12 +205,9 @@ impl From<&DolHeaderData> for DolHeader { impl DolHeader { pub fn section_at(&self, addr: u32) -> Option<&DolSection> { - for section in &self.sections { - if (section.target..(section.target + section.size)).contains(&addr) { - return Some(section); - } - } - None + self.sections.iter() + .find(|§ion| (section.target..(section.target + section.size)) + .contains(&addr)) } } diff --git a/genisa/src/main.rs b/genisa/src/main.rs index c15abde..92fa847 100644 --- a/genisa/src/main.rs +++ b/genisa/src/main.rs @@ -6,7 +6,7 @@ use std::process::{Command, Stdio}; use std::str::FromStr; use itertools::Itertools; -use proc_macro2::{Ident, Literal, Span, TokenStream, TokenTree}; +use proc_macro2::{Group, Ident, Literal, Span, TokenStream, TokenTree}; use quote::quote; use serde::{Deserialize, Deserializer}; use syn::{LitChar, LitInt, LitStr}; @@ -74,8 +74,8 @@ pub(crate) struct BitRange(Range); impl<'de> Deserialize<'de> for BitRange { fn deserialize(deserializer: D) -> std::result::Result - where - D: Deserializer<'de>, + where + D: Deserializer<'de>, { let range_str: String = Deserialize::deserialize(deserializer)?; if let Some((start_str, stop_str)) = range_str.split_once("..") { @@ -232,7 +232,8 @@ impl Opcode { pub(crate) struct Mnemonic { name: String, opcode: String, - modifiers: Vec, + // Overrides modifier list from opcode + modifiers: Option>, args: Vec, condition: String, } @@ -243,23 +244,31 @@ pub(crate) struct Modifier { name: String, suffix: char, bit: u8, + condition: String, } impl Modifier { - fn express_value_self(&self) -> TokenStream { - let modifier_bit = self.bit as usize; - quote!(self.bit(#modifier_bit)) + fn express_value_self(&self, field_by_name: &HashMap) -> Result { + if self.condition.is_empty() { + let modifier_bit = self.bit as usize; + Ok(quote!(self.bit(#modifier_bit))) + } else { + compile_mnemonic_condition( + field_by_name, + &self.condition, + ) + } } - fn construct_accessor(&self) -> TokenStream { + fn construct_accessor(&self, field_by_name: &HashMap) -> Result { let field_variant = to_rust_ident("field_", &self.name); - let value = self.express_value_self(); - quote! { + let value = self.express_value_self(field_by_name)?; + Ok(quote! { #[inline(always)] pub fn #field_variant(&self) -> bool { #value } - } + }) } } @@ -482,7 +491,7 @@ impl Isa { }); // Generate modifiers. - let suffix = express_suffix(&modifier_by_name, opcode)?; + let suffix = express_suffix(&modifier_by_name, &field_by_name, &opcode.modifiers)?; suffix_match_arms.push(quote! { Opcode::#ident => #suffix, }); @@ -556,21 +565,29 @@ impl Isa { )?); // Emit branch. let mnemonic_lit = LitStr::new(&mnemonic.name, Span::call_site()); + // Emit suffix. + let modifiers = mnemonic.modifiers.as_ref().unwrap_or(&opcode.modifiers); + let suffix = express_suffix(&modifier_by_name, &field_by_name, modifiers)?; // Extract arguments. let mut args = Vec::new(); for arg in &mnemonic.args { + let (field_name, expression) = arg.split_once('=').unwrap_or((arg, arg)); let field = field_by_name - .get(arg) + .get(field_name) .unwrap_or_else(|| panic!("field not found: {}", arg)); let variant = Ident::new(field.arg.as_ref().unwrap(), Span::call_site()); - let value = field.express_value_self(); - args.push(quote!(Argument::#variant(#variant(#value as _)),)); + let value = compile_mnemonic_condition( + &field_by_name, + expression, + )?; + args.push(quote!(Argument::#variant(#variant((#value) as _)),)); } let args = token_stream!(args); simplified_conditions.push(quote! { { return SimplifiedIns { mnemonic: #mnemonic_lit, + suffix: #suffix, args: vec![#args], ins: self, }; @@ -592,11 +609,10 @@ impl Isa { let simplified_ins_match_arms = token_stream!(simplified_ins_match_arms); let field_accessors = TokenStream::from_iter(self.fields.iter().map(|field| field.construct_accessor())); - let modifier_accessors = TokenStream::from_iter( - self.modifiers - .iter() - .map(|modifier| modifier.construct_accessor()), - ); + let modifiers: Vec = self.modifiers + .iter() + .map(|modifier| modifier.construct_accessor(&field_by_name)).try_collect()?; + let modifier_accessors = TokenStream::from_iter(modifiers); // Generate final fields function. let ins_impl = quote! { #[allow(clippy::all, unused_mut)] @@ -701,31 +717,41 @@ fn compile_mnemonic_condition( code: &str, ) -> Result { let src_stream = TokenStream::from_str(code)?; - let token_iter = src_stream.into_iter().flat_map(|token| { - if let TokenTree::Ident(ref ident) = token { - if let Some(field) = field_by_name.get(&ident.to_string()) { - return field.express_value_self(); + fn map_ident(field_by_name: &HashMap, token: TokenTree) -> TokenStream { + match token { + TokenTree::Ident(ref ident) => { + if let Some(field) = field_by_name.get(&ident.to_string()) { + return field.express_value_self(); + } } + TokenTree::Group(ref group) => { + let iter = group.stream().into_iter().flat_map(|token| map_ident(field_by_name, token)); + let stream = TokenStream::from_iter(iter); + return TokenStream::from(TokenTree::Group(Group::new(group.delimiter(), stream))); + } + _ => {} } token.into() - }); + } + let token_iter = src_stream.into_iter().flat_map(|token| map_ident(field_by_name, token)); Ok(TokenStream::from_iter(token_iter)) } fn express_suffix( modifier_by_name: &HashMap, - opcode: &Opcode, + field_by_name: &HashMap, + modifiers: &[String], ) -> Result { - Ok(if opcode.modifiers.is_empty() { + Ok(if modifiers.is_empty() { quote!(String::new()) } else { let mut chars = Vec::new(); - for mod_name in &opcode.modifiers { + for mod_name in modifiers { let modifier: &Modifier = modifier_by_name .get(mod_name) .ok_or_else(|| Error::from(format!("undefined modifier {}", mod_name)))?; let lit_char = LitChar::new(modifier.suffix, Span::call_site()); - let modifier_bit = modifier.express_value_self(); + let modifier_bit = modifier.express_value_self(field_by_name)?; chars.push(quote! { if #modifier_bit { s.push(#lit_char); diff --git a/isa.yaml b/isa.yaml index 25bbf68..2c28fc6 100644 --- a/isa.yaml +++ b/isa.yaml @@ -20,7 +20,7 @@ fields: arg: OpaqueU bits: 6..11 - name: BI - arg: OpaqueU + arg: CRBit bits: 11..16 - name: BH arg: OpaqueU @@ -175,6 +175,18 @@ modifiers: - name: AA suffix: a bit: 30 + # Predict branch to be taken + - name: BP + suffix: + + condition: BO & 1 == 1 && BD >= 0 + # Predict branch not to be taken (fall through) + - name: BNP + suffix: '-' + condition: BO & 1 == 1 && BD < 0 + # Predict branch to be taken (implicit dest for LR/CTR) + - name: BP_ND + suffix: + + condition: BO & 1 == 1 opcodes: - name: add @@ -302,14 +314,14 @@ opcodes: desc: Branch Conditional bitmask: 0xfc000000 pattern: 0x40000000 - modifiers: [ LK, AA ] + modifiers: [ LK, AA, BP, BNP ] args: [ BO, BI, BD ] - name: bcctr desc: Branch Conditional to Count Register bitmask: 0xfc007ffe pattern: 0x4c000420 - modifiers: [ LK ] + modifiers: [ LK, BP_ND ] args: [ BO, BI, BH ] uses: [ ctr ] @@ -317,7 +329,7 @@ opcodes: desc: Branch Conditional to Link Register bitmask: 0xfc007ffe pattern: 0x4c000020 - modifiers: [ LK ] + modifiers: [ LK, BP_ND ] args: [ BO, BI, BH ] uses: [ lr ] @@ -1974,14 +1986,34 @@ mnemonics: condition: rA == 0 && rS == 0 && uimm == 0 # Rotates/Shifts + - name: rotlw + opcode: rlwnm + args: [ rA, rS, rB ] + condition: MB == 0 && ME == 31 + + # TODO rlwimi: inslwi/insrwi + + # Rotates/Shifts Immediate + - name: clrrwi + opcode: rlwinm + args: [ rA, rS, ME=31-ME ] + condition: SH == 0 && MB == 0 && ME < 32 - name: clrlwi opcode: rlwinm args: [ rA, rS, MB ] condition: SH == 0 && ME == 31 + - name: clrlslwi + opcode: rlwinm + args: [ rA, rS, MB=32-SH, SH ] + condition: SH < 32 && MB >= SH && ME == 31 - SH - name: rotlwi opcode: rlwinm args: [ rA, rS, SH ] - condition: MB == 0 && ME == 31 + condition: MB == 0 && ME == 31 && SH <= 16 + - name: rotrwi + opcode: rlwinm + args: [ rA, rS, SH=32-SH ] + condition: MB == 0 && ME == 31 && SH > 16 - name: slwi opcode: rlwinm args: [ rA, rS, SH ] @@ -1990,6 +2022,14 @@ mnemonics: opcode: rlwinm args: [ rA, rS, MB ] condition: ME == 31 && 32 - MB == SH + - name: extlwi + opcode: rlwinm + args: [ rA, rS, ME=ME+1, SH ] + condition: MB == 0 + - name: extrwi + opcode: rlwinm + args: [ rA, rS, MB=32-MB, SH=SH-(32-MB) ] + condition: ME == 31 && SH >= 32 - MB # Compares Word - name: cmpwi @@ -2070,11 +2110,11 @@ mnemonics: condition: crbD == crbA && crbD == crbB - name: crmove opcode: cror - args: [ crbD, crbA, crbB ] + args: [ crbD, crbA ] condition: crbA == crbB - name: crnot opcode: crnor - args: [ crbD, crbA, crbB ] + args: [ crbD, crbA ] condition: crbA == crbB # Misc @@ -2223,111 +2263,109 @@ mnemonics: condition: spr & 0b1111111001 == 537 # Branch Conditional - # bc branch always - - name: b - opcode: bc - modifiers: [ LK, AA ] - condition: BO == 20 && BI == 0 # bc branch if negative - name: blt opcode: bc - modifiers: [ LK, AA ] args: [ BD ] - condition: BO == 12 && BI & 0b11 == 0b00 && crfS == 0 + condition: BO & 0b11110 == 12 && BI == 0 - name: blt opcode: bc - modifiers: [ LK, AA ] args: [ crfS, BD ] - condition: BO == 12 && BI & 0b11 == 0b00 + condition: BO & 0b11110 == 12 && BI & 0b11 == 0 # bc branch if not positive - name: ble opcode: bc - modifiers: [ LK, AA ] args: [ BD ] - condition: BO == 4 && BI & 0b11 == 0b01 && crfS == 0 + condition: BO & 0b11110 == 4 && BI == 1 - name: ble opcode: bc - modifiers: [ LK, AA ] args: [ crfS, BD ] - condition: BO == 4 && BI & 0b11 == 0b01 + condition: BO & 0b11110 == 4 && BI & 0b11 == 1 # bc branch if zero - name: beq opcode: bc - modifiers: [ LK, AA ] args: [ BD ] - condition: BO == 12 && BI & 0b11 == 0b10 && crfS == 0 + condition: BO & 0b11110 == 12 && BI == 2 - name: beq opcode: bc - modifiers: [ LK, AA ] args: [ crfS, BD ] - condition: BO == 12 && BI & 0b11 == 0b10 + condition: BO & 0b11110 == 12 && BI & 0b11 == 2 # bc branch if not negative - name: bge opcode: bc - modifiers: [ LK, AA ] args: [ BD ] - condition: BO == 4 && BI & 0b11 == 0b00 && crfS == 0 + condition: BO & 0b11110 == 4 && BI == 0 - name: bge opcode: bc - modifiers: [ LK, AA ] args: [ crfS, BD ] - condition: BO == 4 && BI & 0b11 == 0b00 + condition: BO & 0b11110 == 4 && BI & 0b11 == 0 # bc branch if positive - name: bgt opcode: bc - modifiers: [ LK, AA ] args: [ BD ] - condition: BO == 12 && BI & 0b11 == 0b01 && crfS == 0 + condition: BO & 0b11110 == 12 && BI == 1 - name: bgt opcode: bc - modifiers: [ LK, AA ] args: [ crfS, BD ] - condition: BO == 12 && BI & 0b11 == 0b01 + condition: BO & 0b11110 == 12 && BI & 0b11 == 1 # bc branch if not zero - name: bne opcode: bc - modifiers: [ LK, AA ] args: [ BD ] - condition: BO == 4 && BI & 0b11 == 0b10 && crfS == 0 + condition: BO & 0b11110 == 4 && BI == 2 - name: bne opcode: bc - modifiers: [ LK, AA ] args: [ crfS, BD ] - condition: BO == 4 && BI & 0b11 == 0b10 + condition: BO & 0b11110 == 4 && BI & 0b11 == 2 # bc branch if summary overflow - name: bso opcode: bc - modifiers: [ LK, AA ] args: [ BD ] - condition: BO == 12 && BI & 0b11 == 0b11 && crfS == 0 + condition: BO & 0b11110 == 12 && BI == 3 - name: bso opcode: bc - modifiers: [ LK, AA ] args: [ crfS, BD ] - condition: BO == 12 && BI & 0b11 == 0b11 + condition: BO & 0b11110 == 12 && BI & 0b11 == 3 # bc branch if not summary overflow - name: bns opcode: bc - modifiers: [ LK, AA ] args: [ BD ] - condition: BO == 4 && BI & 0b11 == 0b11 && crfS == 0 + condition: BO & 0b11110 == 4 && BI == 3 - name: bns opcode: bc - modifiers: [ LK, AA ] args: [ crfS, BD ] - condition: BO == 4 && BI & 0b11 == 0b11 + condition: BO & 0b11110 == 4 && BI & 0b11 == 3 + # bc decrement CTR, branch if CTR non-zero - name: bdnz opcode: bc - modifiers: [ LK, AA ] args: [ BD ] - condition: BO == 16 && BI == 0 + condition: BO & 0b11110 == 16 && BI == 0 + # bc decrement CTR, branch if CTR non-zero AND condition true + - name: bdnzt + opcode: bc + args: [ BI, BD ] + condition: BO & 0b11110 == 8 + # bc decrement CTR, branch if CTR non-zero AND condition false + - name: bdnzf + opcode: bc + args: [ BI, BD ] + condition: BO & 0b11110 == 0 + # bc decrement CTR, branch if CTR zero - name: bdz opcode: bc - modifiers: [ LK, AA ] args: [ BD ] - condition: BO == 18 && BI == 0 - # TODO support conditional bd... + condition: BO & 0b11110 == 18 && BI == 0 + # bc decrement CTR, branch if CTR zero AND condition true + - name: bdzt + opcode: bc + args: [ BI, BD ] + condition: BO & 0b11110 == 10 + # bc decrement CTR, branch if CTR zero AND condition false + - name: bdzf + opcode: bc + args: [ BI, BD ] + condition: BO & 0b11110 == 2 # Branch Conditional to Count Register # bcctr branch always @@ -2338,86 +2376,69 @@ mnemonics: # bcctr branch if negative - name: bltctr opcode: bcctr - modifiers: [ LK ] - condition: BO == 12 && BI & 0b11 == 0b00 && crfS == 0 + condition: BO & 0b11110 == 12 && BI == 0 - name: bltctr opcode: bcctr - modifiers: [ LK ] args: [ crfS ] - condition: BO == 12 && BI & 0b11 == 0b00 + condition: BO & 0b11110 == 12 && BI & 0b11 == 0 # bcctr branch if not positive - name: blectr opcode: bcctr - modifiers: [ LK ] - condition: BO == 4 && BI & 0b11 == 0b01 && crfS == 0 + condition: BO & 0b11110 == 4 && BI == 1 - name: blectr opcode: bcctr - modifiers: [ LK ] args: [ crfS ] - condition: BO == 4 && BI & 0b11 == 0b01 + condition: BO & 0b11110 == 4 && BI & 0b11 == 1 # bcctr branch if zero - name: beqctr opcode: bcctr - modifiers: [ LK ] - condition: BO == 12 && BI & 0b11 == 0b10 && crfS == 0 + condition: BO & 0b11110 == 12 && BI == 2 - name: beqctr opcode: bcctr - modifiers: [ LK ] args: [ crfS ] - condition: BO == 12 && BI & 0b11 == 0b10 + condition: BO & 0b11110 == 12 && BI & 0b11 == 2 # bcctr branch if not negative - name: bgectr opcode: bcctr - modifiers: [ LK ] - condition: BO == 4 && BI & 0b11 == 0b00 && crfS == 0 + condition: BO & 0b11110 == 4 && BI == 0 - name: bgectr opcode: bcctr - modifiers: [ LK ] args: [ crfS ] - condition: BO == 4 && BI & 0b11 == 0b00 + condition: BO & 0b11110 == 4 && BI & 0b11 == 0 # bcctr branch if positive - name: bgtctr opcode: bcctr - modifiers: [ LK ] - condition: BO == 12 && BI & 0b11 == 0b01 && crfS == 0 + condition: BO & 0b11110 == 12 && BI == 1 - name: bgtctr opcode: bcctr - modifiers: [ LK ] args: [ crfS ] - condition: BO == 12 && BI & 0b11 == 0b01 + condition: BO & 0b11110 == 12 && BI & 0b11 == 1 # bcctr branch if not zero - name: bnectr opcode: bcctr - modifiers: [ LK ] - condition: BO == 4 && BI & 0b11 == 0b10 && crfS == 0 + condition: BO & 0b11110 == 4 && BI == 2 - name: bnectr opcode: bcctr - modifiers: [ LK ] args: [ crfS ] - condition: BO == 4 && BI & 0b11 == 0b10 + condition: BO & 0b11110 == 4 && BI & 0b11 == 2 # bcctr branch if summary overflow - name: bsoctr opcode: bcctr - modifiers: [ LK ] - condition: BO == 12 && BI & 0b11 == 0b11 && crfS == 0 + condition: BO & 0b11110 == 12 && BI == 3 - name: bsoctr opcode: bcctr - modifiers: [ LK ] args: [ crfS ] - condition: BO == 12 && BI & 0b11 == 0b11 + condition: BO & 0b11110 == 12 && BI & 0b11 == 3 # bcctr branch if not summary overflow - name: bnsctr opcode: bcctr - modifiers: [ LK ] - condition: BO == 4 && BI & 0b11 == 0b11 && crfS == 0 + condition: BO & 0b11110 == 4 && BI == 3 - name: bnsctr opcode: bcctr - modifiers: [ LK ] args: [ crfS ] - condition: BO == 4 && BI & 0b11 == 0b11 + condition: BO & 0b11110 == 4 && BI & 0b11 == 3 # Branch Conditional to Link Register - # bclr branch always - name: blr opcode: bclr @@ -2426,80 +2447,92 @@ mnemonics: # bclr branch if negative - name: bltlr opcode: bclr - modifiers: [ LK ] - condition: BO == 12 && BI & 0b11 == 0b00 && crfS == 0 + condition: BO & 0b11110 == 12 && BI == 0 - name: bltlr opcode: bclr - modifiers: [ LK ] args: [ crfS ] - condition: BO == 12 && BI & 0b11 == 0b00 + condition: BO & 0b11110 == 12 && BI & 0b11 == 0 # bclr branch if not positive - name: blelr opcode: bclr - modifiers: [ LK ] - condition: BO == 4 && BI & 0b11 == 0b01 && crfS == 0 + condition: BO & 0b11110 == 4 && BI == 1 - name: blelr opcode: bclr - modifiers: [ LK ] args: [ crfS ] - condition: BO == 4 && BI & 0b11 == 0b01 + condition: BO & 0b11110 == 4 && BI & 0b11 == 1 # bclr branch if zero - name: beqlr opcode: bclr - modifiers: [ LK ] - condition: BO == 12 && BI & 0b11 == 0b10 && crfS == 0 + condition: BO & 0b11110 == 12 && BI == 2 - name: beqlr opcode: bclr - modifiers: [ LK ] args: [ crfS ] - condition: BO == 12 && BI & 0b11 == 0b10 + condition: BO & 0b11110 == 12 && BI & 0b11 == 2 # bclr branch if not negative - name: bgelr opcode: bclr - modifiers: [ LK ] - condition: BO == 4 && BI & 0b11 == 0b00 && crfS == 0 + condition: BO & 0b11110 == 4 && BI == 0 - name: bgelr opcode: bclr - modifiers: [ LK ] args: [ crfS ] - condition: BO == 4 && BI & 0b11 == 0b00 + condition: BO & 0b11110 == 4 && BI & 0b11 == 0 # bclr branch if positive - name: bgtlr opcode: bclr - modifiers: [ LK ] - condition: BO == 12 && BI & 0b11 == 0b01 && crfS == 0 + condition: BO & 0b11110 == 12 && BI == 1 - name: bgtlr opcode: bclr - modifiers: [ LK ] args: [ crfS ] - condition: BO == 12 && BI & 0b11 == 0b01 + condition: BO & 0b11110 == 12 && BI & 0b11 == 1 # bclr branch if not zero - name: bnelr opcode: bclr - modifiers: [ LK ] - condition: BO == 4 && BI & 0b11 == 0b10 && crfS == 0 + condition: BO & 0b11110 == 4 && BI == 2 - name: bnelr opcode: bclr - modifiers: [ LK ] args: [ crfS ] - condition: BO == 4 && BI & 0b11 == 0b10 + condition: BO & 0b11110 == 4 && BI & 0b11 == 2 # bclr branch if summary overflow - name: bsolr opcode: bclr - modifiers: [ LK ] - condition: BO == 12 && BI & 0b11 == 0b11 && crfS == 0 + condition: BO & 0b11110 == 12 && BI == 3 - name: bsolr opcode: bclr - modifiers: [ LK ] args: [ crfS ] - condition: BO == 12 && BI & 0b11 == 0b11 + condition: BO & 0b11110 == 12 && BI & 0b11 == 3 # bclr branch if not summary overflow - name: bnslr opcode: bclr - modifiers: [ LK ] - condition: BO == 4 && BI & 0b11 == 0b11 && crfS == 0 + condition: BO & 0b11110 == 4 && BI == 3 - name: bnslr opcode: bclr - modifiers: [ LK ] args: [ crfS ] - condition: BO == 4 && BI & 0b11 == 0b11 + condition: BO & 0b11110 == 4 && BI & 0b11 == 3 + # bclr decrement CTR, branch if CTR non-zero + - name: bdnzlr + opcode: bclr + condition: BO & 0b11110 == 16 && BI == 0 + # bclr decrement CTR, branch if CTR non-zero AND condition true + - name: bdnztlr + opcode: bclr + args: [ BI ] + condition: BO & 0b11110 == 8 + # bclr decrement CTR, branch if CTR non-zero AND condition false + - name: bdnzflr + opcode: bclr + args: [ BI ] + condition: BO & 0b11110 == 0 + # bclr decrement CTR, branch if CTR zero + - name: bdzlr + opcode: bclr + condition: BO & 0b11110 == 18 && BI == 0 + # bclr decrement CTR, branch if CTR zero AND condition true + - name: bdztlr + opcode: bclr + args: [ BI ] + condition: BO & 0b11110 == 10 + # bclr decrement CTR, branch if CTR zero AND condition false + - name: bdzflr + opcode: bclr + args: [ BI ] + condition: BO & 0b11110 == 0