Remove loops in RSP code (#136)
* Remove loops in RSP cose * more * more * more * more * more
This commit is contained in:
parent
cd106345c9
commit
d3c26fb359
@ -85,6 +85,7 @@ int _mm_extract_epi8__extern(__m128i __a, const int __imm8)
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
__m128i _mm_insert_epi16__extern(__m128i __a, int __i, const int __imm8)
|
||||
{
|
||||
switch (__imm8)
|
||||
@ -134,3 +135,63 @@ int _mm_extract_epi16__extern(__m128i __a, const int __imm8)
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
__m128i _mm_insert_epi32__extern(__m128i __a, int __i, const int __imm8)
|
||||
{
|
||||
switch (__imm8)
|
||||
{
|
||||
case 0:
|
||||
return _mm_insert_epi32(__a, __i, 0);
|
||||
case 1:
|
||||
return _mm_insert_epi32(__a, __i, 1);
|
||||
case 2:
|
||||
return _mm_insert_epi32(__a, __i, 2);
|
||||
case 3:
|
||||
return _mm_insert_epi32(__a, __i, 3);
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
int _mm_extract_epi32__extern(__m128i __a, const int __imm8)
|
||||
{
|
||||
switch (__imm8)
|
||||
{
|
||||
case 0:
|
||||
return _mm_extract_epi32(__a, 0);
|
||||
case 1:
|
||||
return _mm_extract_epi32(__a, 1);
|
||||
case 2:
|
||||
return _mm_extract_epi32(__a, 2);
|
||||
case 3:
|
||||
return _mm_extract_epi32(__a, 3);
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
__m128i _mm_insert_epi64__extern(__m128i __a, int64_t __i, const int __imm8)
|
||||
{
|
||||
switch (__imm8)
|
||||
{
|
||||
case 0:
|
||||
return _mm_insert_epi64(__a, __i, 0);
|
||||
case 1:
|
||||
return _mm_insert_epi64(__a, __i, 1);
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
int64_t _mm_extract_epi64__extern(__m128i __a, const int __imm8)
|
||||
{
|
||||
switch (__imm8)
|
||||
{
|
||||
case 0:
|
||||
return _mm_extract_epi64(__a, 0);
|
||||
case 1:
|
||||
return _mm_extract_epi64(__a, 1);
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,4 +21,27 @@ unsafe extern "C" {
|
||||
|
||||
#[link_name = "_mm_extract_epi16__extern"]
|
||||
pub fn _mm_extract_epi16(__a: __m128i, __imm8: ::std::os::raw::c_int) -> ::std::os::raw::c_int;
|
||||
|
||||
#[link_name = "_mm_insert_epi32__extern"]
|
||||
pub fn _mm_insert_epi32(
|
||||
__a: __m128i,
|
||||
__i: ::std::os::raw::c_int,
|
||||
__imm8: ::std::os::raw::c_int,
|
||||
) -> __m128i;
|
||||
|
||||
#[link_name = "_mm_extract_epi32__extern"]
|
||||
pub fn _mm_extract_epi32(__a: __m128i, __imm8: ::std::os::raw::c_int) -> ::std::os::raw::c_int;
|
||||
|
||||
#[link_name = "_mm_insert_epi64__extern"]
|
||||
pub fn _mm_insert_epi64(
|
||||
__a: __m128i,
|
||||
__i: ::std::os::raw::c_longlong,
|
||||
__imm8: ::std::os::raw::c_int,
|
||||
) -> __m128i;
|
||||
|
||||
#[link_name = "_mm_extract_epi64__extern"]
|
||||
pub fn _mm_extract_epi64(
|
||||
__a: __m128i,
|
||||
__imm8: ::std::os::raw::c_int,
|
||||
) -> ::std::os::raw::c_longlong;
|
||||
}
|
||||
|
||||
@ -46,7 +46,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 __m128i, element: u8, value: u8) {
|
||||
pub fn modify_vpr8(vpr: &mut __m128i, element: u8, value: u8) {
|
||||
unsafe {
|
||||
*vpr = match element & 15 {
|
||||
0 => _mm_insert_epi8(*vpr, value as i32, 15),
|
||||
@ -70,7 +70,7 @@ pub fn modify_vpr_byte(vpr: &mut __m128i, element: u8, value: u8) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_vpr_byte(vpr: __m128i, element: u8) -> u8 {
|
||||
pub fn get_vpr8(vpr: __m128i, element: u8) -> u8 {
|
||||
unsafe {
|
||||
match element & 15 {
|
||||
0 => _mm_extract_epi8(vpr, 15) as u8,
|
||||
@ -94,7 +94,7 @@ pub fn get_vpr_byte(vpr: __m128i, element: u8) -> u8 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn modify_vpr_element(vpr: &mut __m128i, element: u8, value: u16) {
|
||||
pub fn modify_vpr16(vpr: &mut __m128i, element: u8, value: u16) {
|
||||
unsafe {
|
||||
*vpr = match element & 7 {
|
||||
0 => _mm_insert_epi16(*vpr, value as i32, 7),
|
||||
@ -110,7 +110,7 @@ pub fn modify_vpr_element(vpr: &mut __m128i, element: u8, value: u16) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_vpr_element(vpr: __m128i, element: u8) -> u16 {
|
||||
pub fn get_vpr16(vpr: __m128i, element: u8) -> u16 {
|
||||
unsafe {
|
||||
match element & 7 {
|
||||
0 => _mm_extract_epi16(vpr, 7) as u16,
|
||||
@ -126,6 +126,58 @@ pub fn get_vpr_element(vpr: __m128i, element: u8) -> u16 {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn modify_vpr32(vpr: &mut __m128i, element: u8, value: u32) {
|
||||
unsafe {
|
||||
*vpr = match element & 3 {
|
||||
0 => _mm_insert_epi32(*vpr, value as i32, 3),
|
||||
1 => _mm_insert_epi32(*vpr, value as i32, 2),
|
||||
2 => _mm_insert_epi32(*vpr, value as i32, 1),
|
||||
3 => _mm_insert_epi32(*vpr, value as i32, 0),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_vpr32(vpr: __m128i, element: u8) -> u32 {
|
||||
unsafe {
|
||||
match element & 3 {
|
||||
0 => _mm_extract_epi32(vpr, 3) as u32,
|
||||
1 => _mm_extract_epi32(vpr, 2) as u32,
|
||||
2 => _mm_extract_epi32(vpr, 1) as u32,
|
||||
3 => _mm_extract_epi32(vpr, 0) as u32,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn modify_vpr64(vpr: &mut __m128i, element: u8, value: u64) {
|
||||
unsafe {
|
||||
*vpr = match element & 1 {
|
||||
0 => _mm_insert_epi64(*vpr, value as i64, 1),
|
||||
1 => _mm_insert_epi64(*vpr, value as i64, 0),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_vpr64(vpr: __m128i, element: u8) -> u64 {
|
||||
unsafe {
|
||||
match element & 1 {
|
||||
0 => _mm_extract_epi64(vpr, 1) as u64,
|
||||
1 => _mm_extract_epi64(vpr, 0) as u64,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn modify_vpr128(vpr: &mut __m128i, value: u128) {
|
||||
unsafe { *vpr = std::mem::transmute::<u128, __m128i>(value) }
|
||||
}
|
||||
|
||||
pub fn get_vpr128(vpr: __m128i) -> u128 {
|
||||
unsafe { std::mem::transmute::<__m128i, u128>(vpr) }
|
||||
}
|
||||
|
||||
pub fn j(device: &mut device::Device, opcode: u32) {
|
||||
if device::rsp_cpu::in_delay_slot_taken(device) {
|
||||
return;
|
||||
@ -544,8 +596,8 @@ pub fn mtc0(device: &mut device::Device, opcode: u32) {
|
||||
}
|
||||
|
||||
pub fn mfc2(device: &mut device::Device, opcode: u32) {
|
||||
let hi = get_vpr_byte(device.rsp.cpu.vpr[rd(opcode) as usize], velement(opcode));
|
||||
let lo = get_vpr_byte(
|
||||
let hi = get_vpr8(device.rsp.cpu.vpr[rd(opcode) as usize], velement(opcode));
|
||||
let lo = get_vpr8(
|
||||
device.rsp.cpu.vpr[rd(opcode) as usize],
|
||||
velement(opcode) + 1,
|
||||
);
|
||||
@ -583,13 +635,13 @@ pub fn cfc2(device: &mut device::Device, opcode: u32) {
|
||||
}
|
||||
|
||||
pub fn mtc2(device: &mut device::Device, opcode: u32) {
|
||||
modify_vpr_byte(
|
||||
modify_vpr8(
|
||||
&mut device.rsp.cpu.vpr[rd(opcode) as usize],
|
||||
velement(opcode),
|
||||
(device.rsp.cpu.gpr[rt(opcode) as usize] >> 8) as u8,
|
||||
);
|
||||
if velement(opcode) != 15 {
|
||||
modify_vpr_byte(
|
||||
modify_vpr8(
|
||||
&mut device.rsp.cpu.vpr[rd(opcode) as usize],
|
||||
velement(opcode) + 1,
|
||||
device.rsp.cpu.gpr[rt(opcode) as usize] as u8,
|
||||
@ -652,7 +704,7 @@ pub fn lbv(device: &mut device::Device, opcode: u32) {
|
||||
.wrapping_add(sign_extend_7bit_offset(voffset(opcode), 0));
|
||||
|
||||
let element = velement(opcode);
|
||||
modify_vpr_byte(
|
||||
modify_vpr8(
|
||||
&mut device.rsp.cpu.vpr[rt(opcode) as usize],
|
||||
element,
|
||||
device.rsp.mem[(address & 0xFFF) as usize],
|
||||
@ -664,15 +716,25 @@ pub fn lsv(device: &mut device::Device, opcode: u32) {
|
||||
.wrapping_add(sign_extend_7bit_offset(voffset(opcode), 1));
|
||||
|
||||
let mut element = velement(opcode);
|
||||
let end = std::cmp::min(element + 2, 16);
|
||||
while element < end {
|
||||
modify_vpr_byte(
|
||||
|
||||
if element % 2 == 0 {
|
||||
modify_vpr16(
|
||||
&mut device.rsp.cpu.vpr[rt(opcode) as usize],
|
||||
element,
|
||||
device.rsp.mem[(address & 0xFFF) as usize],
|
||||
element / 2,
|
||||
(device.rsp.mem[(address & 0xFFF) as usize] as u16) << 8
|
||||
| (device.rsp.mem[((address + 1) & 0xFFF) as usize] as u16),
|
||||
);
|
||||
address += 1;
|
||||
element += 1;
|
||||
} else {
|
||||
let end = std::cmp::min(element + 2, 16);
|
||||
while element < end {
|
||||
modify_vpr8(
|
||||
&mut device.rsp.cpu.vpr[rt(opcode) as usize],
|
||||
element,
|
||||
device.rsp.mem[(address & 0xFFF) as usize],
|
||||
);
|
||||
address += 1;
|
||||
element += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -681,15 +743,27 @@ pub fn llv(device: &mut device::Device, opcode: u32) {
|
||||
.wrapping_add(sign_extend_7bit_offset(voffset(opcode), 2));
|
||||
|
||||
let mut element = velement(opcode);
|
||||
let end = std::cmp::min(element + 4, 16);
|
||||
while element < end {
|
||||
modify_vpr_byte(
|
||||
|
||||
if element % 4 == 0 {
|
||||
modify_vpr32(
|
||||
&mut device.rsp.cpu.vpr[rt(opcode) as usize],
|
||||
element,
|
||||
device.rsp.mem[(address & 0xFFF) as usize],
|
||||
element / 4,
|
||||
(device.rsp.mem[(address & 0xFFF) as usize] as u32) << (8 * 3)
|
||||
| (device.rsp.mem[((address + 1) & 0xFFF) as usize] as u32) << (8 * 2)
|
||||
| (device.rsp.mem[((address + 2) & 0xFFF) as usize] as u32) << 8
|
||||
| (device.rsp.mem[((address + 3) & 0xFFF) as usize] as u32),
|
||||
);
|
||||
address += 1;
|
||||
element += 1;
|
||||
} else {
|
||||
let end = std::cmp::min(element + 4, 16);
|
||||
while element < end {
|
||||
modify_vpr8(
|
||||
&mut device.rsp.cpu.vpr[rt(opcode) as usize],
|
||||
element,
|
||||
device.rsp.mem[(address & 0xFFF) as usize],
|
||||
);
|
||||
address += 1;
|
||||
element += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -698,15 +772,31 @@ pub fn ldv(device: &mut device::Device, opcode: u32) {
|
||||
.wrapping_add(sign_extend_7bit_offset(voffset(opcode), 3));
|
||||
|
||||
let mut element = velement(opcode);
|
||||
let end = std::cmp::min(element + 8, 16);
|
||||
while element < end {
|
||||
modify_vpr_byte(
|
||||
|
||||
if element % 8 == 0 {
|
||||
modify_vpr64(
|
||||
&mut device.rsp.cpu.vpr[rt(opcode) as usize],
|
||||
element,
|
||||
device.rsp.mem[(address & 0xFFF) as usize],
|
||||
element / 8,
|
||||
(device.rsp.mem[(address & 0xFFF) as usize] as u64) << (8 * 7)
|
||||
| (device.rsp.mem[((address + 1) & 0xFFF) as usize] as u64) << (8 * 6)
|
||||
| (device.rsp.mem[((address + 2) & 0xFFF) as usize] as u64) << (8 * 5)
|
||||
| (device.rsp.mem[((address + 3) & 0xFFF) as usize] as u64) << (8 * 4)
|
||||
| (device.rsp.mem[((address + 4) & 0xFFF) as usize] as u64) << (8 * 3)
|
||||
| (device.rsp.mem[((address + 5) & 0xFFF) as usize] as u64) << (8 * 2)
|
||||
| (device.rsp.mem[((address + 6) & 0xFFF) as usize] as u64) << 8
|
||||
| (device.rsp.mem[((address + 7) & 0xFFF) as usize] as u64),
|
||||
);
|
||||
address += 1;
|
||||
element += 1;
|
||||
} else {
|
||||
let end = std::cmp::min(element + 8, 16);
|
||||
while element < end {
|
||||
modify_vpr8(
|
||||
&mut device.rsp.cpu.vpr[rt(opcode) as usize],
|
||||
element,
|
||||
device.rsp.mem[(address & 0xFFF) as usize],
|
||||
);
|
||||
address += 1;
|
||||
element += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -715,15 +805,38 @@ pub fn lqv(device: &mut device::Device, opcode: u32) {
|
||||
.wrapping_add(sign_extend_7bit_offset(voffset(opcode), 4));
|
||||
|
||||
let mut element = velement(opcode);
|
||||
let end = std::cmp::min(16 + element - ((address & 15) as u8), 16);
|
||||
while element < end {
|
||||
modify_vpr_byte(
|
||||
|
||||
if element == 0 && address % 16 == 0 {
|
||||
modify_vpr128(
|
||||
&mut device.rsp.cpu.vpr[rt(opcode) as usize],
|
||||
element,
|
||||
device.rsp.mem[(address & 0xFFF) as usize],
|
||||
(device.rsp.mem[(address & 0xFFF) as usize] as u128) << (8 * 15)
|
||||
| (device.rsp.mem[((address + 1) & 0xFFF) as usize] as u128) << (8 * 14)
|
||||
| (device.rsp.mem[((address + 2) & 0xFFF) as usize] as u128) << (8 * 13)
|
||||
| (device.rsp.mem[((address + 3) & 0xFFF) as usize] as u128) << (8 * 12)
|
||||
| (device.rsp.mem[((address + 4) & 0xFFF) as usize] as u128) << (8 * 11)
|
||||
| (device.rsp.mem[((address + 5) & 0xFFF) as usize] as u128) << (8 * 10)
|
||||
| (device.rsp.mem[((address + 6) & 0xFFF) as usize] as u128) << (8 * 9)
|
||||
| (device.rsp.mem[((address + 7) & 0xFFF) as usize] as u128) << (8 * 8)
|
||||
| (device.rsp.mem[((address + 8) & 0xFFF) as usize] as u128) << (8 * 7)
|
||||
| (device.rsp.mem[((address + 9) & 0xFFF) as usize] as u128) << (8 * 6)
|
||||
| (device.rsp.mem[((address + 10) & 0xFFF) as usize] as u128) << (8 * 5)
|
||||
| (device.rsp.mem[((address + 11) & 0xFFF) as usize] as u128) << (8 * 4)
|
||||
| (device.rsp.mem[((address + 12) & 0xFFF) as usize] as u128) << (8 * 3)
|
||||
| (device.rsp.mem[((address + 13) & 0xFFF) as usize] as u128) << (8 * 2)
|
||||
| (device.rsp.mem[((address + 14) & 0xFFF) as usize] as u128) << 8
|
||||
| (device.rsp.mem[((address + 15) & 0xFFF) as usize] as u128),
|
||||
);
|
||||
address += 1;
|
||||
element += 1;
|
||||
} else {
|
||||
let end = std::cmp::min(16 + element - ((address & 15) as u8), 16);
|
||||
while element < end {
|
||||
modify_vpr8(
|
||||
&mut device.rsp.cpu.vpr[rt(opcode) as usize],
|
||||
element,
|
||||
device.rsp.mem[(address & 0xFFF) as usize],
|
||||
);
|
||||
address += 1;
|
||||
element += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -733,14 +846,36 @@ pub fn lrv(device: &mut device::Device, opcode: u32) {
|
||||
|
||||
let mut element = 16u8.wrapping_sub(((address & 15) as u8).wrapping_sub(velement(opcode)));
|
||||
address &= !15;
|
||||
while element < 16 {
|
||||
modify_vpr_byte(
|
||||
if element == 0 {
|
||||
modify_vpr128(
|
||||
&mut device.rsp.cpu.vpr[rt(opcode) as usize],
|
||||
element,
|
||||
device.rsp.mem[(address & 0xFFF) as usize],
|
||||
(device.rsp.mem[(address & 0xFFF) as usize] as u128) << (8 * 15)
|
||||
| (device.rsp.mem[((address + 1) & 0xFFF) as usize] as u128) << (8 * 14)
|
||||
| (device.rsp.mem[((address + 2) & 0xFFF) as usize] as u128) << (8 * 13)
|
||||
| (device.rsp.mem[((address + 3) & 0xFFF) as usize] as u128) << (8 * 12)
|
||||
| (device.rsp.mem[((address + 4) & 0xFFF) as usize] as u128) << (8 * 11)
|
||||
| (device.rsp.mem[((address + 5) & 0xFFF) as usize] as u128) << (8 * 10)
|
||||
| (device.rsp.mem[((address + 6) & 0xFFF) as usize] as u128) << (8 * 9)
|
||||
| (device.rsp.mem[((address + 7) & 0xFFF) as usize] as u128) << (8 * 8)
|
||||
| (device.rsp.mem[((address + 8) & 0xFFF) as usize] as u128) << (8 * 7)
|
||||
| (device.rsp.mem[((address + 9) & 0xFFF) as usize] as u128) << (8 * 6)
|
||||
| (device.rsp.mem[((address + 10) & 0xFFF) as usize] as u128) << (8 * 5)
|
||||
| (device.rsp.mem[((address + 11) & 0xFFF) as usize] as u128) << (8 * 4)
|
||||
| (device.rsp.mem[((address + 12) & 0xFFF) as usize] as u128) << (8 * 3)
|
||||
| (device.rsp.mem[((address + 13) & 0xFFF) as usize] as u128) << (8 * 2)
|
||||
| (device.rsp.mem[((address + 14) & 0xFFF) as usize] as u128) << 8
|
||||
| (device.rsp.mem[((address + 15) & 0xFFF) as usize] as u128),
|
||||
);
|
||||
address += 1;
|
||||
element += 1;
|
||||
} else {
|
||||
while element < 16 {
|
||||
modify_vpr8(
|
||||
&mut device.rsp.cpu.vpr[rt(opcode) as usize],
|
||||
element,
|
||||
device.rsp.mem[(address & 0xFFF) as usize],
|
||||
);
|
||||
address += 1;
|
||||
element += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -750,14 +885,34 @@ pub fn lpv(device: &mut device::Device, opcode: u32) {
|
||||
|
||||
let index = ((address & 7) as u8).wrapping_sub(velement(opcode));
|
||||
address &= !7;
|
||||
for offset in 0..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,
|
||||
);
|
||||
unsafe {
|
||||
device.rsp.cpu.vpr[rt(opcode) as usize] =
|
||||
_mm_set_epi16(
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(0)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 8,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(1)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 8,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(2)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 8,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(3)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 8,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(4)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 8,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(5)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 8,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(6)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 8,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(7)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 8,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -767,14 +922,34 @@ pub fn luv(device: &mut device::Device, opcode: u32) {
|
||||
|
||||
let index = ((address & 7) as u8).wrapping_sub(velement(opcode));
|
||||
address &= !7;
|
||||
for offset in 0..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,
|
||||
);
|
||||
unsafe {
|
||||
device.rsp.cpu.vpr[rt(opcode) as usize] =
|
||||
_mm_set_epi16(
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(0)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 7,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(1)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 7,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(2)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 7,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(3)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 7,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(4)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 7,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(5)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 7,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(6)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 7,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(7)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 7,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -784,14 +959,34 @@ pub fn lhv(device: &mut device::Device, opcode: u32) {
|
||||
|
||||
let index = ((address & 7) as u8).wrapping_sub(velement(opcode));
|
||||
address &= !7;
|
||||
for offset in 0..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,
|
||||
);
|
||||
unsafe {
|
||||
device.rsp.cpu.vpr[rt(opcode) as usize] =
|
||||
_mm_set_epi16(
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(0)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 7,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(2)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 7,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(4)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 7,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(6)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 7,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(8)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 7,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(10)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 7,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(12)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 7,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(14)) & 15) as u32))
|
||||
& 0xFFF) as usize] as i16)
|
||||
<< 7,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -806,14 +1001,14 @@ pub fn lfv(device: &mut device::Device, opcode: u32) {
|
||||
let mut tmp: __m128i = unsafe { _mm_setzero_si128() };
|
||||
let mut offset: u8 = 0;
|
||||
while offset < 4 {
|
||||
modify_vpr_element(
|
||||
modify_vpr16(
|
||||
&mut tmp,
|
||||
offset,
|
||||
(device.rsp.mem[((address.wrapping_add(((index.wrapping_add(offset * 4)) & 15) as u32))
|
||||
& 0xFFF) as usize] as u16)
|
||||
<< 7,
|
||||
);
|
||||
modify_vpr_element(
|
||||
modify_vpr16(
|
||||
&mut tmp,
|
||||
offset + 4,
|
||||
(device.rsp.mem[((address
|
||||
@ -825,8 +1020,8 @@ pub fn lfv(device: &mut device::Device, opcode: u32) {
|
||||
}
|
||||
offset = start;
|
||||
while offset < end {
|
||||
let value = get_vpr_byte(tmp, offset);
|
||||
modify_vpr_byte(&mut device.rsp.cpu.vpr[rt(opcode) as usize], offset, value);
|
||||
let value = get_vpr8(tmp, offset);
|
||||
modify_vpr8(&mut device.rsp.cpu.vpr[rt(opcode) as usize], offset, value);
|
||||
offset += 1;
|
||||
}
|
||||
}
|
||||
@ -842,7 +1037,7 @@ pub fn ltv(device: &mut device::Device, opcode: u32) {
|
||||
let vtbase = rt(opcode) & !7;
|
||||
let mut vtoff = (velement(opcode)) as u32 >> 1;
|
||||
for i in 0..8 {
|
||||
modify_vpr_byte(
|
||||
modify_vpr8(
|
||||
&mut device.rsp.cpu.vpr[(vtbase + vtoff) as usize],
|
||||
i * 2,
|
||||
device.rsp.mem[(address & 0xFFF) as usize],
|
||||
@ -851,7 +1046,7 @@ pub fn ltv(device: &mut device::Device, opcode: u32) {
|
||||
if address == begin + 16 {
|
||||
address = begin
|
||||
}
|
||||
modify_vpr_byte(
|
||||
modify_vpr8(
|
||||
&mut device.rsp.cpu.vpr[(vtbase + vtoff) as usize],
|
||||
i * 2 + 1,
|
||||
device.rsp.mem[(address & 0xFFF) as usize],
|
||||
@ -869,7 +1064,7 @@ pub fn sbv(device: &mut device::Device, opcode: u32) {
|
||||
.wrapping_add(sign_extend_7bit_offset(voffset(opcode), 0));
|
||||
|
||||
device.rsp.mem[(address & 0xFFF) as usize] =
|
||||
get_vpr_byte(device.rsp.cpu.vpr[rt(opcode) as usize], velement(opcode))
|
||||
get_vpr8(device.rsp.cpu.vpr[rt(opcode) as usize], velement(opcode))
|
||||
}
|
||||
|
||||
pub fn ssv(device: &mut device::Device, opcode: u32) {
|
||||
@ -877,12 +1072,20 @@ pub fn ssv(device: &mut device::Device, opcode: u32) {
|
||||
.wrapping_add(sign_extend_7bit_offset(voffset(opcode), 1));
|
||||
|
||||
let mut element = velement(opcode);
|
||||
let end = element + 2;
|
||||
while element < end {
|
||||
device.rsp.mem[(address & 0xFFF) as usize] =
|
||||
get_vpr_byte(device.rsp.cpu.vpr[rt(opcode) as usize], element);
|
||||
address += 1;
|
||||
element += 1;
|
||||
|
||||
if element % 2 == 0 {
|
||||
device.rsp.mem[(address & 0xFFF) as usize..((address + 2) & 0xFFF) as usize]
|
||||
.copy_from_slice(
|
||||
&get_vpr16(device.rsp.cpu.vpr[rt(opcode) as usize], element / 2).to_be_bytes(),
|
||||
);
|
||||
} else {
|
||||
let end = element + 2;
|
||||
while element < end {
|
||||
device.rsp.mem[(address & 0xFFF) as usize] =
|
||||
get_vpr8(device.rsp.cpu.vpr[rt(opcode) as usize], element);
|
||||
address += 1;
|
||||
element += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -891,12 +1094,20 @@ pub fn slv(device: &mut device::Device, opcode: u32) {
|
||||
.wrapping_add(sign_extend_7bit_offset(voffset(opcode), 2));
|
||||
|
||||
let mut element = velement(opcode);
|
||||
let end = element + 4;
|
||||
while element < end {
|
||||
device.rsp.mem[(address & 0xFFF) as usize] =
|
||||
get_vpr_byte(device.rsp.cpu.vpr[rt(opcode) as usize], element);
|
||||
address += 1;
|
||||
element += 1;
|
||||
|
||||
if element % 4 == 0 {
|
||||
device.rsp.mem[(address & 0xFFF) as usize..((address + 4) & 0xFFF) as usize]
|
||||
.copy_from_slice(
|
||||
&get_vpr32(device.rsp.cpu.vpr[rt(opcode) as usize], element / 4).to_be_bytes(),
|
||||
);
|
||||
} else {
|
||||
let end = element + 4;
|
||||
while element < end {
|
||||
device.rsp.mem[(address & 0xFFF) as usize] =
|
||||
get_vpr8(device.rsp.cpu.vpr[rt(opcode) as usize], element);
|
||||
address += 1;
|
||||
element += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -905,12 +1116,20 @@ pub fn sdv(device: &mut device::Device, opcode: u32) {
|
||||
.wrapping_add(sign_extend_7bit_offset(voffset(opcode), 3));
|
||||
|
||||
let mut element = velement(opcode);
|
||||
let end = element + 8;
|
||||
while element < end {
|
||||
device.rsp.mem[(address & 0xFFF) as usize] =
|
||||
get_vpr_byte(device.rsp.cpu.vpr[rt(opcode) as usize], element);
|
||||
address += 1;
|
||||
element += 1;
|
||||
|
||||
if element % 8 == 0 {
|
||||
device.rsp.mem[(address & 0xFFF) as usize..((address + 8) & 0xFFF) as usize]
|
||||
.copy_from_slice(
|
||||
&get_vpr64(device.rsp.cpu.vpr[rt(opcode) as usize], element / 8).to_be_bytes(),
|
||||
);
|
||||
} else {
|
||||
let end = element + 8;
|
||||
while element < end {
|
||||
device.rsp.mem[(address & 0xFFF) as usize] =
|
||||
get_vpr8(device.rsp.cpu.vpr[rt(opcode) as usize], element);
|
||||
address += 1;
|
||||
element += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -919,12 +1138,18 @@ pub fn sqv(device: &mut device::Device, opcode: u32) {
|
||||
.wrapping_add(sign_extend_7bit_offset(voffset(opcode), 4));
|
||||
|
||||
let mut element = velement(opcode);
|
||||
let end = element + (16 - (address & 15)) as u8;
|
||||
while element < end {
|
||||
device.rsp.mem[(address & 0xFFF) as usize] =
|
||||
get_vpr_byte(device.rsp.cpu.vpr[rt(opcode) as usize], element);
|
||||
address += 1;
|
||||
element += 1;
|
||||
|
||||
if element == 0 && address % 16 == 0 {
|
||||
device.rsp.mem[(address & 0xFFF) as usize..((address + 16) & 0xFFF) as usize]
|
||||
.copy_from_slice(&get_vpr128(device.rsp.cpu.vpr[rt(opcode) as usize]).to_be_bytes());
|
||||
} else {
|
||||
let end = element + (16 - (address & 15)) as u8;
|
||||
while element < end {
|
||||
device.rsp.mem[(address & 0xFFF) as usize] =
|
||||
get_vpr8(device.rsp.cpu.vpr[rt(opcode) as usize], element);
|
||||
address += 1;
|
||||
element += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -936,11 +1161,17 @@ pub fn srv(device: &mut device::Device, opcode: u32) {
|
||||
let end = element + (address & 15) as u8;
|
||||
let base = (16 - (address & 15)) as u8;
|
||||
address &= !15;
|
||||
while element < end {
|
||||
device.rsp.mem[(address & 0xFFF) as usize] =
|
||||
get_vpr_byte(device.rsp.cpu.vpr[rt(opcode) as usize], element + base);
|
||||
address += 1;
|
||||
element += 1;
|
||||
|
||||
if element == 0 && base == 0 {
|
||||
device.rsp.mem[(address & 0xFFF) as usize..((address + 16) & 0xFFF) as usize]
|
||||
.copy_from_slice(&get_vpr128(device.rsp.cpu.vpr[rt(opcode) as usize]).to_be_bytes());
|
||||
} else {
|
||||
while element < end {
|
||||
device.rsp.mem[(address & 0xFFF) as usize] =
|
||||
get_vpr8(device.rsp.cpu.vpr[rt(opcode) as usize], element + base);
|
||||
address += 1;
|
||||
element += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -953,10 +1184,10 @@ pub fn spv(device: &mut device::Device, opcode: u32) {
|
||||
while element < end {
|
||||
if (element & 15) < 8 {
|
||||
device.rsp.mem[(address & 0xFFF) as usize] =
|
||||
get_vpr_byte(device.rsp.cpu.vpr[rt(opcode) as usize], (element & 7) << 1);
|
||||
get_vpr8(device.rsp.cpu.vpr[rt(opcode) as usize], (element & 7) << 1);
|
||||
} else {
|
||||
device.rsp.mem[(address & 0xFFF) as usize] =
|
||||
(get_vpr_element(device.rsp.cpu.vpr[rt(opcode) as usize], element) >> 7) as u8;
|
||||
(get_vpr16(device.rsp.cpu.vpr[rt(opcode) as usize], element) >> 7) as u8;
|
||||
}
|
||||
address += 1;
|
||||
element += 1;
|
||||
@ -972,10 +1203,10 @@ pub fn suv(device: &mut device::Device, opcode: u32) {
|
||||
while element < end {
|
||||
if (element & 15) < 8 {
|
||||
device.rsp.mem[(address & 0xFFF) as usize] =
|
||||
(get_vpr_element(device.rsp.cpu.vpr[rt(opcode) as usize], element) >> 7) as u8;
|
||||
(get_vpr16(device.rsp.cpu.vpr[rt(opcode) as usize], element) >> 7) as u8;
|
||||
} else {
|
||||
device.rsp.mem[(address & 0xFFF) as usize] =
|
||||
get_vpr_byte(device.rsp.cpu.vpr[rt(opcode) as usize], (element & 7) << 1);
|
||||
get_vpr8(device.rsp.cpu.vpr[rt(opcode) as usize], (element & 7) << 1);
|
||||
}
|
||||
address += 1;
|
||||
element += 1;
|
||||
@ -991,8 +1222,8 @@ pub fn shv(device: &mut device::Device, opcode: u32) {
|
||||
address &= !7;
|
||||
for offset in 0..8 {
|
||||
let byte_val = element + offset * 2;
|
||||
let value = (get_vpr_byte(device.rsp.cpu.vpr[rt(opcode) as usize], byte_val) << 1)
|
||||
| (get_vpr_byte(device.rsp.cpu.vpr[rt(opcode) as usize], byte_val + 1) >> 7);
|
||||
let value = (get_vpr8(device.rsp.cpu.vpr[rt(opcode) as usize], byte_val) << 1)
|
||||
| (get_vpr8(device.rsp.cpu.vpr[rt(opcode) as usize], byte_val + 1) >> 7);
|
||||
device.rsp.mem[((address + ((index + offset * 2) & 15) as u32) & 0xFFF) as usize] = value;
|
||||
}
|
||||
}
|
||||
@ -1021,7 +1252,7 @@ pub fn sfv(device: &mut device::Device, opcode: u32) {
|
||||
let mut offset = 0;
|
||||
for element in elements {
|
||||
device.rsp.mem[((address + ((base + offset) & 15)) & 0xFFF) as usize] =
|
||||
(get_vpr_element(device.rsp.cpu.vpr[rt(opcode) as usize], element) >> 7) as u8;
|
||||
(get_vpr16(device.rsp.cpu.vpr[rt(opcode) as usize], element) >> 7) as u8;
|
||||
offset += 4;
|
||||
}
|
||||
}
|
||||
@ -1036,7 +1267,7 @@ pub fn swv(device: &mut device::Device, opcode: u32) {
|
||||
address &= !7;
|
||||
while element < end {
|
||||
device.rsp.mem[((address + (base & 15)) & 0xFFF) as usize] =
|
||||
get_vpr_byte(device.rsp.cpu.vpr[rt(opcode) as usize], element);
|
||||
get_vpr8(device.rsp.cpu.vpr[rt(opcode) as usize], element);
|
||||
base += 1;
|
||||
element += 1;
|
||||
}
|
||||
@ -1053,11 +1284,11 @@ pub fn stv(device: &mut device::Device, opcode: u32) {
|
||||
let mut offset = start;
|
||||
while offset < end {
|
||||
device.rsp.mem[((address + (base & 15)) & 0xFFF) as usize] =
|
||||
get_vpr_byte(device.rsp.cpu.vpr[offset as usize], element);
|
||||
get_vpr8(device.rsp.cpu.vpr[offset as usize], element);
|
||||
base = base.wrapping_add(1);
|
||||
element += 1;
|
||||
device.rsp.mem[((address + (base & 15)) & 0xFFF) as usize] =
|
||||
get_vpr_byte(device.rsp.cpu.vpr[offset as usize], element);
|
||||
get_vpr8(device.rsp.cpu.vpr[offset as usize], element);
|
||||
base = base.wrapping_add(1);
|
||||
element += 1;
|
||||
offset += 1;
|
||||
|
||||
@ -5,7 +5,7 @@ include!(concat!(env!("OUT_DIR"), "/simd_bindings.rs"));
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
include!("../compat/aarch64.rs");
|
||||
use crate::device;
|
||||
use crate::device::rsp_su_instructions::{get_vpr_element, modify_vpr_element};
|
||||
use crate::device::rsp_su_instructions::{get_vpr16, modify_vpr16};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::arch::x86_64::*;
|
||||
|
||||
@ -107,25 +107,25 @@ pub fn vrndp(device: &mut device::Device, opcode: u32) {
|
||||
let accl: &mut __m128i = &mut device.rsp.cpu.accl;
|
||||
|
||||
for n in 0..8 {
|
||||
let mut product = get_vpr_element(vte, n) as i16 as i32;
|
||||
let mut product = get_vpr16(vte, n) as i16 as i32;
|
||||
if vs(opcode) & 1 != 0 {
|
||||
product <<= 16
|
||||
}
|
||||
let mut acc = 0;
|
||||
acc |= get_vpr_element(*acch, n) as i64;
|
||||
acc |= get_vpr16(*acch, n) as i64;
|
||||
acc <<= 16;
|
||||
acc |= get_vpr_element(*accm, n) as i64;
|
||||
acc |= get_vpr16(*accm, n) as i64;
|
||||
acc <<= 16;
|
||||
acc |= get_vpr_element(*accl, n) as i64;
|
||||
acc |= get_vpr16(*accl, n) as i64;
|
||||
acc <<= 16;
|
||||
acc >>= 16;
|
||||
if acc >= 0 {
|
||||
acc = s_clip(acc + (product as i64), 48)
|
||||
}
|
||||
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(
|
||||
modify_vpr16(acch, n, (acc >> 32) as u16);
|
||||
modify_vpr16(accm, n, (acc >> 16) as u16);
|
||||
modify_vpr16(accl, n, acc as u16);
|
||||
modify_vpr16(
|
||||
&mut device.rsp.cpu.vpr[vd(opcode) as usize],
|
||||
n,
|
||||
clamp_signed_64(acc >> 16) as u16,
|
||||
@ -140,16 +140,15 @@ pub fn vmulq(device: &mut device::Device, opcode: u32) {
|
||||
let accl: &mut __m128i = &mut device.rsp.cpu.accl;
|
||||
|
||||
for n in 0..8 {
|
||||
let mut product = (get_vpr_element(device.rsp.cpu.vpr[vs(opcode) as usize], n) as i16
|
||||
as i32)
|
||||
.wrapping_mul(get_vpr_element(vte, n) as i16 as i32);
|
||||
let mut product = (get_vpr16(device.rsp.cpu.vpr[vs(opcode) as usize], n) as i16 as i32)
|
||||
.wrapping_mul(get_vpr16(vte, n) as i16 as i32);
|
||||
if product < 0 {
|
||||
product += 31;
|
||||
}
|
||||
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(
|
||||
modify_vpr16(acch, n, (product >> 16) as u16);
|
||||
modify_vpr16(accm, n, (product) as u16);
|
||||
modify_vpr16(accl, n, 0);
|
||||
modify_vpr16(
|
||||
&mut device.rsp.cpu.vpr[vd(opcode) as usize],
|
||||
n,
|
||||
(clamp_signed_32(product >> 1) & !15) as u16,
|
||||
@ -282,25 +281,25 @@ pub fn vrndn(device: &mut device::Device, opcode: u32) {
|
||||
let accl: &mut __m128i = &mut device.rsp.cpu.accl;
|
||||
|
||||
for n in 0..8 {
|
||||
let mut product = get_vpr_element(vte, n) as i16 as i32;
|
||||
let mut product = get_vpr16(vte, n) as i16 as i32;
|
||||
if vs(opcode) & 1 != 0 {
|
||||
product <<= 16
|
||||
}
|
||||
let mut acc = 0;
|
||||
acc |= get_vpr_element(*acch, n) as i64;
|
||||
acc |= get_vpr16(*acch, n) as i64;
|
||||
acc <<= 16;
|
||||
acc |= get_vpr_element(*accm, n) as i64;
|
||||
acc |= get_vpr16(*accm, n) as i64;
|
||||
acc <<= 16;
|
||||
acc |= get_vpr_element(*accl, n) as i64;
|
||||
acc |= get_vpr16(*accl, n) as i64;
|
||||
acc <<= 16;
|
||||
acc >>= 16;
|
||||
if acc < 0 {
|
||||
acc = s_clip(acc + (product as i64), 48)
|
||||
}
|
||||
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(
|
||||
modify_vpr16(acch, n, (acc >> 32) as u16);
|
||||
modify_vpr16(accm, n, (acc >> 16) as u16);
|
||||
modify_vpr16(accl, n, acc as u16);
|
||||
modify_vpr16(
|
||||
&mut device.rsp.cpu.vpr[vd(opcode) as usize],
|
||||
n,
|
||||
clamp_signed_64(acc >> 16) as u16,
|
||||
@ -313,16 +312,15 @@ pub fn vmacq(device: &mut device::Device, opcode: u32) {
|
||||
let accm: &mut __m128i = &mut device.rsp.cpu.accm;
|
||||
|
||||
for n in 0..8 {
|
||||
let mut product =
|
||||
((get_vpr_element(*acch, n) as i32) << 16) | (get_vpr_element(*accm, n) as i32);
|
||||
let mut product = ((get_vpr16(*acch, n) as i32) << 16) | (get_vpr16(*accm, n) as i32);
|
||||
if product < 0 && (product & (1 << 5)) == 0 {
|
||||
product += 32
|
||||
} else if product >= 32 && (product & (1 << 5)) == 0 {
|
||||
product -= 32
|
||||
}
|
||||
modify_vpr_element(acch, n, (product >> 16) as u16);
|
||||
modify_vpr_element(accm, n, (product) as u16);
|
||||
modify_vpr_element(
|
||||
modify_vpr16(acch, n, (product >> 16) as u16);
|
||||
modify_vpr16(accm, n, (product) as u16);
|
||||
modify_vpr16(
|
||||
&mut device.rsp.cpu.vpr[vd(opcode) as usize],
|
||||
n,
|
||||
(clamp_signed_32(product >> 1) & !15) as u16,
|
||||
@ -779,8 +777,7 @@ pub fn vnxor(device: &mut device::Device, opcode: u32) {
|
||||
pub fn vrcp(device: &mut device::Device, opcode: u32) {
|
||||
let mut result;
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let input =
|
||||
get_vpr_element(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16 as i32;
|
||||
let input = get_vpr16(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16 as i32;
|
||||
let mask = input >> 31;
|
||||
let mut data = input ^ mask;
|
||||
if input > -32768 {
|
||||
@ -800,7 +797,7 @@ pub fn vrcp(device: &mut device::Device, opcode: u32) {
|
||||
device.rsp.cpu.divdp = false;
|
||||
device.rsp.cpu.divout = (result >> 16) as i16;
|
||||
device.rsp.cpu.accl = vte;
|
||||
modify_vpr_element(
|
||||
modify_vpr16(
|
||||
&mut device.rsp.cpu.vpr[vd(opcode) as usize],
|
||||
de(opcode) as u8,
|
||||
result as u16,
|
||||
@ -812,10 +809,9 @@ pub fn vrcpl(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let input = if device.rsp.cpu.divdp {
|
||||
((device.rsp.cpu.divin as i32) << 16)
|
||||
| get_vpr_element(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as u16
|
||||
as i32
|
||||
| get_vpr16(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as u16 as i32
|
||||
} else {
|
||||
get_vpr_element(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16 as i32
|
||||
get_vpr16(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16 as i32
|
||||
};
|
||||
let mask = input >> 31;
|
||||
let mut data = input ^ mask;
|
||||
@ -836,7 +832,7 @@ pub fn vrcpl(device: &mut device::Device, opcode: u32) {
|
||||
device.rsp.cpu.divdp = false;
|
||||
device.rsp.cpu.divout = (result >> 16) as i16;
|
||||
device.rsp.cpu.accl = vte;
|
||||
modify_vpr_element(
|
||||
modify_vpr16(
|
||||
&mut device.rsp.cpu.vpr[vd(opcode) as usize],
|
||||
de(opcode) as u8,
|
||||
result as u16,
|
||||
@ -849,8 +845,8 @@ pub fn vrcph(device: &mut device::Device, opcode: u32) {
|
||||
device.rsp.cpu.divdp = true;
|
||||
|
||||
device.rsp.cpu.divin =
|
||||
get_vpr_element(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16;
|
||||
modify_vpr_element(
|
||||
get_vpr16(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16;
|
||||
modify_vpr16(
|
||||
&mut device.rsp.cpu.vpr[vd(opcode) as usize],
|
||||
de(opcode) as u8,
|
||||
device.rsp.cpu.divout as u16,
|
||||
@ -859,8 +855,8 @@ pub fn vrcph(device: &mut device::Device, opcode: u32) {
|
||||
|
||||
pub fn vmov(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let value = get_vpr_element(vte, de(opcode) as u8);
|
||||
modify_vpr_element(
|
||||
let value = get_vpr16(vte, de(opcode) as u8);
|
||||
modify_vpr16(
|
||||
&mut device.rsp.cpu.vpr[vd(opcode) as usize],
|
||||
de(opcode) as u8,
|
||||
value,
|
||||
@ -871,8 +867,7 @@ pub fn vmov(device: &mut device::Device, opcode: u32) {
|
||||
pub fn vrsq(device: &mut device::Device, opcode: u32) {
|
||||
let mut result;
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let input =
|
||||
get_vpr_element(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16 as i32;
|
||||
let input = get_vpr16(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16 as i32;
|
||||
let mask = input >> 31;
|
||||
let mut data = input ^ mask;
|
||||
if input > -32768 {
|
||||
@ -893,7 +888,7 @@ pub fn vrsq(device: &mut device::Device, opcode: u32) {
|
||||
device.rsp.cpu.divdp = false;
|
||||
device.rsp.cpu.divout = (result >> 16) as i16;
|
||||
device.rsp.cpu.accl = vte;
|
||||
modify_vpr_element(
|
||||
modify_vpr16(
|
||||
&mut device.rsp.cpu.vpr[vd(opcode) as usize],
|
||||
de(opcode) as u8,
|
||||
result as u16,
|
||||
@ -905,10 +900,9 @@ pub fn vrsql(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let input = if device.rsp.cpu.divdp {
|
||||
((device.rsp.cpu.divin as i32) << 16)
|
||||
| get_vpr_element(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as u16
|
||||
as i32
|
||||
| get_vpr16(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as u16 as i32
|
||||
} else {
|
||||
get_vpr_element(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16 as i32
|
||||
get_vpr16(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16 as i32
|
||||
};
|
||||
let mask = input >> 31;
|
||||
let mut data = input ^ mask;
|
||||
@ -930,7 +924,7 @@ pub fn vrsql(device: &mut device::Device, opcode: u32) {
|
||||
device.rsp.cpu.divdp = false;
|
||||
device.rsp.cpu.divout = (result >> 16) as i16;
|
||||
device.rsp.cpu.accl = vte;
|
||||
modify_vpr_element(
|
||||
modify_vpr16(
|
||||
&mut device.rsp.cpu.vpr[vd(opcode) as usize],
|
||||
de(opcode) as u8,
|
||||
result as u16,
|
||||
@ -943,8 +937,8 @@ pub fn vrsqh(device: &mut device::Device, opcode: u32) {
|
||||
device.rsp.cpu.divdp = true;
|
||||
|
||||
device.rsp.cpu.divin =
|
||||
get_vpr_element(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16;
|
||||
modify_vpr_element(
|
||||
get_vpr16(device.rsp.cpu.vpr[vt(opcode) as usize], ve(opcode) as u8) as i16;
|
||||
modify_vpr16(
|
||||
&mut device.rsp.cpu.vpr[vd(opcode) as usize],
|
||||
de(opcode) as u8,
|
||||
device.rsp.cpu.divout as u16,
|
||||
|
||||
Reference in New Issue
Block a user