RSP cleanup (#124)

This commit is contained in:
Logan McNaughton 2025-01-11 14:34:16 +01:00 committed by GitHub
parent e71d5a1b2d
commit 9a3a56d0c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 41 additions and 52 deletions

View File

@ -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 {

View File

@ -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,
);
}