aarch64 support (#128)
* First step for aarch64 * more * more * more * more * more * more * more * more * more * more * more * more * more * more * more * test with cpp * more * more * more * more * more * more * more * more
This commit is contained in:
parent
5d00eccb19
commit
9058cd1715
37
.github/workflows/build.yml
vendored
37
.github/workflows/build.yml
vendored
@ -12,8 +12,9 @@ env:
|
||||
jobs:
|
||||
build-linux:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
TARGET: x86_64-unknown-linux-gnu
|
||||
strategy:
|
||||
matrix:
|
||||
target: [x86_64-unknown-linux-gnu]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
@ -23,53 +24,57 @@ jobs:
|
||||
sudo apt -y install libsdl2-dev
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
rustflags: ""
|
||||
- name: Build
|
||||
run: |
|
||||
cargo build --release -v --target=${{ env.TARGET }}
|
||||
cargo build --release -v --target=${{ matrix.target }}
|
||||
- name: Upload file
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: gopher64-linux
|
||||
path: target/${{ env.TARGET }}/release/gopher64
|
||||
name: gopher64-${{ matrix.target }}
|
||||
path: target/${{ matrix.target }}/release/gopher64
|
||||
|
||||
build-windows:
|
||||
runs-on: windows-latest
|
||||
env:
|
||||
TARGET: x86_64-pc-windows-msvc
|
||||
strategy:
|
||||
matrix:
|
||||
target: [x86_64-pc-windows-msvc]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
rustflags: ""
|
||||
- name: Build
|
||||
run: |
|
||||
cargo build --release -v --target=${{ env.TARGET }}
|
||||
cargo build --release -v --target=${{ matrix.target }}
|
||||
- name: Upload file
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: gopher64-windows
|
||||
path: target/${{ env.TARGET }}/release/gopher64.exe
|
||||
name: gopher64-${{ matrix.target }}
|
||||
path: target/${{ matrix.target }}/release/gopher64.exe
|
||||
|
||||
build-macos:
|
||||
runs-on: macos-latest
|
||||
env:
|
||||
TARGET: x86_64-apple-darwin
|
||||
strategy:
|
||||
matrix:
|
||||
target: [x86_64-apple-darwin, aarch64-apple-darwin]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@v1
|
||||
with:
|
||||
target: ${{ env.TARGET }}
|
||||
target: ${{ matrix.target }}
|
||||
rustflags: ""
|
||||
- name: Build
|
||||
run: |
|
||||
cargo build --release -v --target=${{ env.TARGET }}
|
||||
cargo build --release -v --target=${{ matrix.target }}
|
||||
- name: Upload file
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: gopher64-mac
|
||||
path: target/${{ env.TARGET }}/release/gopher64
|
||||
name: gopher64-${{ matrix.target }}
|
||||
path: target/${{ matrix.target }}/release/gopher64
|
||||
|
||||
69
build.rs
69
build.rs
@ -1,6 +1,7 @@
|
||||
fn main() {
|
||||
println!("cargo::rerun-if-changed=parallel-rdp");
|
||||
|
||||
let mut simd_build = cc::Build::new();
|
||||
let mut build = cc::Build::new();
|
||||
build
|
||||
.cpp(true)
|
||||
@ -54,11 +55,12 @@ fn main() {
|
||||
|
||||
let os = std::env::var("CARGO_CFG_TARGET_OS").unwrap();
|
||||
let arch = std::env::var("CARGO_CFG_TARGET_ARCH").unwrap();
|
||||
let mut simd_header = "";
|
||||
if os == "windows" {
|
||||
if arch == "x86_64" {
|
||||
build.flag("/arch:AVX2");
|
||||
} else if arch == "aarch64" {
|
||||
build.flag("/arch:armv8.2");
|
||||
panic!("unsupported platform")
|
||||
} else {
|
||||
panic!("unknown arch")
|
||||
}
|
||||
@ -73,6 +75,9 @@ fn main() {
|
||||
build.flag("-march=x86-64-v3");
|
||||
} else if arch == "aarch64" {
|
||||
build.flag("-march=armv8.2-a");
|
||||
simd_build.flag("-march=armv8.2-a");
|
||||
simd_build.file("src/compat/aarch64.c");
|
||||
simd_header = "src/compat/sse2neon.h";
|
||||
} else {
|
||||
panic!("unknown arch")
|
||||
}
|
||||
@ -82,9 +87,9 @@ fn main() {
|
||||
|
||||
build.compile("parallel-rdp");
|
||||
|
||||
let out_path = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap());
|
||||
|
||||
let parallel_bindings = bindgen::Builder::default()
|
||||
// The input header we would like to generate
|
||||
// bindings for.
|
||||
.header("parallel-rdp/interface.hpp")
|
||||
.allowlist_function("rdp_init")
|
||||
.allowlist_function("rdp_close")
|
||||
@ -92,17 +97,63 @@ fn main() {
|
||||
.allowlist_function("rdp_update_screen")
|
||||
.allowlist_function("rdp_process_commands")
|
||||
.allowlist_function("rdp_full_sync")
|
||||
// Tell cargo to invalidate the built crate whenever any of the
|
||||
// included header files changed.
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
|
||||
// Finish the builder and generate the bindings.
|
||||
.generate()
|
||||
// Unwrap the Result and panic on failure.
|
||||
.expect("Unable to generate bindings");
|
||||
|
||||
// Write the bindings to the $OUT_DIR/bindings.rs file.
|
||||
let out_path = std::path::PathBuf::from(std::env::var("OUT_DIR").unwrap());
|
||||
parallel_bindings
|
||||
.write_to_file(out_path.join("parallel_bindings.rs"))
|
||||
.expect("Couldn't write bindings!");
|
||||
|
||||
if arch == "aarch64" {
|
||||
let simd_bindings = bindgen::Builder::default()
|
||||
.header(simd_header)
|
||||
.allowlist_function("_mm_setzero_si128")
|
||||
.allowlist_function("_mm_set_epi8")
|
||||
.allowlist_function("_mm_movemask_epi8")
|
||||
.allowlist_function("_mm_shuffle_epi8")
|
||||
.allowlist_function("_mm_packs_epi16")
|
||||
.allowlist_function("_mm_set_epi16")
|
||||
.allowlist_function("_mm_cmpeq_epi8")
|
||||
.allowlist_function("_mm_and_si128")
|
||||
.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")
|
||||
.allowlist_function("_mm_srai_epi16")
|
||||
.allowlist_function("_mm_andnot_si128")
|
||||
.allowlist_function("_mm_or_si128")
|
||||
.allowlist_function("_mm_mulhi_epu16")
|
||||
.allowlist_function("_mm_sub_epi16")
|
||||
.allowlist_function("_mm_unpacklo_epi16")
|
||||
.allowlist_function("_mm_unpackhi_epi16")
|
||||
.allowlist_function("_mm_packs_epi32")
|
||||
.allowlist_function("_mm_adds_epu16")
|
||||
.allowlist_function("_mm_cmpgt_epi16")
|
||||
.allowlist_function("_mm_blendv_epi8")
|
||||
.allowlist_function("_mm_min_epi16")
|
||||
.allowlist_function("_mm_max_epi16")
|
||||
.allowlist_function("_mm_subs_epi16")
|
||||
.allowlist_function("_mm_adds_epi16")
|
||||
.allowlist_function("_mm_xor_si128")
|
||||
.allowlist_function("_mm_cmplt_epi16")
|
||||
.allowlist_function("_mm_subs_epu16")
|
||||
.allowlist_function("_mm_set1_epi32")
|
||||
.blocklist_type("__m128i")
|
||||
.wrap_static_fns(true)
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
|
||||
.generate()
|
||||
.expect("Unable to generate bindings");
|
||||
|
||||
simd_bindings
|
||||
.write_to_file(out_path.join("simd_bindings.rs"))
|
||||
.expect("Couldn't write bindings!");
|
||||
|
||||
simd_build.file(std::env::temp_dir().join("bindgen").join("extern.c"));
|
||||
simd_build.include(".");
|
||||
simd_build.compile("simd");
|
||||
}
|
||||
}
|
||||
|
||||
5
src/compat/aarch64.c
Normal file
5
src/compat/aarch64.c
Normal file
@ -0,0 +1,5 @@
|
||||
#include "src/compat/sse2neon.h"
|
||||
|
||||
// Static wrappers
|
||||
|
||||
__m128i _mm_srli_epi16__extern(__m128i __a, int __imm8) { return _mm_srli_epi16(__a, __imm8); }
|
||||
4
src/compat/aarch64.rs
Normal file
4
src/compat/aarch64.rs
Normal file
@ -0,0 +1,4 @@
|
||||
unsafe extern "C" {
|
||||
#[link_name = "_mm_srli_epi16__extern"]
|
||||
pub fn _mm_srli_epi16(__a: __m128i, __imm8: ::std::os::raw::c_int) -> __m128i;
|
||||
}
|
||||
9417
src/compat/sse2neon.h
Normal file
9417
src/compat/sse2neon.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,3 +1,15 @@
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(improper_ctypes)]
|
||||
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
#[derive(Copy, Clone)]
|
||||
#[allow(dead_code)]
|
||||
pub struct __m128i(std::arch::aarch64::int64x2_t);
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
include!(concat!(env!("OUT_DIR"), "/simd_bindings.rs"));
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::arch::x86_64::*;
|
||||
|
||||
use crate::ui;
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
@ -228,6 +240,7 @@ impl Device {
|
||||
cop1: cop1::Cop1 {
|
||||
fcr0: 0,
|
||||
fcr31: 0,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
flush_mode: 0,
|
||||
fgr32: [[0; 4]; 32],
|
||||
fgr64: [[0; 8]; 32],
|
||||
@ -334,15 +347,15 @@ impl Device {
|
||||
divdp: false,
|
||||
divin: 0,
|
||||
divout: 0,
|
||||
shuffle: unsafe { [std::arch::x86_64::_mm_setzero_si128(); 16] },
|
||||
vcol: unsafe { std::arch::x86_64::_mm_setzero_si128() },
|
||||
vcoh: unsafe { std::arch::x86_64::_mm_setzero_si128() },
|
||||
vccl: unsafe { std::arch::x86_64::_mm_setzero_si128() },
|
||||
vcch: unsafe { std::arch::x86_64::_mm_setzero_si128() },
|
||||
vce: unsafe { std::arch::x86_64::_mm_setzero_si128() },
|
||||
accl: unsafe { std::arch::x86_64::_mm_setzero_si128() },
|
||||
accm: unsafe { std::arch::x86_64::_mm_setzero_si128() },
|
||||
acch: unsafe { std::arch::x86_64::_mm_setzero_si128() },
|
||||
shuffle: unsafe { [_mm_setzero_si128(); 16] },
|
||||
vcol: unsafe { _mm_setzero_si128() },
|
||||
vcoh: unsafe { _mm_setzero_si128() },
|
||||
vccl: unsafe { _mm_setzero_si128() },
|
||||
vcch: unsafe { _mm_setzero_si128() },
|
||||
vce: unsafe { _mm_setzero_si128() },
|
||||
accl: unsafe { _mm_setzero_si128() },
|
||||
accm: unsafe { _mm_setzero_si128() },
|
||||
acch: unsafe { _mm_setzero_si128() },
|
||||
special_instrs: [rsp_su_instructions::reserved; 64],
|
||||
regimm_instrs: [rsp_su_instructions::reserved; 32],
|
||||
cop0_instrs: [rsp_su_instructions::reserved; 32],
|
||||
|
||||
@ -17,6 +17,7 @@ use crate::device;
|
||||
//const FCR31_CAUSE_INVALID_BIT: u32 = 1 << 16;
|
||||
const FCR31_CAUSE_UNIMP_BIT: u32 = 1 << 17;
|
||||
pub const FCR31_CMP_BIT: u32 = 1 << 23;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
const FCR31_FS_BIT: u32 = 1 << 24;
|
||||
|
||||
const FCR31_CAUSE_MASK: u32 = 0b00000000000000111111000000000000;
|
||||
@ -26,6 +27,7 @@ const FCR31_WRITE_MASK: u32 = 0b00000001100000111111111111111111;
|
||||
pub struct Cop1 {
|
||||
pub fcr0: u32,
|
||||
pub fcr31: u32,
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
pub flush_mode: u32,
|
||||
pub fgr32: [[u8; 4]; 32],
|
||||
pub fgr64: [[u8; 8]; 32],
|
||||
@ -367,21 +369,24 @@ pub fn set_control_registers_fpu(device: &mut device::Device, index: u32, data:
|
||||
device::exceptions::floating_point_exception(device)
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let flush_mode;
|
||||
if (device.cpu.cop1.fcr31 & 2) != 0 {
|
||||
if (device.cpu.cop1.fcr31 & FCR31_FS_BIT) != 0 {
|
||||
flush_mode = std::arch::x86_64::_MM_FLUSH_ZERO_OFF
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
{
|
||||
unsafe {
|
||||
let flush_mode;
|
||||
if (device.cpu.cop1.fcr31 & 2) != 0 {
|
||||
if (device.cpu.cop1.fcr31 & FCR31_FS_BIT) != 0 {
|
||||
flush_mode = std::arch::x86_64::_MM_FLUSH_ZERO_OFF
|
||||
} else {
|
||||
flush_mode = std::arch::x86_64::_MM_FLUSH_ZERO_ON;
|
||||
}
|
||||
} else {
|
||||
flush_mode = std::arch::x86_64::_MM_FLUSH_ZERO_ON;
|
||||
}
|
||||
} else {
|
||||
flush_mode = std::arch::x86_64::_MM_FLUSH_ZERO_ON;
|
||||
}
|
||||
if flush_mode != device.cpu.cop1.flush_mode {
|
||||
#[allow(deprecated)]
|
||||
std::arch::x86_64::_MM_SET_FLUSH_ZERO_MODE(flush_mode);
|
||||
device.cpu.cop1.flush_mode = flush_mode;
|
||||
if flush_mode != device.cpu.cop1.flush_mode {
|
||||
#[allow(deprecated)]
|
||||
std::arch::x86_64::_MM_SET_FLUSH_ZERO_MODE(flush_mode);
|
||||
device.cpu.cop1.flush_mode = flush_mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,9 @@
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use device::__m128i;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
include!(concat!(env!("OUT_DIR"), "/simd_bindings.rs"));
|
||||
use crate::device;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::arch::x86_64::*;
|
||||
|
||||
pub struct BranchState {
|
||||
@ -33,14 +38,14 @@ pub struct Cpu {
|
||||
pub vpr: [u128; 32],
|
||||
pub reciprocals: [u16; 512],
|
||||
pub inverse_square_roots: [u16; 512],
|
||||
pub vcol: std::arch::x86_64::__m128i,
|
||||
pub vcoh: std::arch::x86_64::__m128i,
|
||||
pub vccl: std::arch::x86_64::__m128i,
|
||||
pub vcch: std::arch::x86_64::__m128i,
|
||||
pub vce: std::arch::x86_64::__m128i,
|
||||
pub accl: std::arch::x86_64::__m128i,
|
||||
pub accm: std::arch::x86_64::__m128i,
|
||||
pub acch: std::arch::x86_64::__m128i,
|
||||
pub vcol: __m128i,
|
||||
pub vcoh: __m128i,
|
||||
pub vccl: __m128i,
|
||||
pub vcch: __m128i,
|
||||
pub vce: __m128i,
|
||||
pub accl: __m128i,
|
||||
pub accm: __m128i,
|
||||
pub acch: __m128i,
|
||||
pub divdp: bool,
|
||||
pub divin: i16,
|
||||
pub divout: i16,
|
||||
|
||||
@ -1,4 +1,9 @@
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
use device::__m128i;
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
include!(concat!(env!("OUT_DIR"), "/simd_bindings.rs"));
|
||||
use crate::device;
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::arch::x86_64::*;
|
||||
|
||||
pub fn rd(opcode: u32) -> u32 {
|
||||
@ -574,7 +579,7 @@ pub fn ctc2(device: &mut device::Device, opcode: u32) {
|
||||
),
|
||||
_mm_setzero_si128(),
|
||||
);
|
||||
*hi = std::arch::x86_64::_mm_cmpeq_epi8(
|
||||
*hi = _mm_cmpeq_epi8(
|
||||
_mm_and_si128(
|
||||
_mm_set1_epi8(!(device.rsp.cpu.gpr[rt(opcode) as usize] >> 8) as i8),
|
||||
mask,
|
||||
|
||||
@ -1,5 +1,12 @@
|
||||
#[cfg(target_arch = "aarch64")]
|
||||
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;
|
||||
use crate::device::rsp_su_instructions::{get_vpr_element, modify_vpr_element};
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
use std::arch::x86_64::*;
|
||||
|
||||
pub fn vt(opcode: u32) -> u32 {
|
||||
@ -39,9 +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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vt as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vt as usize]),
|
||||
device.rsp.cpu.shuffle[index],
|
||||
)
|
||||
}
|
||||
@ -52,9 +57,7 @@ pub fn vmulf(device: &mut device::Device, opcode: u32) {
|
||||
let (mut lo, mut hi, mut round, mut sign1, sign2, neq, eq, neg);
|
||||
unsafe {
|
||||
lo = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
round = _mm_cmpeq_epi16(_mm_setzero_si128(), _mm_setzero_si128());
|
||||
@ -62,9 +65,7 @@ pub fn vmulf(device: &mut device::Device, opcode: u32) {
|
||||
lo = _mm_add_epi16(lo, lo);
|
||||
round = _mm_slli_epi16(round, 15);
|
||||
hi = _mm_mulhi_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
sign2 = _mm_srli_epi16(lo, 15);
|
||||
@ -72,9 +73,7 @@ pub fn vmulf(device: &mut device::Device, opcode: u32) {
|
||||
sign1 = _mm_add_epi16(sign1, sign2);
|
||||
hi = _mm_slli_epi16(hi, 1);
|
||||
neq = _mm_cmpeq_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.accm = _mm_add_epi16(hi, sign1);
|
||||
@ -82,10 +81,8 @@ pub fn vmulf(device: &mut device::Device, opcode: u32) {
|
||||
|
||||
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::<
|
||||
std::arch::x86_64::__m128i,
|
||||
u128,
|
||||
>(_mm_add_epi16(device.rsp.cpu.accm, eq));
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<__m128i, u128>(_mm_add_epi16(device.rsp.cpu.accm, eq));
|
||||
}
|
||||
}
|
||||
|
||||
@ -94,9 +91,7 @@ pub fn vmulu(device: &mut device::Device, opcode: u32) {
|
||||
let (mut lo, mut hi, mut round, mut sign1, sign2, neq, neg);
|
||||
unsafe {
|
||||
lo = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
round = _mm_cmpeq_epi16(_mm_setzero_si128(), _mm_setzero_si128());
|
||||
@ -104,9 +99,7 @@ pub fn vmulu(device: &mut device::Device, opcode: u32) {
|
||||
lo = _mm_add_epi16(lo, lo);
|
||||
round = _mm_slli_epi16(round, 15);
|
||||
hi = _mm_mulhi_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
sign2 = _mm_srli_epi16(lo, 15);
|
||||
@ -114,9 +107,7 @@ pub fn vmulu(device: &mut device::Device, opcode: u32) {
|
||||
sign1 = _mm_add_epi16(sign1, sign2);
|
||||
hi = _mm_slli_epi16(hi, 1);
|
||||
neq = _mm_cmpeq_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
device.rsp.cpu.accm = _mm_add_epi16(hi, sign1);
|
||||
@ -125,20 +116,13 @@ pub fn vmulu(device: &mut device::Device, opcode: u32) {
|
||||
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::<std::arch::x86_64::__m128i, u128>(_mm_andnot_si128(
|
||||
device.rsp.cpu.acch,
|
||||
hi,
|
||||
));
|
||||
std::mem::transmute::<__m128i, u128>(_mm_andnot_si128(device.rsp.cpu.acch, hi));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vrndp(device: &mut device::Device, opcode: u32) {
|
||||
let vte = unsafe {
|
||||
std::mem::transmute::<std::arch::x86_64::__m128i, u128>(vte(
|
||||
device,
|
||||
vt(opcode),
|
||||
ve(opcode) as usize,
|
||||
))
|
||||
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) };
|
||||
@ -173,11 +157,7 @@ pub fn vrndp(device: &mut device::Device, opcode: u32) {
|
||||
|
||||
pub fn vmulq(device: &mut device::Device, opcode: u32) {
|
||||
let vte = unsafe {
|
||||
std::mem::transmute::<std::arch::x86_64::__m128i, u128>(vte(
|
||||
device,
|
||||
vt(opcode),
|
||||
ve(opcode) as usize,
|
||||
))
|
||||
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) };
|
||||
@ -205,15 +185,13 @@ 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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -222,28 +200,22 @@ pub fn vmudm(device: &mut device::Device, opcode: u32) {
|
||||
let (sign, vta);
|
||||
unsafe {
|
||||
device.rsp.cpu.accl = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
sign = _mm_srai_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accm);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accm);
|
||||
}
|
||||
}
|
||||
|
||||
@ -252,28 +224,22 @@ pub fn vmudn(device: &mut device::Device, opcode: u32) {
|
||||
let (sign, vsa);
|
||||
unsafe {
|
||||
device.rsp.cpu.accl = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
sign = _mm_srai_epi16(vte, 15);
|
||||
vsa = _mm_and_si128(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -283,21 +249,17 @@ pub fn vmudh(device: &mut device::Device, opcode: u32) {
|
||||
unsafe {
|
||||
device.rsp.cpu.accl = _mm_setzero_si128();
|
||||
device.rsp.cpu.accm = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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::<std::arch::x86_64::__m128i, u128>(_mm_packs_epi32(lo, hi));
|
||||
std::mem::transmute::<__m128i, u128>(_mm_packs_epi32(lo, hi));
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,15 +268,11 @@ pub fn vmacf(device: &mut device::Device, opcode: u32) {
|
||||
let (mut lo, mut md, mut hi, mut carry, mut omask);
|
||||
unsafe {
|
||||
lo = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
hi = _mm_mulhi_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
md = _mm_slli_epi16(hi, 1);
|
||||
@ -340,7 +298,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::<std::arch::x86_64::__m128i, u128>(_mm_packs_epi32(lo, hi));
|
||||
std::mem::transmute::<__m128i, u128>(_mm_packs_epi32(lo, hi));
|
||||
}
|
||||
}
|
||||
|
||||
@ -349,15 +307,11 @@ pub fn vmacu(device: &mut device::Device, opcode: u32) {
|
||||
let (mut lo, mut md, mut hi, mut carry, mut omask, mmask, hmask);
|
||||
unsafe {
|
||||
lo = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
hi = _mm_mulhi_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
md = _mm_slli_epi16(hi, 1);
|
||||
@ -386,17 +340,13 @@ pub fn vmacu(device: &mut device::Device, opcode: u32) {
|
||||
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::<std::arch::x86_64::__m128i, u128>(_mm_or_si128(omask, md));
|
||||
std::mem::transmute::<__m128i, u128>(_mm_or_si128(omask, md));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vrndn(device: &mut device::Device, opcode: u32) {
|
||||
let vte = unsafe {
|
||||
std::mem::transmute::<std::arch::x86_64::__m128i, u128>(vte(
|
||||
device,
|
||||
vt(opcode),
|
||||
ve(opcode) as usize,
|
||||
))
|
||||
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) };
|
||||
@ -456,9 +406,7 @@ pub fn vmadl(device: &mut device::Device, opcode: u32) {
|
||||
let (mut hi, mut omask, nhi, nmd, shi, smd, cmask, cval);
|
||||
unsafe {
|
||||
hi = _mm_mulhi_epu16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
omask = _mm_adds_epu16(device.rsp.cpu.accl, hi);
|
||||
@ -478,11 +426,7 @@ pub fn vmadl(device: &mut device::Device, opcode: u32) {
|
||||
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::<std::arch::x86_64::__m128i, u128>(_mm_blendv_epi8(
|
||||
cval,
|
||||
device.rsp.cpu.accl,
|
||||
cmask,
|
||||
));
|
||||
std::mem::transmute::<__m128i, u128>(_mm_blendv_epi8(cval, device.rsp.cpu.accl, cmask));
|
||||
}
|
||||
}
|
||||
|
||||
@ -491,21 +435,15 @@ pub fn vmadm(device: &mut device::Device, opcode: u32) {
|
||||
let (mut lo, mut hi, sign, vta, mut omask);
|
||||
unsafe {
|
||||
lo = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
hi = _mm_mulhi_epu16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
sign = _mm_srai_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
15,
|
||||
);
|
||||
vta = _mm_and_si128(vte, sign);
|
||||
@ -525,7 +463,7 @@ pub fn vmadm(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::<std::arch::x86_64::__m128i, u128>(_mm_packs_epi32(lo, hi));
|
||||
std::mem::transmute::<__m128i, u128>(_mm_packs_epi32(lo, hi));
|
||||
}
|
||||
}
|
||||
|
||||
@ -534,22 +472,16 @@ pub fn vmadn(device: &mut device::Device, opcode: u32) {
|
||||
let (lo, mut hi, sign, vsa, mut omask, nhi, nmd, shi, smd, cmask, cval);
|
||||
unsafe {
|
||||
lo = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
hi = _mm_mulhi_epu16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
sign = _mm_srai_epi16(vte, 15);
|
||||
vsa = _mm_and_si128(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
sign,
|
||||
);
|
||||
hi = _mm_sub_epi16(hi, vsa);
|
||||
@ -572,11 +504,7 @@ pub fn vmadn(device: &mut device::Device, opcode: u32) {
|
||||
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::<std::arch::x86_64::__m128i, u128>(_mm_blendv_epi8(
|
||||
cval,
|
||||
device.rsp.cpu.accl,
|
||||
cmask,
|
||||
));
|
||||
std::mem::transmute::<__m128i, u128>(_mm_blendv_epi8(cval, device.rsp.cpu.accl, cmask));
|
||||
}
|
||||
}
|
||||
|
||||
@ -585,15 +513,11 @@ pub fn vmadh(device: &mut device::Device, opcode: u32) {
|
||||
let (mut lo, mut hi, mut omask);
|
||||
unsafe {
|
||||
lo = _mm_mullo_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
hi = _mm_mulhi_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
omask = _mm_adds_epu16(device.rsp.cpu.accm, lo);
|
||||
@ -605,7 +529,7 @@ pub fn vmadh(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::<std::arch::x86_64::__m128i, u128>(_mm_packs_epi32(lo, hi));
|
||||
std::mem::transmute::<__m128i, u128>(_mm_packs_epi32(lo, hi));
|
||||
}
|
||||
}
|
||||
|
||||
@ -614,27 +538,21 @@ pub fn vadd(device: &mut device::Device, opcode: u32) {
|
||||
let (sum, mut min, max);
|
||||
unsafe {
|
||||
sum = _mm_add_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
max = _mm_max_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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::<std::arch::x86_64::__m128i, u128>(_mm_adds_epi16(min, max));
|
||||
std::mem::transmute::<__m128i, u128>(_mm_adds_epi16(min, max));
|
||||
device.rsp.cpu.vcol = _mm_setzero_si128();
|
||||
device.rsp.cpu.vcoh = _mm_setzero_si128();
|
||||
}
|
||||
@ -647,24 +565,18 @@ pub fn vsub(device: &mut device::Device, opcode: u32) {
|
||||
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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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::<std::arch::x86_64::__m128i, u128>(_mm_subs_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(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,
|
||||
));
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<std::arch::x86_64::__m128i, u128>(_mm_adds_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
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,
|
||||
));
|
||||
device.rsp.cpu.vcol = _mm_setzero_si128();
|
||||
@ -676,19 +588,13 @@ 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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
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::<std::arch::x86_64::__m128i, u128>(_mm_xor_si128(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
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]),
|
||||
));
|
||||
}
|
||||
}
|
||||
@ -698,37 +604,27 @@ pub fn vabs(device: &mut device::Device, opcode: u32) {
|
||||
let (vs0, slt);
|
||||
unsafe {
|
||||
vs0 = _mm_cmpeq_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
_mm_setzero_si128(),
|
||||
);
|
||||
slt = _mm_srai_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
15,
|
||||
);
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<std::arch::x86_64::__m128i, u128>(_mm_andnot_si128(vs0, vte));
|
||||
std::mem::transmute::<__m128i, u128>(_mm_andnot_si128(vs0, vte));
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
std::mem::transmute::<std::arch::x86_64::__m128i, u128>(_mm_xor_si128(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize],
|
||||
),
|
||||
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::<std::arch::x86_64::__m128i, u128>(_mm_subs_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
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,
|
||||
));
|
||||
}
|
||||
@ -739,22 +635,18 @@ pub fn vaddc(device: &mut device::Device, opcode: u32) {
|
||||
let sum;
|
||||
unsafe {
|
||||
sum = _mm_adds_epu16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -763,47 +655,38 @@ pub fn vsubc(device: &mut device::Device, opcode: u32) {
|
||||
let (equal, udiff, diff0);
|
||||
unsafe {
|
||||
udiff = _mm_subs_epu16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
equal = _mm_cmpeq_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.acch)
|
||||
};
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
unsafe { std::mem::transmute::<__m128i, u128>(device.rsp.cpu.acch) };
|
||||
}
|
||||
0x9 => {
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = unsafe {
|
||||
std::mem::transmute::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accm)
|
||||
};
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] =
|
||||
unsafe { std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accm) };
|
||||
}
|
||||
0xa => {
|
||||
device.rsp.cpu.vpr[vd(opcode) as usize] = unsafe {
|
||||
std::mem::transmute::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl)
|
||||
};
|
||||
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] = 0;
|
||||
@ -816,15 +699,11 @@ pub fn vlt(device: &mut device::Device, opcode: u32) {
|
||||
let (mut eq, lt);
|
||||
unsafe {
|
||||
eq = _mm_cmpeq_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
lt = _mm_cmplt_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
eq = _mm_and_si128(device.rsp.cpu.vcoh, eq);
|
||||
@ -832,16 +711,14 @@ pub fn vlt(device: &mut device::Device, opcode: u32) {
|
||||
device.rsp.cpu.vccl = _mm_or_si128(lt, eq);
|
||||
device.rsp.cpu.accl = _mm_blendv_epi8(
|
||||
vte,
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -850,24 +727,20 @@ pub fn veq(device: &mut device::Device, opcode: u32) {
|
||||
let eq;
|
||||
unsafe {
|
||||
eq = _mm_cmpeq_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -876,9 +749,7 @@ pub fn vne(device: &mut device::Device, opcode: u32) {
|
||||
let (eq, ne);
|
||||
unsafe {
|
||||
eq = _mm_cmpeq_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
ne = _mm_cmpeq_epi16(eq, _mm_setzero_si128());
|
||||
@ -886,16 +757,14 @@ pub fn vne(device: &mut device::Device, opcode: u32) {
|
||||
device.rsp.cpu.vccl = _mm_or_si128(device.rsp.cpu.vccl, ne);
|
||||
device.rsp.cpu.accl = _mm_blendv_epi8(
|
||||
vte,
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -904,15 +773,11 @@ pub fn vge(device: &mut device::Device, opcode: u32) {
|
||||
let (mut eq, gt, es);
|
||||
unsafe {
|
||||
eq = _mm_cmpeq_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
gt = _mm_cmpgt_epi16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
es = _mm_and_si128(device.rsp.cpu.vcoh, device.rsp.cpu.vcol);
|
||||
@ -920,16 +785,14 @@ pub fn vge(device: &mut device::Device, opcode: u32) {
|
||||
device.rsp.cpu.vccl = _mm_or_si128(gt, eq);
|
||||
device.rsp.cpu.accl = _mm_blendv_epi8(
|
||||
vte,
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -953,15 +816,11 @@ pub fn vcl(device: &mut device::Device, opcode: u32) {
|
||||
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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
nvt,
|
||||
);
|
||||
ncarry = _mm_adds_epu16(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
ncarry = _mm_cmpeq_epi16(diff, ncarry);
|
||||
@ -974,9 +833,7 @@ pub fn vcl(device: &mut device::Device, opcode: u32) {
|
||||
leeq = _mm_or_si128(lec1, lec2);
|
||||
geeq = _mm_subs_epu16(
|
||||
vte,
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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);
|
||||
@ -985,9 +842,7 @@ pub fn vcl(device: &mut device::Device, opcode: u32) {
|
||||
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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
nvt,
|
||||
mask,
|
||||
);
|
||||
@ -997,7 +852,7 @@ pub fn vcl(device: &mut device::Device, opcode: u32) {
|
||||
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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1006,18 +861,14 @@ pub fn vch(device: &mut device::Device, opcode: u32) {
|
||||
let (mut nvt, diff, diff0, vtn, mut dlez, dgez, mask);
|
||||
unsafe {
|
||||
device.rsp.cpu.vcol = _mm_xor_si128(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
nvt,
|
||||
);
|
||||
diff0 = _mm_cmpeq_epi16(diff, _mm_setzero_si128());
|
||||
@ -1037,14 +888,12 @@ pub fn vch(device: &mut device::Device, opcode: u32) {
|
||||
device.rsp.cpu.vcol,
|
||||
);
|
||||
device.rsp.cpu.accl = _mm_blendv_epi8(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1053,24 +902,18 @@ pub fn vcr(device: &mut device::Device, opcode: u32) {
|
||||
let (mut sign, mut dlez, mut dgez, nvt, mask);
|
||||
unsafe {
|
||||
sign = _mm_xor_si128(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
vte,
|
||||
);
|
||||
sign = _mm_srai_epi16(sign, 15);
|
||||
dlez = _mm_and_si128(
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(device.rsp.cpu.vpr[vs(opcode) as usize]),
|
||||
sign,
|
||||
);
|
||||
dgez = _mm_min_epi16(dgez, vte);
|
||||
@ -1078,14 +921,12 @@ pub fn vcr(device: &mut device::Device, opcode: u32) {
|
||||
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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(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();
|
||||
@ -1097,15 +938,13 @@ pub fn vmrg(device: &mut device::Device, opcode: u32) {
|
||||
unsafe {
|
||||
device.rsp.cpu.accl = _mm_blendv_epi8(
|
||||
vte,
|
||||
std::mem::transmute::<u128, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1113,13 +952,11 @@ 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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1127,14 +964,12 @@ 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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1142,13 +977,11 @@ 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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1156,14 +989,12 @@ 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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1171,13 +1002,11 @@ 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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1185,14 +1014,12 @@ 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, std::arch::x86_64::__m128i>(
|
||||
device.rsp.cpu.vpr[vs(opcode) as usize],
|
||||
),
|
||||
std::mem::transmute::<u128, __m128i>(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::<std::arch::x86_64::__m128i, u128>(device.rsp.cpu.accl);
|
||||
std::mem::transmute::<__m128i, u128>(device.rsp.cpu.accl);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1280,7 +1107,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::<std::arch::x86_64::__m128i, u128>(vte) },
|
||||
unsafe { std::mem::transmute::<__m128i, u128>(vte) },
|
||||
de(opcode) as u8,
|
||||
);
|
||||
modify_vpr_element(
|
||||
|
||||
Reference in New Issue
Block a user