minor tweaks
This commit is contained in:
parent
921667859d
commit
59329154b7
2 changed files with 12 additions and 15 deletions
|
|
@ -1,4 +1,4 @@
|
|||
use rustc_abi::{CanonAbi, Size};
|
||||
use rustc_abi::CanonAbi;
|
||||
use rustc_middle::mir::BinOp;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
|
|
@ -60,8 +60,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
// Vector table lookup: each index selects a byte from the 16-byte table, out-of-range -> 0.
|
||||
// Used to implement vtbl1_u8 function.
|
||||
// LLVM does not have a portable shuffle that takes non-const indices.
|
||||
// So we need to implement this ourselves
|
||||
// LLVM does not have a portable shuffle that takes non-const indices
|
||||
// so we need to implement this ourselves.
|
||||
// https://developer.arm.com/architectures/instruction-sets/intrinsics/vtbl1_u8
|
||||
"neon.tbl1.v16i8" => {
|
||||
let [table, indices] =
|
||||
|
|
@ -73,15 +73,11 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
assert_eq!(table_len, 16);
|
||||
assert_eq!(idx_len, dest_len);
|
||||
|
||||
let table_len = u128::from(table_len);
|
||||
let elem_size = Size::from_bytes(1);
|
||||
for i in 0..dest_len {
|
||||
let idx = this.read_immediate(&this.project_index(&indices, i)?)?;
|
||||
let idx_u = idx.to_scalar().to_uint(elem_size)?;
|
||||
let val = if idx_u < table_len {
|
||||
let t = this.read_immediate(
|
||||
&this.project_index(&table, idx_u.try_into().unwrap())?,
|
||||
)?;
|
||||
let idx_u = idx.to_scalar().to_u8()?;
|
||||
let val = if u64::from(idx_u) < table_len {
|
||||
let t = this.read_immediate(&this.project_index(&table, idx_u.into())?)?;
|
||||
t.to_scalar()
|
||||
} else {
|
||||
Scalar::from_u8(0)
|
||||
|
|
|
|||
|
|
@ -10,13 +10,13 @@ fn main() {
|
|||
assert!(is_aarch64_feature_detected!("neon"));
|
||||
|
||||
unsafe {
|
||||
test_neon();
|
||||
tbl1_v16i8_basic();
|
||||
test_vpmaxq_u8();
|
||||
test_tbl1_v16i8_basic();
|
||||
}
|
||||
}
|
||||
|
||||
#[target_feature(enable = "neon")]
|
||||
unsafe fn test_neon() {
|
||||
unsafe fn test_vpmaxq_u8() {
|
||||
// Adapted from library/stdarch/crates/core_arch/src/aarch64/neon/mod.rs
|
||||
unsafe fn test_vpmaxq_u8() {
|
||||
let a = vld1q_u8([1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8].as_ptr());
|
||||
|
|
@ -42,18 +42,19 @@ unsafe fn test_neon() {
|
|||
}
|
||||
|
||||
#[target_feature(enable = "neon")]
|
||||
fn tbl1_v16i8_basic() {
|
||||
fn test_tbl1_v16i8_basic() {
|
||||
unsafe {
|
||||
// table = 0..15
|
||||
let table: uint8x16_t =
|
||||
transmute::<[u8; 16], _>([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
|
||||
// indices: include in-range, 15 (last), 16 and 255 (out-of-range → 0)
|
||||
// indices
|
||||
let idx: uint8x16_t =
|
||||
transmute::<[u8; 16], _>([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
|
||||
let got = vqtbl1q_u8(table, idx);
|
||||
let got_arr: [u8; 16] = transmute(got);
|
||||
assert_eq!(got_arr, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
|
||||
|
||||
// Also try different order and out-of-range indices (16, 255).
|
||||
let idx2: uint8x16_t =
|
||||
transmute::<[u8; 16], _>([15, 16, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
|
||||
let got2 = vqtbl1q_u8(table, idx2);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue