Skip to content

Commit d6b30b8

Browse files
committed
Move llvm.x86.* implementations into shims::x86
1 parent 5ddf866 commit d6b30b8

File tree

4 files changed

+75
-36
lines changed

4 files changed

+75
-36
lines changed

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

Lines changed: 7 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use rustc_target::{
2222
};
2323

2424
use super::backtrace::EvalContextExt as _;
25-
use crate::helpers::{convert::Truncate, target_os_is_unix};
25+
use crate::helpers::target_os_is_unix;
2626
use crate::*;
2727

2828
/// Returned by `emulate_foreign_item_by_name`.
@@ -981,30 +981,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
981981
throw_unsup_format!("unsupported `llvm.prefetch` type argument: {}", ty);
982982
}
983983
}
984-
"llvm.x86.addcarry.64" if this.tcx.sess.target.arch == "x86_64" => {
985-
// Computes u8+u64+u64, returning tuple (u8,u64) comprising the output carry and truncated sum.
986-
let [c_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
987-
let c_in = this.read_scalar(c_in)?.to_u8()?;
988-
let a = this.read_scalar(a)?.to_u64()?;
989-
let b = this.read_scalar(b)?.to_u64()?;
990-
991-
#[allow(clippy::arithmetic_side_effects)]
992-
// adding two u64 and a u8 cannot wrap in a u128
993-
let wide_sum = u128::from(c_in) + u128::from(a) + u128::from(b);
994-
#[allow(clippy::arithmetic_side_effects)] // it's a u128, we can shift by 64
995-
let (c_out, sum) = ((wide_sum >> 64).truncate::<u8>(), wide_sum.truncate::<u64>());
996-
997-
let c_out_field = this.project_field(dest, 0)?;
998-
this.write_scalar(Scalar::from_u8(c_out), &c_out_field)?;
999-
let sum_field = this.project_field(dest, 1)?;
1000-
this.write_scalar(Scalar::from_u64(sum), &sum_field)?;
1001-
}
1002-
"llvm.x86.sse2.pause"
1003-
if this.tcx.sess.target.arch == "x86" || this.tcx.sess.target.arch == "x86_64" =>
1004-
{
1005-
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
1006-
this.yield_active_thread();
1007-
}
984+
// FIXME: Move these to an `arm` submodule.
1008985
"llvm.aarch64.isb" if this.tcx.sess.target.arch == "aarch64" => {
1009986
let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
1010987
let arg = this.read_scalar(arg)?.to_i32()?;
@@ -1055,13 +1032,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
10551032
}
10561033
}
10571034

1058-
name if name.starts_with("llvm.x86.sse.") => {
1059-
return shims::x86::sse::EvalContextExt::emulate_x86_sse_intrinsic(
1060-
this, link_name, abi, args, dest,
1061-
);
1062-
}
1063-
name if name.starts_with("llvm.x86.sse2.") => {
1064-
return shims::x86::sse2::EvalContextExt::emulate_x86_sse2_intrinsic(
1035+
name if name.starts_with("llvm.x86.")
1036+
&& (this.tcx.sess.target.arch == "x86"
1037+
|| this.tcx.sess.target.arch == "x86_64") =>
1038+
{
1039+
return shims::x86::EvalContextExt::emulate_x86_intrinsic(
10651040
this, link_name, abi, args, dest,
10661041
);
10671042
}

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

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,65 @@
11
use rustc_middle::mir;
2+
use rustc_span::Symbol;
23
use rustc_target::abi::Size;
4+
use rustc_target::spec::abi::Abi;
35

46
use crate::*;
57
use helpers::bool_to_simd_element;
8+
use helpers::convert::Truncate as _;
9+
use shims::foreign_items::EmulateByNameResult;
10+
11+
mod sse;
12+
mod sse2;
13+
14+
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
15+
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
16+
crate::MiriInterpCxExt<'mir, 'tcx>
17+
{
18+
fn emulate_x86_intrinsic(
19+
&mut self,
20+
link_name: Symbol,
21+
abi: Abi,
22+
args: &[OpTy<'tcx, Provenance>],
23+
dest: &PlaceTy<'tcx, Provenance>,
24+
) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
25+
let this = self.eval_context_mut();
26+
// Prefix should have already been checked.
27+
let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.").unwrap();
28+
match unprefixed_name {
29+
"addcarry.64" if this.tcx.sess.target.arch == "x86_64" => {
30+
// Computes u8+u64+u64, returning tuple (u8,u64) comprising the output carry and truncated sum.
31+
let [c_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
32+
let c_in = this.read_scalar(c_in)?.to_u8()?;
33+
let a = this.read_scalar(a)?.to_u64()?;
34+
let b = this.read_scalar(b)?.to_u64()?;
35+
36+
#[allow(clippy::arithmetic_side_effects)]
37+
// adding two u64 and a u8 cannot wrap in a u128
38+
let wide_sum = u128::from(c_in) + u128::from(a) + u128::from(b);
39+
#[allow(clippy::arithmetic_side_effects)] // it's a u128, we can shift by 64
40+
let (c_out, sum) = ((wide_sum >> 64).truncate::<u8>(), wide_sum.truncate::<u64>());
41+
42+
let c_out_field = this.project_field(dest, 0)?;
43+
this.write_scalar(Scalar::from_u8(c_out), &c_out_field)?;
44+
let sum_field = this.project_field(dest, 1)?;
45+
this.write_scalar(Scalar::from_u64(sum), &sum_field)?;
46+
}
647

7-
pub(super) mod sse;
8-
pub(super) mod sse2;
48+
name if name.starts_with("sse.") => {
49+
return sse::EvalContextExt::emulate_x86_sse_intrinsic(
50+
this, link_name, abi, args, dest,
51+
);
52+
}
53+
name if name.starts_with("sse2.") => {
54+
return sse2::EvalContextExt::emulate_x86_sse2_intrinsic(
55+
this, link_name, abi, args, dest,
56+
);
57+
}
58+
_ => return Ok(EmulateByNameResult::NotSupported),
59+
}
60+
Ok(EmulateByNameResult::NeedsJumping)
61+
}
62+
}
963

1064
/// Floating point comparison operation
1165
///

src/tools/miri/src/shims/x86/sse.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ use crate::*;
1010
use shims::foreign_items::EmulateByNameResult;
1111

1212
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
13-
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
13+
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
14+
crate::MiriInterpCxExt<'mir, 'tcx>
15+
{
1416
fn emulate_x86_sse_intrinsic(
1517
&mut self,
1618
link_name: Symbol,

src/tools/miri/src/shims/x86/sse2.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ use crate::*;
1313
use shims::foreign_items::EmulateByNameResult;
1414

1515
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
16-
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
16+
pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
17+
crate::MiriInterpCxExt<'mir, 'tcx>
18+
{
1719
fn emulate_x86_sse2_intrinsic(
1820
&mut self,
1921
link_name: Symbol,
@@ -753,6 +755,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
753755

754756
this.write_scalar(Scalar::from_u32(res.try_into().unwrap()), dest)?;
755757
}
758+
// Used to implement the `_mm_pause` function.
759+
// The intrinsic is used to hint the processor that the code is in a spin-loop.
760+
"pause" => {
761+
let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
762+
this.yield_active_thread();
763+
}
756764
_ => return Ok(EmulateByNameResult::NotSupported),
757765
}
758766
Ok(EmulateByNameResult::NeedsJumping)

0 commit comments

Comments
 (0)