RSP cleanup (#124)
This commit is contained in:
parent
e71d5a1b2d
commit
9a3a56d0c6
@ -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 {
|
||||
|
||||
@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user