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... --- src/lib.rs | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 121 insertions(+), 1 deletion(-) (limited to 'src/lib.rs') 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); -- cgit v1.1