Skip to content

Pass FnAbi to find_mir_or_eval_fn #133103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Dec 20, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion compiler/rustc_const_eval/src/const_eval/dummy_machine.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use rustc_middle::mir::interpret::{AllocId, ConstAllocation, InterpResult};
use rustc_middle::mir::*;
use rustc_middle::query::TyCtxtAt;
use rustc_middle::ty::Ty;
use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::{bug, span_bug, ty};
use rustc_span::def_id::DefId;
use rustc_target::callconv::FnAbi;

use crate::interpret::{
self, HasStaticRootDefId, ImmTy, Immediate, InterpCx, PointerArithmetic, interp_ok,
@@ -86,7 +88,7 @@ impl<'tcx> interpret::Machine<'tcx> for DummyMachine {
fn find_mir_or_eval_fn(
_ecx: &mut InterpCx<'tcx, Self>,
_instance: ty::Instance<'tcx>,
_abi: rustc_abi::ExternAbi,
_abi: &FnAbi<'tcx, Ty<'tcx>>,
_args: &[interpret::FnArg<'tcx, Self::Provenance>],
_destination: &interpret::MPlaceTy<'tcx, Self::Provenance>,
_target: Option<BasicBlock>,
5 changes: 3 additions & 2 deletions compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ use std::borrow::{Borrow, Cow};
use std::fmt;
use std::hash::Hash;

use rustc_abi::{Align, ExternAbi, Size};
use rustc_abi::{Align, Size};
use rustc_ast::Mutability;
use rustc_data_structures::fx::{FxHashMap, FxIndexMap, IndexEntry};
use rustc_hir::def_id::{DefId, LocalDefId};
@@ -14,6 +14,7 @@ use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::{bug, mir};
use rustc_span::{Span, Symbol, sym};
use rustc_target::callconv::FnAbi;
use tracing::debug;

use super::error::*;
@@ -339,7 +340,7 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> {
fn find_mir_or_eval_fn(
ecx: &mut InterpCx<'tcx, Self>,
orig_instance: ty::Instance<'tcx>,
_abi: ExternAbi,
_abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[FnArg<'tcx>],
dest: &MPlaceTy<'tcx>,
ret: Option<mir::BasicBlock>,
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/call.rs
Original file line number Diff line number Diff line change
@@ -519,7 +519,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
return M::call_extra_fn(
self,
extra,
caller_abi,
caller_fn_abi,
args,
destination,
target,
@@ -570,7 +570,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
let Some((body, instance)) = M::find_mir_or_eval_fn(
self,
instance,
caller_abi,
caller_fn_abi,
args,
destination,
target,
9 changes: 5 additions & 4 deletions compiler/rustc_const_eval/src/interpret/machine.rs
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@ use std::borrow::{Borrow, Cow};
use std::fmt::Debug;
use std::hash::Hash;

use rustc_abi::{Align, ExternAbi, Size};
use rustc_abi::{Align, Size};
use rustc_apfloat::{Float, FloatConvert};
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_middle::query::TyCtxtAt;
@@ -15,6 +15,7 @@ use rustc_middle::ty::layout::TyAndLayout;
use rustc_middle::{mir, ty};
use rustc_span::Span;
use rustc_span::def_id::DefId;
use rustc_target::callconv::FnAbi;

use super::{
AllocBytes, AllocId, AllocKind, AllocRange, Allocation, CTFE_ALLOC_SALT, ConstAllocation,
@@ -201,7 +202,7 @@ pub trait Machine<'tcx>: Sized {
fn find_mir_or_eval_fn(
ecx: &mut InterpCx<'tcx, Self>,
instance: ty::Instance<'tcx>,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[FnArg<'tcx, Self::Provenance>],
destination: &MPlaceTy<'tcx, Self::Provenance>,
target: Option<mir::BasicBlock>,
@@ -213,7 +214,7 @@ pub trait Machine<'tcx>: Sized {
fn call_extra_fn(
ecx: &mut InterpCx<'tcx, Self>,
fn_val: Self::ExtraFnVal,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[FnArg<'tcx, Self::Provenance>],
destination: &MPlaceTy<'tcx, Self::Provenance>,
target: Option<mir::BasicBlock>,
@@ -656,7 +657,7 @@ pub macro compile_time_machine(<$tcx: lifetime>) {
fn call_extra_fn(
_ecx: &mut InterpCx<$tcx, Self>,
fn_val: !,
_abi: ExternAbi,
_abi: &FnAbi<$tcx, Ty<$tcx>>,
_args: &[FnArg<$tcx>],
_destination: &MPlaceTy<$tcx, Self::Provenance>,
_target: Option<mir::BasicBlock>,
19 changes: 9 additions & 10 deletions src/tools/miri/src/helpers.rs
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@ use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, MaybeResult, TyAndLayout};
use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, UintTy};
use rustc_session::config::CrateType;
use rustc_span::{Span, Symbol};
use rustc_target::callconv::{Conv, FnAbi};

use crate::*;

@@ -914,13 +915,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
}

/// Check that the ABI is what we expect.
fn check_abi<'a>(&self, abi: ExternAbi, exp_abi: ExternAbi) -> InterpResult<'a, ()> {
if abi != exp_abi {
fn check_abi<'a>(&self, fn_abi: &FnAbi<'tcx, Ty<'tcx>>, exp_abi: Conv) -> InterpResult<'a, ()> {
if fn_abi.conv != exp_abi {
throw_ub_format!(
"calling a function with ABI {} using caller ABI {}",
exp_abi.name(),
abi.name()
)
"calling a function with ABI {:?} using caller ABI {:?}",
exp_abi, fn_abi.conv);
}
interp_ok(())
}
@@ -950,8 +949,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

fn check_abi_and_shim_symbol_clash(
&mut self,
abi: ExternAbi,
exp_abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
exp_abi: Conv,
link_name: Symbol,
) -> InterpResult<'tcx, ()> {
self.check_abi(abi, exp_abi)?;
@@ -975,8 +974,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

fn check_shim<'a, const N: usize>(
&mut self,
abi: ExternAbi,
exp_abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
exp_abi: Conv,
link_name: Symbol,
args: &'a [OpTy<'tcx>],
) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]>
5 changes: 3 additions & 2 deletions src/tools/miri/src/machine.rs
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ use rand::{Rng, SeedableRng};
use rustc_abi::{Align, ExternAbi, Size};
use rustc_attr_parsing::InlineAttr;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_target::callconv::FnAbi;
#[allow(unused)]
use rustc_data_structures::static_assert_size;
use rustc_middle::mir;
@@ -1010,7 +1011,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
fn find_mir_or_eval_fn(
ecx: &mut MiriInterpCx<'tcx>,
instance: ty::Instance<'tcx>,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[FnArg<'tcx, Provenance>],
dest: &MPlaceTy<'tcx>,
ret: Option<mir::BasicBlock>,
@@ -1037,7 +1038,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
fn call_extra_fn(
ecx: &mut MiriInterpCx<'tcx>,
fn_val: DynSym,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[FnArg<'tcx, Provenance>],
dest: &MPlaceTy<'tcx>,
ret: Option<mir::BasicBlock>,
21 changes: 11 additions & 10 deletions src/tools/miri/src/shims/backtrace.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use rustc_abi::{ExternAbi, Size};
use rustc_abi::Size;
use rustc_middle::ty::layout::LayoutOf as _;
use rustc_middle::ty::{self, Instance, Ty};
use rustc_span::{BytePos, Loc, Symbol, hygiene};
use rustc_target::callconv::{Conv, FnAbi};

use crate::helpers::check_min_arg_count;
use crate::*;
@@ -10,13 +11,13 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn handle_miri_backtrace_size(
&mut self,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
link_name: Symbol,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let [flags] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
let [flags] = this.check_shim(abi, Conv::Rust, link_name, args)?;

let flags = this.read_scalar(flags)?.to_u64()?;
if flags != 0 {
@@ -30,7 +31,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

fn handle_miri_get_backtrace(
&mut self,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
link_name: Symbol,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
@@ -71,7 +72,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// storage for pointers is allocated by miri
// deallocating the slice is undefined behavior with a custom global allocator
0 => {
let [_flags] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
let [_flags] = this.check_shim(abi, Conv::Rust, link_name, args)?;

let alloc = this.allocate(array_layout, MiriMemoryKind::Rust.into())?;

@@ -86,7 +87,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
}
// storage for pointers is allocated by the caller
1 => {
let [_flags, buf] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
let [_flags, buf] = this.check_shim(abi, Conv::Rust, link_name, args)?;

let buf_place = this.deref_pointer(buf)?;

@@ -136,13 +137,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

fn handle_miri_resolve_frame(
&mut self,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
link_name: Symbol,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let [ptr, flags] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
let [ptr, flags] = this.check_shim(abi, Conv::Rust, link_name, args)?;

let flags = this.read_scalar(flags)?.to_u64()?;

@@ -207,14 +208,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

fn handle_miri_resolve_frame_names(
&mut self,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
link_name: Symbol,
args: &[OpTy<'tcx>],
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();

let [ptr, flags, name_ptr, filename_ptr] =
this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
this.check_shim(abi, Conv::Rust, link_name, args)?;

let flags = this.read_scalar(flags)?.to_u64()?;
if flags != 0 {
88 changes: 45 additions & 43 deletions src/tools/miri/src/shims/foreign_items.rs

Large diffs are not rendered by default.

17 changes: 10 additions & 7 deletions src/tools/miri/src/shims/unix/android/foreign_items.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use rustc_abi::ExternAbi;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};



use crate::shims::unix::android::thread::prctl;
use crate::shims::unix::linux_like::epoll::EvalContextExt as _;
@@ -16,7 +19,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -25,31 +28,31 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// epoll, eventfd
"epoll_create1" => {
let [flag] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.epoll_create1(flag)?;
this.write_scalar(result, dest)?;
}
"epoll_ctl" => {
let [epfd, op, fd, event] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.epoll_ctl(epfd, op, fd, event)?;
this.write_scalar(result, dest)?;
}
"epoll_wait" => {
let [epfd, events, maxevents, timeout] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
this.epoll_wait(epfd, events, maxevents, timeout, dest)?;
}
"eventfd" => {
let [val, flag] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.eventfd(val, flag)?;
this.write_scalar(result, dest)?;
}

// Miscellaneous
"__errno" => {
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
let errno_place = this.last_error_place()?;
this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
}
8 changes: 5 additions & 3 deletions src/tools/miri/src/shims/unix/android/thread.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use rustc_abi::{ExternAbi, Size};
use rustc_abi::Size;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use crate::helpers::check_min_arg_count;
use crate::shims::unix::thread::{EvalContextExt as _, ThreadNameResult};
@@ -10,13 +12,13 @@ const TASK_COMM_LEN: usize = 16;
pub fn prctl<'tcx>(
ecx: &mut MiriInterpCx<'tcx>,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx> {
// We do not use `check_shim` here because `prctl` is variadic. The argument
// count is checked bellow.
ecx.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?;
ecx.check_abi_and_shim_symbol_clash(abi, Conv::C, link_name)?;

// FIXME: Use constants once https://github.com/rust-lang/libc/pull/3941 backported to the 0.2 branch.
let pr_set_name = 15;
206 changes: 103 additions & 103 deletions src/tools/miri/src/shims/unix/foreign_items.rs

Large diffs are not rendered by default.

21 changes: 11 additions & 10 deletions src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rustc_abi::ExternAbi;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use crate::shims::unix::*;
use crate::*;
@@ -13,7 +14,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -22,7 +23,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Threading
"pthread_set_name_np" => {
let [thread, name] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let max_len = usize::MAX; // FreeBSD does not seem to have a limit.
// FreeBSD's pthread_set_name_np does not return anything.
this.pthread_setname_np(
@@ -34,7 +35,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
}
"pthread_get_name_np" => {
let [thread, name, len] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
// FreeBSD's pthread_get_name_np does not return anything
// and uses strlcpy, which truncates the resulting value,
// but always adds a null terminator (except for zero-sized buffers).
@@ -52,32 +53,32 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// since freebsd 12 the former form can be expected.
"stat" | "stat@FBSD_1.0" => {
let [path, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.macos_fbsd_solaris_stat(path, buf)?;
this.write_scalar(result, dest)?;
}
"lstat" | "lstat@FBSD_1.0" => {
let [path, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.macos_fbsd_solaris_lstat(path, buf)?;
this.write_scalar(result, dest)?;
}
"fstat" | "fstat@FBSD_1.0" => {
let [fd, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.macos_fbsd_solaris_fstat(fd, buf)?;
this.write_scalar(result, dest)?;
}
"readdir_r" | "readdir_r@FBSD_1.0" => {
let [dirp, entry, result] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.macos_fbsd_readdir_r(dirp, entry, result)?;
this.write_scalar(result, dest)?;
}

// Miscellaneous
"__error" => {
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
let errno_place = this.last_error_place()?;
this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
}
@@ -86,7 +87,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// These shims are enabled only when the caller is in the standard library.
"pthread_attr_get_np" if this.frame_in_std() => {
let [_thread, _attr] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
this.write_null(dest)?;
}

39 changes: 20 additions & 19 deletions src/tools/miri/src/shims/unix/linux/foreign_items.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rustc_abi::ExternAbi;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use self::shims::unix::linux::mem::EvalContextExt as _;
use self::shims::unix::linux_like::epoll::EvalContextExt as _;
@@ -24,7 +25,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -36,52 +37,52 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// File related shims
"readdir64" => {
let [dirp] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.linux_readdir64(dirp)?;
this.write_scalar(result, dest)?;
}
"sync_file_range" => {
let [fd, offset, nbytes, flags] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.sync_file_range(fd, offset, nbytes, flags)?;
this.write_scalar(result, dest)?;
}
"statx" => {
let [dirfd, pathname, flags, mask, statxbuf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.linux_statx(dirfd, pathname, flags, mask, statxbuf)?;
this.write_scalar(result, dest)?;
}

// epoll, eventfd
"epoll_create1" => {
let [flag] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.epoll_create1(flag)?;
this.write_scalar(result, dest)?;
}
"epoll_ctl" => {
let [epfd, op, fd, event] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.epoll_ctl(epfd, op, fd, event)?;
this.write_scalar(result, dest)?;
}
"epoll_wait" => {
let [epfd, events, maxevents, timeout] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
this.epoll_wait(epfd, events, maxevents, timeout, dest)?;
}
"eventfd" => {
let [val, flag] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.eventfd(val, flag)?;
this.write_scalar(result, dest)?;
}

// Threading
"pthread_setname_np" => {
let [thread, name] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let res = match this.pthread_setname_np(
this.read_scalar(thread)?,
this.read_scalar(name)?,
@@ -97,7 +98,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
}
"pthread_getname_np" => {
let [thread, name, len] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
// The function's behavior isn't portable between platforms.
// In case of glibc, the length of the output buffer must
// be not shorter than TASK_COMM_LEN.
@@ -120,7 +121,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
this.write_scalar(res, dest)?;
}
"gettid" => {
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.linux_gettid()?;
this.write_scalar(result, dest)?;
}
@@ -133,35 +134,35 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Miscellaneous
"mmap64" => {
let [addr, length, prot, flags, fd, offset] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let offset = this.read_scalar(offset)?.to_i64()?;
let ptr = this.mmap(addr, length, prot, flags, fd, offset.into())?;
this.write_scalar(ptr, dest)?;
}
"mremap" => {
let [old_address, old_size, new_size, flags] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let ptr = this.mremap(old_address, old_size, new_size, flags)?;
this.write_scalar(ptr, dest)?;
}
"__xpg_strerror_r" => {
let [errnum, buf, buflen] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.strerror_r(errnum, buf, buflen)?;
this.write_scalar(result, dest)?;
}
"__errno_location" => {
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
let errno_place = this.last_error_place()?;
this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
}
"__libc_current_sigrtmin" => {
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;

this.write_int(SIGRTMIN, dest)?;
}
"__libc_current_sigrtmax" => {
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;

this.write_int(SIGRTMAX, dest)?;
}
@@ -170,7 +171,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// These shims are enabled only when the caller is in the standard library.
"pthread_getattr_np" if this.frame_in_std() => {
let [_thread, _attr] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
this.write_null(dest)?;
}

8 changes: 5 additions & 3 deletions src/tools/miri/src/shims/unix/linux_like/syscall.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use rustc_abi::ExternAbi;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};


use crate::helpers::check_min_arg_count;
use crate::shims::unix::linux_like::eventfd::EvalContextExt as _;
@@ -9,13 +11,13 @@ use crate::*;
pub fn syscall<'tcx>(
ecx: &mut MiriInterpCx<'tcx>,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx> {
// We do not use `check_shim` here because `syscall` is variadic. The argument
// count is checked bellow.
ecx.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?;
ecx.check_abi_and_shim_symbol_clash(abi, Conv::C, link_name)?;
// The syscall variadic function is legal to call with more arguments than needed,
// extra arguments are simply ignored. The important check is that when we use an
// argument, we have to also check all arguments *before* it to ensure that they
55 changes: 28 additions & 27 deletions src/tools/miri/src/shims/unix/macos/foreign_items.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rustc_abi::ExternAbi;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use super::sync::EvalContextExt as _;
use crate::shims::unix::*;
@@ -14,7 +15,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -25,66 +26,66 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
match link_name.as_str() {
// errno
"__error" => {
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
let errno_place = this.last_error_place()?;
this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
}

// File related shims
"close$NOCANCEL" => {
let [result] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.close(result)?;
this.write_scalar(result, dest)?;
}
"stat" | "stat64" | "stat$INODE64" => {
let [path, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.macos_fbsd_solaris_stat(path, buf)?;
this.write_scalar(result, dest)?;
}
"lstat" | "lstat64" | "lstat$INODE64" => {
let [path, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.macos_fbsd_solaris_lstat(path, buf)?;
this.write_scalar(result, dest)?;
}
"fstat" | "fstat64" | "fstat$INODE64" => {
let [fd, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.macos_fbsd_solaris_fstat(fd, buf)?;
this.write_scalar(result, dest)?;
}
"opendir$INODE64" => {
let [name] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.opendir(name)?;
this.write_scalar(result, dest)?;
}
"readdir_r" | "readdir_r$INODE64" => {
let [dirp, entry, result] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.macos_fbsd_readdir_r(dirp, entry, result)?;
this.write_scalar(result, dest)?;
}
"realpath$DARWIN_EXTSN" => {
let [path, resolved_path] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.realpath(path, resolved_path)?;
this.write_scalar(result, dest)?;
}

// Environment related shims
"_NSGetEnviron" => {
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
let environ = this.machine.env_vars.unix().environ();
this.write_pointer(environ, dest)?;
}

// Random data generation
"CCRandomGenerateBytes" => {
let [bytes, count] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let bytes = this.read_pointer(bytes)?;
let count = this.read_target_usize(count)?;
let success = this.eval_libc_i32("kCCSuccess");
@@ -94,30 +95,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

// Time related shims
"mach_absolute_time" => {
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.mach_absolute_time()?;
this.write_scalar(result, dest)?;
}

"mach_timebase_info" => {
let [info] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.mach_timebase_info(info)?;
this.write_scalar(result, dest)?;
}

// Access to command-line arguments
"_NSGetArgc" => {
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
this.write_pointer(this.machine.argc.expect("machine must be initialized"), dest)?;
}
"_NSGetArgv" => {
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
this.write_pointer(this.machine.argv.expect("machine must be initialized"), dest)?;
}
"_NSGetExecutablePath" => {
let [buf, bufsize] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
this.check_no_isolation("`_NSGetExecutablePath`")?;

let buf_ptr = this.read_pointer(buf)?;
@@ -143,7 +144,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Thread-local storage
"_tlv_atexit" => {
let [dtor, data] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let dtor = this.read_pointer(dtor)?;
let dtor = this.get_ptr_fn(dtor)?.as_instance()?;
let data = this.read_scalar(data)?;
@@ -154,14 +155,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Querying system information
"pthread_get_stackaddr_np" => {
let [thread] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
this.read_target_usize(thread)?;
let stack_addr = Scalar::from_uint(this.machine.stack_addr, this.pointer_size());
this.write_scalar(stack_addr, dest)?;
}
"pthread_get_stacksize_np" => {
let [thread] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
this.read_target_usize(thread)?;
let stack_size = Scalar::from_uint(this.machine.stack_size, this.pointer_size());
this.write_scalar(stack_size, dest)?;
@@ -170,7 +171,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Threading
"pthread_setname_np" => {
let [name] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

// The real implementation has logic in two places:
// * in userland at https://github.com/apple-oss-distributions/libpthread/blob/c032e0b076700a0a47db75528a282b8d3a06531a/src/pthread.c#L1178-L1200,
@@ -198,7 +199,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
}
"pthread_getname_np" => {
let [thread, name, len] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

// The function's behavior isn't portable between platforms.
// In case of macOS, a truncated name (due to a too small buffer)
@@ -224,27 +225,27 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

"os_unfair_lock_lock" => {
let [lock_op] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
this.os_unfair_lock_lock(lock_op)?;
}
"os_unfair_lock_trylock" => {
let [lock_op] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
this.os_unfair_lock_trylock(lock_op, dest)?;
}
"os_unfair_lock_unlock" => {
let [lock_op] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
this.os_unfair_lock_unlock(lock_op)?;
}
"os_unfair_lock_assert_owner" => {
let [lock_op] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
this.os_unfair_lock_assert_owner(lock_op)?;
}
"os_unfair_lock_assert_not_owner" => {
let [lock_op] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
this.os_unfair_lock_assert_not_owner(lock_op)?;
}

23 changes: 12 additions & 11 deletions src/tools/miri/src/shims/unix/solarish/foreign_items.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rustc_abi::ExternAbi;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use crate::shims::unix::foreign_items::EvalContextExt as _;
use crate::shims::unix::*;
@@ -14,7 +15,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -23,7 +24,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Threading
"pthread_setname_np" => {
let [thread, name] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
// THREAD_NAME_MAX allows a thread name of 31+1 length
// https://github.com/illumos/illumos-gate/blob/7671517e13b8123748eda4ef1ee165c6d9dba7fe/usr/src/uts/common/sys/thread.h#L613
let max_len = 32;
@@ -42,7 +43,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
}
"pthread_getname_np" => {
let [thread, name, len] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
// See https://illumos.org/man/3C/pthread_getname_np for the error codes.
let res = match this.pthread_getname_np(
this.read_scalar(thread)?,
@@ -60,33 +61,33 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// File related shims
"stat" | "stat64" => {
let [path, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.macos_fbsd_solaris_stat(path, buf)?;
this.write_scalar(result, dest)?;
}
"lstat" | "lstat64" => {
let [path, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.macos_fbsd_solaris_lstat(path, buf)?;
this.write_scalar(result, dest)?;
}
"fstat" | "fstat64" => {
let [fd, buf] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.macos_fbsd_solaris_fstat(fd, buf)?;
this.write_scalar(result, dest)?;
}

// Miscellaneous
"___errno" => {
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
let errno_place = this.last_error_place()?;
this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
}

"stack_getbounds" => {
let [stack] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let stack = this.deref_pointer_as(stack, this.libc_ty_layout("stack_t"))?;

this.write_int_fields_named(
@@ -105,7 +106,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

"pset_info" => {
let [pset, tpe, cpus, list] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
// We do not need to handle the current process cpu mask, available_parallelism
// implementation pass null anyway. We only care for the number of
// cpus.
@@ -135,7 +136,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {

"__sysconf_xpg7" => {
let [val] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.sysconf(val)?;
this.write_scalar(result, dest)?;
}
9 changes: 5 additions & 4 deletions src/tools/miri/src/shims/wasi/foreign_items.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rustc_abi::ExternAbi;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use crate::shims::alloc::EvalContextExt as _;
use crate::*;
@@ -13,7 +14,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_foreign_item_inner(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -22,13 +23,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Allocation
"posix_memalign" => {
let [memptr, align, size] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let result = this.posix_memalign(memptr, align, size)?;
this.write_scalar(result, dest)?;
}
"aligned_alloc" => {
let [align, size] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let res = this.aligned_alloc(align, size)?;
this.write_pointer(res, dest)?;
}
125 changes: 66 additions & 59 deletions src/tools/miri/src/shims/windows/foreign_items.rs

Large diffs are not rendered by default.

18 changes: 7 additions & 11 deletions src/tools/miri/src/shims/x86/aesni.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use rustc_abi::ExternAbi;
use rustc_middle::ty::Ty;
use rustc_middle::ty::layout::LayoutOf as _;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use crate::*;

@@ -10,7 +10,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_x86_aesni_intrinsic(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -27,8 +27,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdec_si128
"aesdec" | "aesdec.256" | "aesdec.512" => {
let [state, key] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;

this.check_shim(abi, Conv::C, link_name, args)?;
aes_round(this, state, key, dest, |state, key| {
let key = aes::Block::from(key.to_le_bytes());
let mut state = aes::Block::from(state.to_le_bytes());
@@ -45,7 +44,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdeclast_si128
"aesdeclast" | "aesdeclast.256" | "aesdeclast.512" => {
let [state, key] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

aes_round(this, state, key, dest, |state, key| {
let mut state = aes::Block::from(state.to_le_bytes());
@@ -70,8 +69,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenc_si128
"aesenc" | "aesenc.256" | "aesenc.512" => {
let [state, key] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;

this.check_shim(abi, Conv::C, link_name, args)?;
aes_round(this, state, key, dest, |state, key| {
let key = aes::Block::from(key.to_le_bytes());
let mut state = aes::Block::from(state.to_le_bytes());
@@ -88,8 +86,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenclast_si128
"aesenclast" | "aesenclast.256" | "aesenclast.512" => {
let [state, key] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;

this.check_shim(abi, Conv::C, link_name, args)?;
aes_round(this, state, key, dest, |state, key| {
let mut state = aes::Block::from(state.to_le_bytes());
// `aes::hazmat::cipher_round` does the following operations:
@@ -109,8 +106,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Used to implement the _mm_aesimc_si128 function.
// Performs the AES InvMixColumns operation on `op`
"aesimc" => {
let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;

let [op] = this.check_shim(abi, Conv::C, link_name, args)?;
// Transmute to `u128`
let op = op.transmute(this.machine.layouts.u128, this)?;
let dest = dest.transmute(this.machine.layouts.u128, this)?;
42 changes: 21 additions & 21 deletions src/tools/miri/src/shims/x86/avx.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use rustc_abi::ExternAbi;
use rustc_apfloat::ieee::{Double, Single};
use rustc_middle::mir;
use rustc_middle::ty::Ty;
use rustc_middle::ty::layout::LayoutOf as _;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use super::{
FloatBinOp, FloatUnaryOp, bin_op_simd_float_all, conditional_dot_product, convert_float_to_int,
@@ -17,7 +17,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_x86_avx_intrinsic(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -34,7 +34,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// semantics.
"min.ps.256" | "max.ps.256" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which = match unprefixed_name {
"min.ps.256" => FloatBinOp::Min,
@@ -47,7 +47,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Used to implement _mm256_min_pd and _mm256_max_pd functions.
"min.pd.256" | "max.pd.256" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which = match unprefixed_name {
"min.pd.256" => FloatBinOp::Min,
@@ -61,22 +61,22 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Rounds the elements of `op` according to `rounding`.
"round.ps.256" => {
let [op, rounding] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

round_all::<rustc_apfloat::ieee::Single>(this, op, rounding, dest)?;
}
// Used to implement the _mm256_round_pd function.
// Rounds the elements of `op` according to `rounding`.
"round.pd.256" => {
let [op, rounding] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

round_all::<rustc_apfloat::ieee::Double>(this, op, rounding, dest)?;
}
// Used to implement _mm256_{rcp,rsqrt}_ps functions.
// Performs the operations on all components of `op`.
"rcp.ps.256" | "rsqrt.ps.256" => {
let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [op] = this.check_shim(abi, Conv::C, link_name, args)?;

let which = match unprefixed_name {
"rcp.ps.256" => FloatUnaryOp::Rcp,
@@ -89,7 +89,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Used to implement the _mm256_dp_ps function.
"dp.ps.256" => {
let [left, right, imm] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

conditional_dot_product(this, left, right, imm, dest)?;
}
@@ -98,7 +98,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// in `left` and `right`.
"hadd.ps.256" | "hadd.pd.256" | "hsub.ps.256" | "hsub.pd.256" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which = match unprefixed_name {
"hadd.ps.256" | "hadd.pd.256" => mir::BinOp::Add,
@@ -114,7 +114,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// if true.
"cmp.ps.256" => {
let [left, right, imm] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which =
FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
@@ -127,7 +127,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// if true.
"cmp.pd.256" => {
let [left, right, imm] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which =
FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
@@ -138,7 +138,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// and _mm256_cvttpd_epi32 functions.
// Converts packed f32/f64 to packed i32.
"cvt.ps2dq.256" | "cvtt.ps2dq.256" | "cvt.pd2dq.256" | "cvtt.pd2dq.256" => {
let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [op] = this.check_shim(abi, Conv::C, link_name, args)?;

let rnd = match unprefixed_name {
// "current SSE rounding mode", assume nearest
@@ -157,7 +157,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// `control` determines which element of the current `data` array is written.
"vpermilvar.ps" | "vpermilvar.ps.256" => {
let [data, control] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (data, data_len) = this.project_to_simd(data)?;
let (control, control_len) = this.project_to_simd(control)?;
@@ -191,7 +191,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// written.
"vpermilvar.pd" | "vpermilvar.pd.256" => {
let [data, control] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (data, data_len) = this.project_to_simd(data)?;
let (control, control_len) = this.project_to_simd(control)?;
@@ -224,7 +224,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// zero, according to `imm`.
"vperm2f128.ps.256" | "vperm2f128.pd.256" | "vperm2f128.si.256" => {
let [left, right, imm] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

assert_eq!(dest.layout, left.layout);
assert_eq!(dest.layout, right.layout);
@@ -268,7 +268,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// loaded.
"maskload.ps" | "maskload.pd" | "maskload.ps.256" | "maskload.pd.256" => {
let [ptr, mask] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

mask_load(this, ptr, mask, dest)?;
}
@@ -279,7 +279,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Unlike SSE2's _mm_maskmoveu_si128, these are not non-temporal stores.
"maskstore.ps" | "maskstore.pd" | "maskstore.ps.256" | "maskstore.pd.256" => {
let [ptr, mask, value] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

mask_store(this, ptr, mask, value)?;
}
@@ -290,7 +290,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// unaligned read.
"ldu.dq.256" => {
let [src_ptr] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let src_ptr = this.read_pointer(src_ptr)?;
let dest = dest.force_mplace(this)?;

@@ -303,7 +303,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// `op & mask != 0 && op & mask != mask`
"ptestz.256" | "ptestc.256" | "ptestnzc.256" => {
let [op, mask] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (all_zero, masked_set) = test_bits_masked(this, op, mask)?;
let res = match unprefixed_name {
@@ -327,7 +327,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
| "vtestnzc.pd" | "vtestz.ps.256" | "vtestc.ps.256" | "vtestnzc.ps.256"
| "vtestz.ps" | "vtestc.ps" | "vtestnzc.ps" => {
let [op, mask] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (direct, negated) = test_high_bits_masked(this, op, mask)?;
let res = match unprefixed_name {
@@ -349,7 +349,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// compiler, making these functions no-ops.

// The only thing that needs to be ensured is the correct calling convention.
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
}
_ => return interp_ok(EmulateItemResult::NotSupported),
}
44 changes: 22 additions & 22 deletions src/tools/miri/src/shims/x86/avx2.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use rustc_abi::ExternAbi;
use rustc_middle::mir;
use rustc_middle::ty::Ty;
use rustc_middle::ty::layout::LayoutOf as _;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use super::{
ShiftOp, horizontal_bin_op, int_abs, mask_load, mask_store, mpsadbw, packssdw, packsswb,
@@ -15,7 +15,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_x86_avx2_intrinsic(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -28,7 +28,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Used to implement the _mm256_abs_epi{8,16,32} functions.
// Calculates the absolute value of packed 8/16/32-bit integers.
"pabs.b" | "pabs.w" | "pabs.d" => {
let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [op] = this.check_shim(abi, Conv::C, link_name, args)?;

int_abs(this, op, dest)?;
}
@@ -37,7 +37,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// integer values in `left` and `right`.
"phadd.w" | "phadd.sw" | "phadd.d" | "phsub.w" | "phsub.sw" | "phsub.d" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (which, saturating) = match unprefixed_name {
"phadd.w" | "phadd.d" => (mir::BinOp::Add, false),
@@ -58,7 +58,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
| "gather.d.pd.256" | "gather.q.pd" | "gather.q.pd.256" | "gather.d.ps"
| "gather.d.ps.256" | "gather.q.ps" | "gather.q.ps.256" => {
let [src, slice, offsets, mask, scale] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

assert_eq!(dest.layout, src.layout);

@@ -116,7 +116,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// intermediate 32-bit integers, and pack the results in `dest`.
"pmadd.wd" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (left, left_len) = this.project_to_simd(left)?;
let (right, right_len) = this.project_to_simd(right)?;
@@ -153,7 +153,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// produces the output at index `i`.
"pmadd.ub.sw" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (left, left_len) = this.project_to_simd(left)?;
let (right, right_len) = this.project_to_simd(right)?;
@@ -188,7 +188,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// loaded.
"maskload.d" | "maskload.q" | "maskload.d.256" | "maskload.q.256" => {
let [ptr, mask] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

mask_load(this, ptr, mask, dest)?;
}
@@ -199,7 +199,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Unlike SSE2's _mm_maskmoveu_si128, these are not non-temporal stores.
"maskstore.d" | "maskstore.q" | "maskstore.d.256" | "maskstore.q.256" => {
let [ptr, mask, value] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

mask_store(this, ptr, mask, value)?;
}
@@ -211,7 +211,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_mpsadbw_epu8
"mpsadbw" => {
let [left, right, imm] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

mpsadbw(this, left, right, imm, dest)?;
}
@@ -223,7 +223,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_mulhrs_epi16
"pmul.hr.sw" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

pmulhrsw(this, left, right, dest)?;
}
@@ -232,7 +232,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// vector with signed saturation.
"packsswb" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

packsswb(this, left, right, dest)?;
}
@@ -241,7 +241,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// vector with signed saturation.
"packssdw" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

packssdw(this, left, right, dest)?;
}
@@ -250,7 +250,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// unsigned integer vector with saturation.
"packuswb" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

packuswb(this, left, right, dest)?;
}
@@ -259,7 +259,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// the result to a 16-bit unsigned integer vector with saturation.
"packusdw" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

packusdw(this, left, right, dest)?;
}
@@ -269,7 +269,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// as indices.
"permd" | "permps" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (left, left_len) = this.project_to_simd(left)?;
let (right, right_len) = this.project_to_simd(right)?;
@@ -290,7 +290,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Shuffles 128-bit blocks of `a` and `b` using `imm` as pattern.
"vperm2i128" => {
let [left, right, imm] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

assert_eq!(left.layout.size.bits(), 256);
assert_eq!(right.layout.size.bits(), 256);
@@ -328,7 +328,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_sad_epu8
"psad.bw" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (left, left_len) = this.project_to_simd(left)?;
let (right, right_len) = this.project_to_simd(right)?;
@@ -361,7 +361,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Each 128-bit block is shuffled independently.
"pshuf.b" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (left, left_len) = this.project_to_simd(left)?;
let (right, right_len) = this.project_to_simd(right)?;
@@ -393,7 +393,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Basically, we multiply `left` with `right.signum()`.
"psign.b" | "psign.w" | "psign.d" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

psign(this, left, right, dest)?;
}
@@ -408,7 +408,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"psll.w" | "psrl.w" | "psra.w" | "psll.d" | "psrl.d" | "psra.d" | "psll.q"
| "psrl.q" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which = match unprefixed_name {
"psll.w" | "psll.d" | "psll.q" => ShiftOp::Left,
@@ -424,7 +424,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"psllv.d" | "psllv.d.256" | "psllv.q" | "psllv.q.256" | "psrlv.d" | "psrlv.d.256"
| "psrlv.q" | "psrlv.q.256" | "psrav.d" | "psrav.d.256" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which = match unprefixed_name {
"psllv.d" | "psllv.d.256" | "psllv.q" | "psllv.q.256" => ShiftOp::Left,
7 changes: 4 additions & 3 deletions src/tools/miri/src/shims/x86/bmi.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rustc_abi::ExternAbi;
use rustc_span::Symbol;
use rustc_middle::ty::Ty;
use rustc_target::callconv::{Conv, FnAbi};

use crate::*;

@@ -8,7 +9,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_x86_bmi_intrinsic(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -34,7 +35,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
}

let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let left = this.read_scalar(left)?;
let right = this.read_scalar(right)?;

12 changes: 6 additions & 6 deletions src/tools/miri/src/shims/x86/gfni.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rustc_abi::ExternAbi;
use rustc_span::Symbol;
use rustc_middle::ty::Ty;
use rustc_target::callconv::{Conv, FnAbi};

use crate::*;

@@ -8,7 +9,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_x86_gfni_intrinsic(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -30,15 +31,15 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8affine_
"vgf2p8affineqb.128" | "vgf2p8affineqb.256" | "vgf2p8affineqb.512" => {
let [left, right, imm8] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
affine_transform(this, left, right, imm8, dest, /* inverse */ false)?;
}
// Used to implement the `_mm{, 256, 512}_gf2p8affineinv_epi64_epi8` functions.
// See `affine_transform` for details.
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8affineinv
"vgf2p8affineinvqb.128" | "vgf2p8affineinvqb.256" | "vgf2p8affineinvqb.512" => {
let [left, right, imm8] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
affine_transform(this, left, right, imm8, dest, /* inverse */ true)?;
}
// Used to implement the `_mm{, 256, 512}_gf2p8mul_epi8` functions.
@@ -48,8 +49,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8mul
"vgf2p8mulb.128" | "vgf2p8mulb.256" | "vgf2p8mulb.512" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;

this.check_shim(abi, Conv::C, link_name, args)?;
let (left, left_len) = this.project_to_simd(left)?;
let (right, right_len) = this.project_to_simd(right)?;
let (dest, dest_len) = this.project_to_simd(dest)?;
15 changes: 7 additions & 8 deletions src/tools/miri/src/shims/x86/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use rustc_abi::{ExternAbi, Size};
use rustc_abi::Size;
use rustc_apfloat::Float;
use rustc_apfloat::ieee::Single;
use rustc_middle::ty::Ty;
use rustc_middle::ty::layout::LayoutOf as _;
use rustc_middle::{mir, ty};
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use self::helpers::bool_to_simd_element;
use crate::*;
@@ -27,7 +28,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_x86_intrinsic(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -45,8 +46,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
return interp_ok(EmulateItemResult::NotSupported);
}

let [cb_in, a, b] = this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?;

let [cb_in, a, b] = this.check_shim(abi, Conv::C, link_name, args)?;
let op = if unprefixed_name.starts_with("add") {
mir::BinOp::AddWithOverflow
} else {
@@ -68,9 +68,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
if is_u64 && this.tcx.sess.target.arch != "x86_64" {
return interp_ok(EmulateItemResult::NotSupported);
}

let [c_in, a, b, out] =
this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let out = this.deref_pointer_as(
out,
if is_u64 { this.machine.layouts.u64 } else { this.machine.layouts.u32 },
@@ -87,7 +86,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// the instruction behaves like a no-op, so it is always safe to call the
// intrinsic.
"sse2.pause" => {
let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
// Only exhibit the spin-loop hint behavior when SSE2 is enabled.
if this.tcx.sess.unstable_target_features.contains(&Symbol::intern("sse2")) {
this.yield_active_thread();
@@ -107,7 +106,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
}

let [left, right, imm] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

pclmulqdq(this, left, right, imm, dest, len)?;
}
11 changes: 6 additions & 5 deletions src/tools/miri/src/shims/x86/sha.rs
Original file line number Diff line number Diff line change
@@ -4,8 +4,9 @@
//!
//! [RustCrypto's sha256 module]: https://github.com/RustCrypto/hashes/blob/6be8466247e936c415d8aafb848697f39894a386/sha2/src/sha256/soft.rs
use rustc_abi::ExternAbi;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use crate::*;

@@ -14,7 +15,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_x86_sha_intrinsic(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -52,7 +53,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Used to implement the _mm_sha256rnds2_epu32 function.
"256rnds2" => {
let [a, b, k] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (a_reg, a_len) = this.project_to_simd(a)?;
let (b_reg, b_len) = this.project_to_simd(b)?;
@@ -74,7 +75,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Used to implement the _mm_sha256msg1_epu32 function.
"256msg1" => {
let [a, b] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (a_reg, a_len) = this.project_to_simd(a)?;
let (b_reg, b_len) = this.project_to_simd(b)?;
@@ -93,7 +94,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Used to implement the _mm_sha256msg2_epu32 function.
"256msg2" => {
let [a, b] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (a_reg, a_len) = this.project_to_simd(a)?;
let (b_reg, b_len) = this.project_to_simd(b)?;
23 changes: 12 additions & 11 deletions src/tools/miri/src/shims/x86/sse.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rustc_abi::ExternAbi;
use rustc_apfloat::ieee::Single;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use super::{
FloatBinOp, FloatUnaryOp, bin_op_simd_float_all, bin_op_simd_float_first, unary_op_ps,
@@ -13,7 +14,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_x86_sse_intrinsic(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -33,7 +34,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// `right` and copies the remaining components from `left`.
"min.ss" | "max.ss" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which = match unprefixed_name {
"min.ss" => FloatBinOp::Min,
@@ -50,7 +51,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// semantics.
"min.ps" | "max.ps" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which = match unprefixed_name {
"min.ps" => FloatBinOp::Min,
@@ -64,7 +65,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Performs the operations on the first component of `op` and
// copies the remaining components from `op`.
"rcp.ss" | "rsqrt.ss" => {
let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [op] = this.check_shim(abi, Conv::C, link_name, args)?;

let which = match unprefixed_name {
"rcp.ss" => FloatUnaryOp::Rcp,
@@ -77,7 +78,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Used to implement _mm_{sqrt,rcp,rsqrt}_ps functions.
// Performs the operations on all components of `op`.
"rcp.ps" | "rsqrt.ps" => {
let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [op] = this.check_shim(abi, Conv::C, link_name, args)?;

let which = match unprefixed_name {
"rcp.ps" => FloatUnaryOp::Rcp,
@@ -97,7 +98,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// with hard-coded operations.
"cmp.ss" => {
let [left, right, imm] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which =
FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
@@ -114,7 +115,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// with hard-coded operations.
"cmp.ps" => {
let [left, right, imm] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which =
FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
@@ -128,7 +129,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
| "ucomieq.ss" | "ucomilt.ss" | "ucomile.ss" | "ucomigt.ss" | "ucomige.ss"
| "ucomineq.ss" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (left, left_len) = this.project_to_simd(left)?;
let (right, right_len) = this.project_to_simd(right)?;
@@ -156,7 +157,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// _mm_cvtss_si64 and _mm_cvttss_si64 functions.
// Converts the first component of `op` from f32 to i32/i64.
"cvtss2si" | "cvttss2si" | "cvtss2si64" | "cvttss2si64" => {
let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [op] = this.check_shim(abi, Conv::C, link_name, args)?;
let (op, _) = this.project_to_simd(op)?;

let op = this.read_immediate(&this.project_index(&op, 0)?)?;
@@ -185,7 +186,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.felixcloutier.com/x86/cvtsi2ss
"cvtsi2ss" | "cvtsi642ss" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (left, left_len) = this.project_to_simd(left)?;
let (dest, dest_len) = this.project_to_simd(dest)?;
33 changes: 17 additions & 16 deletions src/tools/miri/src/shims/x86/sse2.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rustc_abi::ExternAbi;
use rustc_apfloat::ieee::Double;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use super::{
FloatBinOp, ShiftOp, bin_op_simd_float_all, bin_op_simd_float_first, convert_float_to_int,
@@ -13,7 +14,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_x86_sse2_intrinsic(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -40,7 +41,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// intermediate 32-bit integers, and pack the results in `dest`.
"pmadd.wd" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (left, left_len) = this.project_to_simd(left)?;
let (right, right_len) = this.project_to_simd(right)?;
@@ -79,7 +80,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sad_epu8
"psad.bw" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (left, left_len) = this.project_to_simd(left)?;
let (right, right_len) = this.project_to_simd(right)?;
@@ -118,7 +119,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"psll.w" | "psrl.w" | "psra.w" | "psll.d" | "psrl.d" | "psra.d" | "psll.q"
| "psrl.q" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which = match unprefixed_name {
"psll.w" | "psll.d" | "psll.q" => ShiftOp::Left,
@@ -133,7 +134,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// and _mm_cvttpd_epi32 functions.
// Converts packed f32/f64 to packed i32.
"cvtps2dq" | "cvttps2dq" | "cvtpd2dq" | "cvttpd2dq" => {
let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [op] = this.check_shim(abi, Conv::C, link_name, args)?;

let (op_len, _) = op.layout.ty.simd_size_and_type(*this.tcx);
let (dest_len, _) = dest.layout.ty.simd_size_and_type(*this.tcx);
@@ -171,7 +172,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// vector with signed saturation.
"packsswb.128" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

packsswb(this, left, right, dest)?;
}
@@ -180,7 +181,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// unsigned integer vector with saturation.
"packuswb.128" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

packuswb(this, left, right, dest)?;
}
@@ -189,7 +190,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// vector with signed saturation.
"packssdw.128" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

packssdw(this, left, right, dest)?;
}
@@ -200,7 +201,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// semantics.
"min.sd" | "max.sd" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which = match unprefixed_name {
"min.sd" => FloatBinOp::Min,
@@ -217,7 +218,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// semantics.
"min.pd" | "max.pd" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which = match unprefixed_name {
"min.pd" => FloatBinOp::Min,
@@ -237,7 +238,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// with hard-coded operations.
"cmp.sd" => {
let [left, right, imm] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which =
FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
@@ -254,7 +255,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// with hard-coded operations.
"cmp.pd" => {
let [left, right, imm] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which =
FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
@@ -268,7 +269,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
| "ucomieq.sd" | "ucomilt.sd" | "ucomile.sd" | "ucomigt.sd" | "ucomige.sd"
| "ucomineq.sd" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (left, left_len) = this.project_to_simd(left)?;
let (right, right_len) = this.project_to_simd(right)?;
@@ -296,7 +297,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// _mm_cvtsd_si64 and _mm_cvttsd_si64 functions.
// Converts the first component of `op` from f64 to i32/i64.
"cvtsd2si" | "cvttsd2si" | "cvtsd2si64" | "cvttsd2si64" => {
let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [op] = this.check_shim(abi, Conv::C, link_name, args)?;
let (op, _) = this.project_to_simd(op)?;

let op = this.read_immediate(&this.project_index(&op, 0)?)?;
@@ -323,7 +324,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// the remaining elements from `left`
"cvtsd2ss" | "cvtss2sd" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (left, left_len) = this.project_to_simd(left)?;
let (right, _) = this.project_to_simd(right)?;
9 changes: 5 additions & 4 deletions src/tools/miri/src/shims/x86/sse3.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rustc_abi::ExternAbi;
use rustc_middle::mir;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use super::horizontal_bin_op;
use crate::*;
@@ -10,7 +11,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_x86_sse3_intrinsic(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -25,7 +26,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// in `left` and `right`.
"hadd.ps" | "hadd.pd" | "hsub.ps" | "hsub.pd" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let which = match unprefixed_name {
"hadd.ps" | "hadd.pd" => mir::BinOp::Add,
@@ -42,7 +43,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// unaligned read.
"ldu.dq" => {
let [src_ptr] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let src_ptr = this.read_pointer(src_ptr)?;
let dest = dest.force_mplace(this)?;

25 changes: 13 additions & 12 deletions src/tools/miri/src/shims/x86/sse41.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use rustc_abi::ExternAbi;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use super::{conditional_dot_product, mpsadbw, packusdw, round_all, round_first, test_bits_masked};
use crate::*;
@@ -9,7 +10,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_x86_sse41_intrinsic(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -27,7 +28,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// `i` is zeroed.
"insertps" => {
let [left, right, imm] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (left, left_len) = this.project_to_simd(left)?;
let (right, right_len) = this.project_to_simd(right)?;
@@ -63,7 +64,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// the result to a 16-bit unsigned integer vector with saturation.
"packusdw" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

packusdw(this, left, right, dest)?;
}
@@ -74,7 +75,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// 4 bits of `imm`.
"dpps" | "dppd" => {
let [left, right, imm] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

conditional_dot_product(this, left, right, imm, dest)?;
}
@@ -83,15 +84,15 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// and copies the remaining elements from `left`.
"round.ss" => {
let [left, right, rounding] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

round_first::<rustc_apfloat::ieee::Single>(this, left, right, rounding, dest)?;
}
// Used to implement the _mm_floor_ps, _mm_ceil_ps and _mm_round_ps
// functions. Rounds the elements of `op` according to `rounding`.
"round.ps" => {
let [op, rounding] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

round_all::<rustc_apfloat::ieee::Single>(this, op, rounding, dest)?;
}
@@ -100,23 +101,23 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// and copies the remaining elements from `left`.
"round.sd" => {
let [left, right, rounding] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

round_first::<rustc_apfloat::ieee::Double>(this, left, right, rounding, dest)?;
}
// Used to implement the _mm_floor_pd, _mm_ceil_pd and _mm_round_pd
// functions. Rounds the elements of `op` according to `rounding`.
"round.pd" => {
let [op, rounding] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

round_all::<rustc_apfloat::ieee::Double>(this, op, rounding, dest)?;
}
// Used to implement the _mm_minpos_epu16 function.
// Find the minimum unsinged 16-bit integer in `op` and
// returns its value and position.
"phminposuw" => {
let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [op] = this.check_shim(abi, Conv::C, link_name, args)?;

let (op, op_len) = this.project_to_simd(op)?;
let (dest, dest_len) = this.project_to_simd(dest)?;
@@ -151,7 +152,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mpsadbw_epu8
"mpsadbw" => {
let [left, right, imm] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

mpsadbw(this, left, right, imm, dest)?;
}
@@ -161,7 +162,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// `(op & mask) != 0 && (op & mask) != mask`
"ptestz" | "ptestc" | "ptestnzc" => {
let [op, mask] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (all_zero, masked_set) = test_bits_masked(this, op, mask)?;
let res = match unprefixed_name {
17 changes: 9 additions & 8 deletions src/tools/miri/src/shims/x86/sse42.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use rustc_abi::{ExternAbi, Size};
use rustc_abi::Size;
use rustc_middle::mir;
use rustc_middle::ty::Ty;
use rustc_middle::ty::layout::LayoutOf as _;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use crate::*;

@@ -200,7 +201,7 @@ fn deconstruct_args<'tcx>(
unprefixed_name: &str,
ecx: &mut MiriInterpCx<'tcx>,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
) -> InterpResult<'tcx, (OpTy<'tcx>, OpTy<'tcx>, Option<(u64, u64)>, u8)> {
let array_layout_fn = |ecx: &mut MiriInterpCx<'tcx>, imm: u8| {
@@ -223,7 +224,7 @@ fn deconstruct_args<'tcx>(

if is_explicit {
let [str1, len1, str2, len2, imm] =
ecx.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
ecx.check_shim(abi, Conv::C, link_name, args)?;
let imm = ecx.read_scalar(imm)?.to_u8()?;

let default_len = default_len::<u32>(imm);
@@ -237,7 +238,7 @@ fn deconstruct_args<'tcx>(
interp_ok((str1, str2, Some((len1, len2)), imm))
} else {
let [str1, str2, imm] =
ecx.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
ecx.check_shim(abi, Conv::C, link_name, args)?;
let imm = ecx.read_scalar(imm)?.to_u8()?;

let array_layout = array_layout_fn(ecx, imm)?;
@@ -279,7 +280,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_x86_sse42_intrinsic(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -388,7 +389,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=924,925
"pcmpistriz128" | "pcmpistris128" => {
let [str1, str2, imm] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let imm = this.read_scalar(imm)?.to_u8()?;

let str = if unprefixed_name == "pcmpistris128" { str1 } else { str2 };
@@ -409,7 +410,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=1046,1047
"pcmpestriz128" | "pcmpestris128" => {
let [_, len1, _, len2, imm] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let len = if unprefixed_name == "pcmpestris128" { len1 } else { len2 };
let len = this.read_scalar(len)?.to_i32()?;
let imm = this.read_scalar(imm)?.to_u8()?;
@@ -437,7 +438,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
}

let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;
let left = this.read_scalar(left)?;
let right = this.read_scalar(right)?;

17 changes: 9 additions & 8 deletions src/tools/miri/src/shims/x86/ssse3.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use rustc_abi::ExternAbi;
use rustc_middle::mir;
use rustc_middle::ty::Ty;
use rustc_span::Symbol;
use rustc_target::callconv::{Conv, FnAbi};

use super::{horizontal_bin_op, int_abs, pmulhrsw, psign};
use crate::*;
@@ -10,7 +11,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
fn emulate_x86_ssse3_intrinsic(
&mut self,
link_name: Symbol,
abi: ExternAbi,
abi: &FnAbi<'tcx, Ty<'tcx>>,
args: &[OpTy<'tcx>],
dest: &MPlaceTy<'tcx>,
) -> InterpResult<'tcx, EmulateItemResult> {
@@ -23,7 +24,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Used to implement the _mm_abs_epi{8,16,32} functions.
// Calculates the absolute value of packed 8/16/32-bit integers.
"pabs.b.128" | "pabs.w.128" | "pabs.d.128" => {
let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
let [op] = this.check_shim(abi, Conv::C, link_name, args)?;

int_abs(this, op, dest)?;
}
@@ -32,7 +33,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shuffle_epi8
"pshuf.b.128" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (left, left_len) = this.project_to_simd(left)?;
let (right, right_len) = this.project_to_simd(right)?;
@@ -62,7 +63,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
"phadd.w.128" | "phadd.sw.128" | "phadd.d.128" | "phsub.w.128" | "phsub.sw.128"
| "phsub.d.128" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (which, saturating) = match unprefixed_name {
"phadd.w.128" | "phadd.d.128" => (mir::BinOp::Add, false),
@@ -82,7 +83,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_maddubs_epi16
"pmadd.ub.sw.128" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

let (left, left_len) = this.project_to_simd(left)?;
let (right, right_len) = this.project_to_simd(right)?;
@@ -118,7 +119,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mulhrs_epi16
"pmul.hr.sw.128" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

pmulhrsw(this, left, right, dest)?;
}
@@ -129,7 +130,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
// Basically, we multiply `left` with `right.signum()`.
"psign.b.128" | "psign.w.128" | "psign.d.128" => {
let [left, right] =
this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
this.check_shim(abi, Conv::C, link_name, args)?;

psign(this, left, right, dest)?;
}