diff --git a/build.rs b/build.rs index f2410e94..c204cc96 100644 --- a/build.rs +++ b/build.rs @@ -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") diff --git a/src/compat/aarch64.c b/src/compat/aarch64.c index 6f0a517c..4c4e13ec 100644 --- a/src/compat/aarch64.c +++ b/src/compat/aarch64.c @@ -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(); + } +} diff --git a/src/compat/aarch64.rs b/src/compat/aarch64.rs index 102d9fe4..87869d7b 100644 --- a/src/compat/aarch64.rs +++ b/src/compat/aarch64.rs @@ -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; +} diff --git a/src/device.rs b/src/device.rs index cab92543..7c5aa147 100644 --- a/src/device.rs +++ b/src/device.rs @@ -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, diff --git a/src/device/rsp_cpu.rs b/src/device/rsp_cpu.rs index 5539cee6..3d41440d 100644 --- a/src/device/rsp_cpu.rs +++ b/src/device/rsp_cpu.rs @@ -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, diff --git a/src/device/rsp_su_instructions.rs b/src/device/rsp_su_instructions.rs index ba9b802e..22654640 100644 --- a/src/device/rsp_su_instructions.rs +++ b/src/device/rsp_su_instructions.rs @@ -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( diff --git a/src/device/rsp_vu_instructions.rs b/src/device/rsp_vu_instructions.rs index 3cb5504e..85e44ed1 100644 --- a/src/device/rsp_vu_instructions.rs +++ b/src/device/rsp_vu_instructions.rs @@ -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::(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::(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::(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::(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::(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::(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::(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::(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::(device.rsp.cpu.vpr[vs(opcode) as usize]), - vte, - ); - device.rsp.cpu.accm = _mm_mulhi_epu16( - std::mem::transmute::(device.rsp.cpu.vpr[vs(opcode) as usize]), - vte, - ); - sign = _mm_srai_epi16( - std::mem::transmute::(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::(device.rsp.cpu.vpr[vs(opcode) as usize]), - vte, - ); - device.rsp.cpu.accm = _mm_mulhi_epu16( - std::mem::transmute::(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::(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::(device.rsp.cpu.vpr[vs(opcode) as usize]), - vte, - ); - device.rsp.cpu.acch = _mm_mulhi_epi16( - std::mem::transmute::(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::(device.rsp.cpu.vpr[vs(opcode) as usize]), - vte, - ); - hi = _mm_mulhi_epi16( - std::mem::transmute::(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::(device.rsp.cpu.vpr[vs(opcode) as usize]), - vte, - ); - hi = _mm_mulhi_epi16( - std::mem::transmute::(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::(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::(device.rsp.cpu.vpr[vs(opcode) as usize]), - vte, - ); - hi = _mm_mulhi_epu16( - std::mem::transmute::(device.rsp.cpu.vpr[vs(opcode) as usize]), - vte, - ); - sign = _mm_srai_epi16( - std::mem::transmute::(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::(device.rsp.cpu.vpr[vs(opcode) as usize]), - vte, - ); - hi = _mm_mulhi_epu16( - std::mem::transmute::(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::(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::(device.rsp.cpu.vpr[vs(opcode) as usize]), - vte, - ); - hi = _mm_mulhi_epi16( - std::mem::transmute::(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::(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::(device.rsp.cpu.vpr[vs(opcode) as usize]), - vte, - ); - max = _mm_max_epi16( - std::mem::transmute::(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::(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::(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::(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::(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::(device.rsp.cpu.vpr[vd(opcode) as usize]), - std::mem::transmute::(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::(device.rsp.cpu.vpr[vs(opcode) as usize]), - _mm_setzero_si128(), - ); - slt = _mm_srai_epi16( - std::mem::transmute::(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::(device.rsp.cpu.vpr[vd(opcode) as usize]), - slt, - )); - device.rsp.cpu.accl = _mm_sub_epi16( - std::mem::transmute::(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::(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::(device.rsp.cpu.vpr[vs(opcode) as usize]), - vte, - ); - device.rsp.cpu.accl = _mm_add_epi16( - std::mem::transmute::(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::(device.rsp.cpu.vpr[vs(opcode) as usize]), - vte, - ); - equal = _mm_cmpeq_epi16( - std::mem::transmute::(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::(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::(device.rsp.cpu.vpr[vs(opcode) as usize]), - vte, - ); - lt = _mm_cmplt_epi16( - std::mem::transmute::(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::(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::(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::(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::(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::(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::(device.rsp.cpu.vpr[vs(opcode) as usize]), - vte, - ); - gt = _mm_cmpgt_epi16( - std::mem::transmute::(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::(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::(device.rsp.cpu.vpr[vs(opcode) as usize]), - nvt, - ); - ncarry = _mm_adds_epu16( - std::mem::transmute::(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::(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::(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::(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::(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::(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::(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::(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::(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::(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::(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::(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::(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::(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::(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::(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::(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,