diff options
-rw-r--r-- | notes/encoding_table | 4 | ||||
-rw-r--r-- | notes/reordered_encodings | 4 | ||||
-rw-r--r-- | src/display.rs | 28 | ||||
-rw-r--r-- | src/lib.rs | 59 | ||||
-rw-r--r-- | tests/from_brain.rs | 67 |
5 files changed, 142 insertions, 20 deletions
diff --git a/notes/encoding_table b/notes/encoding_table index 1e9c6f1..e2c2fba 100644 --- a/notes/encoding_table +++ b/notes/encoding_table @@ -1307,8 +1307,8 @@ A L I A S A L I A S A L I A S A L I A S A L I A S | Rd=zxtb(Rs) |1 1 1 0|1 0 1 0|0 0 0|s s s s s| P P |0 t t t t t|0 1 1|x x x x x| Rxx+=dfmpylh(Rss,Rtt) - XTYPE FP/slot 2,3 |1 1 1 0|1 0 1 0|1 0 0|s s s s s| P P |0 t t t t t|0 1 1|x x x x x| Rxx+=dfmpyhh(Rss,Rtt) - XTYPE FP/slot 2,3 -|1 1 1 0|1 1 1 1|0 0 0|s s s s s| P P |0 t t t t t|1 0 0|x x x x x| Rx+=sfmpy(Rss,Rtt) - XTYPE FP/slot 2,3 -|1 1 1 0|1 1 1 1|0 0 0|s s s s s| P P |0 t t t t t|1 0 1|x x x x x| Rx-=sfmpy(Rss,Rtt) - XTYPE FP/slot 2,3 +|1 1 1 0|1 1 1 1|0 0 0|s s s s s| P P |0 t t t t t|1 0 0|x x x x x| Rx+=sfmpy(Rs,Rt) - XTYPE FP/slot 2,3 +|1 1 1 0|1 1 1 1|0 0 0|s s s s s| P P |0 t t t t t|1 0 1|x x x x x| Rx-=sfmpy(Rs,Rt) - XTYPE FP/slot 2,3 |1 1 1 0|1 1 1 1|0 1 1|s s s s s| P P |0 t t t t t|1 u u|x x x x x| Rx+=sfmpy(Rs,Rt,Pu):scale - XTYPE FP/slot 2,3 diff --git a/notes/reordered_encodings b/notes/reordered_encodings index 135fbc8..ab8d5ee 100644 --- a/notes/reordered_encodings +++ b/notes/reordered_encodings @@ -1397,8 +1397,8 @@ A L I A S A L I A S A L I A S A L I A S A L I A S | Rd=zxtb(Rs) |1 1 1 0|1 1 1 1|0 0 0|s s s s s| P P |0 t t t t t|0 0 0|x x x x x| Rx+=mpyi(Rs,Rt) - XTYPE FP/slot 2,3 |1 1 1 0|1 1 1 1|0 0 0|s s s s s| P P |0 t t t t t|0 0 1|x x x x x| Rx+=add(Rs,Rt) - XTYPE ALU/slot 2,3 |1 1 1 0|1 1 1 1|0 0 0|s s s s s| P P |0 t t t t t|0 1 1|x x x x x| Rx+=sub(Rt,Rs) - XTYPE ALU/slot 2,3 -|1 1 1 0|1 1 1 1|0 0 0|s s s s s| P P |0 t t t t t|1 0 0|x x x x x| Rx+=sfmpy(Rss,Rtt) - XTYPE FP/slot 2,3 -|1 1 1 0|1 1 1 1|0 0 0|s s s s s| P P |0 t t t t t|1 0 1|x x x x x| Rx-=sfmpy(Rss,Rtt) - XTYPE FP/slot 2,3 +|1 1 1 0|1 1 1 1|0 0 0|s s s s s| P P |0 t t t t t|1 0 0|x x x x x| Rx+=sfmpy(Rs,Rt) - XTYPE FP/slot 2,3 +|1 1 1 0|1 1 1 1|0 0 0|s s s s s| P P |0 t t t t t|1 0 1|x x x x x| Rx-=sfmpy(Rs,Rt) - XTYPE FP/slot 2,3 |1 1 1 0|1 1 1 1|0 0 0|s s s s s| P P |0 t t t t t|1 1 0|x x x x x| Rx+=sfmpy(Rs,Rt):lib - XTYPE FP/slot 2,3 |1 1 1 0|1 1 1 1|0 0 0|s s s s s| P P |0 t t t t t|1 1 1|x x x x x| Rx-=sfmpy(Rs,Rt):lib - XTYPE FP/slot 2,3 |1 1 1 0|1 1 1 1|0 0 1|s s s s s| P P |0 t t t t t|0 0 0|x x x x x| Rx|=and(Rs,~Rt) - XTYPE ALU/slot 2,3 diff --git a/src/display.rs b/src/display.rs index babff2c..352ff3f 100644 --- a/src/display.rs +++ b/src/display.rs @@ -27,6 +27,19 @@ impl fmt::Display for InstructionPacket { } } +fn assign_mode_label(mode: Option<AssignMode>) -> &'static str { + match mode { + None => "=", + Some(AssignMode::AddAssign) => "+=", + Some(AssignMode::SubAssign) => "-=", + Some(AssignMode::AndAssign) => "&=", + Some(AssignMode::OrAssign) => "|=", + Some(AssignMode::XorAssign) => "^=", + Some(AssignMode::ClrBit) => "BUG", + Some(AssignMode::SetBit) => "BUG", + } +} + impl fmt::Display for Instruction { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { if special_display_rules(&self.opcode) { @@ -44,7 +57,8 @@ impl fmt::Display for Instruction { self.sources[0], self.sources[1], self.sources[2]); } Opcode::AndNot => { - return write!(f, "{} = and({}, !{})", self.dest.as_ref().unwrap(), + return write!(f, "{} {} and({}, ~{})", self.dest.as_ref().unwrap(), + assign_mode_label(self.flags.assign_mode), self.sources[0], self.sources[1]); } Opcode::OrOr => { @@ -64,7 +78,8 @@ impl fmt::Display for Instruction { self.sources[0], self.sources[1], self.sources[2]); } Opcode::OrNot => { - return write!(f, "{} = or({}, !{})", self.dest.as_ref().unwrap(), + return write!(f, "{} {} or({}, !{})", self.dest.as_ref().unwrap(), + assign_mode_label(self.flags.assign_mode), self.sources[0], self.sources[1]); } Opcode::OrOrNot => { @@ -398,6 +413,12 @@ impl fmt::Display for Instruction { f.write_str(":sat")?; } } + if self.flags.scale { + f.write_str(":scale")?; + } + if self.flags.library { + f.write_str(":lib")?; + } if self.flags.deprecated { f.write_str(":deprecated")?; } @@ -894,6 +915,9 @@ impl fmt::Display for Operand { Operand::Gpr64b { reg_low } => { write!(f, "R{}:{}", reg_low + 1, reg_low) } + Operand::Gpr64bConjugate { reg_low } => { + write!(f, "R{}:{}*", reg_low + 1, reg_low) + } Operand::Cr64b { reg_low } => { write!(f, "C{}:{}", reg_low + 1, reg_low) } @@ -324,6 +324,8 @@ struct InstFlags { branch_hint: Option<BranchHint>, negated: bool, saturate: bool, + scale: bool, + library: bool, chop: bool, rounded: Option<RoundingMode>, threads: Option<DomainHint>, @@ -348,6 +350,8 @@ impl Default for InstFlags { branch_hint: None, negated: false, saturate: false, + scale: false, + library: false, chop: false, rounded: None, threads: None, @@ -1134,7 +1138,7 @@ pub enum Operand { /// the complex conjugate of `R<reg>`. this is only used in a few instructions performing /// complex multiplies, and is displayed as `Rn*`. GprConjugate { reg: u8 }, - /// `Rn:m`, register pair forming a 64-bit location + /// `Rn:m`, register pair forming a 64-bit value /// /// V73 Section 2.1: /// > the general registers can be specified as a pair that represent a single 64-bit register. @@ -1144,6 +1148,10 @@ pub enum Operand { /// /// from Table 2-2, note there is an entry of `R31:R30 (LR:FP)` Gpr64b { reg_low: u8 }, + /// `Rn:m*`, a register pair interpreted as a complex number, conjugated + /// + /// this is only used for forms of `cmpy*w` + Gpr64bConjugate { reg_low: u8 }, /// `Cn:m`, control register pair forming a 64-bit location Cr64b { reg_low: u8 }, /// `Sn:m`, control register pair forming a 64-bit location @@ -1231,6 +1239,11 @@ impl Operand { Ok(Self::Gpr64b { reg_low: num }) } + fn gprpair_conjugate(num: u8) -> Result<Self, yaxpeax_arch::StandardDecodeError> { + operand_check!(num & 1 == 0); + Ok(Self::Gpr64bConjugate { reg_low: num }) + } + fn crpair(num: u8) -> Result<Self, yaxpeax_arch::StandardDecodeError> { operand_check!(num & 1 == 0); Ok(Self::Cr64b { reg_low: num }) @@ -1360,6 +1373,8 @@ trait DecodeHandler<T: Reader<<Hexagon as Arch>::Address, <Hexagon as Arch>::Wor fn inst_predicated(&mut self, _num: u8, _negated: bool, _pred_new: bool) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) } fn negate_result(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) } fn saturate(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) } + fn scale(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) } + fn library(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) } fn branch_hint(&mut self, _hint_taken: bool) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) } fn domain_hint(&mut self, _domain: DomainHint) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) } fn rounded(&mut self, _mode: RoundingMode) -> Result<(), <Hexagon as Arch>::DecodeError> { Ok(()) } @@ -1423,7 +1438,18 @@ impl<T: yaxpeax_arch::Reader<<Hexagon as Arch>::Address, <Hexagon as Arch>::Word assert!(!flags.saturate); flags.saturate = true; Ok(()) - + } + fn scale(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> { + let flags = &mut self.instructions[self.instruction_count as usize].flags; + assert!(!flags.scale); + flags.scale = true; + Ok(()) + } + fn library(&mut self) -> Result<(), <Hexagon as Arch>::DecodeError> { + let flags = &mut self.instructions[self.instruction_count as usize].flags; + assert!(!flags.scale); + flags.library = true; + Ok(()) } fn branch_hint(&mut self, hint_taken: bool) -> Result<(), <Hexagon as Arch>::DecodeError> { let flags = &mut self.instructions[self.instruction_count as usize].flags; @@ -5956,12 +5982,12 @@ fn decode_instruction< // all of these may have `<<N`, though some are only valid with `<<1`. let n = (op_hi >> 2) & 1; handler.shift_left(n)?; + handler.on_source_decoded(Operand::gprpair(sssss)?)?; + handler.on_source_decoded(Operand::gprpair(ttttt)?)?; + if op_lo == 0b010 && op_hi & 0b011 == 0b001 { handler.on_opcode_decoded(Vrmpywoh)?; } else { - handler.on_source_decoded(Operand::gprpair(sssss)?)?; - handler.on_source_decoded(Operand::gprpair(ttttt)?)?; - let opc = (op_lo & 0b11) | ((op_hi & 0b11) << 2); match opc { 0b0000 => { @@ -6051,17 +6077,17 @@ fn decode_instruction< let opc = (op_lo & 0b11) | (op_hi << 2); handler.on_opcode_decoded(decode_opcode!(OPCODES[opc as usize]))?; - if opc == 0b0101 { + if opc == 0b0101 || opc == 0b10101 { handler.saturate()?; } + eprintln!("ok op_lo: {:02b}, opc: {:05b}", op_lo, opc); if (op_lo & 0b11) == 0b00 { handler.on_source_decoded(Operand::gprpair(ttttt)?)?; handler.on_source_decoded(Operand::gprpair(sssss)?)?; - } else if opc == 0b1010 || opc == 0b1110 { - // cmpyiw(Rss,Rtt*) + } else if opc == 0b11010 || opc == 0b11110 { handler.on_source_decoded(Operand::gprpair(sssss)?)?; - // TODO: Rtt*? + handler.on_source_decoded(Operand::gprpair_conjugate(ttttt)?)?; } else { handler.on_source_decoded(Operand::gprpair(sssss)?)?; handler.on_source_decoded(Operand::gprpair(ttttt)?)?; @@ -6504,7 +6530,7 @@ fn decode_instruction< Some((AddAssign, Mpyi)), Some((AddAssign, Add)), None, Some((AddAssign, Sub)), Some((AddAssign, SfMpy)), Some((SubAssign, SfMpy)), Some((AddAssign, SfMpy)), Some((SubAssign, SfMpy)), // 001_000 - Some((OrAssign, AndNot)), Some((AddAssign, AndNot)), Some((XorAssign, AndNot)), None, + Some((OrAssign, AndNot)), Some((AndAssign, AndNot)), Some((XorAssign, AndNot)), None, None, None, None, None, // 010_000 Some((AndAssign, And)), Some((AndAssign, Or)), Some((AndAssign, Xor)), Some((OrAssign, And)), @@ -6529,21 +6555,26 @@ fn decode_instruction< let (assign_mode, opcode) = decode_operand!(OPCODES[opc as usize]); handler.on_opcode_decoded(opcode)?; handler.assign_mode(assign_mode)?; + handler.on_dest_decoded(Operand::gpr(ddddd))?; - if opc == 0b000100 || opc == 0b000101 { - handler.on_source_decoded(Operand::gprpair(sssss)?)?; - handler.on_source_decoded(Operand::gprpair(ttttt)?)?; + if opcode == Opcode::Sub { + handler.on_source_decoded(Operand::gpr(ttttt))?; + handler.on_source_decoded(Operand::gpr(sssss))?; } else { handler.on_source_decoded(Operand::gpr(sssss))?; handler.on_source_decoded(Operand::gpr(ttttt))?; } + if opc == 0b000110 || opc == 0b000111 { + handler.library()?; + } + if opc == 0b011000 || opc == 0b011001 { handler.shift_left(1)?; handler.saturate()?; } else if opc >= 0b011100 && opc < 0b100000 { handler.on_source_decoded(Operand::pred(op_lo & 0b11))?; - // TODO: :scale? + handler.scale()?; } } } diff --git a/tests/from_brain.rs b/tests/from_brain.rs index a715e9f..dae984f 100644 --- a/tests/from_brain.rs +++ b/tests/from_brain.rs @@ -1539,6 +1539,73 @@ fn inst_1110() { test_display(&0b1110_0111_110_10100_11_000110_110_10110u32.to_le_bytes(), "{ R23:22 += cmpy(R20, R6*):<<1:sat }"); test_display(&0b1110_0111_100_10100_11_000110_111_10110u32.to_le_bytes(), "{ R23:22 -= cmpy(R20, R6):<<1:sat }"); test_display(&0b1110_0111_110_10100_11_000110_111_10110u32.to_le_bytes(), "{ R23:22 -= cmpy(R20, R6*):<<1:sat }"); + + test_display(&0b1110_1000_000_10100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 = vrmpyh(R21:20, R7:6) }"); + test_display(&0b1110_1000_000_10100_11_000110_011_10110u32.to_le_bytes(), "{ R23:22 = dfadd(R21:20, R7:6) }"); + test_display(&0b1110_1000_001_10100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 = vabsdiffw(R7:6, R21:20) }"); + test_display(&0b1110_1000_001_10100_11_000110_011_10110u32.to_le_bytes(), "{ R23:22 = dfmax(R21:20, R7:6) }"); + test_display(&0b1110_1000_010_10100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 = vraddub(R21:20, R7:6) }"); + test_display(&0b1110_1000_010_10100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 = vrsadub(R21:20, R7:6) }"); + test_display(&0b1110_1000_010_10100_11_000110_011_10110u32.to_le_bytes(), "{ R23:22 = dfmpyfix(R21:20, R7:6) }"); + test_display(&0b1110_1000_011_10100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 = vabsdiffh(R7:6, R21:20) }"); + test_display(&0b1110_1000_011_10100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 = cmpyiw(R21:20, R7:6) }"); + test_display(&0b1110_1000_100_10100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 = vrmpyu(R21:20, R7:6) }"); + test_display(&0b1110_1000_100_10100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 = cmpyrw(R21:20, R7:6) }"); + test_display(&0b1110_1000_100_10100_11_000110_011_10110u32.to_le_bytes(), "{ R23:22 = dfsub(R21:20, R7:6) }"); + test_display(&0b1110_1000_101_10100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 = vabsdiffub(R7:6, R21:20) }"); + test_display(&0b1110_1000_101_10100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 = vdmpybsu(R21:20, R7:6):sat }"); + test_display(&0b1110_1000_101_10100_11_000110_011_10110u32.to_le_bytes(), "{ R23:22 = dfmpyll(R21:20, R7:6) }"); + test_display(&0b1110_1000_110_10100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 = vrmpysu(R21:20, R7:6) }"); + test_display(&0b1110_1000_110_10100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 = cmpyrw(R21:20, R7:6*) }"); + test_display(&0b1110_1000_110_10100_11_000110_011_10110u32.to_le_bytes(), "{ R23:22 = dfmin(R21:20, R7:6) }"); + test_display(&0b1110_1000_111_10100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 = vabsdiffb(R7:6, R21:20) }"); + test_display(&0b1110_1000_111_10100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 = cmpyiw(R21:20, R7:6*) }"); + test_display(&0b1110_1000_101_10100_11_000110_100_10110u32.to_le_bytes(), "{ R23:22 = vrcmpys(R21:20, R7:6):<<1:sat:raw:hi }"); + test_display(&0b1110_1000_111_10100_11_000110_100_10110u32.to_le_bytes(), "{ R23:22 = vrcmpys(R21:20, R7:6):<<1:sat:raw:lo }"); + + /* + test_display(&0b1110_1000_000_10100_11_000110_100_10110u32.to_le_bytes(), "{ R23:22 = vdmpy(R21:20, R7:6):sat }"); + test_display(&0b1110_1000_000_10100_11_000110_101_10110u32.to_le_bytes(), "{ R23:22 = vmpyweh(R21:20, R7:6):sat }"); + test_display(&0b1110_1000_000_10100_11_000110_110_10110u32.to_le_bytes(), "{ R23:22 = vmpyeh(R21:20, R7:6):sat }"); + test_display(&0b1110_1000_000_10100_11_000110_111_10110u32.to_le_bytes(), "{ R23:22 = vmpywoh(R21:20, R7:6):sat }"); + test_display(&0b1110_1000_001_10100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 = vrmpywoh(R21:20, R7:6) }"); + test_display(&0b1110_1000_001_10100_11_000110_101_10110u32.to_le_bytes(), "{ R23:22 = vmpyweh(R21:20, R7:6):rnd:sat }"); + test_display(&0b1110_1000_001_10100_11_000110_110_10110u32.to_le_bytes(), "{ R23:22 = vcmpyr(R21:20, R7:6):sat }"); + test_display(&0b1110_1000_001_10100_11_000110_111_10110u32.to_le_bytes(), "{ R23:22 = vmpywoh(R21:20, R7:6):rnd:sat }"); + test_display(&0b1110_1000_010_10100_11_000110_100_10110u32.to_le_bytes(), "{ R23:22 = vrmpywoh(R21:20, R7:6) }"); + test_display(&0b1110_1000_010_10100_11_000110_101_10110u32.to_le_bytes(), "{ R23:22 = vmpyweuh(R21:20, R7:6):sat }"); + test_display(&0b1110_1000_010_10100_11_000110_110_10110u32.to_le_bytes(), "{ R23:22 = vcmpyi(R21:20, R7:6):sat }"); + test_display(&0b1110_1000_010_10100_11_000110_111_10110u32.to_le_bytes(), "{ R23:22 = vmpywouh(R21:20, R7:6):sat }"); + test_display(&0b1110_1000_011_10100_11_000110_101_10110u32.to_le_bytes(), "{ R23:22 = vmpyweuh(R21:20, R7:6):rnd:sat }"); + test_display(&0b1110_1000_011_10100_11_000110_111_10110u32.to_le_bytes(), "{ R23:22 = vmpywouh(R21:20, R7:6):rnd:sat }"); + */ + + test_display(&0b1110_1111_000_10100_11_000110_000_10110u32.to_le_bytes(), "{ R22 += mpyi(R20, R6) }"); + test_display(&0b1110_1111_000_10100_11_000110_001_10110u32.to_le_bytes(), "{ R22 += add(R20, R6) }"); + test_invalid(&0b1110_1111_000_10100_11_000110_010_10110u32.to_le_bytes(), DecodeError::InvalidOperand); + test_display(&0b1110_1111_000_10100_11_000110_011_10110u32.to_le_bytes(), "{ R22 += sub(R6, R20) }"); + test_display(&0b1110_1111_000_10100_11_000110_100_10110u32.to_le_bytes(), "{ R22 += sfmpy(R20, R6) }"); + test_display(&0b1110_1111_000_10100_11_000110_101_10110u32.to_le_bytes(), "{ R22 -= sfmpy(R20, R6) }"); + test_display(&0b1110_1111_000_10100_11_000110_110_10110u32.to_le_bytes(), "{ R22 += sfmpy(R20, R6):lib }"); + test_display(&0b1110_1111_000_10100_11_000110_111_10110u32.to_le_bytes(), "{ R22 -= sfmpy(R20, R6):lib }"); + test_display(&0b1110_1111_001_10100_11_000110_000_10110u32.to_le_bytes(), "{ R22 |= and(R20, ~R6) }"); + test_display(&0b1110_1111_001_10100_11_000110_001_10110u32.to_le_bytes(), "{ R22 &= and(R20, ~R6) }"); + test_display(&0b1110_1111_001_10100_11_000110_010_10110u32.to_le_bytes(), "{ R22 ^= and(R20, ~R6) }"); + test_display(&0b1110_1111_010_10100_11_000110_000_10110u32.to_le_bytes(), "{ R22 &= and(R20, R6) }"); + test_display(&0b1110_1111_010_10100_11_000110_001_10110u32.to_le_bytes(), "{ R22 &= or(R20, R6) }"); + test_display(&0b1110_1111_010_10100_11_000110_010_10110u32.to_le_bytes(), "{ R22 &= xor(R20, R6) }"); + test_display(&0b1110_1111_010_10100_11_000110_011_10110u32.to_le_bytes(), "{ R22 |= and(R20, R6) }"); + test_display(&0b1110_1111_011_10100_11_000110_000_10110u32.to_le_bytes(), "{ R22 += mpy(R20, R6):<<1:sat }"); + test_display(&0b1110_1111_011_10100_11_000110_001_10110u32.to_le_bytes(), "{ R22 -= mpy(R20, R6):<<1:sat }"); + test_display(&0b1110_1111_011_10100_11_000110_101_10110u32.to_le_bytes(), "{ R22 += sfmpy(R20, R6, P1):scale }"); + test_display(&0b1110_1111_100_10100_11_000110_000_10110u32.to_le_bytes(), "{ R22 -= mpyi(R20, R6) }"); + test_display(&0b1110_1111_100_10100_11_000110_001_10110u32.to_le_bytes(), "{ R22 -= add(R20, R6) }"); + test_invalid(&0b1110_1111_100_10100_11_000110_010_10110u32.to_le_bytes(), DecodeError::InvalidOperand); + test_display(&0b1110_1111_100_10100_11_000110_011_10110u32.to_le_bytes(), "{ R22 ^= xor(R20, R6) }"); + test_display(&0b1110_1111_110_10100_11_000110_000_10110u32.to_le_bytes(), "{ R22 |= or(R20, R6) }"); + test_display(&0b1110_1111_110_10100_11_000110_001_10110u32.to_le_bytes(), "{ R22 |= xor(R20, R6) }"); + test_display(&0b1110_1111_110_10100_11_000110_010_10110u32.to_le_bytes(), "{ R22 ^= and(R20, R6) }"); + test_display(&0b1110_1111_110_10100_11_000110_011_10110u32.to_le_bytes(), "{ R22 ^= or(R20, R6) }"); } #[test] |