diff options
author | iximeow <me@iximeow.net> | 2025-04-07 23:12:25 -0700 |
---|---|---|
committer | iximeow <me@iximeow.net> | 2025-04-07 23:12:25 -0700 |
commit | f902e9a1df4f7b03c029491e72aca72977d23f5b (patch) | |
tree | e0cb37aeda49f9bc9890d769cf31f81fd7c58868 | |
parent | b0609b1b20851cf33eb03a8f9491502121c4f127 (diff) |
wowowowow cargo test passes
-rw-r--r-- | src/display.rs | 27 | ||||
-rw-r--r-- | src/lib.rs | 11 | ||||
-rw-r--r-- | tests/from_brain.rs | 2 |
3 files changed, 28 insertions, 12 deletions
diff --git a/src/display.rs b/src/display.rs index 6349d4c..071633c 100644 --- a/src/display.rs +++ b/src/display.rs @@ -57,9 +57,18 @@ 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(), - assign_mode_label(self.flags.assign_mode), - self.sources[0], self.sources[1]); + // not entirely sure if these should be the same opcode, but "not" as in + // "bitswise negation" as in "! for boolean predicates and ~ for integer + // registers" seems... ok? + if let Some(dest @ Operand::PredicateReg { .. }) = self.dest.as_ref() { + return write!(f, "{} {} and({}, !{})", dest, + assign_mode_label(self.flags.assign_mode), + self.sources[0], self.sources[1]); + } else { + return write!(f, "{} {} and({}, ~{})", self.dest.as_ref().unwrap(), + assign_mode_label(self.flags.assign_mode), + self.sources[0], self.sources[1]); + } } Opcode::OrOr => { return write!(f, "{} = or({}, or({}, {}))", self.dest.as_ref().unwrap(), @@ -152,9 +161,15 @@ impl fmt::Display for Instruction { self.opcode, self.sources[0], self.sources[1]); } Opcode::Vminub => { - return write!(f, "{}, {} = {}({}, {})", - self.dest.as_ref().unwrap(), self.alt_dest.as_ref().unwrap(), - self.opcode, self.sources[0], self.sources[1]); + if let Some(alt_dest) = self.alt_dest.as_ref() { + return write!(f, "{}, {} = {}({}, {})", + self.dest.as_ref().unwrap(), alt_dest, + self.opcode, self.sources[0], self.sources[1]); + } else { + return write!(f, "{} = {}({}, {})", + self.dest.as_ref().unwrap(), + self.opcode, self.sources[0], self.sources[1]); + } } Opcode::SfRecipa => { return write!(f, "{}, {} = {}({}, {})", @@ -223,7 +223,7 @@ pub struct InstructionPacket { /// /// `elst` describes access of the bit fields in register `Rds`. V5x Figure 1-4: /// -/// ``` +/// ```text /// | .b[7] | .b[6] | .b[5] | .b[4] | .b[3] | .b[2] | .b[1] | .b[0] | signed bytes /// | .ub[7] | .ub[6] | .ub[5] | .ub[4] | .ub[3] | .ub[2] | .ub[1] | .ub[0] | unsigned bytes /// | .h[3] | .h[2] | .h[1] | .h[0] | signed halfwords @@ -235,12 +235,14 @@ pub struct InstructionPacket { /// meanwhile a register can be accessed as a single element with some trailing specifiers. V5x /// Table 1-2: /// +/// ```text /// | Symbol | Meaning | /// |--------|---------| /// | .sN | Bits `[N-1:0]` are treated as an N-bit signed number. For example, R0.s16 means the least significant 16 bits of R0 are treated as a 16-bit signed number. | /// | .uN | Bits `[N-1:0]` are treated as an N-bit unsigned number. | /// | .H | The most significant 16 bits of a 32-bit register. | /// | .L | The least significant 16 bits of a 32-bit register. | +/// ``` /// /// and finally, "Duplex instructions" (V73 Section 3.6): /// > Unlike Compound instructions, duplex instructions do not have distinctive syntax – in @@ -367,7 +369,7 @@ impl Default for InstFlags { /// /// additionally, V73 Section 3.2 outlines instruction classes which relate to the available /// execution units: -/// ``` +/// ```text /// XTYPE /// XTYPE ALU 64-bit ALU operations /// XTYPE BIT Bit operations @@ -2931,7 +2933,7 @@ fn decode_instruction< handler.on_source_decoded(Operand::gprpair(ttttt)?)?; } _ => { - eprintln!("!!! TODO: {:07b} !!!", opbits); + opcode_check!(false); } } } @@ -6769,8 +6771,7 @@ fn decode_instruction< } } _ => { - eprintln!("iclass: {:04b}", iclass); - // TODO: exhaustive + panic!("TODO: remainder"); } } diff --git a/tests/from_brain.rs b/tests/from_brain.rs index 047db47..14be5ff 100644 --- a/tests/from_brain.rs +++ b/tests/from_brain.rs @@ -346,7 +346,7 @@ fn inst_0111() { test_display(&0b0111_0000000_00011_11_1_0_1101_000_00100u32.to_le_bytes(), "{ if (!P1.new) R4 = aslh(R3) }"); test_display(&0b0111_0000011_00001_11_0_0_0000_000_00100u32.to_le_bytes(), "{ R4 = R1 }"); - test_invalid(&0b0111_0000011_00001_11_0_0_0000_000_00100u32.to_le_bytes(), DecodeError::InvalidOpcode); + test_invalid(&0b0111_0000011_00001_11_1_0_0000_000_00100u32.to_le_bytes(), DecodeError::InvalidOpcode); test_display(&0b0111_0001011_00010_11_0_0_0000_001_00000u32.to_le_bytes(), "{ R2.L = #0x4020 }"); test_display(&0b0111_0001101_00010_11_0_0_0000_001_00000u32.to_le_bytes(), "{ R2.L = #0x8020 }"); |