use proc_bitfield::bitfield; bitfield! { #[derive(Clone, Copy, Debug)] pub struct Instruction(pub u32): FromStorage, IntoStorage, DerefStorage { pub special: u8 @ 0..6, pub regimm: u8 @ 16..21, pub rt: u8 @ 16..21, pub cop_rt: u8 @ 16..21, pub rs: u8 @ 21..26, pub cop_rs: u8 @ 21..26, pub opcode: u8 @ 26..32, pub imm: u16 @ 0..16, pub target: u32 @ 0..26, pub funct: u8 @ 0..6, pub sa: u8 @ 6..11, pub rd: u8 @ 11..16, } } pub enum BranchType { Pure, Likely, Link, LinkLikely, } impl Instruction { pub fn get_branch(self) -> Option { match self.opcode() { Instruction::BEQ | Instruction::BNE | Instruction::BLEZ | Instruction::BGTZ => { Some(BranchType::Pure) } Instruction::BEQL | Instruction::BNEL | Instruction::BLEZL | Instruction::BGTZL => { Some(BranchType::Likely) } Instruction::REGIMM => match self.regimm() { Instruction::BLTZ | Instruction::BGEZ => Some(BranchType::Pure), Instruction::BLTZAL | Instruction::BGEZAL => Some(BranchType::Link), Instruction::BLTZL | Instruction::BGEZL => Some(BranchType::Likely), Instruction::BLTZALL | Instruction::BGEZALL => Some(BranchType::LinkLikely), _ => None, }, Instruction::COP1 => { if self.cop_rs() == 8 { match self.cop_rt() { 0 | 1 => Some(BranchType::Pure), 2 | 3 => Some(BranchType::Likely), _ => None, } } else { None } } _ => None, } } pub const SPECIAL: u8 = 0b000000; pub const REGIMM: u8 = 0b000001; pub const J: u8 = 0b000010; pub const JAL: u8 = 0b000011; pub const BEQ: u8 = 0b000100; pub const BNE: u8 = 0b000101; pub const BLEZ: u8 = 0b000110; pub const BGTZ: u8 = 0b000111; pub const ADDI: u8 = 0b001000; pub const ADDIU: u8 = 0b001001; pub const SLTI: u8 = 0b001010; pub const SLTIU: u8 = 0b001011; pub const ANDI: u8 = 0b001100; pub const ORI: u8 = 0b001101; pub const XORI: u8 = 0b001110; pub const LUI: u8 = 0b001111; pub const COP0: u8 = 0b010000; pub const COP1: u8 = 0b010001; pub const COP2: u8 = 0b010010; pub const BEQL: u8 = 0b010100; pub const BNEL: u8 = 0b010101; pub const BLEZL: u8 = 0b010110; pub const BGTZL: u8 = 0b010111; pub const DADDI: u8 = 0b011000; pub const DADDIU: u8 = 0b011001; pub const LDL: u8 = 0b011010; pub const LDR: u8 = 0b011011; pub const LB: u8 = 0b100000; pub const LH: u8 = 0b100001; pub const LWL: u8 = 0b100010; pub const LW: u8 = 0b100011; pub const LBU: u8 = 0b100100; pub const LHU: u8 = 0b100101; pub const LWR: u8 = 0b100110; pub const LWU: u8 = 0b100111; pub const SB: u8 = 0b101000; pub const SH: u8 = 0b101001; pub const SWL: u8 = 0b101010; pub const SW: u8 = 0b101011; pub const SDL: u8 = 0b101100; pub const SDR: u8 = 0b101101; pub const SWR: u8 = 0b101110; pub const CACHE: u8 = 0b101111; pub const LL: u8 = 0b110000; pub const LWC1: u8 = 0b110001; pub const LWC2: u8 = 0b110010; pub const LLD: u8 = 0b110100; pub const LDC1: u8 = 0b110101; pub const LDC2: u8 = 0b110110; pub const LD: u8 = 0b110111; pub const SC: u8 = 0b111000; pub const SWC1: u8 = 0b111001; pub const SWC2: u8 = 0b111010; pub const SCD: u8 = 0b111100; pub const SDC1: u8 = 0b111101; pub const SDC2: u8 = 0b111110; pub const SD: u8 = 0b111111; // special pub const SLL: u8 = 0b000000; pub const SRL: u8 = 0b000010; pub const SRA: u8 = 0b000011; pub const SLLV: u8 = 0b000100; pub const SRLV: u8 = 0b000110; pub const SRAV: u8 = 0b000111; pub const JR: u8 = 0b001000; pub const JALR: u8 = 0b001001; pub const SYSCALL: u8 = 0b001100; pub const BREAK: u8 = 0b001101; pub const SYNC: u8 = 0b001111; pub const MFHI: u8 = 0b010000; pub const MTHI: u8 = 0b010001; pub const MFLO: u8 = 0b010010; pub const MTLO: u8 = 0b010011; pub const DSLLV: u8 = 0b010100; pub const DSRLV: u8 = 0b010110; pub const DSRAV: u8 = 0b010111; pub const MULT: u8 = 0b011000; pub const MULTU: u8 = 0b011001; pub const DIV: u8 = 0b011010; pub const DIVU: u8 = 0b011011; pub const DMULT: u8 = 0b011100; pub const DMULTU: u8 = 0b011101; pub const DDIV: u8 = 0b011110; pub const DDIVU: u8 = 0b011111; pub const ADD: u8 = 0b100000; pub const ADDU: u8 = 0b100001; pub const SUB: u8 = 0b100010; pub const SUBU: u8 = 0b100011; pub const AND: u8 = 0b100100; pub const OR: u8 = 0b100101; pub const XOR: u8 = 0b100110; pub const NOR: u8 = 0b100111; pub const SLT: u8 = 0b101010; pub const SLTU: u8 = 0b101011; pub const DADD: u8 = 0b101100; pub const DADDU: u8 = 0b101101; pub const DSUB: u8 = 0b101110; pub const DSUBU: u8 = 0b101111; pub const TGE: u8 = 0b110000; pub const TGEU: u8 = 0b110001; pub const TLT: u8 = 0b110010; pub const TLTU: u8 = 0b110011; pub const TEQ: u8 = 0b110100; pub const TNE: u8 = 0b110110; pub const DSLL: u8 = 0b111000; pub const DSRL: u8 = 0b111010; pub const DSRA: u8 = 0b111011; pub const DSLL32: u8 = 0b111100; pub const DSRL32: u8 = 0b111110; pub const DSRA32: u8 = 0b111111; // regimm pub const BLTZ: u8 = 0b00000; pub const BGEZ: u8 = 0b00001; pub const BLTZL: u8 = 0b00010; pub const BGEZL: u8 = 0b00011; pub const TGEI: u8 = 0b01000; pub const TGEIU: u8 = 0b01001; pub const TLTI: u8 = 0b01010; pub const TLTIU: u8 = 0b01011; pub const TEQI: u8 = 0b01100; pub const TNEI: u8 = 0b01110; pub const BLTZAL: u8 = 0b10000; pub const BGEZAL: u8 = 0b10001; pub const BLTZALL: u8 = 0b10010; pub const BGEZALL: u8 = 0b10011; }