summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/display.rs21
-rw-r--r--src/lib.rs42
-rw-r--r--tests/from_brain.rs119
3 files changed, 156 insertions, 26 deletions
diff --git a/src/display.rs b/src/display.rs
index ad21cdd..309781b 100644
--- a/src/display.rs
+++ b/src/display.rs
@@ -107,6 +107,10 @@ impl fmt::Display for Instruction {
return write!(f, "{} = or({}, asl({}, {}))", self.dest.as_ref().unwrap(),
self.sources[0], self.sources[1], self.sources[2]);
},
+ Opcode::AddMpyi => {
+ return write!(f, "{} = add({}, mpyi({}, {}))", self.dest.as_ref().unwrap(),
+ self.sources[0], self.sources[1], self.sources[2]);
+ },
Opcode::AddClb => {
return write!(f, "{} = add(clb({}), {})", self.dest.as_ref().unwrap(),
self.sources[0], self.sources[1]);
@@ -345,6 +349,15 @@ impl fmt::Display for Instruction {
if self.flags.saturate {
f.write_str(":sat")?;
}
+ if let Some(shift) = self.flags.shift_left {
+ write!(f, ":<<{}", shift)?;
+ }
+ if let Some(shift) = self.flags.shift_right {
+ write!(f, ":>>{}", shift)?;
+ }
+ if self.flags.deprecated {
+ f.write_str(":deprecated")?;
+ }
match self.flags.branch_hint {
Some(BranchHint::Taken) => { f.write_str(":t")? },
Some(BranchHint::NotTaken) => { f.write_str(":nt")? },
@@ -430,11 +443,11 @@ impl fmt::Display for Opcode {
Opcode::Add => { f.write_str("add") },
Opcode::And => { f.write_str("and") },
Opcode::And_nRR => { f.write_str("and") },
- Opcode::And_RnR => { f.write_str("and_RnR") },
+ Opcode::And_RnR => { f.write_str("and") },
Opcode::Sub => { f.write_str("sub") },
Opcode::Or => { f.write_str("or") },
Opcode::Or_nRR => { f.write_str("or") },
- Opcode::Or_RnR => { f.write_str("or_RnR") },
+ Opcode::Or_RnR => { f.write_str("or") },
Opcode::Xor => { f.write_str("xor") },
Opcode::Contains => { f.write_str("contains") },
@@ -580,6 +593,7 @@ impl fmt::Display for Opcode {
Opcode::Vminuw => { f.write_str("vminuw") },
Opcode::Vminh => { f.write_str("vminh") },
Opcode::Vminuh => { f.write_str("vminuh") },
+ Opcode::Vminw => { f.write_str("vminw") },
Opcode::Vmaxw => { f.write_str("vmaxw") },
Opcode::Vmaxuw => { f.write_str("vmaxuw") },
Opcode::Vmaxh => { f.write_str("vmaxh") },
@@ -601,6 +615,7 @@ impl fmt::Display for Opcode {
Opcode::Vsubuh => { f.write_str("vsubuh") },
Opcode::Vavgh => { f.write_str("vavgh") },
Opcode::Vnavgh => { f.write_str("vnavgh") },
+ Opcode::Vnavgw => { f.write_str("vnavgw") },
Opcode::Packhl => { f.write_str("packhl") },
Opcode::DcCleanA => { f.write_str("dccleana") },
@@ -751,7 +766,7 @@ impl fmt::Display for Opcode {
Opcode::SfFixupn => { f.write_str("sffixupn") },
Opcode::SfFixupd => { f.write_str("sffixupd") },
Opcode::SfRecipa => { f.write_str("sfrecipa") },
- Opcode::Swiz => { f.write_str("Swiz") },
+ Opcode::Swiz => { f.write_str("swiz") },
Opcode::Shuffeb => { f.write_str("shuffeb") },
Opcode::Shuffob => { f.write_str("shuffob") },
Opcode::Shuffeh => { f.write_str("shuffeh") },
diff --git a/src/lib.rs b/src/lib.rs
index 4806a7e..c9b2bb0 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -637,6 +637,7 @@ pub enum Opcode {
Vavgh,
Vavguh,
Vnavgh,
+ Vnavgw,
Packhl,
@@ -706,6 +707,7 @@ pub enum Opcode {
Vminuw,
Vminh,
Vminuh,
+ Vminw,
Vmaxw,
Vmaxuw,
Vmaxh,
@@ -4488,14 +4490,14 @@ fn decode_instruction<
match op_hi {
0b00 => {
- static OPCODES: [Opcode; 4] = [
- Opcode::Extractu, Opcode::Shuffeb,
- Opcode::Shuffob, Opcode::Shuffeh
+ static OPCODES: [Opcode; 8] = [
+ Opcode::Extractu, Opcode::Extractu, Opcode::Shuffeb, Opcode::Shuffeb,
+ Opcode::Shuffob, Opcode::Shuffob, Opcode::Shuffeh, Opcode::Shuffeh,
];
handler.on_opcode_decoded(OPCODES[op_lo as usize])?;
handler.on_dest_decoded(Operand::gprpair(ddddd)?)?;
- if op_lo < 0b10 {
+ if op_lo < 0b100 {
handler.on_source_decoded(Operand::gprpair(sssss)?)?;
handler.on_source_decoded(Operand::gprpair(ttttt)?)?;
} else {
@@ -5143,7 +5145,7 @@ fn decode_instruction<
do_decode_dst(handler, Opcode::Vavguw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
}
0b011100 => {
- do_decode_dst(handler, Opcode::Vavgw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
+ do_decode_dst(handler, Opcode::Vavguw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
handler.rounded(RoundingMode::Round)?;
}
0b011101 => {
@@ -5159,30 +5161,30 @@ fn decode_instruction<
handler.raw_mode(RawMode::Hi)?;
}
0b100000 => {
- do_decode_dst(handler, Opcode::Vnavgh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
+ do_decode_dts(handler, Opcode::Vnavgh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
}
0b100001 => {
- do_decode_dst(handler, Opcode::Vnavgh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
+ do_decode_dts(handler, Opcode::Vnavgh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
handler.rounded(RoundingMode::Round)?;
handler.saturate()?;
}
0b100010 => {
- do_decode_dst(handler, Opcode::Vnavgh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
+ do_decode_dts(handler, Opcode::Vnavgh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
handler.rounded(RoundingMode::Cround)?;
handler.saturate()?;
}
0b100011 => {
- do_decode_dst(handler, Opcode::Vnavgh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
+ do_decode_dts(handler, Opcode::Vnavgw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
}
// low bit of opc is `-`
0b100100 | 0b100101 => {
- do_decode_dst(handler, Opcode::Vnavgh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
+ do_decode_dts(handler, Opcode::Vnavgw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
handler.rounded(RoundingMode::Round)?;
handler.saturate()?;
}
// low bit of opc is `-`
0b100110 | 0b100111 => {
- do_decode_dst(handler, Opcode::Vnavgh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
+ do_decode_dts(handler, Opcode::Vnavgw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
handler.rounded(RoundingMode::Cround)?;
handler.saturate()?;
}
@@ -5196,7 +5198,7 @@ fn decode_instruction<
do_decode_dts(handler, Opcode::Vminuh, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
}
0b101011 => {
- do_decode_dts(handler, Opcode::Vminuw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
+ do_decode_dts(handler, Opcode::Vminw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
}
0b101100 => {
do_decode_dts(handler, Opcode::Vminuw, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
@@ -5238,13 +5240,13 @@ fn decode_instruction<
do_decode_dst(handler, Opcode::And, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
}
0b111001 => {
- do_decode_dst(handler, Opcode::AndNot, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
+ do_decode_dst(handler, Opcode::And_RnR, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
}
0b111010 => {
do_decode_dst(handler, Opcode::Or, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
}
0b111011 => {
- do_decode_dst(handler, Opcode::OrNot, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
+ do_decode_dst(handler, Opcode::Or_RnR, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
}
0b111100 => {
do_decode_dst(handler, Opcode::Xor, Operand::gprpair, Operand::gprpair, Operand::gprpair)?;
@@ -5301,7 +5303,7 @@ fn decode_instruction<
if shl {
// 1101|0101|X1X|sssss|PP|-ttttt|xxx|ddddd
- handler.shift_left(1)?;
+ handler.shift_left(16)?;
if op_lo & 0b010 == 0 {
handler.on_source_decoded(Operand::gpr_low(ttttt))?;
} else {
@@ -5323,14 +5325,15 @@ fn decode_instruction<
}
} else {
handler.on_dest_decoded(Operand::gpr(ddddd))?;
- if op_hi == 0b001 {
+ let op = ((inst >> 7) & 1) | (op_hi & 0b11) << 1;
+ if op == 0b001 {
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))?;
}
- match op_hi {
+ match op {
0b000 => {
handler.on_opcode_decoded(Opcode::Add)?;
handler.saturate()?;
@@ -5377,7 +5380,6 @@ fn decode_instruction<
} else {
handler.rounded(RoundingMode::Neg)?;
}
- panic!("SfMake");
} else {
opcode_check!(op_hi == 0b111);
static OPCODES: [Option<Opcode>; 8] = [
@@ -5386,7 +5388,7 @@ fn decode_instruction<
];
handler.on_opcode_decoded(decode_opcode!(OPCODES[op_lo as usize]))?;
- handler.on_dest_decoded(Operand::gpr(reg_b0(inst)))?;
+ handler.on_dest_decoded(Operand::pred(reg_b0(inst) & 0b11))?;
handler.on_source_decoded(Operand::gprpair(reg_b16(inst))?)?;
handler.on_source_decoded(Operand::gprpair(reg_b8(inst))?)?;
}
@@ -5397,6 +5399,8 @@ fn decode_instruction<
let ttttt = reg_b8(inst);
let sssss = reg_b16(inst);
+ opcode_check!(inst & 0x80_00_00 == 0);
+
let i_lo = (inst >> 5) & 0b111;
let i_mid = (inst >> 13) & 0b1;
let i_hi = (inst >> 21) & 0b11;
diff --git a/tests/from_brain.rs b/tests/from_brain.rs
index eb7624e..644195d 100644
--- a/tests/from_brain.rs
+++ b/tests/from_brain.rs
@@ -1045,10 +1045,10 @@ fn inst_1011() {
fn inst_1100() {
test_display(&0b1100_0000_000_00100_11_0_1_0000_010_10110u32.to_le_bytes(), "{ R23:22 = valignb(R17:16, R5:4, #0x2) }");
test_display(&0b1100_0000_100_00100_11_0_1_0000_010_10110u32.to_le_bytes(), "{ R23:22 = vspliceb(R5:4, R17:16, #0x2) }");
-// test_display(&0b1100_0001_000_00100_11_0_1_0000_000_10110u32.to_le_bytes(), "{ R23:22 = extractu(R5:4, R17:16) }");
-// test_display(&0b1100_0001_000_00100_11_0_1_0000_010_10110u32.to_le_bytes(), "{ R23:22 = shuffeb(R5:4, R17:16) }");
-// test_display(&0b1100_0001_000_00100_11_0_1_0000_100_10110u32.to_le_bytes(), "{ R23:22 = shuffob(R17:16, R5:4) }");
-// test_display(&0b1100_0001_000_00100_11_0_1_0000_110_10110u32.to_le_bytes(), "{ R23:22 = shuffeh(R17:16, R5:4) }");
+ test_display(&0b1100_0001_000_00100_11_0_1_0000_000_10110u32.to_le_bytes(), "{ R23:22 = extractu(R5:4, R17:16) }");
+ test_display(&0b1100_0001_000_00100_11_0_1_0000_010_10110u32.to_le_bytes(), "{ R23:22 = shuffeb(R5:4, R17:16) }");
+ test_display(&0b1100_0001_000_00100_11_0_1_0000_100_10110u32.to_le_bytes(), "{ R23:22 = shuffob(R17:16, R5:4) }");
+ test_display(&0b1100_0001_000_00100_11_0_1_0000_110_10110u32.to_le_bytes(), "{ R23:22 = shuffeh(R17:16, R5:4) }");
// test_display(&0b1100_0011110_10100_11_000110_011_10110u32.to_le_bytes(), "{ R23:22 = vcnegh(R21:20, R6) }");
@@ -1121,6 +1121,117 @@ fn inst_1101() {
test_display(&0b1101_0010_100_10100_11_100110_000_10110u32.to_le_bytes(), "{ P2 = cmp.gt(R21:20, R7:6) }");
test_display(&0b1101_0010_100_10100_11_100110_010_10110u32.to_le_bytes(), "{ P2 = cmp.eq(R21:20, R7:6) }");
test_display(&0b1101_0010_100_10100_11_100110_100_10110u32.to_le_bytes(), "{ P2 = cmp.gtu(R21:20, R7:6) }");
+
+ test_display(&0b1101_0011_000_10100_11_100110_000_10110u32.to_le_bytes(), "{ R23:22 = vaddub(R21:20, R7:6) }");
+ test_display(&0b1101_0011_000_10100_11_100110_001_10110u32.to_le_bytes(), "{ R23:22 = vaddub(R21:20, R7:6):sat }");
+ test_display(&0b1101_0011_000_10100_11_100110_010_10110u32.to_le_bytes(), "{ R23:22 = vaddh(R21:20, R7:6) }");
+ test_display(&0b1101_0011_000_10100_11_100110_011_10110u32.to_le_bytes(), "{ R23:22 = vaddh(R21:20, R7:6):sat }");
+ test_display(&0b1101_0011_000_10100_11_100110_100_10110u32.to_le_bytes(), "{ R23:22 = vadduh(R21:20, R7:6):sat }");
+ test_display(&0b1101_0011_000_10100_11_100110_101_10110u32.to_le_bytes(), "{ R23:22 = vaddw(R21:20, R7:6) }");
+ test_display(&0b1101_0011_000_10100_11_100110_110_10110u32.to_le_bytes(), "{ R23:22 = vaddw(R21:20, R7:6):sat }");
+ test_display(&0b1101_0011_000_10100_11_100110_111_10110u32.to_le_bytes(), "{ R23:22 = add(R21:20, R7:6) }");
+ test_display(&0b1101_0011_001_10100_11_100110_000_10110u32.to_le_bytes(), "{ R23:22 = vsubub(R7:6, R21:20) }");
+ test_display(&0b1101_0011_001_10100_11_100110_001_10110u32.to_le_bytes(), "{ R23:22 = vsubub(R7:6, R21:20):sat }");
+ test_display(&0b1101_0011_001_10100_11_100110_010_10110u32.to_le_bytes(), "{ R23:22 = vsubh(R7:6, R21:20) }");
+ test_display(&0b1101_0011_001_10100_11_100110_011_10110u32.to_le_bytes(), "{ R23:22 = vsubh(R7:6, R21:20):sat }");
+ test_display(&0b1101_0011_001_10100_11_100110_100_10110u32.to_le_bytes(), "{ R23:22 = vsubuh(R7:6, R21:20):sat }");
+ test_display(&0b1101_0011_001_10100_11_100110_101_10110u32.to_le_bytes(), "{ R23:22 = vsubw(R7:6, R21:20) }");
+ test_display(&0b1101_0011_001_10100_11_100110_110_10110u32.to_le_bytes(), "{ R23:22 = vsubw(R7:6, R21:20):sat }");
+ test_display(&0b1101_0011_001_10100_11_100110_111_10110u32.to_le_bytes(), "{ R23:22 = sub(R7:6, R21:20) }");
+
+ test_display(&0b1101_0011_010_10100_11_100110_000_10110u32.to_le_bytes(), "{ R23:22 = vavgub(R21:20, R7:6) }");
+ test_display(&0b1101_0011_010_10100_11_100110_001_10110u32.to_le_bytes(), "{ R23:22 = vavgub(R21:20, R7:6):rnd }");
+ test_display(&0b1101_0011_010_10100_11_100110_010_10110u32.to_le_bytes(), "{ R23:22 = vavgh(R21:20, R7:6) }");
+ test_display(&0b1101_0011_010_10100_11_100110_011_10110u32.to_le_bytes(), "{ R23:22 = vavgh(R21:20, R7:6):rnd }");
+ test_display(&0b1101_0011_010_10100_11_100110_100_10110u32.to_le_bytes(), "{ R23:22 = vavgh(R21:20, R7:6):crnd }");
+ test_display(&0b1101_0011_010_10100_11_100110_101_10110u32.to_le_bytes(), "{ R23:22 = vavguh(R21:20, R7:6) }");
+ test_display(&0b1101_0011_010_10100_11_100110_110_10110u32.to_le_bytes(), "{ R23:22 = vavguh(R21:20, R7:6):rnd }");
+
+ test_display(&0b1101_0011_011_10100_11_100110_000_10110u32.to_le_bytes(), "{ R23:22 = vavgw(R21:20, R7:6) }");
+ test_display(&0b1101_0011_011_10100_11_100110_001_10110u32.to_le_bytes(), "{ R23:22 = vavgw(R21:20, R7:6):rnd }");
+ test_display(&0b1101_0011_011_10100_11_100110_010_10110u32.to_le_bytes(), "{ R23:22 = vavgw(R21:20, R7:6):crnd }");
+ test_display(&0b1101_0011_011_10100_11_100110_011_10110u32.to_le_bytes(), "{ R23:22 = vavguw(R21:20, R7:6) }");
+ test_display(&0b1101_0011_011_10100_11_100110_100_10110u32.to_le_bytes(), "{ R23:22 = vavguw(R21:20, R7:6):rnd }");
+ test_display(&0b1101_0011_011_10100_11_100110_101_10110u32.to_le_bytes(), "{ R23:22 = add(R21:20, R7:6):sat }");
+ test_display(&0b1101_0011_011_10100_11_100110_110_10110u32.to_le_bytes(), "{ R23:22 = add(R21:20, R7:6):raw:lo }");
+ test_display(&0b1101_0011_011_10100_11_100110_111_10110u32.to_le_bytes(), "{ R23:22 = add(R21:20, R7:6):raw:hi }");
+
+ test_display(&0b1101_0011_100_10100_11_100110_000_10110u32.to_le_bytes(), "{ R23:22 = vnavgh(R7:6, R21:20) }");
+ test_display(&0b1101_0011_100_10100_11_100110_001_10110u32.to_le_bytes(), "{ R23:22 = vnavgh(R7:6, R21:20):rnd:sat }");
+ test_display(&0b1101_0011_100_10100_11_100110_010_10110u32.to_le_bytes(), "{ R23:22 = vnavgh(R7:6, R21:20):crnd:sat }");
+ test_display(&0b1101_0011_100_10100_11_100110_011_10110u32.to_le_bytes(), "{ R23:22 = vnavgw(R7:6, R21:20) }");
+ test_display(&0b1101_0011_100_10100_11_100110_100_10110u32.to_le_bytes(), "{ R23:22 = vnavgw(R7:6, R21:20):rnd:sat }");
+ test_display(&0b1101_0011_100_10100_11_100110_101_10110u32.to_le_bytes(), "{ R23:22 = vnavgw(R7:6, R21:20):rnd:sat }");
+ test_display(&0b1101_0011_100_10100_11_100110_110_10110u32.to_le_bytes(), "{ R23:22 = vnavgw(R7:6, R21:20):crnd:sat }");
+ test_display(&0b1101_0011_100_10100_11_100110_111_10110u32.to_le_bytes(), "{ R23:22 = vnavgw(R7:6, R21:20):crnd:sat }");
+
+ test_display(&0b1101_0011_101_10100_11_100110_000_10110u32.to_le_bytes(), "{ R23:22 = vminub(R7:6, R21:20) }");
+ test_display(&0b1101_0011_101_10100_11_100110_001_10110u32.to_le_bytes(), "{ R23:22 = vminh(R7:6, R21:20) }");
+ test_display(&0b1101_0011_101_10100_11_100110_010_10110u32.to_le_bytes(), "{ R23:22 = vminuh(R7:6, R21:20) }");
+ test_display(&0b1101_0011_101_10100_11_100110_011_10110u32.to_le_bytes(), "{ R23:22 = vminw(R7:6, R21:20) }");
+ test_display(&0b1101_0011_101_10100_11_100110_100_10110u32.to_le_bytes(), "{ R23:22 = vminuw(R7:6, R21:20) }");
+ test_display(&0b1101_0011_101_10100_11_100110_101_10110u32.to_le_bytes(), "{ R23:22 = vmaxuw(R7:6, R21:20) }");
+ test_display(&0b1101_0011_101_10100_11_100110_110_10110u32.to_le_bytes(), "{ R23:22 = min(R7:6, R21:20) }");
+ test_display(&0b1101_0011_101_10100_11_100110_111_10110u32.to_le_bytes(), "{ R23:22 = minu(R7:6, R21:20) }");
+
+ test_display(&0b1101_0011_110_10100_11_100110_000_10110u32.to_le_bytes(), "{ R23:22 = vmaxub(R7:6, R21:20) }");
+ test_display(&0b1101_0011_110_10100_11_100110_001_10110u32.to_le_bytes(), "{ R23:22 = vmaxh(R7:6, R21:20) }");
+ test_display(&0b1101_0011_110_10100_11_100110_010_10110u32.to_le_bytes(), "{ R23:22 = vmaxuh(R7:6, R21:20) }");
+ test_display(&0b1101_0011_110_10100_11_100110_011_10110u32.to_le_bytes(), "{ R23:22 = vmaxw(R7:6, R21:20) }");
+ test_display(&0b1101_0011_110_10100_11_100110_100_10110u32.to_le_bytes(), "{ R23:22 = max(R21:20, R7:6) }");
+ test_display(&0b1101_0011_110_10100_11_100110_101_10110u32.to_le_bytes(), "{ R23:22 = maxu(R21:20, R7:6) }");
+ test_display(&0b1101_0011_110_10100_11_100110_110_10110u32.to_le_bytes(), "{ R23:22 = vmaxb(R7:6, R21:20) }");
+ test_display(&0b1101_0011_110_10100_11_100110_111_10110u32.to_le_bytes(), "{ R23:22 = vminb(R7:6, R21:20) }");
+
+ test_display(&0b1101_0011_111_10100_11_100110_000_10110u32.to_le_bytes(), "{ R23:22 = and(R21:20, R7:6) }");
+ test_display(&0b1101_0011_111_10100_11_100110_001_10110u32.to_le_bytes(), "{ R23:22 = and(R21:20, ~R7:6) }");
+ test_display(&0b1101_0011_111_10100_11_100110_010_10110u32.to_le_bytes(), "{ R23:22 = or(R21:20, R7:6) }");
+ test_display(&0b1101_0011_111_10100_11_100110_011_10110u32.to_le_bytes(), "{ R23:22 = or(R21:20, ~R7:6) }");
+ test_display(&0b1101_0011_111_10100_11_100110_100_10110u32.to_le_bytes(), "{ R23:22 = xor(R21:20, R7:6) }");
+ test_invalid(&0b1101_0011_111_10100_11_100110_101_10110u32.to_le_bytes(), DecodeError::InvalidOpcode);
+ test_invalid(&0b1101_0011_111_10100_11_100110_110_10110u32.to_le_bytes(), DecodeError::InvalidOpcode);
+ test_display(&0b1101_0011_111_10100_11_100110_111_10110u32.to_le_bytes(), "{ R22 = modwrap(R20, R6) }");
+
+ test_invalid(&0b1101_0100_000_10100_11_100110_101_10110u32.to_le_bytes(), DecodeError::InvalidOpcode);
+ test_display(&0b1101_0100_001_10100_11_100110_101_10110u32.to_le_bytes(), "{ R23:22 = bitsplit(R20, R6) }");
+
+ test_display(&0b1101_0101_000_10100_11_100110_000_10110u32.to_le_bytes(), "{ R22 = add(R6.L, R20.L) }");
+ test_display(&0b1101_0101_000_10100_11_100110_010_10110u32.to_le_bytes(), "{ R22 = add(R6.L, R20.H) }");
+ test_display(&0b1101_0101_000_10100_11_100110_100_10110u32.to_le_bytes(), "{ R22 = add(R6.L, R20.L):sat }");
+ test_display(&0b1101_0101_000_10100_11_100110_110_10110u32.to_le_bytes(), "{ R22 = add(R6.L, R20.H):sat }");
+ test_display(&0b1101_0101_001_10100_11_100110_000_10110u32.to_le_bytes(), "{ R22 = sub(R6.L, R20.L) }");
+ test_display(&0b1101_0101_001_10100_11_100110_010_10110u32.to_le_bytes(), "{ R22 = sub(R6.L, R20.H) }");
+ test_display(&0b1101_0101_001_10100_11_100110_100_10110u32.to_le_bytes(), "{ R22 = sub(R6.L, R20.L):sat }");
+ test_display(&0b1101_0101_001_10100_11_100110_110_10110u32.to_le_bytes(), "{ R22 = sub(R6.L, R20.H):sat }");
+ test_display(&0b1101_0101_010_10100_11_100110_000_10110u32.to_le_bytes(), "{ R22 = add(R6.L, R20.L):<<16 }");
+ test_display(&0b1101_0101_010_10100_11_100110_001_10110u32.to_le_bytes(), "{ R22 = add(R6.L, R20.H):<<16 }");
+ test_display(&0b1101_0101_010_10100_11_100110_010_10110u32.to_le_bytes(), "{ R22 = add(R6.H, R20.L):<<16 }");
+ test_display(&0b1101_0101_010_10100_11_100110_011_10110u32.to_le_bytes(), "{ R22 = add(R6.H, R20.H):<<16 }");
+ test_display(&0b1101_0101_010_10100_11_100110_100_10110u32.to_le_bytes(), "{ R22 = add(R6.L, R20.L):sat:<<16 }");
+ test_display(&0b1101_0101_010_10100_11_100110_101_10110u32.to_le_bytes(), "{ R22 = add(R6.L, R20.H):sat:<<16 }");
+ test_display(&0b1101_0101_010_10100_11_100110_110_10110u32.to_le_bytes(), "{ R22 = add(R6.H, R20.L):sat:<<16 }");
+ test_display(&0b1101_0101_010_10100_11_100110_111_10110u32.to_le_bytes(), "{ R22 = add(R6.H, R20.H):sat:<<16 }");
+
+ test_display(&0b1101_0101_100_10100_11_100110_000_10110u32.to_le_bytes(), "{ R22 = add(R20, R6):sat:deprecated }");
+ test_display(&0b1101_0101_100_10100_11_100110_100_10110u32.to_le_bytes(), "{ R22 = sub(R6, R20):sat:deprecated }");
+ test_display(&0b1101_0101_101_10100_11_100110_000_10110u32.to_le_bytes(), "{ R22 = min(R20, R6) }");
+ test_display(&0b1101_0101_101_10100_11_100110_100_10110u32.to_le_bytes(), "{ R22 = minu(R20, R6) }");
+ test_display(&0b1101_0101_110_10100_11_100110_000_10110u32.to_le_bytes(), "{ R22 = max(R20, R6) }");
+ test_display(&0b1101_0101_110_10100_11_100110_100_10110u32.to_le_bytes(), "{ R22 = maxu(R20, R6) }");
+ test_display(&0b1101_0101_111_10100_11_100110_000_10110u32.to_le_bytes(), "{ R22 = parity(R20, R6) }");
+ test_display(&0b1101_0101_111_10100_11_100110_100_10110u32.to_le_bytes(), "{ R22 = parity(R20, R6) }");
+
+ test_display(&0b1101_0110_001_10100_11_100110_100_10110u32.to_le_bytes(), "{ R22 = sfmake(#0x334):pos }");
+ test_display(&0b1101_0110_011_10100_11_100110_100_10110u32.to_le_bytes(), "{ R22 = sfmake(#0x334):neg }");
+ test_display(&0b1101_0110_111_10100_11_100110_000_10110u32.to_le_bytes(), "{ P2 = dfcmp.eq(R21:20, R7:6) }");
+ test_display(&0b1101_0110_111_10100_11_100110_001_10110u32.to_le_bytes(), "{ P2 = dfcmp.gt(R21:20, R7:6) }");
+ test_display(&0b1101_0110_111_10100_11_100110_011_10110u32.to_le_bytes(), "{ P2 = dfcmp.ge(R21:20, R7:6) }");
+ test_display(&0b1101_0110_111_10100_11_100110_100_10110u32.to_le_bytes(), "{ P2 = dfcmp.uo(R21:20, R7:6) }");
+
+ test_display(&0b1101_0111_010_10100_11_100110_100_10110u32.to_le_bytes(), "{ R22 = add(#0x2c, mpyi(R20, R6)) }");
+ test_invalid(&0b1101_0111_110_10100_11_100110_100_10110u32.to_le_bytes(), DecodeError::InvalidOpcode);
+
+ test_display(&0b1101_1000_110_10100_11_100110_100_10110u32.to_le_bytes(), "{ R6 = add(#0x2c, mpyi(R20, #0x36)) }");
}
#[test]