Skip to content

Commit ad0810b

Browse files
committed
Implement vpmaxq_u8 on aarch64
1 parent 17f218d commit ad0810b

File tree

3 files changed

+83
-13
lines changed

3 files changed

+83
-13
lines changed

src/tools/miri/src/shims/aarch64.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
use rustc_middle::mir::BinOp;
2+
use rustc_middle::ty::Ty;
3+
use rustc_span::Symbol;
4+
use rustc_target::callconv::{Conv, FnAbi};
5+
6+
use crate::*;
7+
8+
impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
9+
pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
10+
fn emulate_aarch64_intrinsic(
11+
&mut self,
12+
link_name: Symbol,
13+
abi: &FnAbi<'tcx, Ty<'tcx>>,
14+
args: &[OpTy<'tcx>],
15+
dest: &MPlaceTy<'tcx>,
16+
) -> InterpResult<'tcx, EmulateItemResult> {
17+
let this = self.eval_context_mut();
18+
// Prefix should have already been checked.
19+
let unprefixed_name = link_name.as_str().strip_prefix("llvm.aarch64.").unwrap();
20+
match unprefixed_name {
21+
"isb" => {
22+
let [arg] = this.check_shim(abi, Conv::C, link_name, args)?;
23+
let arg = this.read_scalar(arg)?.to_i32()?;
24+
match arg {
25+
// SY ("full system scope")
26+
15 => {
27+
this.yield_active_thread();
28+
}
29+
_ => {
30+
throw_unsup_format!("unsupported llvm.aarch64.isb argument {}", arg);
31+
}
32+
}
33+
}
34+
35+
// Used to implement the vpmaxq_u8 function.
36+
// Folding maximum of adjacent pairs.
37+
// https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxq_u8
38+
"neon.umaxp.v16i8" => {
39+
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
40+
41+
let (left, left_len) = this.project_to_simd(left)?;
42+
let (right, right_len) = this.project_to_simd(right)?;
43+
let (dest, lane_count) = this.project_to_simd(dest)?;
44+
assert_eq!(left_len, right_len);
45+
assert_eq!(lane_count, left_len);
46+
47+
for lane_idx in 0..lane_count {
48+
let src = if lane_idx < (lane_count / 2) { &left } else { &right };
49+
#[allow(clippy::arithmetic_side_effects)]
50+
let src_idx = lane_idx % (lane_count / 2);
51+
52+
#[allow(clippy::arithmetic_side_effects)]
53+
let lhs_lane = this.read_immediate(&this.project_index(src, src_idx * 2)?)?;
54+
#[allow(clippy::arithmetic_side_effects)]
55+
let rhs_lane =
56+
this.read_immediate(&this.project_index(src, src_idx * 2 + 1)?)?;
57+
58+
let res_lane = if this
59+
.binary_op(BinOp::Gt, &lhs_lane, &rhs_lane)?
60+
.to_scalar()
61+
.to_bool()?
62+
{
63+
lhs_lane
64+
} else {
65+
rhs_lane
66+
};
67+
68+
let dest = this.project_index(&dest, lane_idx)?;
69+
this.write_immediate(*res_lane, &dest)?;
70+
}
71+
}
72+
73+
_ => return interp_ok(EmulateItemResult::NotSupported),
74+
}
75+
interp_ok(EmulateItemResult::NeedsReturn)
76+
}
77+
}

src/tools/miri/src/shims/foreign_items.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -939,20 +939,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
939939
this, link_name, abi, args, dest,
940940
);
941941
}
942-
// FIXME: Move these to an `arm` submodule.
943-
"llvm.aarch64.isb" if this.tcx.sess.target.arch == "aarch64" => {
944-
let [arg] = this.check_shim(abi, Conv::C, link_name, args)?;
945-
let arg = this.read_scalar(arg)?.to_i32()?;
946-
match arg {
947-
// SY ("full system scope")
948-
15 => {
949-
this.yield_active_thread();
950-
}
951-
_ => {
952-
throw_unsup_format!("unsupported llvm.aarch64.isb argument {}", arg);
953-
}
954-
}
942+
name if name.starts_with("llvm.aarch64.") && this.tcx.sess.target.arch == "aarch64" => {
943+
return shims::aarch64::EvalContextExt::emulate_aarch64_intrinsic(
944+
this, link_name, abi, args, dest,
945+
);
955946
}
947+
// FIXME: Move this to an `arm` submodule.
956948
"llvm.arm.hint" if this.tcx.sess.target.arch == "arm" => {
957949
let [arg] = this.check_shim(abi, Conv::C, link_name, args)?;
958950
let arg = this.read_scalar(arg)?.to_i32()?;

src/tools/miri/src/shims/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![warn(clippy::arithmetic_side_effects)]
22

3+
mod aarch64;
34
mod alloc;
45
mod backtrace;
56
mod files;

0 commit comments

Comments
 (0)