From 9a3a56d0c62c3aefbb03f138dc9f9da6aa42476e Mon Sep 17 00:00:00 2001 From: Logan McNaughton <848146+loganmc10@users.noreply.github.com> Date: Sat, 11 Jan 2025 14:34:16 +0100 Subject: [PATCH] RSP cleanup (#124) --- src/device/rsp_su_instructions.rs | 36 +++++++++---------- src/device/rsp_vu_instructions.rs | 57 +++++++++++++------------------ 2 files changed, 41 insertions(+), 52 deletions(-) diff --git a/src/device/rsp_su_instructions.rs b/src/device/rsp_su_instructions.rs index 64b95e2..5671db8 100644 --- a/src/device/rsp_su_instructions.rs +++ b/src/device/rsp_su_instructions.rs @@ -39,7 +39,7 @@ pub fn sign_extend_7bit_offset(offset: u8, shift_amount: u32) -> u32 { (((soffset) as i32) as u32) << shift_amount } -pub fn modify_vpr_byte(vpr: &mut u128, value: u8, element: u8) { +pub fn modify_vpr_byte(vpr: &mut u128, element: u8, value: u8) { let pos = 15 - (element & 15); let mask = 0xFF << (pos * 8); *vpr &= !mask; @@ -51,7 +51,7 @@ pub fn get_vpr_byte(vpr: u128, element: u8) -> u8 { (vpr >> (pos * 8)) as u8 } -pub fn modify_vpr_element(vpr: &mut u128, value: u16, element: u8) { +pub fn modify_vpr_element(vpr: &mut u128, element: u8, value: u16) { let pos = 7 - (element & 7); let mask = 0xFFFF << (pos * 16); *vpr &= !mask; @@ -522,14 +522,14 @@ pub fn cfc2(device: &mut device::Device, opcode: u32) { pub fn mtc2(device: &mut device::Device, opcode: u32) { modify_vpr_byte( &mut device.rsp.cpu.vpr[rd(opcode) as usize], - (device.rsp.cpu.gpr[rt(opcode) as usize] >> 8) as u8, velement(opcode), + (device.rsp.cpu.gpr[rt(opcode) as usize] >> 8) as u8, ); if velement(opcode) != 15 { modify_vpr_byte( &mut device.rsp.cpu.vpr[rd(opcode) as usize], - device.rsp.cpu.gpr[rt(opcode) as usize] as u8, velement(opcode) + 1, + device.rsp.cpu.gpr[rt(opcode) as usize] as u8, ); } } @@ -591,8 +591,8 @@ pub fn lbv(device: &mut device::Device, opcode: u32) { let element = velement(opcode); modify_vpr_byte( &mut device.rsp.cpu.vpr[rt(opcode) as usize], - device.rsp.mem[(address & 0xFFF) as usize], element, + device.rsp.mem[(address & 0xFFF) as usize], ); } @@ -605,8 +605,8 @@ pub fn lsv(device: &mut device::Device, opcode: u32) { while element < end { modify_vpr_byte( &mut device.rsp.cpu.vpr[rt(opcode) as usize], - device.rsp.mem[(address & 0xFFF) as usize], element, + device.rsp.mem[(address & 0xFFF) as usize], ); address += 1; element += 1; @@ -622,8 +622,8 @@ pub fn llv(device: &mut device::Device, opcode: u32) { while element < end { modify_vpr_byte( &mut device.rsp.cpu.vpr[rt(opcode) as usize], - device.rsp.mem[(address & 0xFFF) as usize], element, + device.rsp.mem[(address & 0xFFF) as usize], ); address += 1; element += 1; @@ -639,8 +639,8 @@ pub fn ldv(device: &mut device::Device, opcode: u32) { while element < end { modify_vpr_byte( &mut device.rsp.cpu.vpr[rt(opcode) as usize], - device.rsp.mem[(address & 0xFFF) as usize], element, + device.rsp.mem[(address & 0xFFF) as usize], ); address += 1; element += 1; @@ -656,8 +656,8 @@ pub fn lqv(device: &mut device::Device, opcode: u32) { while element < end { modify_vpr_byte( &mut device.rsp.cpu.vpr[rt(opcode) as usize], - device.rsp.mem[(address & 0xFFF) as usize], element, + device.rsp.mem[(address & 0xFFF) as usize], ); address += 1; element += 1; @@ -673,8 +673,8 @@ pub fn lrv(device: &mut device::Device, opcode: u32) { while element < 16 { modify_vpr_byte( &mut device.rsp.cpu.vpr[rt(opcode) as usize], - device.rsp.mem[(address & 0xFFF) as usize], element, + device.rsp.mem[(address & 0xFFF) as usize], ); address += 1; element += 1; @@ -691,10 +691,10 @@ pub fn lpv(device: &mut device::Device, opcode: u32) { while offset < 8 { modify_vpr_element( &mut device.rsp.cpu.vpr[rt(opcode) as usize], + offset, (device.rsp.mem[((address.wrapping_add(((index.wrapping_add(offset)) & 15) as u32)) & 0xFFF) as usize] as u16) << 8, - offset, ); offset += 1; } @@ -710,10 +710,10 @@ pub fn luv(device: &mut device::Device, opcode: u32) { while offset < 8 { modify_vpr_element( &mut device.rsp.cpu.vpr[rt(opcode) as usize], + offset, (device.rsp.mem[((address.wrapping_add(((index.wrapping_add(offset)) & 15) as u32)) & 0xFFF) as usize] as u16) << 7, - offset, ); offset += 1; } @@ -729,10 +729,10 @@ pub fn lhv(device: &mut device::Device, opcode: u32) { while offset < 8 { modify_vpr_element( &mut device.rsp.cpu.vpr[rt(opcode) as usize], + offset, (device.rsp.mem[((address.wrapping_add(((index.wrapping_add(offset * 2)) & 15) as u32)) & 0xFFF) as usize] as u16) << 7, - offset, ); offset += 1; } @@ -751,25 +751,25 @@ pub fn lfv(device: &mut device::Device, opcode: u32) { while offset < 4 { modify_vpr_element( &mut tmp, + offset, (device.rsp.mem[((address.wrapping_add(((index.wrapping_add(offset * 4)) & 15) as u32)) & 0xFFF) as usize] as u16) << 7, - offset, ); modify_vpr_element( &mut tmp, + offset + 4, (device.rsp.mem[((address .wrapping_add(((index.wrapping_add(offset * 4).wrapping_add(8)) & 15) as u32)) & 0xFFF) as usize] as u16) << 7, - offset + 4, ); offset += 1; } offset = start; while offset < end { let value = get_vpr_byte(tmp, offset); - modify_vpr_byte(&mut device.rsp.cpu.vpr[rt(opcode) as usize], value, offset); + modify_vpr_byte(&mut device.rsp.cpu.vpr[rt(opcode) as usize], offset, value); offset += 1; } } @@ -788,8 +788,8 @@ pub fn ltv(device: &mut device::Device, opcode: u32) { while i < 8 { modify_vpr_byte( &mut device.rsp.cpu.vpr[(vtbase + vtoff) as usize], - device.rsp.mem[(address & 0xFFF) as usize], i * 2, + device.rsp.mem[(address & 0xFFF) as usize], ); address += 1; if address == begin + 16 { @@ -797,8 +797,8 @@ pub fn ltv(device: &mut device::Device, opcode: u32) { } modify_vpr_byte( &mut device.rsp.cpu.vpr[(vtbase + vtoff) as usize], - device.rsp.mem[(address & 0xFFF) as usize], i * 2 + 1, + device.rsp.mem[(address & 0xFFF) as usize], ); address += 1; if address == begin + 16 { diff --git a/src/device/rsp_vu_instructions.rs b/src/device/rsp_vu_instructions.rs index 214456c..3108cb0 100644 --- a/src/device/rsp_vu_instructions.rs +++ b/src/device/rsp_vu_instructions.rs @@ -1,4 +1,5 @@ use crate::device; +use crate::device::rsp_su_instructions::{get_vpr_element, modify_vpr_element}; use std::arch::x86_64::*; pub fn vt(opcode: u32) -> u32 { @@ -58,18 +59,6 @@ pub fn s_clip(x: i64, bits: u32) -> i64 { ((((x as u64) & m) ^ b).wrapping_sub(b)) as i64 } -pub fn modify_vpr_element(vpr: &mut u128, value: u16, element: u8) { - let pos = 7 - (element & 7); - let mask = 0xFFFF << (pos * 16); - *vpr &= !mask; - *vpr |= (value as u128) << (pos * 16); -} - -pub fn get_vpr_element(vpr: u128, element: u8) -> u16 { - let pos = 7 - (element & 7); - (vpr >> (pos * 16)) as u16 -} - pub fn vte(device: &device::Device, vt: u32, index: usize) -> __m128i { unsafe { _mm_shuffle_epi8( @@ -195,13 +184,13 @@ pub fn vrndp(device: &mut device::Device, opcode: u32) { if acc >= 0 { acc = s_clip(acc + (product as i64), 48) } - modify_vpr_element(acch, (acc >> 32) as u16, n); - modify_vpr_element(accm, (acc >> 16) as u16, n); - modify_vpr_element(accl, acc as u16, n); + modify_vpr_element(acch, n, (acc >> 32) as u16); + modify_vpr_element(accm, n, (acc >> 16) as u16); + modify_vpr_element(accl, n, acc as u16); modify_vpr_element( &mut device.rsp.cpu.vpr[vd(opcode) as usize], - clamp_signed_64(acc >> 16) as u16, n, + clamp_signed_64(acc >> 16) as u16, ); n += 1; @@ -228,13 +217,13 @@ pub fn vmulq(device: &mut device::Device, opcode: u32) { if product < 0 { product += 31; } - modify_vpr_element(acch, (product >> 16) as u16, n); - modify_vpr_element(accm, (product) as u16, n); - modify_vpr_element(accl, 0, n); + modify_vpr_element(acch, n, (product >> 16) as u16); + modify_vpr_element(accm, n, (product) as u16); + modify_vpr_element(accl, n, 0); modify_vpr_element( &mut device.rsp.cpu.vpr[vd(opcode) as usize], - (clamp_signed_32(product >> 1) & !15) as u16, n, + (clamp_signed_32(product >> 1) & !15) as u16, ); n += 1; } @@ -458,13 +447,13 @@ pub fn vrndn(device: &mut device::Device, opcode: u32) { if acc < 0 { acc = s_clip(acc + (product as i64), 48) } - modify_vpr_element(acch, (acc >> 32) as u16, n); - modify_vpr_element(accm, (acc >> 16) as u16, n); - modify_vpr_element(accl, acc as u16, n); + modify_vpr_element(acch, n, (acc >> 32) as u16); + modify_vpr_element(accm, n, (acc >> 16) as u16); + modify_vpr_element(accl, n, acc as u16); modify_vpr_element( &mut device.rsp.cpu.vpr[vd(opcode) as usize], - clamp_signed_64(acc >> 16) as u16, n, + clamp_signed_64(acc >> 16) as u16, ); n += 1; @@ -484,12 +473,12 @@ pub fn vmacq(device: &mut device::Device, opcode: u32) { } else if product >= 32 && (product & (1 << 5)) == 0 { product -= 32 } - modify_vpr_element(acch, (product >> 16) as u16, n); - modify_vpr_element(accm, (product) as u16, n); + modify_vpr_element(acch, n, (product >> 16) as u16); + modify_vpr_element(accm, n, (product) as u16); modify_vpr_element( &mut device.rsp.cpu.vpr[vd(opcode) as usize], - (clamp_signed_32(product >> 1) & !15) as u16, n, + (clamp_signed_32(product >> 1) & !15) as u16, ); n += 1; } @@ -1266,8 +1255,8 @@ pub fn vrcp(device: &mut device::Device, opcode: u32) { device.rsp.cpu.accl = vte; modify_vpr_element( &mut device.rsp.cpu.vpr[vd(opcode) as usize], - result as u16, de(opcode) as u8, + result as u16, ); } @@ -1302,8 +1291,8 @@ pub fn vrcpl(device: &mut device::Device, opcode: u32) { device.rsp.cpu.accl = vte; modify_vpr_element( &mut device.rsp.cpu.vpr[vd(opcode) as usize], - result as u16, de(opcode) as u8, + result as u16, ); } @@ -1316,8 +1305,8 @@ pub fn vrcph(device: &mut device::Device, opcode: u32) { get_vpr_element(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16; modify_vpr_element( &mut device.rsp.cpu.vpr[vd(opcode) as usize], - device.rsp.cpu.divout as u16, de(opcode) as u8, + device.rsp.cpu.divout as u16, ); } @@ -1329,8 +1318,8 @@ pub fn vmov(device: &mut device::Device, opcode: u32) { ); modify_vpr_element( &mut device.rsp.cpu.vpr[vd(opcode) as usize], - value, de(opcode) as u8, + value, ); device.rsp.cpu.accl = vte; } @@ -1362,8 +1351,8 @@ pub fn vrsq(device: &mut device::Device, opcode: u32) { device.rsp.cpu.accl = vte; modify_vpr_element( &mut device.rsp.cpu.vpr[vd(opcode) as usize], - result as u16, de(opcode) as u8, + result as u16, ); } @@ -1399,8 +1388,8 @@ pub fn vrsql(device: &mut device::Device, opcode: u32) { device.rsp.cpu.accl = vte; modify_vpr_element( &mut device.rsp.cpu.vpr[vd(opcode) as usize], - result as u16, de(opcode) as u8, + result as u16, ); } @@ -1413,8 +1402,8 @@ pub fn vrsqh(device: &mut device::Device, opcode: u32) { get_vpr_element(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16; modify_vpr_element( &mut device.rsp.cpu.vpr[vd(opcode) as usize], - device.rsp.cpu.divout as u16, de(opcode) as u8, + device.rsp.cpu.divout as u16, ); }