diff options
-rw-r--r-- | src/display.rs | 2 | ||||
-rw-r--r-- | src/lib.rs | 24 | ||||
-rw-r--r-- | tests/from_brain.rs | 58 |
3 files changed, 74 insertions, 10 deletions
diff --git a/src/display.rs b/src/display.rs index fc4fd3a..babff2c 100644 --- a/src/display.rs +++ b/src/display.rs @@ -596,7 +596,6 @@ impl fmt::Display for Opcode { Opcode::Cmpyrwh => { f.write_str("cmpyrwh") }, Opcode::Cmpyi => { f.write_str("cmpyi") }, Opcode::Cmpyr => { f.write_str("cmpyr") }, - Opcode::Pcmpyw => { f.write_str("pcmpyw") }, Opcode::Vacsh => { f.write_str("vacsh") }, Opcode::Vcmpyi => { f.write_str("vcmpyi") }, Opcode::Vcmpyr => { f.write_str("vcmpyr") }, @@ -604,7 +603,6 @@ impl fmt::Display for Opcode { Opcode::Vmpyh => { f.write_str("vmpyh") }, Opcode::Vmpyhsu => { f.write_str("vmpyhsu") }, Opcode::Vmpybsu => { f.write_str("vmpybsu") }, - Opcode::Vpcmpyw => { f.write_str("vpcmpyw") }, Opcode::Vrmpybsu => { f.write_str("vrmpybsu") }, Opcode::Vdmpybsu => { f.write_str("vdmpybsu") }, Opcode::Vrmpybu => { f.write_str("vrmpybu") }, @@ -596,7 +596,6 @@ pub enum Opcode { Cmpyrwh, Cmpyi, Cmpyr, - Pcmpyw, Vacsh, Vcmpyi, Vcmpyr, @@ -604,7 +603,6 @@ pub enum Opcode { Vmpyh, Vmpyhsu, Vmpybsu, - Vpcmpyw, Vrmpybsu, Vdmpybsu, Vrmpybu, @@ -5817,6 +5815,7 @@ fn decode_instruction< } operand_check!(op_lo & 0b100 == 0); + handler.on_dest_decoded(Operand::gprpair(ddddd)?)?; if op_lo & 0b10 == 0 { handler.on_source_decoded(Operand::gpr_low(sssss))?; } else { @@ -5866,6 +5865,7 @@ fn decode_instruction< Some(Cmpyi), Some(Vmpyh), None, None, Some(Vmpybu), None, Some(Vmpybsu), None, ]; + handler.assign_mode(AssignMode::AddAssign)?; handler.on_opcode_decoded(decode_opcode!(OPCODES[op_hi as usize]))?; } 0b010 => { @@ -5873,12 +5873,14 @@ fn decode_instruction< handler.on_dest_decoded(Operand::gprpair(xxxxx)?)?; handler.on_source_decoded(Operand::gpr(sssss))?; handler.on_source_decoded(Operand::gpr(ttttt))?; + handler.assign_mode(AssignMode::AddAssign)?; handler.on_opcode_decoded(Opcode::Cmpyr)?; } 0b101 => { handler.on_dest_decoded(Operand::gprpair(xxxxx)?)?; handler.shift_left(op_hi >> 2)?; handler.saturate()?; + handler.assign_mode(AssignMode::AddAssign)?; match op_hi & 0b11 { 0b00 => { @@ -5895,10 +5897,15 @@ fn decode_instruction< } } 0b110 => { + handler.on_opcode_decoded(Opcode::Cmpy)?; handler.on_dest_decoded(Operand::gprpair(xxxxx)?)?; handler.on_source_decoded(Operand::gpr(sssss))?; - // TODO: handle `cmpy(Rs,Rt*)` - handler.on_source_decoded(Operand::gpr(ttttt))?; + if op_hi & 0b010 == 0 { + handler.on_source_decoded(Operand::gpr(ttttt))?; + } else { + handler.on_source_decoded(Operand::gpr_conjugate(ttttt))?; + } + handler.assign_mode(AssignMode::AddAssign)?; handler.shift_left(op_hi >> 2)?; handler.saturate()?; } @@ -5906,8 +5913,7 @@ fn decode_instruction< handler.on_dest_decoded(Operand::gprpair(xxxxx)?)?; handler.on_source_decoded(Operand::gpr(sssss))?; if op_hi & 0b011 == 0b010 { - // TODO: handle cmpy(Rs,Rt*) - handler.on_source_decoded(Operand::gpr(ttttt))?; + handler.on_source_decoded(Operand::gpr_conjugate(ttttt))?; } else { handler.on_source_decoded(Operand::gpr(ttttt))?; } @@ -5915,15 +5921,17 @@ fn decode_instruction< 0b000 | 0b100 | 0b010 | 0b110 => { handler.assign_mode(AssignMode::SubAssign)?; + handler.saturate()?; handler.on_opcode_decoded(Opcode::Cmpy)?; + handler.shift_left(op_hi >> 2)?; } 0b001 => { handler.assign_mode(AssignMode::XorAssign)?; - handler.on_opcode_decoded(Opcode::Pcmpyw)?; + handler.on_opcode_decoded(Opcode::Pmpyw)?; } 0b101 => { handler.assign_mode(AssignMode::XorAssign)?; - handler.on_opcode_decoded(Opcode::Vpcmpyw)?; + handler.on_opcode_decoded(Opcode::Vpmpyh)?; } _ => { return Err(DecodeError::InvalidOpcode); diff --git a/tests/from_brain.rs b/tests/from_brain.rs index f98ca03..a715e9f 100644 --- a/tests/from_brain.rs +++ b/tests/from_brain.rs @@ -1481,6 +1481,64 @@ fn inst_1110() { test_display(&0b1110_0101_100_10100_11_000110_110_10110u32.to_le_bytes(), "{ R23:22 = cmpy(R20, R6):<<1:sat }"); test_display(&0b1110_0101_100_10100_11_000110_111_10110u32.to_le_bytes(), "{ R23:22 = vmpyhsu(R20, R6):<<1:sat }"); test_display(&0b1110_0101_110_10100_11_000110_110_10110u32.to_le_bytes(), "{ R23:22 = cmpy(R20, R6*):<<1:sat }"); + + test_display(&0b1110_0110_000_10100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 += mpy(R20.L, R6.L) }"); + test_display(&0b1110_0110_000_10100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 += mpy(R20.L, R6.H) }"); + test_display(&0b1110_0110_000_10100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 += mpy(R20.H, R6.L) }"); + test_display(&0b1110_0110_000_10100_11_000110_011_10110u32.to_le_bytes(), "{ R23:22 += mpy(R20.H, R6.H) }"); + test_display(&0b1110_0110_001_10100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 -= mpy(R20.L, R6.L) }"); + test_display(&0b1110_0110_001_10100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 -= mpy(R20.L, R6.H) }"); + test_display(&0b1110_0110_001_10100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 -= mpy(R20.H, R6.L) }"); + test_display(&0b1110_0110_001_10100_11_000110_011_10110u32.to_le_bytes(), "{ R23:22 -= mpy(R20.H, R6.H) }"); + test_display(&0b1110_0110_010_10100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 += mpyu(R20.L, R6.L) }"); + test_display(&0b1110_0110_010_10100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 += mpyu(R20.L, R6.H) }"); + test_display(&0b1110_0110_010_10100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 += mpyu(R20.H, R6.L) }"); + test_display(&0b1110_0110_010_10100_11_000110_011_10110u32.to_le_bytes(), "{ R23:22 += mpyu(R20.H, R6.H) }"); + test_display(&0b1110_0110_011_10100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 -= mpyu(R20.L, R6.L) }"); + test_display(&0b1110_0110_011_10100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 -= mpyu(R20.L, R6.H) }"); + test_display(&0b1110_0110_011_10100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 -= mpyu(R20.H, R6.L) }"); + test_display(&0b1110_0110_011_10100_11_000110_011_10110u32.to_le_bytes(), "{ R23:22 -= mpyu(R20.H, R6.H) }"); + test_display(&0b1110_0110_100_10100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 += mpy(R20.L, R6.L):<<1 }"); + test_display(&0b1110_0110_100_10100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 += mpy(R20.L, R6.H):<<1 }"); + test_display(&0b1110_0110_100_10100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 += mpy(R20.H, R6.L):<<1 }"); + test_display(&0b1110_0110_100_10100_11_000110_011_10110u32.to_le_bytes(), "{ R23:22 += mpy(R20.H, R6.H):<<1 }"); + test_display(&0b1110_0110_101_10100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 -= mpy(R20.L, R6.L):<<1 }"); + test_display(&0b1110_0110_101_10100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 -= mpy(R20.L, R6.H):<<1 }"); + test_display(&0b1110_0110_101_10100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 -= mpy(R20.H, R6.L):<<1 }"); + test_display(&0b1110_0110_101_10100_11_000110_011_10110u32.to_le_bytes(), "{ R23:22 -= mpy(R20.H, R6.H):<<1 }"); + test_display(&0b1110_0110_110_10100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 += mpyu(R20.L, R6.L):<<1 }"); + test_display(&0b1110_0110_110_10100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 += mpyu(R20.L, R6.H):<<1 }"); + test_display(&0b1110_0110_110_10100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 += mpyu(R20.H, R6.L):<<1 }"); + test_display(&0b1110_0110_110_10100_11_000110_011_10110u32.to_le_bytes(), "{ R23:22 += mpyu(R20.H, R6.H):<<1 }"); + test_display(&0b1110_0110_111_10100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 -= mpyu(R20.L, R6.L):<<1 }"); + test_display(&0b1110_0110_111_10100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 -= mpyu(R20.L, R6.H):<<1 }"); + test_display(&0b1110_0110_111_10100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 -= mpyu(R20.H, R6.L):<<1 }"); + test_display(&0b1110_0110_111_10100_11_000110_011_10110u32.to_le_bytes(), "{ R23:22 -= mpyu(R20.H, R6.H):<<1 }"); + + test_display(&0b1110_0111_000_10100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 += mpy(R20, R6) }"); + test_display(&0b1110_0111_001_10100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 -= mpy(R20, R6) }"); + test_display(&0b1110_0111_010_10100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 += mpyu(R20, R6) }"); + test_display(&0b1110_0111_011_10100_11_000110_000_10110u32.to_le_bytes(), "{ R23:22 -= mpyu(R20, R6) }"); + test_display(&0b1110_0111_000_10100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 += cmpyi(R20, R6) }"); + test_display(&0b1110_0111_001_10100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 += vmpyh(R21:20, R7:6) }"); + test_display(&0b1110_0111_100_10100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 += vmpybu(R21:20, R7:6) }"); + test_display(&0b1110_0111_110_10100_11_000110_001_10110u32.to_le_bytes(), "{ R23:22 += vmpybsu(R21:20, R7:6) }"); + test_display(&0b1110_0111_000_10100_11_000110_010_10110u32.to_le_bytes(), "{ R23:22 += cmpyr(R20, R6) }"); + test_display(&0b1110_0111_001_10100_11_000110_111_10110u32.to_le_bytes(), "{ R23:22 ^= pmpyw(R20, R6) }"); + test_display(&0b1110_0111_101_10100_11_000110_111_10110u32.to_le_bytes(), "{ R23:22 ^= vpmpyh(R20, R6) }"); + + test_display(&0b1110_0111_000_10100_11_000110_101_10110u32.to_le_bytes(), "{ R23:22 += vmpyh(R21:20, R7:6):sat }"); + test_display(&0b1110_0111_011_10100_11_000110_101_10110u32.to_le_bytes(), "{ R23:22 += vmpyhsu(R20, R6):sat }"); + test_display(&0b1110_0111_000_10100_11_000110_110_10110u32.to_le_bytes(), "{ R23:22 += cmpy(R20, R6):sat }"); + test_display(&0b1110_0111_010_10100_11_000110_110_10110u32.to_le_bytes(), "{ R23:22 += cmpy(R20, R6*):sat }"); + test_display(&0b1110_0111_000_10100_11_000110_111_10110u32.to_le_bytes(), "{ R23:22 -= cmpy(R20, R6):sat }"); + test_display(&0b1110_0111_010_10100_11_000110_111_10110u32.to_le_bytes(), "{ R23:22 -= cmpy(R20, R6*):sat }"); + test_display(&0b1110_0111_100_10100_11_000110_101_10110u32.to_le_bytes(), "{ R23:22 += vmpyh(R21:20, R7:6):<<1:sat }"); + test_display(&0b1110_0111_111_10100_11_000110_101_10110u32.to_le_bytes(), "{ R23:22 += vmpyhsu(R20, R6):<<1:sat }"); + test_display(&0b1110_0111_100_10100_11_000110_110_10110u32.to_le_bytes(), "{ R23:22 += cmpy(R20, R6):<<1:sat }"); + 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] |