From 96847c9d1f17d745fd1538ee18c9411df0e2b138 Mon Sep 17 00:00:00 2001 From: iximeow Date: Sun, 13 Apr 2025 18:54:11 -0700 Subject: l2 cache management instructions are system and undocumented --- src/display.rs | 4 ++++ src/lib.rs | 48 +++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 43 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/display.rs b/src/display.rs index a9e5e49..6827108 100644 --- a/src/display.rs +++ b/src/display.rs @@ -717,6 +717,10 @@ impl fmt::Display for Opcode { Opcode::DcKill => { f.write_str("dckill") }, Opcode::IcKill => { f.write_str("ickill") }, Opcode::L2Fetch => { f.write_str("l2fetch") }, + Opcode::L2Kill => { f.write_str("l2kill") }, + Opcode::L2Gunlock => { f.write_str("l2gunlock") }, + Opcode::L2Gclean => { f.write_str("l2gclean") }, + Opcode::L2Gcleaninv => { f.write_str("l2gcleaninv") }, Opcode::DmSyncHt => { f.write_str("dmsyncht") }, Opcode::SyncHt => { f.write_str("syncht") }, diff --git a/src/lib.rs b/src/lib.rs index 12e6fd1..b5ffe05 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -649,6 +649,10 @@ pub enum Opcode { DcKill, IcKill, L2Fetch, + L2Kill, + L2Gunlock, + L2Gclean, + L2Gcleaninv, DmSyncHt, SyncHt, @@ -5088,19 +5092,36 @@ fn decode_instruction< } else { // if there are any encodings like 1010|010, they are not in the V73 // manual... + // + // ... surprise! L2 cache management instructions are system instructions + // and last described in the V65 manual. opcode_check!(opc_upper == 0b11); let opc_lower = (inst >> 21) & 0b111; - // similar.. - opcode_check!(opc_lower & 0b11 == 0b00); - handler.on_opcode_decoded(Opcode::L2Fetch)?; - handler.on_source_decoded(Rs)?; let ttttt = reg_b8(inst); - if opc_lower == 0b100 { - handler.on_source_decoded(Operand::gprpair(ttttt)?)?; - } else { - opcode_check!((inst >> 5) & 0b111 == 0b000); - handler.on_source_decoded(Operand::gpr(ttttt))?; + match opc_lower { + 0b000 => { + handler.on_opcode_decoded(Opcode::L2Fetch)?; + handler.on_source_decoded(Rs)?; + opcode_check!((inst >> 5) & 0b111 == 0b000); + handler.on_source_decoded(Operand::gpr(ttttt))?; + } + 0b100 => { + handler.on_opcode_decoded(Opcode::L2Fetch)?; + handler.on_source_decoded(Rs)?; + handler.on_source_decoded(Operand::gprpair(ttttt)?)?; + } + 0b101 => { + handler.on_opcode_decoded(Opcode::L2Gclean)?; + handler.on_source_decoded(Operand::gprpair(ttttt)?)?; + } + 0b110 => { + handler.on_opcode_decoded(Opcode::L2Gcleaninv)?; + handler.on_source_decoded(Operand::gprpair(ttttt)?)?; + } + _ => { + opcode_check!(false); + } } } } else { @@ -5133,8 +5154,17 @@ fn decode_instruction< 0b000 => { // barrier, dmsyncht, syncht. not much here (maybe these are supervisor // instructions?) + // + // ... yes! l2 cache operations are packed in here. if inst & 0x00_e0_00_e0 == 0 { handler.on_opcode_decoded(Opcode::Barrier)?; + } else if inst & 0x00_e0_00_00 == 0x00_20_00_00 { + let op = (inst >> 10) & 0b111; + static OPCODES: [Option; 8] = [ + Some(L2Kill), None, Some(L2Gunlock), None, + Some(L2Gclean), None, Some(L2Gcleaninv), None, + ]; + handler.on_opcode_decoded(decode_opcode!(OPCODES[op as usize]))?; } else if inst & 0x00_e0_01_e0 == 0x00_00_00_e0 { handler.on_opcode_decoded(Opcode::DmSyncHt)?; handler.on_dest_decoded(Operand::gpr(inst as u8 & 0b11111))?; -- cgit v1.1