mirror of
https://github.com/gopher64/gopher64.git
synced 2026-11-09 15:49:04 +01:00
Don't transmute values in RSP code (#132)
* remove transmute * fix * more * more * fix
This commit is contained in:
1 parent
21300ab7db
commit
97e4921b6a
7 files changed
+364
-396
No files matched your search
@@ -1,5 +1,6 @@
|
||||
fn main() {
|
||||
println!("cargo::rerun-if-changed=parallel-rdp");
|
||||
println!("cargo::rerun-if-changed=src/compat");
|
||||
|
||||
let mut simd_build = cc::Build::new();
|
||||
let mut build = cc::Build::new();
|
||||
@@ -75,6 +76,7 @@ fn main() {
|
||||
} else if arch == "aarch64" {
|
||||
build.flag("-march=armv8.2-a");
|
||||
simd_build.flag("-march=armv8.2-a");
|
||||
simd_build.flag("-DSSE2NEON_SUPPRESS_WARNINGS");
|
||||
simd_build.file("src/compat/aarch64.c");
|
||||
} else {
|
||||
panic!("unknown arch")
|
||||
@@ -117,7 +119,6 @@ fn main() {
|
||||
.allowlist_function("_mm_set1_epi8")
|
||||
.allowlist_function("_mm_mullo_epi16")
|
||||
.allowlist_function("_mm_cmpeq_epi16")
|
||||
.allowlist_function("_mm_srli_epi16")
|
||||
.allowlist_function("_mm_add_epi16")
|
||||
.allowlist_function("_mm_slli_epi16")
|
||||
.allowlist_function("_mm_mulhi_epi16")
|
||||
|
||||
@@ -3,3 +3,134 @@
|
||||
// Static wrappers
|
||||
|
||||
__m128i _mm_srli_epi16__extern(__m128i __a, int __imm8) { return _mm_srli_epi16(__a, __imm8); }
|
||||
|
||||
__m128i _mm_insert_epi8__extern(__m128i __a, int __i, const int __imm8)
|
||||
{
|
||||
switch (__imm8)
|
||||
{
|
||||
case 0:
|
||||
return _mm_insert_epi8(__a, __i, 0);
|
||||
case 1:
|
||||
return _mm_insert_epi8(__a, __i, 1);
|
||||
case 2:
|
||||
return _mm_insert_epi8(__a, __i, 2);
|
||||
case 3:
|
||||
return _mm_insert_epi8(__a, __i, 3);
|
||||
case 4:
|
||||
return _mm_insert_epi8(__a, __i, 4);
|
||||
case 5:
|
||||
return _mm_insert_epi8(__a, __i, 5);
|
||||
case 6:
|
||||
return _mm_insert_epi8(__a, __i, 6);
|
||||
case 7:
|
||||
return _mm_insert_epi8(__a, __i, 7);
|
||||
case 8:
|
||||
return _mm_insert_epi8(__a, __i, 8);
|
||||
case 9:
|
||||
return _mm_insert_epi8(__a, __i, 9);
|
||||
case 10:
|
||||
return _mm_insert_epi8(__a, __i, 10);
|
||||
case 11:
|
||||
return _mm_insert_epi8(__a, __i, 11);
|
||||
case 12:
|
||||
return _mm_insert_epi8(__a, __i, 12);
|
||||
case 13:
|
||||
return _mm_insert_epi8(__a, __i, 13);
|
||||
case 14:
|
||||
return _mm_insert_epi8(__a, __i, 14);
|
||||
case 15:
|
||||
return _mm_insert_epi8(__a, __i, 15);
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
int _mm_extract_epi8__extern(__m128i __a, const int __imm8)
|
||||
{
|
||||
switch (__imm8)
|
||||
{
|
||||
case 0:
|
||||
return _mm_extract_epi8(__a, 0);
|
||||
case 1:
|
||||
return _mm_extract_epi8(__a, 1);
|
||||
case 2:
|
||||
return _mm_extract_epi8(__a, 2);
|
||||
case 3:
|
||||
return _mm_extract_epi8(__a, 3);
|
||||
case 4:
|
||||
return _mm_extract_epi8(__a, 4);
|
||||
case 5:
|
||||
return _mm_extract_epi8(__a, 5);
|
||||
case 6:
|
||||
return _mm_extract_epi8(__a, 6);
|
||||
case 7:
|
||||
return _mm_extract_epi8(__a, 7);
|
||||
case 8:
|
||||
return _mm_extract_epi8(__a, 8);
|
||||
case 9:
|
||||
return _mm_extract_epi8(__a, 9);
|
||||
case 10:
|
||||
return _mm_extract_epi8(__a, 10);
|
||||
case 11:
|
||||
return _mm_extract_epi8(__a, 11);
|
||||
case 12:
|
||||
return _mm_extract_epi8(__a, 12);
|
||||
case 13:
|
||||
return _mm_extract_epi8(__a, 13);
|
||||
case 14:
|
||||
return _mm_extract_epi8(__a, 14);
|
||||
case 15:
|
||||
return _mm_extract_epi8(__a, 15);
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
__m128i _mm_insert_epi16__extern(__m128i __a, int __i, const int __imm8)
|
||||
{
|
||||
switch (__imm8)
|
||||
{
|
||||
case 0:
|
||||
return _mm_insert_epi16(__a, __i, 0);
|
||||
case 1:
|
||||
return _mm_insert_epi16(__a, __i, 1);
|
||||
case 2:
|
||||
return _mm_insert_epi16(__a, __i, 2);
|
||||
case 3:
|
||||
return _mm_insert_epi16(__a, __i, 3);
|
||||
case 4:
|
||||
return _mm_insert_epi16(__a, __i, 4);
|
||||
case 5:
|
||||
return _mm_insert_epi16(__a, __i, 5);
|
||||
case 6:
|
||||
return _mm_insert_epi16(__a, __i, 6);
|
||||
case 7:
|
||||
return _mm_insert_epi16(__a, __i, 7);
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
int _mm_extract_epi16__extern(__m128i __a, const int __imm8)
|
||||
{
|
||||
switch (__imm8)
|
||||
{
|
||||
case 0:
|
||||
return _mm_extract_epi16(__a, 0);
|
||||
case 1:
|
||||
return _mm_extract_epi16(__a, 1);
|
||||
case 2:
|
||||
return _mm_extract_epi16(__a, 2);
|
||||
case 3:
|
||||
return _mm_extract_epi16(__a, 3);
|
||||
case 4:
|
||||
return _mm_extract_epi16(__a, 4);
|
||||
case 5:
|
||||
return _mm_extract_epi16(__a, 5);
|
||||
case 6:
|
||||
return _mm_extract_epi16(__a, 6);
|
||||
case 7:
|
||||
return _mm_extract_epi16(__a, 7);
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
@@ -2,3 +2,31 @@ unsafe extern "C" {
|
||||
#[link_name = "_mm_srli_epi16__extern"]
|
||||
pub fn _mm_srli_epi16(__a: __m128i, __imm8: ::std::os::raw::c_int) -> __m128i;
|
||||
}
|
||||
|
||||
unsafe extern "C" {
|
||||
#[link_name = "_mm_insert_epi8__extern"]
|
||||
pub fn _mm_insert_epi8(
|
||||
__a: __m128i,
|
||||
__i: ::std::os::raw::c_int,
|
||||
__imm8: ::std::os::raw::c_int,
|
||||
) -> __m128i;
|
||||
}
|
||||
|
||||
unsafe extern "C" {
|
||||
#[link_name = "_mm_extract_epi8__extern"]
|
||||
pub fn _mm_extract_epi8(__a: __m128i, __imm8: ::std::os::raw::c_int) -> ::std::os::raw::c_int;
|
||||
}
|
||||
|
||||
unsafe extern "C" {
|
||||
#[link_name = "_mm_insert_epi16__extern"]
|
||||
pub fn _mm_insert_epi16(
|
||||
__a: __m128i,
|
||||
__i: ::std::os::raw::c_int,
|
||||
__imm8: ::std::os::raw::c_int,
|
||||
) -> __m128i;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
+1
-1
@@ -341,7 +341,7 @@ impl Device {
|
||||
sync_point: false,
|
||||
cycle_counter: 0,
|
||||
gpr: [0; 32],
|
||||
vpr: [0; 32],
|
||||
vpr: unsafe { [_mm_setzero_si128(); 32] },
|
||||
reciprocals: [0; 512],
|
||||
inverse_square_roots: [0; 512],
|
||||
divdp: false,
|
||||
|
||||
@@ -35,7 +35,7 @@ pub struct Cpu {
|
||||
pub cycle_counter: u64,
|
||||
pub shuffle: [__m128i; 16],
|
||||
pub gpr: [u32; 32],
|
||||
pub vpr: [u128; 32],
|
||||
pub vpr: [__m128i; 32],
|
||||
pub reciprocals: [u16; 512],
|
||||
pub inverse_square_roots: [u16; 512],
|
||||
pub vcol: __m128i,
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
use device::__m128i;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
include!(concat!(env!("OUT_DIR"), "/simd_bindings.rs"));
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
include!("../compat/aarch64.rs");
|
||||
use crate::device;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::arch::x86_64::*;
|
||||
@@ -44,28 +46,84 @@ 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, element: u8, value: u8) {
|
||||
let pos = 15 - (element & 15);
|
||||
let mask = 0xFF << (pos * 8);
|
||||
*vpr &= !mask;
|
||||
*vpr |= (value as u128) << (pos * 8);
|
||||
pub fn modify_vpr_byte(vpr: &mut __m128i, element: u8, value: u8) {
|
||||
unsafe {
|
||||
*vpr = match element & 15 {
|
||||
0 => _mm_insert_epi8(*vpr, value as i32, 15),
|
||||
1 => _mm_insert_epi8(*vpr, value as i32, 14),
|
||||
2 => _mm_insert_epi8(*vpr, value as i32, 13),
|
||||
3 => _mm_insert_epi8(*vpr, value as i32, 12),
|
||||
4 => _mm_insert_epi8(*vpr, value as i32, 11),
|
||||
5 => _mm_insert_epi8(*vpr, value as i32, 10),
|
||||
6 => _mm_insert_epi8(*vpr, value as i32, 9),
|
||||
7 => _mm_insert_epi8(*vpr, value as i32, 8),
|
||||
8 => _mm_insert_epi8(*vpr, value as i32, 7),
|
||||
9 => _mm_insert_epi8(*vpr, value as i32, 6),
|
||||
10 => _mm_insert_epi8(*vpr, value as i32, 5),
|
||||
11 => _mm_insert_epi8(*vpr, value as i32, 4),
|
||||
12 => _mm_insert_epi8(*vpr, value as i32, 3),
|
||||
13 => _mm_insert_epi8(*vpr, value as i32, 2),
|
||||
14 => _mm_insert_epi8(*vpr, value as i32, 1),
|
||||
15 => _mm_insert_epi8(*vpr, value as i32, 0),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_vpr_byte(vpr: u128, element: u8) -> u8 {
|
||||
let pos = 15 - (element & 15);
|
||||
(vpr >> (pos * 8)) as u8
|
||||
pub fn get_vpr_byte(vpr: __m128i, element: u8) -> u8 {
|
||||
unsafe {
|
||||
match element & 15 {
|
||||
0 => _mm_extract_epi8(vpr, 15) as u8,
|
||||
1 => _mm_extract_epi8(vpr, 14) as u8,
|
||||
2 => _mm_extract_epi8(vpr, 13) as u8,
|
||||
3 => _mm_extract_epi8(vpr, 12) as u8,
|
||||
4 => _mm_extract_epi8(vpr, 11) as u8,
|
||||
5 => _mm_extract_epi8(vpr, 10) as u8,
|
||||
6 => _mm_extract_epi8(vpr, 9) as u8,
|
||||
7 => _mm_extract_epi8(vpr, 8) as u8,
|
||||
8 => _mm_extract_epi8(vpr, 7) as u8,
|
||||
9 => _mm_extract_epi8(vpr, 6) as u8,
|
||||
10 => _mm_extract_epi8(vpr, 5) as u8,
|
||||
11 => _mm_extract_epi8(vpr, 4) as u8,
|
||||
12 => _mm_extract_epi8(vpr, 3) as u8,
|
||||
13 => _mm_extract_epi8(vpr, 2) as u8,
|
||||
14 => _mm_extract_epi8(vpr, 1) as u8,
|
||||
15 => _mm_extract_epi8(vpr, 0) as u8,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn modify_vpr_element(vpr: &mut u128, element: u8, value: u16) {
|
||||
let pos = 7 - (element & 7);
|
||||
let mask = 0xFFFF << (pos * 16);
|
||||
*vpr &= !mask;
|
||||
*vpr |= (value as u128) << (pos * 16);
|
||||
pub fn modify_vpr_element(vpr: &mut __m128i, element: u8, value: u16) {
|
||||
unsafe {
|
||||
*vpr = match element & 7 {
|
||||
0 => _mm_insert_epi16(*vpr, value as i32, 7),
|
||||
1 => _mm_insert_epi16(*vpr, value as i32, 6),
|
||||
2 => _mm_insert_epi16(*vpr, value as i32, 5),
|
||||
3 => _mm_insert_epi16(*vpr, value as i32, 4),
|
||||
4 => _mm_insert_epi16(*vpr, value as i32, 3),
|
||||
5 => _mm_insert_epi16(*vpr, value as i32, 2),
|
||||
6 => _mm_insert_epi16(*vpr, value as i32, 1),
|
||||
7 => _mm_insert_epi16(*vpr, value as i32, 0),
|
||||
_ => unreachable!(),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_vpr_element(vpr: u128, element: u8) -> u16 {
|
||||
let pos = 7 - (element & 7);
|
||||
(vpr >> (pos * 16)) as u16
|
||||
pub fn get_vpr_element(vpr: __m128i, element: u8) -> u16 {
|
||||
unsafe {
|
||||
match element & 7 {
|
||||
0 => _mm_extract_epi16(vpr, 7) as u16,
|
||||
1 => _mm_extract_epi16(vpr, 6) as u16,
|
||||
2 => _mm_extract_epi16(vpr, 5) as u16,
|
||||
3 => _mm_extract_epi16(vpr, 4) as u16,
|
||||
4 => _mm_extract_epi16(vpr, 3) as u16,
|
||||
5 => _mm_extract_epi16(vpr, 2) as u16,
|
||||
6 => _mm_extract_epi16(vpr, 1) as u16,
|
||||
7 => _mm_extract_epi16(vpr, 0) as u16,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn j(device: &mut device::Device, opcode: u32) {
|
||||
@@ -745,7 +803,7 @@ pub fn lfv(device: &mut device::Device, opcode: u32) {
|
||||
address &= !7;
|
||||
let start = velement(opcode);
|
||||
let end = std::cmp::min(start + 8, 16);
|
||||
let mut tmp: u128 = 0;
|
||||
let mut tmp: __m128i = unsafe { _mm_setzero_si128() };
|
||||
let mut offset: u8 = 0;
|
||||
while offset < 4 {
|
||||
modify_vpr_element(
|
||||
|
||||
+126
-376
@@ -46,7 +46,7 @@ pub fn s_clip(x: i64, bits: u32) -> i64 {
|
||||
pub fn vte(device: &device::Device, vt: u32, index: usize) -> __m128i {
|
||||
unsafe {
|
||||
_mm_shuffle_epi8(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vt as usize]),
|
||||
device.rsp.cpu.vpr[vt as usize],
|
||||
device.rsp.cpu.shuffle[index],
|
||||
)
|
||||
}
|
||||
@@ -56,33 +56,23 @@ pub fn vmulf(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (mut lo, mut hi, mut round, mut sign1, sign2, neq, eq, neg);
|
||||
unsafe {
|
||||
lo = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
lo = _mm_mullo_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
round = _mm_cmpeq_epi16(_mm_setzero_si128(), _mm_setzero_si128());
|
||||
sign1 = _mm_srli_epi16(lo, 15);
|
||||
lo = _mm_add_epi16(lo, lo);
|
||||
round = _mm_slli_epi16(round, 15);
|
||||
hi = _mm_mulhi_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
hi = _mm_mulhi_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
sign2 = _mm_srli_epi16(lo, 15);
|
||||
device.rsp.cpu.accl = _mm_add_epi16(round, lo);
|
||||
sign1 = _mm_add_epi16(sign1, sign2);
|
||||
hi = _mm_slli_epi16(hi, 1);
|
||||
neq = _mm_cmpeq_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
neq = _mm_cmpeq_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.accm = _mm_add_epi16(hi, sign1);
|
||||
neg = _mm_srai_epi16(device.rsp.cpu.accm, 15);
|
||||
|
||||
eq = _mm_and_si128(neq, neg);
|
||||
device.rsp.cpu.acch = _mm_andnot_si128(neq, neg);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_add_epi16(device.rsp.cpu.accm, eq));
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_add_epi16(device.rsp.cpu.accm, eq);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,43 +80,31 @@ pub fn vmulu(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (mut lo, mut hi, mut round, mut sign1, sign2, neq, neg);
|
||||
unsafe {
|
||||
lo = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
lo = _mm_mullo_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
round = _mm_cmpeq_epi16(_mm_setzero_si128(), _mm_setzero_si128());
|
||||
sign1 = _mm_srli_epi16(lo, 15);
|
||||
lo = _mm_add_epi16(lo, lo);
|
||||
round = _mm_slli_epi16(round, 15);
|
||||
hi = _mm_mulhi_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
hi = _mm_mulhi_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
sign2 = _mm_srli_epi16(lo, 15);
|
||||
device.rsp.cpu.accl = _mm_add_epi16(round, lo);
|
||||
sign1 = _mm_add_epi16(sign1, sign2);
|
||||
hi = _mm_slli_epi16(hi, 1);
|
||||
neq = _mm_cmpeq_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
neq = _mm_cmpeq_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.accm = _mm_add_epi16(hi, sign1);
|
||||
neg = _mm_srai_epi16(device.rsp.cpu.accm, 15);
|
||||
|
||||
device.rsp.cpu.acch = _mm_andnot_si128(neq, neg);
|
||||
hi = _mm_or_si128(device.rsp.cpu.accm, neg);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_andnot_si128(device.rsp.cpu.acch, hi));
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_andnot_si128(device.rsp.cpu.acch, hi);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vrndp(device: &mut device::Device, opcode: u32) {
|
||||
let vte = unsafe {
|
||||
std::mem::transmute::<__m128i, u128>(vte(device, vt(opcode), ve(opcode) as usize))
|
||||
};
|
||||
let acch: &mut u128 = unsafe { std::mem::transmute(&mut device.rsp.cpu.acch) };
|
||||
let accm: &mut u128 = unsafe { std::mem::transmute(&mut device.rsp.cpu.accm) };
|
||||
let accl: &mut u128 = unsafe { std::mem::transmute(&mut device.rsp.cpu.accl) };
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let acch: &mut __m128i = &mut device.rsp.cpu.acch;
|
||||
let accm: &mut __m128i = &mut device.rsp.cpu.accm;
|
||||
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;
|
||||
@@ -156,12 +134,10 @@ pub fn vrndp(device: &mut device::Device, opcode: u32) {
|
||||
}
|
||||
|
||||
pub fn vmulq(device: &mut device::Device, opcode: u32) {
|
||||
let vte = unsafe {
|
||||
std::mem::transmute::<__m128i, u128>(vte(device, vt(opcode), ve(opcode) as usize))
|
||||
};
|
||||
let acch: &mut u128 = unsafe { std::mem::transmute(&mut device.rsp.cpu.acch) };
|
||||
let accm: &mut u128 = unsafe { std::mem::transmute(&mut device.rsp.cpu.accm) };
|
||||
let accl: &mut u128 = unsafe { std::mem::transmute(&mut device.rsp.cpu.accl) };
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let acch: &mut __m128i = &mut device.rsp.cpu.acch;
|
||||
let accm: &mut __m128i = &mut device.rsp.cpu.accm;
|
||||
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
|
||||
@@ -184,14 +160,10 @@ pub fn vmulq(device: &mut device::Device, opcode: u32) {
|
||||
pub fn vmudl(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
unsafe {
|
||||
device.rsp.cpu.accl = _mm_mulhi_epu16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.accl = _mm_mulhi_epu16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.accm = _mm_setzero_si128();
|
||||
device.rsp.cpu.acch = _mm_setzero_si128();
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,23 +171,13 @@ pub fn vmudm(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (sign, vta);
|
||||
unsafe {
|
||||
device.rsp.cpu.accl = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.accm = _mm_mulhi_epu16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
sign = _mm_srai_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
15,
|
||||
);
|
||||
device.rsp.cpu.accl = _mm_mullo_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.accm = _mm_mulhi_epu16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
sign = _mm_srai_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], 15);
|
||||
vta = _mm_and_si128(vte, sign);
|
||||
device.rsp.cpu.accm = _mm_sub_epi16(device.rsp.cpu.accm, vta);
|
||||
device.rsp.cpu.acch = _mm_srai_epi16(device.rsp.cpu.accm, 15);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accm);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accm;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,23 +185,13 @@ pub fn vmudn(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (sign, vsa);
|
||||
unsafe {
|
||||
device.rsp.cpu.accl = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.accm = _mm_mulhi_epu16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.accl = _mm_mullo_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.accm = _mm_mulhi_epu16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
sign = _mm_srai_epi16(vte, 15);
|
||||
vsa = _mm_and_si128(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
sign,
|
||||
);
|
||||
vsa = _mm_and_si128(device.rsp.cpu.vpr[vs(opcode) as usize], sign);
|
||||
device.rsp.cpu.accm = _mm_sub_epi16(device.rsp.cpu.accm, vsa);
|
||||
device.rsp.cpu.acch = _mm_srai_epi16(device.rsp.cpu.accm, 15);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,18 +200,11 @@ pub fn vmudh(device: &mut device::Device, opcode: u32) {
|
||||
let (lo, hi);
|
||||
unsafe {
|
||||
device.rsp.cpu.accl = _mm_setzero_si128();
|
||||
device.rsp.cpu.accm = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.acch = _mm_mulhi_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.accm = _mm_mullo_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.acch = _mm_mulhi_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
lo = _mm_unpacklo_epi16(device.rsp.cpu.accm, device.rsp.cpu.acch);
|
||||
hi = _mm_unpackhi_epi16(device.rsp.cpu.accm, device.rsp.cpu.acch);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_packs_epi32(lo, hi));
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_packs_epi32(lo, hi);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,14 +212,8 @@ pub fn vmacf(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (mut lo, mut md, mut hi, mut carry, mut omask);
|
||||
unsafe {
|
||||
lo = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
hi = _mm_mulhi_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
lo = _mm_mullo_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
hi = _mm_mulhi_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
md = _mm_slli_epi16(hi, 1);
|
||||
carry = _mm_srli_epi16(lo, 15);
|
||||
hi = _mm_srai_epi16(hi, 15);
|
||||
@@ -297,8 +236,7 @@ pub fn vmacf(device: &mut device::Device, opcode: u32) {
|
||||
|
||||
lo = _mm_unpacklo_epi16(device.rsp.cpu.accm, device.rsp.cpu.acch);
|
||||
hi = _mm_unpackhi_epi16(device.rsp.cpu.accm, device.rsp.cpu.acch);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_packs_epi32(lo, hi));
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_packs_epi32(lo, hi);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,14 +244,8 @@ pub fn vmacu(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (mut lo, mut md, mut hi, mut carry, mut omask, mmask, hmask);
|
||||
unsafe {
|
||||
lo = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
hi = _mm_mulhi_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
lo = _mm_mullo_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
hi = _mm_mulhi_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
md = _mm_slli_epi16(hi, 1);
|
||||
carry = _mm_srli_epi16(lo, 15);
|
||||
hi = _mm_srai_epi16(hi, 15);
|
||||
@@ -339,18 +271,15 @@ pub fn vmacu(device: &mut device::Device, opcode: u32) {
|
||||
md = _mm_or_si128(mmask, device.rsp.cpu.accm);
|
||||
omask = _mm_cmpgt_epi16(device.rsp.cpu.acch, _mm_setzero_si128());
|
||||
md = _mm_andnot_si128(hmask, md);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_or_si128(omask, md));
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_or_si128(omask, md);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vrndn(device: &mut device::Device, opcode: u32) {
|
||||
let vte = unsafe {
|
||||
std::mem::transmute::<__m128i, u128>(vte(device, vt(opcode), ve(opcode) as usize))
|
||||
};
|
||||
let acch: &mut u128 = unsafe { std::mem::transmute(&mut device.rsp.cpu.acch) };
|
||||
let accm: &mut u128 = unsafe { std::mem::transmute(&mut device.rsp.cpu.accm) };
|
||||
let accl: &mut u128 = unsafe { std::mem::transmute(&mut device.rsp.cpu.accl) };
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let acch: &mut __m128i = &mut device.rsp.cpu.acch;
|
||||
let accm: &mut __m128i = &mut device.rsp.cpu.accm;
|
||||
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;
|
||||
@@ -380,8 +309,8 @@ pub fn vrndn(device: &mut device::Device, opcode: u32) {
|
||||
}
|
||||
|
||||
pub fn vmacq(device: &mut device::Device, opcode: u32) {
|
||||
let acch: &mut u128 = unsafe { std::mem::transmute(&mut device.rsp.cpu.acch) };
|
||||
let accm: &mut u128 = unsafe { std::mem::transmute(&mut device.rsp.cpu.accm) };
|
||||
let acch: &mut __m128i = &mut device.rsp.cpu.acch;
|
||||
let accm: &mut __m128i = &mut device.rsp.cpu.accm;
|
||||
|
||||
for n in 0..8 {
|
||||
let mut product =
|
||||
@@ -405,10 +334,7 @@ pub fn vmadl(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (mut hi, mut omask, nhi, nmd, shi, smd, cmask, cval);
|
||||
unsafe {
|
||||
hi = _mm_mulhi_epu16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
hi = _mm_mulhi_epu16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
omask = _mm_adds_epu16(device.rsp.cpu.accl, hi);
|
||||
device.rsp.cpu.accl = _mm_add_epi16(device.rsp.cpu.accl, hi);
|
||||
omask = _mm_cmpeq_epi16(device.rsp.cpu.accl, omask);
|
||||
@@ -425,8 +351,7 @@ pub fn vmadl(device: &mut device::Device, opcode: u32) {
|
||||
smd = _mm_cmpeq_epi16(nhi, nmd);
|
||||
cmask = _mm_and_si128(smd, shi);
|
||||
cval = _mm_cmpeq_epi16(nhi, _mm_setzero_si128());
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_blendv_epi8(cval, device.rsp.cpu.accl, cmask));
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_blendv_epi8(cval, device.rsp.cpu.accl, cmask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,18 +359,9 @@ pub fn vmadm(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (mut lo, mut hi, sign, vta, mut omask);
|
||||
unsafe {
|
||||
lo = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
hi = _mm_mulhi_epu16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
sign = _mm_srai_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
15,
|
||||
);
|
||||
lo = _mm_mullo_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
hi = _mm_mulhi_epu16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
sign = _mm_srai_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], 15);
|
||||
vta = _mm_and_si128(vte, sign);
|
||||
hi = _mm_sub_epi16(hi, vta);
|
||||
omask = _mm_adds_epu16(device.rsp.cpu.accl, lo);
|
||||
@@ -462,8 +378,7 @@ pub fn vmadm(device: &mut device::Device, opcode: u32) {
|
||||
device.rsp.cpu.acch = _mm_sub_epi16(device.rsp.cpu.acch, omask);
|
||||
lo = _mm_unpacklo_epi16(device.rsp.cpu.accm, device.rsp.cpu.acch);
|
||||
hi = _mm_unpackhi_epi16(device.rsp.cpu.accm, device.rsp.cpu.acch);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_packs_epi32(lo, hi));
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_packs_epi32(lo, hi);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,19 +386,10 @@ pub fn vmadn(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (lo, mut hi, sign, vsa, mut omask, nhi, nmd, shi, smd, cmask, cval);
|
||||
unsafe {
|
||||
lo = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
hi = _mm_mulhi_epu16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
lo = _mm_mullo_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
hi = _mm_mulhi_epu16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
sign = _mm_srai_epi16(vte, 15);
|
||||
vsa = _mm_and_si128(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
sign,
|
||||
);
|
||||
vsa = _mm_and_si128(device.rsp.cpu.vpr[vs(opcode) as usize], sign);
|
||||
hi = _mm_sub_epi16(hi, vsa);
|
||||
omask = _mm_adds_epu16(device.rsp.cpu.accl, lo);
|
||||
device.rsp.cpu.accl = _mm_add_epi16(device.rsp.cpu.accl, lo);
|
||||
@@ -503,8 +409,7 @@ pub fn vmadn(device: &mut device::Device, opcode: u32) {
|
||||
smd = _mm_cmpeq_epi16(nhi, nmd);
|
||||
cmask = _mm_and_si128(smd, shi);
|
||||
cval = _mm_cmpeq_epi16(nhi, _mm_setzero_si128());
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_blendv_epi8(cval, device.rsp.cpu.accl, cmask));
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_blendv_epi8(cval, device.rsp.cpu.accl, cmask);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -512,14 +417,8 @@ pub fn vmadh(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (mut lo, mut hi, mut omask);
|
||||
unsafe {
|
||||
lo = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
hi = _mm_mulhi_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
lo = _mm_mullo_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
hi = _mm_mulhi_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
omask = _mm_adds_epu16(device.rsp.cpu.accm, lo);
|
||||
device.rsp.cpu.accm = _mm_add_epi16(device.rsp.cpu.accm, lo);
|
||||
omask = _mm_cmpeq_epi16(device.rsp.cpu.accm, omask);
|
||||
@@ -528,8 +427,7 @@ pub fn vmadh(device: &mut device::Device, opcode: u32) {
|
||||
device.rsp.cpu.acch = _mm_add_epi16(device.rsp.cpu.acch, hi);
|
||||
lo = _mm_unpacklo_epi16(device.rsp.cpu.accm, device.rsp.cpu.acch);
|
||||
hi = _mm_unpackhi_epi16(device.rsp.cpu.accm, device.rsp.cpu.acch);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_packs_epi32(lo, hi));
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_packs_epi32(lo, hi);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,22 +435,12 @@ pub fn vadd(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (sum, mut min, max);
|
||||
unsafe {
|
||||
sum = _mm_add_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
sum = _mm_add_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.accl = _mm_sub_epi16(sum, device.rsp.cpu.vcol);
|
||||
min = _mm_min_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
max = _mm_max_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
min = _mm_min_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
max = _mm_max_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
min = _mm_subs_epi16(min, device.rsp.cpu.vcol);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_adds_epi16(min, max));
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_adds_epi16(min, max);
|
||||
device.rsp.cpu.vcol = _mm_setzero_si128();
|
||||
device.rsp.cpu.vcoh = _mm_setzero_si128();
|
||||
}
|
||||
@@ -564,21 +452,12 @@ pub fn vsub(device: &mut device::Device, opcode: u32) {
|
||||
unsafe {
|
||||
udiff = _mm_sub_epi16(vte, device.rsp.cpu.vcol);
|
||||
sdiff = _mm_subs_epi16(vte, device.rsp.cpu.vcol);
|
||||
device.rsp.cpu.accl = _mm_sub_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
udiff,
|
||||
);
|
||||
device.rsp.cpu.accl = _mm_sub_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], udiff);
|
||||
ov = _mm_cmpgt_epi16(sdiff, udiff);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_subs_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
sdiff,
|
||||
));
|
||||
_mm_subs_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], sdiff);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_adds_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vd(opcode) as usize]),
|
||||
ov,
|
||||
));
|
||||
_mm_adds_epi16(device.rsp.cpu.vpr[vd(opcode) as usize], ov);
|
||||
device.rsp.cpu.vcol = _mm_setzero_si128();
|
||||
device.rsp.cpu.vcoh = _mm_setzero_si128();
|
||||
}
|
||||
@@ -587,15 +466,11 @@ pub fn vsub(device: &mut device::Device, opcode: u32) {
|
||||
pub fn vzero(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
unsafe {
|
||||
device.rsp.cpu.accl = _mm_add_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
device.rsp.cpu.accl = _mm_add_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_xor_si128(
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize],
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize],
|
||||
);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_xor_si128(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vd(opcode) as usize]),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vd(opcode) as usize]),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,30 +478,14 @@ pub fn vabs(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (vs0, slt);
|
||||
unsafe {
|
||||
vs0 = _mm_cmpeq_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
_mm_setzero_si128(),
|
||||
);
|
||||
slt = _mm_srai_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
15,
|
||||
);
|
||||
vs0 = _mm_cmpeq_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], _mm_setzero_si128());
|
||||
slt = _mm_srai_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], 15);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = _mm_andnot_si128(vs0, vte);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_andnot_si128(vs0, vte));
|
||||
_mm_xor_si128(device.rsp.cpu.vpr[vd(opcode) as usize], slt);
|
||||
device.rsp.cpu.accl = _mm_sub_epi16(device.rsp.cpu.vpr[vd(opcode) as usize], slt);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_xor_si128(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vd(opcode) as usize]),
|
||||
slt,
|
||||
));
|
||||
device.rsp.cpu.accl = _mm_sub_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vd(opcode) as usize]),
|
||||
slt,
|
||||
);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_subs_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vd(opcode) as usize]),
|
||||
slt,
|
||||
));
|
||||
_mm_subs_epi16(device.rsp.cpu.vpr[vd(opcode) as usize], slt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -634,19 +493,12 @@ pub fn vaddc(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let sum;
|
||||
unsafe {
|
||||
sum = _mm_adds_epu16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.accl = _mm_add_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
sum = _mm_adds_epu16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.accl = _mm_add_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.vcol = _mm_cmpeq_epi16(sum, device.rsp.cpu.accl);
|
||||
device.rsp.cpu.vcol = _mm_cmpeq_epi16(device.rsp.cpu.vcol, _mm_setzero_si128());
|
||||
device.rsp.cpu.vcoh = _mm_setzero_si128();
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -654,42 +506,29 @@ pub fn vsubc(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (equal, udiff, diff0);
|
||||
unsafe {
|
||||
udiff = _mm_subs_epu16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
equal = _mm_cmpeq_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
udiff = _mm_subs_epu16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
equal = _mm_cmpeq_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
diff0 = _mm_cmpeq_epi16(udiff, _mm_setzero_si128());
|
||||
device.rsp.cpu.vcoh = _mm_cmpeq_epi16(equal, _mm_setzero_si128());
|
||||
device.rsp.cpu.vcol = _mm_andnot_si128(equal, diff0);
|
||||
device.rsp.cpu.accl = _mm_sub_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.accl = _mm_sub_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vsar(device: &mut device::Device, opcode: u32) {
|
||||
match ve(opcode) {
|
||||
0x8 => {
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
unsafe { std::mem::transmute::<__m128i, u128>(device.rsp.cpu.acch) };
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.acch;
|
||||
}
|
||||
0x9 => {
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
unsafe { std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accm) };
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accm;
|
||||
}
|
||||
0xa => {
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
unsafe { std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl) };
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
_ => {
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = 0;
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = unsafe { _mm_setzero_si128() };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -698,27 +537,20 @@ pub fn vlt(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (mut eq, lt);
|
||||
unsafe {
|
||||
eq = _mm_cmpeq_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
lt = _mm_cmplt_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
eq = _mm_cmpeq_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
lt = _mm_cmplt_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
eq = _mm_and_si128(device.rsp.cpu.vcoh, eq);
|
||||
eq = _mm_and_si128(device.rsp.cpu.vcol, eq);
|
||||
device.rsp.cpu.vccl = _mm_or_si128(lt, eq);
|
||||
device.rsp.cpu.accl = _mm_blendv_epi8(
|
||||
vte,
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
device.rsp.cpu.vccl,
|
||||
);
|
||||
device.rsp.cpu.vcch = _mm_setzero_si128();
|
||||
device.rsp.cpu.vcoh = _mm_setzero_si128();
|
||||
device.rsp.cpu.vcol = _mm_setzero_si128();
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -726,21 +558,17 @@ pub fn veq(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let eq;
|
||||
unsafe {
|
||||
eq = _mm_cmpeq_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
eq = _mm_cmpeq_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.vccl = _mm_andnot_si128(device.rsp.cpu.vcoh, eq);
|
||||
device.rsp.cpu.accl = _mm_blendv_epi8(
|
||||
vte,
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
device.rsp.cpu.vccl,
|
||||
);
|
||||
device.rsp.cpu.vcch = _mm_setzero_si128(); //unverified
|
||||
device.rsp.cpu.vcoh = _mm_setzero_si128();
|
||||
device.rsp.cpu.vcol = _mm_setzero_si128();
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -748,23 +576,19 @@ pub fn vne(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (eq, ne);
|
||||
unsafe {
|
||||
eq = _mm_cmpeq_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
eq = _mm_cmpeq_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
ne = _mm_cmpeq_epi16(eq, _mm_setzero_si128());
|
||||
device.rsp.cpu.vccl = _mm_and_si128(device.rsp.cpu.vcoh, eq);
|
||||
device.rsp.cpu.vccl = _mm_or_si128(device.rsp.cpu.vccl, ne);
|
||||
device.rsp.cpu.accl = _mm_blendv_epi8(
|
||||
vte,
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
device.rsp.cpu.vccl,
|
||||
);
|
||||
device.rsp.cpu.vcch = _mm_setzero_si128();
|
||||
device.rsp.cpu.vcoh = _mm_setzero_si128();
|
||||
device.rsp.cpu.vcol = _mm_setzero_si128();
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -772,27 +596,20 @@ pub fn vge(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (mut eq, gt, es);
|
||||
unsafe {
|
||||
eq = _mm_cmpeq_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
gt = _mm_cmpgt_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
eq = _mm_cmpeq_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
gt = _mm_cmpgt_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
es = _mm_and_si128(device.rsp.cpu.vcoh, device.rsp.cpu.vcol);
|
||||
eq = _mm_andnot_si128(es, eq);
|
||||
device.rsp.cpu.vccl = _mm_or_si128(gt, eq);
|
||||
device.rsp.cpu.accl = _mm_blendv_epi8(
|
||||
vte,
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
device.rsp.cpu.vccl,
|
||||
);
|
||||
device.rsp.cpu.vcch = _mm_setzero_si128();
|
||||
device.rsp.cpu.vcoh = _mm_setzero_si128();
|
||||
device.rsp.cpu.vcol = _mm_setzero_si128();
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -815,14 +632,8 @@ pub fn vcl(device: &mut device::Device, opcode: u32) {
|
||||
unsafe {
|
||||
nvt = _mm_xor_si128(vte, device.rsp.cpu.vcol);
|
||||
nvt = _mm_sub_epi16(nvt, device.rsp.cpu.vcol);
|
||||
diff = _mm_sub_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
nvt,
|
||||
);
|
||||
ncarry = _mm_adds_epu16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
diff = _mm_sub_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], nvt);
|
||||
ncarry = _mm_adds_epu16(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
ncarry = _mm_cmpeq_epi16(diff, ncarry);
|
||||
nvce = _mm_cmpeq_epi16(device.rsp.cpu.vce, _mm_setzero_si128());
|
||||
diff0 = _mm_cmpeq_epi16(diff, _mm_setzero_si128());
|
||||
@@ -831,28 +642,20 @@ pub fn vcl(device: &mut device::Device, opcode: u32) {
|
||||
lec2 = _mm_or_si128(diff0, ncarry);
|
||||
lec2 = _mm_and_si128(device.rsp.cpu.vce, lec2);
|
||||
leeq = _mm_or_si128(lec1, lec2);
|
||||
geeq = _mm_subs_epu16(
|
||||
vte,
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
);
|
||||
geeq = _mm_subs_epu16(vte, device.rsp.cpu.vpr[vs(opcode) as usize]);
|
||||
geeq = _mm_cmpeq_epi16(geeq, _mm_setzero_si128());
|
||||
le = _mm_andnot_si128(device.rsp.cpu.vcoh, device.rsp.cpu.vcol);
|
||||
le = _mm_blendv_epi8(device.rsp.cpu.vccl, leeq, le);
|
||||
ge = _mm_or_si128(device.rsp.cpu.vcol, device.rsp.cpu.vcoh);
|
||||
ge = _mm_blendv_epi8(geeq, device.rsp.cpu.vcch, ge);
|
||||
mask = _mm_blendv_epi8(ge, le, device.rsp.cpu.vcol);
|
||||
device.rsp.cpu.accl = _mm_blendv_epi8(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
nvt,
|
||||
mask,
|
||||
);
|
||||
device.rsp.cpu.accl = _mm_blendv_epi8(device.rsp.cpu.vpr[vs(opcode) as usize], nvt, mask);
|
||||
device.rsp.cpu.vcch = ge;
|
||||
device.rsp.cpu.vccl = le;
|
||||
device.rsp.cpu.vcoh = _mm_setzero_si128();
|
||||
device.rsp.cpu.vcol = _mm_setzero_si128();
|
||||
device.rsp.cpu.vce = _mm_setzero_si128();
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -860,17 +663,11 @@ pub fn vch(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (mut nvt, diff, diff0, vtn, mut dlez, dgez, mask);
|
||||
unsafe {
|
||||
device.rsp.cpu.vcol = _mm_xor_si128(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.vcol = _mm_xor_si128(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.vcol = _mm_cmplt_epi16(device.rsp.cpu.vcol, _mm_setzero_si128());
|
||||
nvt = _mm_xor_si128(vte, device.rsp.cpu.vcol);
|
||||
nvt = _mm_sub_epi16(nvt, device.rsp.cpu.vcol);
|
||||
diff = _mm_sub_epi16(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
nvt,
|
||||
);
|
||||
diff = _mm_sub_epi16(device.rsp.cpu.vpr[vs(opcode) as usize], nvt);
|
||||
diff0 = _mm_cmpeq_epi16(diff, _mm_setzero_si128());
|
||||
vtn = _mm_cmplt_epi16(vte, _mm_setzero_si128());
|
||||
dlez = _mm_cmpgt_epi16(diff, _mm_setzero_si128());
|
||||
@@ -887,13 +684,8 @@ pub fn vch(device: &mut device::Device, opcode: u32) {
|
||||
device.rsp.cpu.vccl,
|
||||
device.rsp.cpu.vcol,
|
||||
);
|
||||
device.rsp.cpu.accl = _mm_blendv_epi8(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
nvt,
|
||||
mask,
|
||||
);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.accl = _mm_blendv_epi8(device.rsp.cpu.vpr[vs(opcode) as usize], nvt, mask);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -901,32 +693,18 @@ pub fn vcr(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
let (mut sign, mut dlez, mut dgez, nvt, mask);
|
||||
unsafe {
|
||||
sign = _mm_xor_si128(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
sign = _mm_xor_si128(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
sign = _mm_srai_epi16(sign, 15);
|
||||
dlez = _mm_and_si128(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
sign,
|
||||
);
|
||||
dlez = _mm_and_si128(device.rsp.cpu.vpr[vs(opcode) as usize], sign);
|
||||
dlez = _mm_add_epi16(dlez, vte);
|
||||
device.rsp.cpu.vccl = _mm_srai_epi16(dlez, 15);
|
||||
dgez = _mm_or_si128(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
sign,
|
||||
);
|
||||
dgez = _mm_or_si128(device.rsp.cpu.vpr[vs(opcode) as usize], sign);
|
||||
dgez = _mm_min_epi16(dgez, vte);
|
||||
device.rsp.cpu.vcch = _mm_cmpeq_epi16(dgez, vte);
|
||||
nvt = _mm_xor_si128(vte, sign);
|
||||
mask = _mm_blendv_epi8(device.rsp.cpu.vcch, device.rsp.cpu.vccl, sign);
|
||||
device.rsp.cpu.accl = _mm_blendv_epi8(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
nvt,
|
||||
mask,
|
||||
);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.accl = _mm_blendv_epi8(device.rsp.cpu.vpr[vs(opcode) as usize], nvt, mask);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
device.rsp.cpu.vcol = _mm_setzero_si128();
|
||||
device.rsp.cpu.vcoh = _mm_setzero_si128();
|
||||
device.rsp.cpu.vce = _mm_setzero_si128();
|
||||
@@ -938,88 +716,63 @@ pub fn vmrg(device: &mut device::Device, opcode: u32) {
|
||||
unsafe {
|
||||
device.rsp.cpu.accl = _mm_blendv_epi8(
|
||||
vte,
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
device.rsp.cpu.vccl,
|
||||
);
|
||||
device.rsp.cpu.vcoh = _mm_setzero_si128();
|
||||
device.rsp.cpu.vcol = _mm_setzero_si128();
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vand(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
unsafe {
|
||||
device.rsp.cpu.accl = _mm_and_si128(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.accl = _mm_and_si128(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vnand(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
unsafe {
|
||||
device.rsp.cpu.accl = _mm_and_si128(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.accl = _mm_and_si128(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.accl = _mm_xor_si128(device.rsp.cpu.accl, _mm_set1_epi32(-1));
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vor(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
unsafe {
|
||||
device.rsp.cpu.accl = _mm_or_si128(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.accl = _mm_or_si128(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vnor(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
unsafe {
|
||||
device.rsp.cpu.accl = _mm_or_si128(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.accl = _mm_or_si128(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.accl = _mm_xor_si128(device.rsp.cpu.accl, _mm_set1_epi32(-1));
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vxor(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
unsafe {
|
||||
device.rsp.cpu.accl = _mm_xor_si128(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.accl = _mm_xor_si128(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vnxor(device: &mut device::Device, opcode: u32) {
|
||||
let vte = vte(device, vt(opcode), ve(opcode) as usize);
|
||||
unsafe {
|
||||
device.rsp.cpu.accl = _mm_xor_si128(
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.accl = _mm_xor_si128(device.rsp.cpu.vpr[vs(opcode) as usize], vte);
|
||||
device.rsp.cpu.accl = _mm_xor_si128(device.rsp.cpu.accl, _mm_set1_epi32(-1));
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = device.rsp.cpu.accl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1106,10 +859,7 @@ 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(
|
||||
unsafe { std::mem::transmute::<__m128i, u128>(vte) },
|
||||
de(opcode) as u8,
|
||||
);
|
||||
let value = get_vpr_element(vte, de(opcode) as u8);
|
||||
modify_vpr_element(
|
||||
&mut device.rsp.cpu.vpr[vd(opcode) as usize],
|
||||
de(opcode) as u8,
|
||||
|
||||
Reference in new issue
Block a user