From 31b97c00c38da0a2ad8995377ac36c9f7d0cbc60 Mon Sep 17 00:00:00 2001 From: iximeow Date: Mon, 7 Apr 2025 01:35:07 -0700 Subject: more tests and cleanup; sub, instruction labels, sfmpy additionally, AndNot should show its special assign mode if one is set. a few instructions have 64-bit register pairs that can be conjugated. vrmpywoh should have operands. :sat applied incompletely AndNot can have |=, &=, and ^= assign modes, not += had a sub with backwards operands --- notes/encoding_table | 4 +-- notes/reordered_encodings | 4 +-- src/display.rs | 28 ++++++++++++++++++-- src/lib.rs | 59 +++++++++++++++++++++++++++++++---------- 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) -> &'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) } diff --git a/src/lib.rs b/src/lib.rs index d58b4fe..fcffc1b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -324,6 +324,8 @@ struct InstFlags { branch_hint: Option, negated: bool, saturate: bool, + scale: bool, + library: bool, chop: bool, rounded: Option, threads: Option, @@ -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`. 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 { + operand_check!(num & 1 == 0); + Ok(Self::Gpr64bConjugate { reg_low: num }) + } + fn crpair(num: u8) -> Result { operand_check!(num & 1 == 0); Ok(Self::Cr64b { reg_low: num }) @@ -1360,6 +1373,8 @@ trait DecodeHandler::Address, ::Wor fn inst_predicated(&mut self, _num: u8, _negated: bool, _pred_new: bool) -> Result<(), ::DecodeError> { Ok(()) } fn negate_result(&mut self) -> Result<(), ::DecodeError> { Ok(()) } fn saturate(&mut self) -> Result<(), ::DecodeError> { Ok(()) } + fn scale(&mut self) -> Result<(), ::DecodeError> { Ok(()) } + fn library(&mut self) -> Result<(), ::DecodeError> { Ok(()) } fn branch_hint(&mut self, _hint_taken: bool) -> Result<(), ::DecodeError> { Ok(()) } fn domain_hint(&mut self, _domain: DomainHint) -> Result<(), ::DecodeError> { Ok(()) } fn rounded(&mut self, _mode: RoundingMode) -> Result<(), ::DecodeError> { Ok(()) } @@ -1423,7 +1438,18 @@ impl::Address, ::Word assert!(!flags.saturate); flags.saturate = true; Ok(()) - + } + fn scale(&mut self) -> Result<(), ::DecodeError> { + let flags = &mut self.instructions[self.instruction_count as usize].flags; + assert!(!flags.scale); + flags.scale = true; + Ok(()) + } + fn library(&mut self) -> Result<(), ::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<(), ::DecodeError> { let flags = &mut self.instructions[self.instruction_count as usize].flags; @@ -5956,12 +5982,12 @@ fn decode_instruction< // all of these may have `<> 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] -- cgit v1.1