From 8bcec993e3c5b9832ccee91e94eb5de6e80c9b24 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sat, 29 Mar 2025 02:27:42 -0700 Subject: 1101* is all thats left... --- notes/todo | 96 ++++++++++++++++++++--------------------- src/display.rs | 28 +++++++++++- src/lib.rs | 122 +++++++++++++++++++++++++++++++++++++++++++++++++++- tests/from_brain.rs | 22 ++++++++++ 4 files changed, 218 insertions(+), 50 deletions(-) diff --git a/notes/todo b/notes/todo index 0445003..5044fad 100644 --- a/notes/todo +++ b/notes/todo @@ -558,38 +558,38 @@ 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 0 0 0|1 1 0 0|0 0 0|s s s s s| P P |0 i i i i i|0 0 0|d d d d d| Rdd=asr(Rs,#u5) - XTYPE PERM/slot 2,3 -|1 0 0 0|1 1 0 0|0 0 0|s s s s s| P P |0 i i i i i|0 0 1|d d d d d| Rdd=lsr(Rs,#u5) - XTYPE PERM/slot 2,3 -|1 0 0 0|1 1 0 0|0 0 0|s s s s s| P P |0 i i i i i|0 1 0|d d d d d| Rdd=asl(Rs,#u5) - XTYPE PERM/slot 2,3 -|1 0 0 0|1 1 0 0|0 0 0|s s s s s| P P |0 i i i i i|0 1 1|d d d d d| Rdd=rol(Rs,#u5) - XTYPE PERM/slot 2,3 -|1 0 0 0|1 1 0 0|0 0 0|s s s s s| P P |- - - - - -|1 0 0|d d d d d| Rd=clb(Rs) - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|0 0 0|s s s s s| P P |- - - - - -|1 0 1|d d d d d| Rd=cl0(Rs) - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|0 0 0|s s s s s| P P |- - - - - -|1 1 0|d d d d d| Rd=cl1(Rs) - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|0 0 0|s s s s s| P P |- - - - - -|1 1 1|d d d d d| Rd=normamt(Rs) - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|0 0 1|s s s s s| P P |i i i i i i|0 0 0|d d d d d| Rd=add(clb(Rs),#s6) - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|0 1 0|s s s s s| P P |0 i i i i i|0 0 0|d d d d d| Rd=asr(Rs,#u5):rnd - XTYPE PERM/slot 2,3 -|1 0 0 0|1 1 0 0|0 1 0|s s s s s| P P |0 i i i i i|0 1 0|d d d d d| Rd=asl(Rs,#u5):sat - XTYPE PERM/slot 2,3 -|1 0 0 0|1 1 0 0|0 1 0|s s s s s| P P |- - - - - -|1 0 0|d d d d d| Rd=ct0(Rs) - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|0 1 0|s s s s s| P P |- - - - - -|1 0 1|d d d d d| Rd=ct1(Rs) - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|0 1 0|s s s s s| P P |- - - - - -|1 1 0|d d d d d| Rd=brev(Rs) - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|0 1 0|s s s s s| P P |- - - - - -|1 1 1|d d d d d| Rd=vsplatb(Rs) - XTYPE PERM/slot 2,3 -|1 0 0 0|1 1 0 0|1 0 -|s s s s s| P P |- - - - - -|0 0 -|d d d d d| Rd=vsathb(Rs) - XTYPE PERM/slot 2,3 -|1 0 0 0|1 1 0 0|1 0 -|s s s s s| P P |- - - - - -|0 1 -|d d d d d| Rd=vsathub(Rs) - XTYPE PERM/slot 2,3 -|1 0 0 0|1 1 0 0|1 0 0|s s s s s| P P |- - - - - -|1 0 0|d d d d d| Rd=abs(Rs) - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|1 0 0|s s s s s| P P |- - - - - -|1 0 1|d d d d d| Rd=abs(Rs):sat - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|1 0 0|s s s s s| P P |- - - - - -|1 1 0|d d d d d| Rd=neg(Rs):sat - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|1 0 0|s s s s s| P P |- - - - - -|1 1 1|d d d d d| Rd=swiz(Rs) - XTYPE PERM/slot 2,3 -|1 0 0 0|1 1 0 0|1 1 0|s s s s s| P P |0 i i i i i|0 0 0|d d d d d| Rd=setbit(Rs,#u5) - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|1 1 0|s s s s s| P P |0 i i i i i|0 0 1|d d d d d| Rd=clrbit(Rs,#u5) - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|1 1 0|s s s s s| P P |0 i i i i i|0 1 0|d d d d d| Rd=togglebit(Rs,#u5) - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|1 1 0|s s s s s| P P |- - - - - -|1 0 0|d d d d d| Rd=sath(Rs) - XTYPE PERM/slot 2,3 -|1 0 0 0|1 1 0 0|1 1 0|s s s s s| P P |- - - - - -|1 0 1|d d d d d| Rd=satuh(Rs) - XTYPE PERM/slot 2,3 -|1 0 0 0|1 1 0 0|1 1 0|s s s s s| P P |- - - - - -|1 1 0|d d d d d| Rd=satub(Rs) - XTYPE PERM/slot 2,3 -|1 0 0 0|1 1 0 0|1 1 0|s s s s s| P P |- - - - - -|1 1 1|d d d d d| Rd=satb(Rs) - XTYPE PERM/slot 2,3 -|1 0 0 0|1 1 0 0|1 1 1|s s s s s| P P |0 i i i i i|0 0 -|d d d d d| Rd=cround(Rs,#u5) - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|1 1 1|s s s s s| P P |i i i i i i|0 1 -|d d d d d| Rdd=cround(Rss,#u6) - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|1 1 1|s s s s s| P P |0 i i i i i|1 0 -|d d d d d| Rd=round(Rs,#u5) - XTYPE ALU/slot 2,3 -|1 0 0 0|1 1 0 0|1 1 1|s s s s s| P P |0 i i i i i|1 1 -|d d d d d| Rd=round(Rs,#u5):sat - XTYPE ALU/slot 2,3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1046,22 +1046,22 @@ 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 0 1|0 0 0 0|- - -|s s s s s| P P |- t t t t t|- - -|d d d d d| Rd=parity(Rss,Rtt) - XTYPE ALU/slot 2,3 -|1 1 0 1|0 0 0 1|- - -|s s s s s| P P |- t t t t t|- u u|d d d d d| Rdd=vmux(Pu,Rss,Rtt) - XTYPE PERM/slot 2,3 -|1 1 0 1|0 0 1 0|0 - -|s s s s s| P P |0 t t t t t|0 0 0|- - - d d| Pd=vcmpw.eq(Rss,Rtt) - XTYPE PERM/slot 2,3 -|1 1 0 1|0 0 1 0|0 - -|s s s s s| P P |0 t t t t t|0 0 1|- - - d d| Pd=vcmpw.gt(Rss,Rtt) - XTYPE PERM/slot 2,3 -|1 1 0 1|0 0 1 0|0 - -|s s s s s| P P |0 t t t t t|0 1 0|- - - d d| Pd=vcmpw.gtu(Rss,Rtt) - XTYPE PERM/slot 2,3 -|1 1 0 1|0 0 1 0|0 - -|s s s s s| P P |0 t t t t t|0 1 1|- - - d d| Pd=vcmph.eq(Rss,Rtt) - XTYPE PERM/slot 2,3 -|1 1 0 1|0 0 1 0|0 - -|s s s s s| P P |0 t t t t t|1 0 0|- - - d d| Pd=vcmph.gt(Rss,Rtt) - XTYPE PERM/slot 2,3 -|1 1 0 1|0 0 1 0|0 - -|s s s s s| P P |0 t t t t t|1 0 1|- - - d d| Pd=vcmph.gtu(Rss,Rtt) - XTYPE PERM/slot 2,3 -|1 1 0 1|0 0 1 0|0 - -|s s s s s| P P |0 t t t t t|1 1 0|- - - d d| Pd=vcmpb.eq(Rss,Rtt) - XTYPE PERM/slot 2,3 -|1 1 0 1|0 0 1 0|0 - -|s s s s s| P P |0 t t t t t|1 1 1|- - - d d| Pd=vcmpb.gtu(Rss,Rtt) - XTYPE PERM/slot 2,3 -|1 1 0 1|0 0 1 0|0 - -|s s s s s| P P |1 t t t t t|0 0 0|- - - d d| Pd=any8(vcmpb.eq(Rss,Rtt)) - XTYPE PERM/slot 2,3 -|1 1 0 1|0 0 1 0|0 - -|s s s s s| P P |1 t t t t t|0 0 1|- - - d d| Pd=!any8(vcmpb.eq(Rss,Rtt)) - XTYPE PERM/slot 2,3 -|1 1 0 1|0 0 1 0|0 - -|s s s s s| P P |1 t t t t t|0 1 0|- - - d d| Pd=vcmpb.gt(Rss,Rtt) - XTYPE PERM/slot 2,3 -|1 1 0 1|0 0 1 0|0 - -|s s s s s| P P |1 t t t t t|0 1 1|- - - d d| Pd=tlbmatch(Rss,Rt) - XTYPE PERM/slot 2,3 -|1 1 0 1|0 0 1 0|0 - -|s s s s s| P P |1 t t t t t|1 0 0|- - - d d| Pd=boundscheck(Rss,Rtt):raw:lo - XTYPE PERM/slot 2,3 -|1 1 0 1|0 0 1 0|0 - -|s s s s s| P P |1 t t t t t|1 0 1|- - - d d| Pd=boundscheck(Rss,Rtt):raw:hi - XTYPE PERM/slot 2,3 + + + + + + + + + + + + + + + + |1 1 0 1|0 0 1 1|0 0 0|s s s s s| P P |- t t t t t|0 0 0|d d d d d| Rdd=vaddub(Rss,Rtt) - XTYPE ALU/slot 2,3 |1 1 0 1|0 0 1 1|0 0 0|s s s s s| P P |- t t t t t|0 0 1|d d d d d| Rdd=vaddub(Rss,Rtt):sat - XTYPE ALU/slot 2,3 |1 1 0 1|0 0 1 1|0 0 0|s s s s s| P P |- t t t t t|0 1 0|d d d d d| Rdd=vaddh(Rss,Rtt) - XTYPE ALU/slot 2,3 diff --git a/src/display.rs b/src/display.rs index ecd9a26..6e1c376 100644 --- a/src/display.rs +++ b/src/display.rs @@ -1,7 +1,7 @@ use core::fmt; use crate::{Instruction, InstructionPacket, Opcode, Operand}; -use crate::{AssignMode, BranchHint, DomainHint}; +use crate::{AssignMode, BranchHint, DomainHint, RawMode}; fn special_display_rules(op: &Opcode) -> bool { *op as u16 & 0x8000 == 0x8000 @@ -80,6 +80,12 @@ impl fmt::Display for Instruction { self.dest.as_ref().unwrap(), self.alt_dest.as_ref().unwrap(), self.opcode, self.sources[0]); } + Opcode::Any8VcmpbEq => { + return write!(f, "{} = {}any8(vcmpb.eq({}, {}))", + self.dest.as_ref().unwrap(), + if self.flags.negated { "!" } else { "" }, + self.sources[0], self.sources[1]); + } _ => { unreachable!("TODO: should be exhaustive for opcodes with special display rules"); } @@ -315,6 +321,12 @@ impl fmt::Display for Instruction { None => {} } + match self.flags.raw_mode { + Some(RawMode::Lo) => { f.write_str(":raw:lo")? }, + Some(RawMode::Hi) => { f.write_str(":raw:hi")? }, + None => {} + } + // DeallocateFrame is shown with `:raw` as a suffix, but after the taken/not-taken hint // same for DeallocReturn if self.opcode == Opcode::AllocFrame || self.opcode == Opcode::DeallocFrame || self.opcode == Opcode::DeallocReturn { @@ -586,6 +598,20 @@ impl fmt::Display for Opcode { Opcode::SfFixupr => { f.write_str("sffixupr") }, Opcode::SfInvsqrta => { f.write_str("sfinvsqrta") }, Opcode::Swiz => { f.write_str("swiz") }, + Opcode::Parity => { f.write_str("parity") }, + Opcode::Tlbmatch => { f.write_str("tlbmatch") }, + Opcode::Boundscheck => { f.write_str("boundscheck") }, + Opcode::Any8VcmpbEq => { f.write_str("any8vcmpbeq") }, + Opcode::Vmux => { f.write_str("vmux") }, + Opcode::VcmpwEq => { f.write_str("vcmpw.eq") }, + Opcode::VcmpwGt => { f.write_str("vcmpw.gt") }, + Opcode::VcmpwGtu => { f.write_str("vcmpw.gtu") }, + Opcode::VcmphEq => { f.write_str("vcmph.eq") }, + Opcode::VcmphGt => { f.write_str("vcmph.gt") }, + Opcode::VcmphGtu => { f.write_str("vcmph.gtu") }, + Opcode::VcmpbEq => { f.write_str("vcmpb.eq") }, + Opcode::VcmpbGt => { f.write_str("vcmpb.gt") }, + Opcode::VcmpbGtu => { f.write_str("vcmpb.gtu") }, } } } diff --git a/src/lib.rs b/src/lib.rs index c225ed1..7a9970c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -303,6 +303,12 @@ enum AssignMode { } #[derive(Debug, Copy, Clone)] +enum RawMode { + Lo, + Hi, +} + +#[derive(Debug, Copy, Clone)] struct InstFlags { predicate: Option, branch_hint: Option, @@ -312,6 +318,7 @@ struct InstFlags { rounded: Option, threads: Option, assign_mode: Option, + raw_mode: Option, } #[derive(Debug, Copy, Clone)] @@ -331,6 +338,7 @@ impl Default for InstFlags { rounded: None, threads: None, assign_mode: None, + raw_mode: None, } } } @@ -651,6 +659,20 @@ pub enum Opcode { SfFixupr, Swiz, + Parity, + Vmux, + VcmpwEq, + VcmpwGt, + VcmpwGtu, + VcmphEq, + VcmphGt, + VcmphGtu, + VcmpbEq, + VcmpbGt, + VcmpbGtu, + Tlbmatch, + Boundscheck, + AndAnd = 0x8000, AndOr, OrAnd, @@ -663,6 +685,7 @@ pub enum Opcode { OrOrNot, AddClb, SfInvsqrta, + Any8VcmpbEq, } impl Opcode { @@ -1140,6 +1163,7 @@ trait DecodeHandler::Address, ::Wor fn domain_hint(&mut self, _domain: DomainHint) -> Result<(), ::DecodeError> { Ok(()) } fn rounded(&mut self, _mode: RoundingMode) -> Result<(), ::DecodeError> { Ok(()) } fn chop(&mut self) -> Result<(), ::DecodeError> { Ok(()) } + fn raw_mode(&mut self, _mode: RawMode) -> Result<(), ::DecodeError> { Ok(()) } fn on_word_read(&mut self, _word: ::Word) {} } @@ -1224,6 +1248,12 @@ impl::Address, ::Word flags.chop = true; Ok(()) } + fn raw_mode(&mut self, mode: RawMode) -> Result<(), ::DecodeError> { + let flags = &mut self.instructions[self.instruction_count as usize].flags; + assert!(flags.raw_mode.is_none()); + flags.raw_mode = Some(mode); + Ok(()) + } #[inline(always)] fn read_inst_word(&mut self, words: &mut T) -> Result::DecodeError> { self.word_count += 1; @@ -4363,7 +4393,97 @@ fn decode_instruction< } } 0b1101 => { - todo!("iclass 1101"); + let opc_hi = (inst >> 24) & 0b1111; + let ddddd = reg_b0(inst); + let ttttt = reg_b8(inst); + let sssss = reg_b16(inst); + + match opc_hi { + 0b0000 => { + handler.on_dest_decoded(Operand::gpr(ddddd))?; + handler.on_source_decoded(Operand::gprpair(sssss)?)?; + handler.on_source_decoded(Operand::gprpair(ttttt)?)?; + handler.on_opcode_decoded(Opcode::Parity)?; + } + 0b0001 => { + let uu = ((inst >> 5) & 0b11) as u8; + handler.on_dest_decoded(Operand::gprpair(ddddd)?)?; + handler.on_source_decoded(Operand::pred(uu))?; + handler.on_source_decoded(Operand::gprpair(sssss)?)?; + handler.on_source_decoded(Operand::gprpair(ttttt)?)?; + handler.on_opcode_decoded(Opcode::Vmux)?; + } + 0b0010 => { + opcode_check!(inst & 0x80_00_00 == 0); + + let ophi = (inst >> 13) & 1; + let oplo = (inst >> 5) & 0b111; + let opc = oplo | (ophi << 3); + let dd = ddddd & 0b11; + + handler.on_dest_decoded(Operand::pred(dd))?; + handler.on_source_decoded(Operand::gprpair(sssss)?)?; + if opc != 0b1011 { + handler.on_source_decoded(Operand::gprpair(ttttt)?)?; + } else { + handler.on_source_decoded(Operand::gpr(ttttt))?; + } + + match opc { + 0b0000 => { + handler.on_opcode_decoded(Opcode::VcmpwEq)?; + } + 0b0001 => { + handler.on_opcode_decoded(Opcode::VcmpwGt)?; + } + 0b0010 => { + handler.on_opcode_decoded(Opcode::VcmpwGtu)?; + } + 0b0011 => { + handler.on_opcode_decoded(Opcode::VcmphEq)?; + } + 0b0100 => { + handler.on_opcode_decoded(Opcode::VcmphGt)?; + } + 0b0101 => { + handler.on_opcode_decoded(Opcode::VcmphGtu)?; + } + 0b0110 => { + handler.on_opcode_decoded(Opcode::VcmpbEq)?; + } + 0b0111 => { + handler.on_opcode_decoded(Opcode::VcmpbGtu)?; + } + 0b1000 => { + handler.on_opcode_decoded(Opcode::Any8VcmpbEq)?; + } + 0b1001 => { + handler.on_opcode_decoded(Opcode::Any8VcmpbEq)?; + handler.negate_result(); + } + 0b1010 => { + handler.on_opcode_decoded(Opcode::VcmpbGt)?; + } + 0b1011 => { + handler.on_opcode_decoded(Opcode::Tlbmatch)?; + } + 0b1100 => { + handler.on_opcode_decoded(Opcode::Boundscheck)?; + handler.raw_mode(RawMode::Lo)?; + } + 0b1101 => { + handler.on_opcode_decoded(Opcode::Boundscheck)?; + handler.raw_mode(RawMode::Hi)?; + } + _ => { + return Err(DecodeError::InvalidOpcode); + } + } + } + _ => { + todo!("other"); + }, + } } 0b1111 => { let ddddd = reg_b0(inst); diff --git a/tests/from_brain.rs b/tests/from_brain.rs index 85eb128..27963ba 100644 --- a/tests/from_brain.rs +++ b/tests/from_brain.rs @@ -1098,6 +1098,28 @@ fn inst_1100() { } #[test] +fn inst_1101() { + test_display(&0b1101_0000_000_10100_11_000110_110_10110u32.to_le_bytes(), "{ R22 = parity(R21:20, R7:6) }"); + // bit 7 is `-` in the listing... + test_display(&0b1101_0001_000_10100_11_000110_110_10110u32.to_le_bytes(), "{ R23:22 = vmux(P2, R21:20, R7:6) }"); + // bits 2, 3, 4 are `-` in the listing + test_display(&0b1101_0010_000_10100_11_000110_000_10110u32.to_le_bytes(), "{ P2 = vcmpw.eq(R21:20, R7:6) }"); + test_display(&0b1101_0010_000_10100_11_000110_001_10110u32.to_le_bytes(), "{ P2 = vcmpw.gt(R21:20, R7:6) }"); + test_display(&0b1101_0010_000_10100_11_000110_010_10110u32.to_le_bytes(), "{ P2 = vcmpw.gtu(R21:20, R7:6) }"); + test_display(&0b1101_0010_000_10100_11_000110_011_10110u32.to_le_bytes(), "{ P2 = vcmph.eq(R21:20, R7:6) }"); + test_display(&0b1101_0010_000_10100_11_000110_100_10110u32.to_le_bytes(), "{ P2 = vcmph.gt(R21:20, R7:6) }"); + test_display(&0b1101_0010_000_10100_11_000110_101_10110u32.to_le_bytes(), "{ P2 = vcmph.gtu(R21:20, R7:6) }"); + test_display(&0b1101_0010_000_10100_11_000110_110_10110u32.to_le_bytes(), "{ P2 = vcmpb.eq(R21:20, R7:6) }"); + test_display(&0b1101_0010_000_10100_11_000110_111_10110u32.to_le_bytes(), "{ P2 = vcmpb.gtu(R21:20, R7:6) }"); + test_display(&0b1101_0010_000_10100_11_100110_000_10110u32.to_le_bytes(), "{ P2 = any8(vcmpb.eq(R21:20, R7:6)) }"); + test_display(&0b1101_0010_000_10100_11_100110_001_10110u32.to_le_bytes(), "{ P2 = !any8(vcmpb.eq(R21:20, R7:6)) }"); + test_display(&0b1101_0010_000_10100_11_100110_010_10110u32.to_le_bytes(), "{ P2 = vcmpb.gt(R21:20, R7:6) }"); + test_display(&0b1101_0010_000_10100_11_100110_011_10110u32.to_le_bytes(), "{ P2 = tlbmatch(R21:20, R6) }"); + test_display(&0b1101_0010_000_10100_11_100110_100_10110u32.to_le_bytes(), "{ P2 = boundscheck(R21:20, R7:6):raw:lo }"); + test_display(&0b1101_0010_000_10100_11_100110_101_10110u32.to_le_bytes(), "{ P2 = boundscheck(R21:20, R7:6):raw:hi }"); +} + +#[test] fn inst_1111() { test_display(&0b1111_0001000_00100_11_0_00011_000_00110u32.to_le_bytes(), "{ R6 = and(R4, R3) }"); test_display(&0b1111_0001001_00100_11_0_00011_000_00110u32.to_le_bytes(), "{ R6 = or(R4, R3) }"); -- cgit v1.1