#[cfg(target_arch = "aarch64")] use device::__m128i; #[cfg(target_arch = "aarch64")] include!(concat!(env!("OUT_DIR"), "/simd_bindings.rs")); use crate::{device, savestates}; #[cfg(target_arch = "x86_64")] use std::arch::x86_64::*; #[derive(serde::Serialize, serde::Deserialize)] pub struct BranchState { pub state: device::cpu::State, pub pc: u32, } #[derive(Copy, Clone, serde::Serialize, serde::Deserialize)] pub struct Instructions { #[serde(skip, default = "savestates::default_instruction")] pub func: fn(&mut device::Device, u32), pub opcode: u32, } #[derive(PartialEq, Copy, Clone, serde::Serialize, serde::Deserialize)] pub enum InstructionType { Su, Vu, } #[derive(serde::Serialize, serde::Deserialize)] pub struct Cpu { #[serde(with = "serde_big_array::BigArray")] pub instructions: [Instructions; 0x1000 / 4], pub last_instruction_type: InstructionType, pub instruction_type: InstructionType, pub pipeline_full: bool, pub branch_state: BranchState, pub broken: bool, pub halted: bool, pub sync_point: bool, pub cycle_counter: u64, #[serde( serialize_with = "savestates::serialize_m128i_array", deserialize_with = "savestates::deserialize_m128i_array" )] pub shuffle: [__m128i; 16], pub gpr: [u32; 32], #[serde( serialize_with = "savestates::serialize_m128i_array", deserialize_with = "savestates::deserialize_m128i_array" )] pub vpr: [__m128i; 32], #[serde(with = "serde_big_array::BigArray")] pub reciprocals: [u16; 512], #[serde(with = "serde_big_array::BigArray")] pub inverse_square_roots: [u16; 512], #[serde( serialize_with = "savestates::serialize_m128i", deserialize_with = "savestates::deserialize_m128i" )] pub vcol: __m128i, #[serde( serialize_with = "savestates::serialize_m128i", deserialize_with = "savestates::deserialize_m128i" )] pub vcoh: __m128i, #[serde( serialize_with = "savestates::serialize_m128i", deserialize_with = "savestates::deserialize_m128i" )] pub vccl: __m128i, #[serde( serialize_with = "savestates::serialize_m128i", deserialize_with = "savestates::deserialize_m128i" )] pub vcch: __m128i, #[serde( serialize_with = "savestates::serialize_m128i", deserialize_with = "savestates::deserialize_m128i" )] pub vce: __m128i, #[serde( serialize_with = "savestates::serialize_m128i", deserialize_with = "savestates::deserialize_m128i" )] pub accl: __m128i, #[serde( serialize_with = "savestates::serialize_m128i", deserialize_with = "savestates::deserialize_m128i" )] pub accm: __m128i, #[serde( serialize_with = "savestates::serialize_m128i", deserialize_with = "savestates::deserialize_m128i" )] pub acch: __m128i, pub divdp: bool, pub divin: i16, pub divout: i16, #[serde(skip, default = "savestates::default_instructions")] pub special_instrs: [fn(&mut device::Device, u32); 64], #[serde(skip, default = "savestates::default_instructions")] pub regimm_instrs: [fn(&mut device::Device, u32); 32], #[serde(skip, default = "savestates::default_instructions")] pub cop0_instrs: [fn(&mut device::Device, u32); 32], #[serde(skip, default = "savestates::default_instructions")] pub cop2_instrs: [fn(&mut device::Device, u32); 32], #[serde(skip, default = "savestates::default_instructions")] pub lwc2_instrs: [fn(&mut device::Device, u32); 32], #[serde(skip, default = "savestates::default_instructions")] pub swc2_instrs: [fn(&mut device::Device, u32); 32], #[serde(skip, default = "savestates::default_instructions")] pub instrs: [fn(&mut device::Device, u32); 64], #[serde(skip, default = "savestates::default_instructions")] pub vec_instrs: [fn(&mut device::Device, u32); 64], } pub fn in_delay_slot(device: &device::Device) -> bool { device.rsp.cpu.branch_state.state == device::cpu::State::DelaySlotTaken || device.rsp.cpu.branch_state.state == device::cpu::State::DelaySlotNotTaken } pub fn in_delay_slot_taken(device: &device::Device) -> bool { device.rsp.cpu.branch_state.state == device::cpu::State::DelaySlotTaken } pub fn run(device: &mut device::Device) -> u64 { device.rsp.cpu.broken = false; device.rsp.cpu.cycle_counter = 0; while !device.rsp.cpu.sync_point { device.rsp.cpu.instruction_type = InstructionType::Su; device.rsp.cpu.gpr[0] = 0; // gpr 0 is read only let instruction = device.rsp.cpu.instructions [(device.rsp.regs2[device::rsp_interface::SP_PC_REG as usize] / 4) as usize]; (instruction.func)(device, instruction.opcode); match device.rsp.cpu.branch_state.state { device::cpu::State::Step => { device.rsp.regs2[device::rsp_interface::SP_PC_REG as usize] += 4; if device.rsp.cpu.broken { break; } } device::cpu::State::Take => { device.rsp.regs2[device::rsp_interface::SP_PC_REG as usize] += 4; device.rsp.cpu.branch_state.state = device::cpu::State::DelaySlotTaken } device::cpu::State::NotTaken => { device.rsp.regs2[device::rsp_interface::SP_PC_REG as usize] += 4; device.rsp.cpu.branch_state.state = device::cpu::State::DelaySlotNotTaken } device::cpu::State::DelaySlotTaken => { device.rsp.regs2[device::rsp_interface::SP_PC_REG as usize] = device.rsp.cpu.branch_state.pc; device.rsp.cpu.branch_state.state = device::cpu::State::Step; if device.rsp.cpu.broken { break; } } device::cpu::State::DelaySlotNotTaken => { device.rsp.regs2[device::rsp_interface::SP_PC_REG as usize] += 4; device.rsp.cpu.branch_state.state = device::cpu::State::Step; if device.rsp.cpu.broken { break; } } device::cpu::State::Discard => { device.rsp.regs2[device::rsp_interface::SP_PC_REG as usize] += 8; device.rsp.cpu.branch_state.state = device::cpu::State::Step } device::cpu::State::Exception => { device.rsp.cpu.branch_state.state = device::cpu::State::Step } } device.rsp.regs2[device::rsp_interface::SP_PC_REG as usize] &= 0xFFC; if device.rsp.cpu.instruction_type == device.rsp.cpu.last_instruction_type { device.rsp.cpu.cycle_counter += 1; device.rsp.cpu.pipeline_full = false; } else { device.rsp.cpu.last_instruction_type = device.rsp.cpu.instruction_type; if device.rsp.cpu.pipeline_full { device.rsp.cpu.cycle_counter += 1; device.rsp.cpu.pipeline_full = false; } else { device.rsp.cpu.pipeline_full = true; } } } (device.rsp.cpu.cycle_counter as f64 * 1.5) as u64 // converting RCP clock to CPU clock } pub fn decode_opcode(device: &device::Device, opcode: u32) -> fn(&mut device::Device, u32) { match opcode >> 26 { 0 => { // SPECIAL device.rsp.cpu.special_instrs[(opcode & 0x3F) as usize] } 1 => { // REGIMM device.rsp.cpu.regimm_instrs[((opcode >> 16) & 0x1F) as usize] } 16 => { // COP0 device.rsp.cpu.cop0_instrs[((opcode >> 21) & 0x1F) as usize] } 18 => { // COP2 device.rsp.cpu.cop2_instrs[((opcode >> 21) & 0x1F) as usize] } 50 => { // LWC2 device.rsp.cpu.lwc2_instrs[((opcode >> 11) & 0x1F) as usize] } 58 => { // SWC2 device.rsp.cpu.swc2_instrs[((opcode >> 11) & 0x1F) as usize] } _ => device.rsp.cpu.instrs[(opcode >> 26) as usize], } } pub fn map_instructions(device: &mut device::Device) { device.rsp.cpu.instrs = [ device::rsp_su_instructions::reserved, // SPECIAL device::rsp_su_instructions::reserved, // REGIMM device::rsp_su_instructions::j, // 2 device::rsp_su_instructions::jal, // 3 device::rsp_su_instructions::beq, // 4 device::rsp_su_instructions::bne, // 5 device::rsp_su_instructions::blez, // 6 device::rsp_su_instructions::bgtz, // 7 device::rsp_su_instructions::addi, // 8 device::rsp_su_instructions::addiu, // 9 device::rsp_su_instructions::slti, // 10 device::rsp_su_instructions::sltiu, // 11 device::rsp_su_instructions::andi, // 12 device::rsp_su_instructions::ori, // 13 device::rsp_su_instructions::xori, // 14 device::rsp_su_instructions::lui, // 15 device::rsp_su_instructions::reserved, // COP0 device::rsp_su_instructions::reserved, // COP1 device::rsp_su_instructions::reserved, // COP2 device::rsp_su_instructions::reserved, // 19 device::rsp_su_instructions::reserved, // 20 device::rsp_su_instructions::reserved, // 21 device::rsp_su_instructions::reserved, // 22 device::rsp_su_instructions::reserved, // 23 device::rsp_su_instructions::reserved, // 24 device::rsp_su_instructions::reserved, // 25 device::rsp_su_instructions::reserved, // 26 device::rsp_su_instructions::reserved, // 27 device::rsp_su_instructions::reserved, // 28 device::rsp_su_instructions::reserved, // 29 device::rsp_su_instructions::reserved, // 30 device::rsp_su_instructions::reserved, // 31 device::rsp_su_instructions::lb, // 32 device::rsp_su_instructions::lh, // 33 device::rsp_su_instructions::reserved, // 34 device::rsp_su_instructions::lw, // 35 device::rsp_su_instructions::lbu, // 36 device::rsp_su_instructions::lhu, // 37 device::rsp_su_instructions::reserved, // 38 device::rsp_su_instructions::lwu, // 39 device::rsp_su_instructions::sb, // 40 device::rsp_su_instructions::sh, // 41 device::rsp_su_instructions::reserved, // 42 device::rsp_su_instructions::sw, // 43 device::rsp_su_instructions::reserved, // 44 device::rsp_su_instructions::reserved, // 45 device::rsp_su_instructions::reserved, // 46 device::rsp_su_instructions::reserved, // 47 device::rsp_su_instructions::reserved, // 48 device::rsp_su_instructions::reserved, // 49 device::rsp_su_instructions::reserved, // lwc2 device::rsp_su_instructions::reserved, // 51 device::rsp_su_instructions::reserved, // 52 device::rsp_su_instructions::reserved, // 53 device::rsp_su_instructions::reserved, // 54 device::rsp_su_instructions::reserved, // 55 device::rsp_su_instructions::reserved, // 56 device::rsp_su_instructions::reserved, // 57 device::rsp_su_instructions::reserved, // swc2 device::rsp_su_instructions::reserved, // 59 device::rsp_su_instructions::reserved, // 60 device::rsp_su_instructions::reserved, // 61 device::rsp_su_instructions::reserved, // 62 device::rsp_su_instructions::reserved, // 63 ]; device.rsp.cpu.special_instrs = [ device::rsp_su_instructions::sll, // 0 device::rsp_su_instructions::special_reserved, // 1 device::rsp_su_instructions::srl, // 2 device::rsp_su_instructions::sra, // 3 device::rsp_su_instructions::sllv, // 4 device::rsp_su_instructions::special_reserved, // 5 device::rsp_su_instructions::srlv, // 6 device::rsp_su_instructions::srav, // 7 device::rsp_su_instructions::jr, // 8 device::rsp_su_instructions::jalr, // 9 device::rsp_su_instructions::special_reserved, // 10 device::rsp_su_instructions::special_reserved, // 11 device::rsp_su_instructions::special_reserved, // 12 device::rsp_su_instructions::break_, // 13 device::rsp_su_instructions::special_reserved, // 14 device::rsp_su_instructions::special_reserved, // 15 device::rsp_su_instructions::special_reserved, // 16 device::rsp_su_instructions::special_reserved, // 17 device::rsp_su_instructions::special_reserved, // 18 device::rsp_su_instructions::special_reserved, // 19 device::rsp_su_instructions::special_reserved, // 20 device::rsp_su_instructions::special_reserved, // 21 device::rsp_su_instructions::special_reserved, // 22 device::rsp_su_instructions::special_reserved, // 23 device::rsp_su_instructions::special_reserved, // 24 device::rsp_su_instructions::special_reserved, // 25 device::rsp_su_instructions::special_reserved, // 26 device::rsp_su_instructions::special_reserved, // 27 device::rsp_su_instructions::special_reserved, // 28 device::rsp_su_instructions::special_reserved, // 29 device::rsp_su_instructions::special_reserved, // 30 device::rsp_su_instructions::special_reserved, // 31 device::rsp_su_instructions::add, // 32 device::rsp_su_instructions::addu, // 33 device::rsp_su_instructions::sub, // 34 device::rsp_su_instructions::subu, // 35 device::rsp_su_instructions::and, // 36 device::rsp_su_instructions::or, // 37 device::rsp_su_instructions::xor, // 38 device::rsp_su_instructions::nor, // 39 device::rsp_su_instructions::special_reserved, // 40 device::rsp_su_instructions::special_reserved, // 41 device::rsp_su_instructions::slt, // 42 device::rsp_su_instructions::sltu, // 43 device::rsp_su_instructions::special_reserved, // 44 device::rsp_su_instructions::special_reserved, // 45 device::rsp_su_instructions::special_reserved, // 46 device::rsp_su_instructions::special_reserved, // 47 device::rsp_su_instructions::special_reserved, // 48 device::rsp_su_instructions::special_reserved, // 49 device::rsp_su_instructions::special_reserved, // 50 device::rsp_su_instructions::special_reserved, // 51 device::rsp_su_instructions::special_reserved, // 52 device::rsp_su_instructions::special_reserved, // 53 device::rsp_su_instructions::special_reserved, // 54 device::rsp_su_instructions::special_reserved, // 55 device::rsp_su_instructions::special_reserved, // 56 device::rsp_su_instructions::special_reserved, // 57 device::rsp_su_instructions::special_reserved, // 58 device::rsp_su_instructions::special_reserved, // 59 device::rsp_su_instructions::special_reserved, // 60 device::rsp_su_instructions::special_reserved, // 61 device::rsp_su_instructions::special_reserved, // 62 device::rsp_su_instructions::special_reserved, // 63 ]; device.rsp.cpu.regimm_instrs = [ device::rsp_su_instructions::bltz, // 0 device::rsp_su_instructions::bgez, // 1 device::rsp_su_instructions::reserved, // 2 device::rsp_su_instructions::reserved, // 3 device::rsp_su_instructions::reserved, // 4 device::rsp_su_instructions::reserved, // 5 device::rsp_su_instructions::reserved, // 6 device::rsp_su_instructions::reserved, // 7 device::rsp_su_instructions::reserved, // 8 device::rsp_su_instructions::reserved, // 9 device::rsp_su_instructions::reserved, // 10 device::rsp_su_instructions::reserved, // 11 device::rsp_su_instructions::reserved, // 12 device::rsp_su_instructions::reserved, // 13 device::rsp_su_instructions::reserved, // 14 device::rsp_su_instructions::reserved, // 15 device::rsp_su_instructions::bltzal, // 16 device::rsp_su_instructions::bgezal, // 17 device::rsp_su_instructions::reserved, // 18 device::rsp_su_instructions::reserved, // 19 device::rsp_su_instructions::reserved, // 20 device::rsp_su_instructions::reserved, // 21 device::rsp_su_instructions::reserved, // 22 device::rsp_su_instructions::reserved, // 23 device::rsp_su_instructions::reserved, // 24 device::rsp_su_instructions::reserved, // 25 device::rsp_su_instructions::reserved, // 26 device::rsp_su_instructions::reserved, // 27 device::rsp_su_instructions::reserved, // 28 device::rsp_su_instructions::reserved, // 29 device::rsp_su_instructions::reserved, // 30 device::rsp_su_instructions::reserved, // 31 ]; device.rsp.cpu.cop0_instrs = [ device::rsp_su_instructions::mfc0, // 0 device::rsp_su_instructions::reserved, // 1 device::rsp_su_instructions::reserved, // 2 device::rsp_su_instructions::reserved, // 3 device::rsp_su_instructions::mtc0, // 4 device::rsp_su_instructions::reserved, // 5 device::rsp_su_instructions::reserved, // 6 device::rsp_su_instructions::reserved, // 7 device::rsp_su_instructions::reserved, // 8 device::rsp_su_instructions::reserved, // 9 device::rsp_su_instructions::reserved, // 10 device::rsp_su_instructions::reserved, // 11 device::rsp_su_instructions::reserved, // 12 device::rsp_su_instructions::reserved, // 13 device::rsp_su_instructions::reserved, // 14 device::rsp_su_instructions::reserved, // 15 device::rsp_su_instructions::reserved, // 16 device::rsp_su_instructions::reserved, // 17 device::rsp_su_instructions::reserved, // 18 device::rsp_su_instructions::reserved, // 19 device::rsp_su_instructions::reserved, // 20 device::rsp_su_instructions::reserved, // 21 device::rsp_su_instructions::reserved, // 22 device::rsp_su_instructions::reserved, // 23 device::rsp_su_instructions::reserved, // 24 device::rsp_su_instructions::reserved, // 25 device::rsp_su_instructions::reserved, // 26 device::rsp_su_instructions::reserved, // 27 device::rsp_su_instructions::reserved, // 28 device::rsp_su_instructions::reserved, // 29 device::rsp_su_instructions::reserved, // 30 device::rsp_su_instructions::reserved, // 31 ]; device.rsp.cpu.cop2_instrs = [ device::rsp_su_instructions::mfc2, // 0 device::rsp_su_instructions::reserved, // 1 device::rsp_su_instructions::cfc2, // 2 device::rsp_su_instructions::reserved, // 3 device::rsp_su_instructions::mtc2, // 4 device::rsp_su_instructions::reserved, // 5 device::rsp_su_instructions::ctc2, // 6 device::rsp_su_instructions::reserved, // 7 device::rsp_su_instructions::reserved, // 8 device::rsp_su_instructions::reserved, // 9 device::rsp_su_instructions::reserved, // 10 device::rsp_su_instructions::reserved, // 11 device::rsp_su_instructions::reserved, // 12 device::rsp_su_instructions::reserved, // 13 device::rsp_su_instructions::reserved, // 14 device::rsp_su_instructions::reserved, // 15 device::rsp_vu_instructions::execute_vec, // 16 device::rsp_vu_instructions::execute_vec, // 17 device::rsp_vu_instructions::execute_vec, // 18 device::rsp_vu_instructions::execute_vec, // 19 device::rsp_vu_instructions::execute_vec, // 20 device::rsp_vu_instructions::execute_vec, // 21 device::rsp_vu_instructions::execute_vec, // 22 device::rsp_vu_instructions::execute_vec, // 23 device::rsp_vu_instructions::execute_vec, // 24 device::rsp_vu_instructions::execute_vec, // 25 device::rsp_vu_instructions::execute_vec, // 26 device::rsp_vu_instructions::execute_vec, // 27 device::rsp_vu_instructions::execute_vec, // 28 device::rsp_vu_instructions::execute_vec, // 29 device::rsp_vu_instructions::execute_vec, // 30 device::rsp_vu_instructions::execute_vec, // 31 ]; device.rsp.cpu.lwc2_instrs = [ device::rsp_su_instructions::lbv, // 0 device::rsp_su_instructions::lsv, // 1 device::rsp_su_instructions::llv, // 2 device::rsp_su_instructions::ldv, // 3 device::rsp_su_instructions::lqv, // 4 device::rsp_su_instructions::lrv, // 5 device::rsp_su_instructions::lpv, // 6 device::rsp_su_instructions::luv, // 7 device::rsp_su_instructions::lhv, // 8 device::rsp_su_instructions::lfv, // 9 device::rsp_su_instructions::lwv, // 10 device::rsp_su_instructions::ltv, // 11 device::rsp_su_instructions::reserved, // 12 device::rsp_su_instructions::reserved, // 13 device::rsp_su_instructions::reserved, // 14 device::rsp_su_instructions::reserved, // 15 device::rsp_su_instructions::reserved, // 16 device::rsp_su_instructions::reserved, // 17 device::rsp_su_instructions::reserved, // 18 device::rsp_su_instructions::reserved, // 19 device::rsp_su_instructions::reserved, // 20 device::rsp_su_instructions::reserved, // 21 device::rsp_su_instructions::reserved, // 22 device::rsp_su_instructions::reserved, // 23 device::rsp_su_instructions::reserved, // 24 device::rsp_su_instructions::reserved, // 25 device::rsp_su_instructions::reserved, // 26 device::rsp_su_instructions::reserved, // 27 device::rsp_su_instructions::reserved, // 28 device::rsp_su_instructions::reserved, // 29 device::rsp_su_instructions::reserved, // 30 device::rsp_su_instructions::reserved, // 31 ]; device.rsp.cpu.swc2_instrs = [ device::rsp_su_instructions::sbv, // 0 device::rsp_su_instructions::ssv, // 1 device::rsp_su_instructions::slv, // 2 device::rsp_su_instructions::sdv, // 3 device::rsp_su_instructions::sqv, // 4 device::rsp_su_instructions::srv, // 5 device::rsp_su_instructions::spv, // 6 device::rsp_su_instructions::suv, // 7 device::rsp_su_instructions::shv, // 8 device::rsp_su_instructions::sfv, // 9 device::rsp_su_instructions::swv, // 10 device::rsp_su_instructions::stv, // 11 device::rsp_su_instructions::reserved, // 12 device::rsp_su_instructions::reserved, // 13 device::rsp_su_instructions::reserved, // 14 device::rsp_su_instructions::reserved, // 15 device::rsp_su_instructions::reserved, // 16 device::rsp_su_instructions::reserved, // 17 device::rsp_su_instructions::reserved, // 18 device::rsp_su_instructions::reserved, // 19 device::rsp_su_instructions::reserved, // 20 device::rsp_su_instructions::reserved, // 21 device::rsp_su_instructions::reserved, // 22 device::rsp_su_instructions::reserved, // 23 device::rsp_su_instructions::reserved, // 24 device::rsp_su_instructions::reserved, // 25 device::rsp_su_instructions::reserved, // 26 device::rsp_su_instructions::reserved, // 27 device::rsp_su_instructions::reserved, // 28 device::rsp_su_instructions::reserved, // 29 device::rsp_su_instructions::reserved, // 30 device::rsp_su_instructions::reserved, // 31 ]; device.rsp.cpu.vec_instrs = [ device::rsp_vu_instructions::vmulf, // 0 device::rsp_vu_instructions::vmulu, // 1 device::rsp_vu_instructions::vrndp, // 2 device::rsp_vu_instructions::vmulq, // 3 device::rsp_vu_instructions::vmudl, // 4 device::rsp_vu_instructions::vmudm, // 5 device::rsp_vu_instructions::vmudn, // 6 device::rsp_vu_instructions::vmudh, // 7 device::rsp_vu_instructions::vmacf, // 8 device::rsp_vu_instructions::vmacu, // 9 device::rsp_vu_instructions::vrndn, // 10 device::rsp_vu_instructions::vmacq, // 11 device::rsp_vu_instructions::vmadl, // 12 device::rsp_vu_instructions::vmadm, // 13 device::rsp_vu_instructions::vmadn, // 14 device::rsp_vu_instructions::vmadh, // 15 device::rsp_vu_instructions::vadd, // 16 device::rsp_vu_instructions::vsub, // 17 device::rsp_vu_instructions::vzero, // 18 device::rsp_vu_instructions::vabs, // 19 device::rsp_vu_instructions::vaddc, // 20 device::rsp_vu_instructions::vsubc, // 21 device::rsp_vu_instructions::vzero, // 22 device::rsp_vu_instructions::vzero, // 23 device::rsp_vu_instructions::vzero, // 24 device::rsp_vu_instructions::vzero, // 25 device::rsp_vu_instructions::vzero, // 26 device::rsp_vu_instructions::vzero, // 27 device::rsp_vu_instructions::vzero, // 28 device::rsp_vu_instructions::vsar, // 29 device::rsp_vu_instructions::vzero, // 30 device::rsp_vu_instructions::vzero, // 31 device::rsp_vu_instructions::vlt, // 32 device::rsp_vu_instructions::veq, // 33 device::rsp_vu_instructions::vne, // 34 device::rsp_vu_instructions::vge, // 35 device::rsp_vu_instructions::vcl, // 36 device::rsp_vu_instructions::vch, // 37 device::rsp_vu_instructions::vcr, // 38 device::rsp_vu_instructions::vmrg, // 39 device::rsp_vu_instructions::vand, // 40 device::rsp_vu_instructions::vnand, // 41 device::rsp_vu_instructions::vor, // 42 device::rsp_vu_instructions::vnor, // 43 device::rsp_vu_instructions::vxor, // 44 device::rsp_vu_instructions::vnxor, // 45 device::rsp_vu_instructions::vzero, // 46 device::rsp_vu_instructions::vzero, // 47 device::rsp_vu_instructions::vrcp, // 48 device::rsp_vu_instructions::vrcpl, // 49 device::rsp_vu_instructions::vrcph, // 50 device::rsp_vu_instructions::vmov, // 51 device::rsp_vu_instructions::vrsq, // 52 device::rsp_vu_instructions::vrsql, // 53 device::rsp_vu_instructions::vrsqh, // 54 device::rsp_vu_instructions::vnop, // 55 device::rsp_vu_instructions::vzero, // 56 device::rsp_vu_instructions::vzero, // 57 device::rsp_vu_instructions::vzero, // 58 device::rsp_vu_instructions::vzero, // 59 device::rsp_vu_instructions::vzero, // 60 device::rsp_vu_instructions::vzero, // 61 device::rsp_vu_instructions::vzero, // 62 device::rsp_vu_instructions::vnop, // 63 ] } pub fn init(device: &mut device::Device) { device.rsp.cpu.reciprocals[0] = u16::MAX; let mut index = 1; while index < 512 { let a = (index + 512) as u64; let b = (1_u64 << 34) / a; device.rsp.cpu.reciprocals[index] = ((b + 1) >> 8) as u16; index += 1; } index = 0; while index < 512 { let mut shift = 0; if index % 2 == 1 { shift = 1 } let a = ((index + 512) >> shift) as u64; let mut b = (1 << 17) as u64; //find the largest b where b < 1.0 / sqrt(a) while a * (b + 1) * (b + 1) < (1_u64 << 44) { b += 1; } device.rsp.cpu.inverse_square_roots[index] = (b >> 1) as u16; index += 1; } device.rsp.cpu.shuffle = unsafe { [ //vector _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0), //01234567 _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0), //01234567 //scalar quarter _mm_set_epi8(15, 14, 15, 14, 11, 10, 11, 10, 7, 6, 7, 6, 3, 2, 3, 2), //00224466 _mm_set_epi8(13, 12, 13, 12, 9, 8, 9, 8, 5, 4, 5, 4, 1, 0, 1, 0), //11335577 //scalar half _mm_set_epi8(15, 14, 15, 14, 15, 14, 15, 14, 7, 6, 7, 6, 7, 6, 7, 6), //00004444 _mm_set_epi8(13, 12, 13, 12, 13, 12, 13, 12, 5, 4, 5, 4, 5, 4, 5, 4), //11115555 _mm_set_epi8(11, 10, 11, 10, 11, 10, 11, 10, 3, 2, 3, 2, 3, 2, 3, 2), //22226666 _mm_set_epi8(9, 8, 9, 8, 9, 8, 9, 8, 1, 0, 1, 0, 1, 0, 1, 0), //33337777 //scalar whole _mm_set_epi8( 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, ), //00000000 _mm_set_epi8( 13, 12, 13, 12, 13, 12, 13, 12, 13, 12, 13, 12, 13, 12, 13, 12, ), //11111111 _mm_set_epi8( 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, 11, 10, ), //22222222 _mm_set_epi8(9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8, 9, 8), //33333333 _mm_set_epi8(7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6, 7, 6), //44444444 _mm_set_epi8(5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4), //55555555 _mm_set_epi8(3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2), //66666666 _mm_set_epi8(1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0), //77777777 ] }; map_instructions(device); }