miri: sed to CanonAbi
This commit is contained in:
parent
87fa1ea9d2
commit
9d42e35e8d
27 changed files with 354 additions and 327 deletions
|
|
@ -3,7 +3,7 @@ use std::time::Duration;
|
|||
use std::{cmp, iter};
|
||||
|
||||
use rand::RngCore;
|
||||
use rustc_abi::{Align, ExternAbi, FieldIdx, FieldsShape, Size, Variants};
|
||||
use rustc_abi::{Align, CanonAbi, ExternAbi, FieldIdx, FieldsShape, Size, Variants};
|
||||
use rustc_apfloat::Float;
|
||||
use rustc_apfloat::ieee::{Double, Half, Quad, Single};
|
||||
use rustc_hir::Safety;
|
||||
|
|
@ -18,7 +18,7 @@ use rustc_middle::ty::{self, Binder, FloatTy, FnSig, IntTy, Ty, TyCtxt, UintTy};
|
|||
use rustc_session::config::CrateType;
|
||||
use rustc_span::{Span, Symbol};
|
||||
use rustc_symbol_mangling::mangle_internal_symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use crate::*;
|
||||
|
||||
|
|
@ -936,11 +936,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
fn check_callconv<'a>(
|
||||
&self,
|
||||
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
|
||||
exp_abi: Conv,
|
||||
exp_abi: CanonAbi,
|
||||
) -> InterpResult<'a, ()> {
|
||||
if fn_abi.conv != exp_abi {
|
||||
throw_ub_format!(
|
||||
"calling a function with calling convention {exp_abi} using caller calling convention {}",
|
||||
r#"calling a function with calling convention "{exp_abi}" using caller calling convention "{}""#,
|
||||
fn_abi.conv
|
||||
);
|
||||
}
|
||||
|
|
@ -973,7 +973,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
fn check_abi_and_shim_symbol_clash(
|
||||
&mut self,
|
||||
abi: &FnAbi<'tcx, Ty<'tcx>>,
|
||||
exp_abi: Conv,
|
||||
exp_abi: CanonAbi,
|
||||
link_name: Symbol,
|
||||
) -> InterpResult<'tcx, ()> {
|
||||
self.check_callconv(abi, exp_abi)?;
|
||||
|
|
@ -998,7 +998,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
fn check_shim<'a, const N: usize>(
|
||||
&mut self,
|
||||
abi: &FnAbi<'tcx, Ty<'tcx>>,
|
||||
exp_abi: Conv,
|
||||
exp_abi: CanonAbi,
|
||||
link_name: Symbol,
|
||||
args: &'a [OpTy<'tcx>],
|
||||
) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]> {
|
||||
|
|
@ -1098,7 +1098,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
fn check_shim_variadic<'a, const N: usize>(
|
||||
&mut self,
|
||||
abi: &FnAbi<'tcx, Ty<'tcx>>,
|
||||
exp_abi: Conv,
|
||||
exp_abi: CanonAbi,
|
||||
link_name: Symbol,
|
||||
args: &'a [OpTy<'tcx>],
|
||||
) -> InterpResult<'tcx, (&'a [OpTy<'tcx>; N], &'a [OpTy<'tcx>])>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
use rustc_middle::mir::BinOp;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use crate::*;
|
||||
|
||||
|
|
@ -19,7 +20,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
let unprefixed_name = link_name.as_str().strip_prefix("llvm.aarch64.").unwrap();
|
||||
match unprefixed_name {
|
||||
"isb" => {
|
||||
let [arg] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [arg] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let arg = this.read_scalar(arg)?.to_i32()?;
|
||||
match arg {
|
||||
// SY ("full system scope")
|
||||
|
|
@ -37,7 +38,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// `left` input, the second half of the output from the `right` input.
|
||||
// https://developer.arm.com/architectures/instruction-sets/intrinsics/vpmaxq_u8
|
||||
"neon.umaxp.v16i8" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (right, right_len) = this.project_to_simd(right)?;
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
use rustc_abi::Size;
|
||||
use rustc_abi::{CanonAbi, 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 rustc_target::callconv::FnAbi;
|
||||
|
||||
use crate::*;
|
||||
|
||||
|
|
@ -16,7 +16,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let [flags] = this.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
let [flags] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
|
||||
let flags = this.read_scalar(flags)?.to_u64()?;
|
||||
if flags != 0 {
|
||||
|
|
@ -38,7 +38,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
let ptr_ty = this.machine.layouts.mut_raw_ptr.ty;
|
||||
let ptr_layout = this.layout_of(ptr_ty)?;
|
||||
|
||||
let [flags, buf] = this.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
let [flags, buf] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
|
||||
let flags = this.read_scalar(flags)?.to_u64()?;
|
||||
let buf_place = this.deref_pointer_as(buf, ptr_layout)?;
|
||||
|
|
@ -118,7 +118,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let this = self.eval_context_mut();
|
||||
let [ptr, flags] = this.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
let [ptr, flags] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
|
||||
let flags = this.read_scalar(flags)?.to_u64()?;
|
||||
|
||||
|
|
@ -190,7 +190,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
let this = self.eval_context_mut();
|
||||
|
||||
let [ptr, flags, name_ptr, filename_ptr] =
|
||||
this.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
|
||||
let flags = this.read_scalar(flags)?.to_u64()?;
|
||||
if flags != 0 {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::collections::hash_map::Entry;
|
|||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
use rustc_abi::{Align, AlignFromBytesError, Size};
|
||||
use rustc_abi::{Align, AlignFromBytesError, CanonAbi, Size};
|
||||
use rustc_apfloat::Float;
|
||||
use rustc_ast::expand::allocator::alloc_error_handler_name;
|
||||
use rustc_hir::def::DefKind;
|
||||
|
|
@ -12,7 +12,7 @@ use rustc_middle::mir::interpret::AllocInit;
|
|||
use rustc_middle::ty::{Instance, Ty};
|
||||
use rustc_middle::{mir, ty};
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use self::helpers::{ToHost, ToSoft};
|
||||
use super::alloc::EvalContextExt as _;
|
||||
|
|
@ -247,7 +247,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// When adding a new shim, you should follow the following pattern:
|
||||
// ```
|
||||
// "shim_name" => {
|
||||
// let [arg1, arg2, arg3] = this.check_shim(abi, Conv::::C , link_name, args)?;
|
||||
// let [arg1, arg2, arg3] = this.check_shim(abi, CanonAbi::C , link_name, args)?;
|
||||
// let result = this.shim_name(arg1, arg2, arg3)?;
|
||||
// this.write_scalar(result, dest)?;
|
||||
// }
|
||||
|
|
@ -285,16 +285,16 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
match link_name.as_str() {
|
||||
// Miri-specific extern functions
|
||||
"miri_start_unwind" => {
|
||||
let [payload] = this.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
let [payload] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
this.handle_miri_start_unwind(payload)?;
|
||||
return interp_ok(EmulateItemResult::NeedsUnwind);
|
||||
}
|
||||
"miri_run_provenance_gc" => {
|
||||
let [] = this.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
this.run_provenance_gc();
|
||||
}
|
||||
"miri_get_alloc_id" => {
|
||||
let [ptr] = this.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
let [ptr] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr, 0).map_err_kind(|_e| {
|
||||
err_machine_stop!(TerminationInfo::Abort(format!(
|
||||
|
|
@ -304,7 +304,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_scalar(Scalar::from_u64(alloc_id.0.get()), dest)?;
|
||||
}
|
||||
"miri_print_borrow_state" => {
|
||||
let [id, show_unnamed] = this.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
let [id, show_unnamed] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
let id = this.read_scalar(id)?.to_u64()?;
|
||||
let show_unnamed = this.read_scalar(show_unnamed)?.to_bool()?;
|
||||
if let Some(id) = std::num::NonZero::new(id).map(AllocId)
|
||||
|
|
@ -318,7 +318,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
"miri_pointer_name" => {
|
||||
// This associates a name to a tag. Very useful for debugging, and also makes
|
||||
// tests more strict.
|
||||
let [ptr, nth_parent, name] = this.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
let [ptr, nth_parent, name] =
|
||||
this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let nth_parent = this.read_scalar(nth_parent)?.to_u8()?;
|
||||
let name = this.read_immediate(name)?;
|
||||
|
|
@ -331,7 +332,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.give_pointer_debug_name(ptr, nth_parent, &name)?;
|
||||
}
|
||||
"miri_static_root" => {
|
||||
let [ptr] = this.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
let [ptr] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let (alloc_id, offset, _) = this.ptr_get_alloc_id(ptr, 0)?;
|
||||
if offset != Size::ZERO {
|
||||
|
|
@ -342,7 +343,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.machine.static_roots.push(alloc_id);
|
||||
}
|
||||
"miri_host_to_target_path" => {
|
||||
let [ptr, out, out_size] = this.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
let [ptr, out, out_size] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let out = this.read_pointer(out)?;
|
||||
let out_size = this.read_scalar(out_size)?.to_target_usize(this)?;
|
||||
|
|
@ -378,7 +379,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Writes some bytes to the interpreter's stdout/stderr. See the
|
||||
// README for details.
|
||||
"miri_write_to_stdout" | "miri_write_to_stderr" => {
|
||||
let [msg] = this.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
let [msg] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
let msg = this.read_immediate(msg)?;
|
||||
let msg = this.read_byte_slice(&msg)?;
|
||||
// Note: we're ignoring errors writing to host stdout/stderr.
|
||||
|
|
@ -392,7 +393,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
"miri_promise_symbolic_alignment" => {
|
||||
use rustc_abi::AlignFromBytesError;
|
||||
|
||||
let [ptr, align] = this.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
let [ptr, align] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let align = this.read_target_usize(align)?;
|
||||
if !align.is_power_of_two() {
|
||||
|
|
@ -433,12 +434,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
// Aborting the process.
|
||||
"exit" => {
|
||||
let [code] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [code] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let code = this.read_scalar(code)?.to_i32()?;
|
||||
throw_machine_stop!(TerminationInfo::Exit { code, leak_check: false });
|
||||
}
|
||||
"abort" => {
|
||||
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
throw_machine_stop!(TerminationInfo::Abort(
|
||||
"the program aborted execution".to_owned()
|
||||
))
|
||||
|
|
@ -446,7 +447,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
// Standard C allocation
|
||||
"malloc" => {
|
||||
let [size] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [size] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let size = this.read_target_usize(size)?;
|
||||
if size <= this.max_size_of_val().bytes() {
|
||||
let res = this.malloc(size, AllocInit::Uninit)?;
|
||||
|
|
@ -460,7 +461,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
}
|
||||
"calloc" => {
|
||||
let [items, elem_size] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [items, elem_size] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let items = this.read_target_usize(items)?;
|
||||
let elem_size = this.read_target_usize(elem_size)?;
|
||||
if let Some(size) = this.compute_size_in_bytes(Size::from_bytes(elem_size), items) {
|
||||
|
|
@ -475,12 +476,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
}
|
||||
"free" => {
|
||||
let [ptr] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [ptr] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
this.free(ptr)?;
|
||||
}
|
||||
"realloc" => {
|
||||
let [old_ptr, new_size] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [old_ptr, new_size] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let old_ptr = this.read_pointer(old_ptr)?;
|
||||
let new_size = this.read_target_usize(new_size)?;
|
||||
if new_size <= this.max_size_of_val().bytes() {
|
||||
|
|
@ -500,7 +501,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
let default = |ecx: &mut MiriInterpCx<'tcx>| {
|
||||
// Only call `check_shim` when `#[global_allocator]` isn't used. When that
|
||||
// macro is used, we act like no shim exists, so that the exported function can run.
|
||||
let [size, align] = ecx.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
let [size, align] = ecx.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
let size = ecx.read_target_usize(size)?;
|
||||
let align = ecx.read_target_usize(align)?;
|
||||
|
||||
|
|
@ -533,7 +534,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
return this.emulate_allocator(|this| {
|
||||
// See the comment for `__rust_alloc` why `check_shim` is only called in the
|
||||
// default case.
|
||||
let [size, align] = this.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
let [size, align] = this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
let size = this.read_target_usize(size)?;
|
||||
let align = this.read_target_usize(align)?;
|
||||
|
||||
|
|
@ -555,7 +556,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// See the comment for `__rust_alloc` why `check_shim` is only called in the
|
||||
// default case.
|
||||
let [ptr, old_size, align] =
|
||||
ecx.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
ecx.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
let ptr = ecx.read_pointer(ptr)?;
|
||||
let old_size = ecx.read_target_usize(old_size)?;
|
||||
let align = ecx.read_target_usize(align)?;
|
||||
|
|
@ -586,7 +587,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// See the comment for `__rust_alloc` why `check_shim` is only called in the
|
||||
// default case.
|
||||
let [ptr, old_size, align, new_size] =
|
||||
this.check_shim(abi, Conv::Rust, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::Rust, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let old_size = this.read_target_usize(old_size)?;
|
||||
let align = this.read_target_usize(align)?;
|
||||
|
|
@ -610,7 +611,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
// C memory handling functions
|
||||
"memcmp" => {
|
||||
let [left, right, n] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right, n] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let left = this.read_pointer(left)?;
|
||||
let right = this.read_pointer(right)?;
|
||||
let n = Size::from_bytes(this.read_target_usize(n)?);
|
||||
|
|
@ -634,7 +635,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_scalar(Scalar::from_i32(result), dest)?;
|
||||
}
|
||||
"memrchr" => {
|
||||
let [ptr, val, num] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [ptr, val, num] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let val = this.read_scalar(val)?.to_i32()?;
|
||||
let num = this.read_target_usize(num)?;
|
||||
|
|
@ -660,7 +661,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
}
|
||||
"memchr" => {
|
||||
let [ptr, val, num] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [ptr, val, num] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let val = this.read_scalar(val)?.to_i32()?;
|
||||
let num = this.read_target_usize(num)?;
|
||||
|
|
@ -683,7 +684,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
}
|
||||
"strlen" => {
|
||||
let [ptr] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [ptr] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
// This reads at least 1 byte, so we are already enforcing that this is a valid pointer.
|
||||
let n = this.read_c_str(ptr)?.len();
|
||||
|
|
@ -693,7 +694,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
)?;
|
||||
}
|
||||
"wcslen" => {
|
||||
let [ptr] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [ptr] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
// This reads at least 1 byte, so we are already enforcing that this is a valid pointer.
|
||||
let n = this.read_wchar_t_str(ptr)?.len();
|
||||
|
|
@ -703,7 +704,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
)?;
|
||||
}
|
||||
"memcpy" => {
|
||||
let [ptr_dest, ptr_src, n] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [ptr_dest, ptr_src, n] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let ptr_dest = this.read_pointer(ptr_dest)?;
|
||||
let ptr_src = this.read_pointer(ptr_src)?;
|
||||
let n = this.read_target_usize(n)?;
|
||||
|
|
@ -717,7 +718,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_pointer(ptr_dest, dest)?;
|
||||
}
|
||||
"strcpy" => {
|
||||
let [ptr_dest, ptr_src] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [ptr_dest, ptr_src] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let ptr_dest = this.read_pointer(ptr_dest)?;
|
||||
let ptr_src = this.read_pointer(ptr_src)?;
|
||||
|
||||
|
|
@ -748,7 +749,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
| "erff"
|
||||
| "erfcf"
|
||||
=> {
|
||||
let [f] = this.check_shim(abi, Conv::C , link_name, args)?;
|
||||
let [f] = this.check_shim(abi, CanonAbi::C , link_name, args)?;
|
||||
let f = this.read_scalar(f)?.to_f32()?;
|
||||
// Using host floats (but it's fine, these operations do not have guaranteed precision).
|
||||
let f_host = f.to_host();
|
||||
|
|
@ -786,7 +787,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
| "atan2f"
|
||||
| "fdimf"
|
||||
=> {
|
||||
let [f1, f2] = this.check_shim(abi, Conv::C , link_name, args)?;
|
||||
let [f1, f2] = this.check_shim(abi, CanonAbi::C , link_name, args)?;
|
||||
let f1 = this.read_scalar(f1)?.to_f32()?;
|
||||
let f2 = this.read_scalar(f2)?.to_f32()?;
|
||||
// underscore case for windows, here and below
|
||||
|
|
@ -825,7 +826,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
| "erf"
|
||||
| "erfc"
|
||||
=> {
|
||||
let [f] = this.check_shim(abi, Conv::C , link_name, args)?;
|
||||
let [f] = this.check_shim(abi, CanonAbi::C , link_name, args)?;
|
||||
let f = this.read_scalar(f)?.to_f64()?;
|
||||
// Using host floats (but it's fine, these operations do not have guaranteed precision).
|
||||
let f_host = f.to_host();
|
||||
|
|
@ -863,7 +864,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
| "atan2"
|
||||
| "fdim"
|
||||
=> {
|
||||
let [f1, f2] = this.check_shim(abi, Conv::C , link_name, args)?;
|
||||
let [f1, f2] = this.check_shim(abi, CanonAbi::C , link_name, args)?;
|
||||
let f1 = this.read_scalar(f1)?.to_f64()?;
|
||||
let f2 = this.read_scalar(f2)?.to_f64()?;
|
||||
// underscore case for windows, here and below
|
||||
|
|
@ -892,7 +893,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
| "ldexp"
|
||||
| "scalbn"
|
||||
=> {
|
||||
let [x, exp] = this.check_shim(abi, Conv::C , link_name, args)?;
|
||||
let [x, exp] = this.check_shim(abi, CanonAbi::C , link_name, args)?;
|
||||
// For radix-2 (binary) systems, `ldexp` and `scalbn` are the same.
|
||||
let x = this.read_scalar(x)?.to_f64()?;
|
||||
let exp = this.read_scalar(exp)?.to_i32()?;
|
||||
|
|
@ -902,7 +903,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
"lgammaf_r" => {
|
||||
let [x, signp] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [x, signp] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let x = this.read_scalar(x)?.to_f32()?;
|
||||
let signp = this.deref_pointer_as(signp, this.machine.layouts.i32)?;
|
||||
|
||||
|
|
@ -918,7 +919,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
"lgamma_r" => {
|
||||
let [x, signp] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [x, signp] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let x = this.read_scalar(x)?.to_f64()?;
|
||||
let signp = this.deref_pointer_as(signp, this.machine.layouts.i32)?;
|
||||
|
||||
|
|
@ -936,7 +937,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
// LLVM intrinsics
|
||||
"llvm.prefetch" => {
|
||||
let [p, rw, loc, ty] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [p, rw, loc, ty] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let _ = this.read_pointer(p)?;
|
||||
let rw = this.read_scalar(rw)?.to_i32()?;
|
||||
|
|
@ -963,7 +964,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Used to implement the x86 `_mm{,256,512}_popcnt_epi{8,16,32,64}` and wasm
|
||||
// `{i,u}8x16_popcnt` functions.
|
||||
name if name.starts_with("llvm.ctpop.v") => {
|
||||
let [op] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [op] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (op, op_len) = this.project_to_simd(op)?;
|
||||
let (dest, dest_len) = this.project_to_simd(dest)?;
|
||||
|
|
@ -999,7 +1000,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
// FIXME: Move this to an `arm` submodule.
|
||||
"llvm.arm.hint" if this.tcx.sess.target.arch == "arm" => {
|
||||
let [arg] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [arg] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let arg = this.read_scalar(arg)?.to_i32()?;
|
||||
// Note that different arguments might have different target feature requirements.
|
||||
match arg {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use crate::shims::unix::android::thread::prctl;
|
||||
use crate::shims::unix::linux_like::epoll::EvalContextExt as _;
|
||||
|
|
@ -25,29 +26,29 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
match link_name.as_str() {
|
||||
// epoll, eventfd
|
||||
"epoll_create1" => {
|
||||
let [flag] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [flag] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [epfd, op, fd, event] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.epoll_wait(epfd, events, maxevents, timeout, dest)?;
|
||||
}
|
||||
"eventfd" => {
|
||||
let [val, flag] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [val, flag] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.eventfd(val, flag)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
||||
// Miscellaneous
|
||||
"__errno" => {
|
||||
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let errno_place = this.last_error_place()?;
|
||||
this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use rustc_abi::Size;
|
||||
use rustc_abi::{CanonAbi, Size};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use crate::helpers::check_min_vararg_count;
|
||||
use crate::shims::unix::thread::{EvalContextExt as _, ThreadNameResult};
|
||||
|
|
@ -16,7 +16,7 @@ pub fn prctl<'tcx>(
|
|||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let ([op], varargs) = ecx.check_shim_variadic(abi, Conv::C, link_name, args)?;
|
||||
let ([op], varargs) = ecx.check_shim_variadic(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
// FIXME: Use constants once https://github.com/rust-lang/libc/pull/3941 backported to the 0.2 branch.
|
||||
let pr_set_name = 15;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
use std::ffi::OsStr;
|
||||
use std::str;
|
||||
|
||||
use rustc_abi::{ExternAbi, Size};
|
||||
use rustc_abi::{CanonAbi, ExternAbi, Size};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::layout::LayoutOf;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use self::shims::unix::android::foreign_items as android;
|
||||
use self::shims::unix::freebsd::foreign_items as freebsd;
|
||||
|
|
@ -334,7 +334,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
"fcntl" => {
|
||||
let ([fd_num, cmd], varargs) =
|
||||
this.check_shim_variadic(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim_variadic(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.fcntl(fd_num, cmd, varargs)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
|
@ -387,7 +387,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// `open` is variadic, the third argument is only present when the second argument
|
||||
// has O_CREAT (or on linux O_TMPFILE, but miri doesn't support that) set
|
||||
let ([path_raw, flag], varargs) =
|
||||
this.check_shim_variadic(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim_variadic(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.open(path_raw, flag, varargs)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
|
@ -701,20 +701,20 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
// Allocation
|
||||
"posix_memalign" => {
|
||||
let [memptr, align, size] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [memptr, align, size] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.posix_memalign(memptr, align, size)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
||||
"mmap" => {
|
||||
let [addr, length, prot, flags, fd, offset] =
|
||||
this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?;
|
||||
let ptr = this.mmap(addr, length, prot, flags, fd, offset)?;
|
||||
this.write_scalar(ptr, dest)?;
|
||||
}
|
||||
"munmap" => {
|
||||
let [addr, length] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [addr, length] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.munmap(addr, length)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
|
@ -722,7 +722,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
"reallocarray" => {
|
||||
// Currently this function does not exist on all Unixes, e.g. on macOS.
|
||||
this.check_target_os(&["linux", "freebsd", "android"], link_name)?;
|
||||
let [ptr, nmemb, size] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [ptr, nmemb, size] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let nmemb = this.read_target_usize(nmemb)?;
|
||||
let size = this.read_target_usize(size)?;
|
||||
|
|
@ -745,14 +745,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
"aligned_alloc" => {
|
||||
// This is a C11 function, we assume all Unixes have it.
|
||||
// (MSVC explicitly does not support this.)
|
||||
let [align, size] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [align, size] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let res = this.aligned_alloc(align, size)?;
|
||||
this.write_pointer(res, dest)?;
|
||||
}
|
||||
|
||||
// Dynamic symbol loading
|
||||
"dlsym" => {
|
||||
let [handle, symbol] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [handle, symbol] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.read_target_usize(handle)?;
|
||||
let symbol = this.read_pointer(symbol)?;
|
||||
let name = this.read_c_str(symbol)?;
|
||||
|
|
@ -768,7 +768,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
// Thread-local storage
|
||||
"pthread_key_create" => {
|
||||
let [key, dtor] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [key, dtor] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let key_place = this.deref_pointer_as(key, this.libc_ty_layout("pthread_key_t"))?;
|
||||
let dtor = this.read_pointer(dtor)?;
|
||||
|
||||
|
|
@ -796,21 +796,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_key_delete" => {
|
||||
let [key] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [key] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let key = this.read_scalar(key)?.to_bits(key.layout.size)?;
|
||||
this.machine.tls.delete_tls_key(key)?;
|
||||
// Return success (0)
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_getspecific" => {
|
||||
let [key] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [key] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let key = this.read_scalar(key)?.to_bits(key.layout.size)?;
|
||||
let active_thread = this.active_thread();
|
||||
let ptr = this.machine.tls.load_tls(key, active_thread, this)?;
|
||||
this.write_scalar(ptr, dest)?;
|
||||
}
|
||||
"pthread_setspecific" => {
|
||||
let [key, new_ptr] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [key, new_ptr] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let key = this.read_scalar(key)?.to_bits(key.layout.size)?;
|
||||
let active_thread = this.active_thread();
|
||||
let new_data = this.read_scalar(new_ptr)?;
|
||||
|
|
@ -822,156 +822,157 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
// Synchronization primitives
|
||||
"pthread_mutexattr_init" => {
|
||||
let [attr] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [attr] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_mutexattr_init(attr)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_mutexattr_settype" => {
|
||||
let [attr, kind] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [attr, kind] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.pthread_mutexattr_settype(attr, kind)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"pthread_mutexattr_destroy" => {
|
||||
let [attr] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [attr] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_mutexattr_destroy(attr)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_mutex_init" => {
|
||||
let [mutex, attr] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [mutex, attr] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_mutex_init(mutex, attr)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_mutex_lock" => {
|
||||
let [mutex] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [mutex] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_mutex_lock(mutex, dest)?;
|
||||
}
|
||||
"pthread_mutex_trylock" => {
|
||||
let [mutex] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [mutex] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.pthread_mutex_trylock(mutex)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"pthread_mutex_unlock" => {
|
||||
let [mutex] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [mutex] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.pthread_mutex_unlock(mutex)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"pthread_mutex_destroy" => {
|
||||
let [mutex] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [mutex] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_mutex_destroy(mutex)?;
|
||||
this.write_int(0, dest)?;
|
||||
}
|
||||
"pthread_rwlock_rdlock" => {
|
||||
let [rwlock] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [rwlock] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_rwlock_rdlock(rwlock, dest)?;
|
||||
}
|
||||
"pthread_rwlock_tryrdlock" => {
|
||||
let [rwlock] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [rwlock] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.pthread_rwlock_tryrdlock(rwlock)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"pthread_rwlock_wrlock" => {
|
||||
let [rwlock] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [rwlock] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_rwlock_wrlock(rwlock, dest)?;
|
||||
}
|
||||
"pthread_rwlock_trywrlock" => {
|
||||
let [rwlock] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [rwlock] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.pthread_rwlock_trywrlock(rwlock)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"pthread_rwlock_unlock" => {
|
||||
let [rwlock] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [rwlock] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_rwlock_unlock(rwlock)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_rwlock_destroy" => {
|
||||
let [rwlock] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [rwlock] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_rwlock_destroy(rwlock)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_condattr_init" => {
|
||||
let [attr] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [attr] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_condattr_init(attr)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_condattr_setclock" => {
|
||||
let [attr, clock_id] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [attr, clock_id] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.pthread_condattr_setclock(attr, clock_id)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"pthread_condattr_getclock" => {
|
||||
let [attr, clock_id] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [attr, clock_id] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_condattr_getclock(attr, clock_id)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_condattr_destroy" => {
|
||||
let [attr] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [attr] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_condattr_destroy(attr)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_cond_init" => {
|
||||
let [cond, attr] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [cond, attr] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_cond_init(cond, attr)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_cond_signal" => {
|
||||
let [cond] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [cond] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_cond_signal(cond)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_cond_broadcast" => {
|
||||
let [cond] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [cond] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_cond_broadcast(cond)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_cond_wait" => {
|
||||
let [cond, mutex] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [cond, mutex] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_cond_wait(cond, mutex, dest)?;
|
||||
}
|
||||
"pthread_cond_timedwait" => {
|
||||
let [cond, mutex, abstime] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [cond, mutex, abstime] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_cond_timedwait(cond, mutex, abstime, dest)?;
|
||||
}
|
||||
"pthread_cond_destroy" => {
|
||||
let [cond] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [cond] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_cond_destroy(cond)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
|
||||
// Threading
|
||||
"pthread_create" => {
|
||||
let [thread, attr, start, arg] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [thread, attr, start, arg] =
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.pthread_create(thread, attr, start, arg)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_join" => {
|
||||
let [thread, retval] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [thread, retval] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let res = this.pthread_join(thread, retval)?;
|
||||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
"pthread_detach" => {
|
||||
let [thread] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [thread] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let res = this.pthread_detach(thread)?;
|
||||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
"pthread_self" => {
|
||||
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let res = this.pthread_self()?;
|
||||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
"sched_yield" => {
|
||||
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.sched_yield()?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"nanosleep" => {
|
||||
let [req, rem] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [req, rem] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.nanosleep(req, rem)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"sched_getaffinity" => {
|
||||
// Currently this function does not exist on all Unixes, e.g. on macOS.
|
||||
this.check_target_os(&["linux", "freebsd", "android"], link_name)?;
|
||||
let [pid, cpusetsize, mask] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [pid, cpusetsize, mask] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let pid = this.read_scalar(pid)?.to_u32()?;
|
||||
let cpusetsize = this.read_target_usize(cpusetsize)?;
|
||||
let mask = this.read_pointer(mask)?;
|
||||
|
|
@ -1008,7 +1009,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
"sched_setaffinity" => {
|
||||
// Currently this function does not exist on all Unixes, e.g. on macOS.
|
||||
this.check_target_os(&["linux", "freebsd", "android"], link_name)?;
|
||||
let [pid, cpusetsize, mask] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [pid, cpusetsize, mask] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let pid = this.read_scalar(pid)?.to_u32()?;
|
||||
let cpusetsize = this.read_target_usize(cpusetsize)?;
|
||||
let mask = this.read_pointer(mask)?;
|
||||
|
|
@ -1048,12 +1049,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
// Miscellaneous
|
||||
"isatty" => {
|
||||
let [fd] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [fd] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.isatty(fd)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"pthread_atfork" => {
|
||||
let [prepare, parent, child] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [prepare, parent, child] =
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.read_pointer(prepare)?;
|
||||
this.read_pointer(parent)?;
|
||||
this.read_pointer(child)?;
|
||||
|
|
@ -1067,7 +1069,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
&["linux", "macos", "freebsd", "illumos", "solaris", "android"],
|
||||
link_name,
|
||||
)?;
|
||||
let [buf, bufsize] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [buf, bufsize] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let buf = this.read_pointer(buf)?;
|
||||
let bufsize = this.read_target_usize(bufsize)?;
|
||||
|
||||
|
|
@ -1085,7 +1087,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
|
||||
"strerror_r" => {
|
||||
let [errnum, buf, buflen] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [errnum, buf, buflen] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.strerror_r(errnum, buf, buflen)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
|
@ -1097,7 +1099,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
&["linux", "freebsd", "illumos", "solaris", "android"],
|
||||
link_name,
|
||||
)?;
|
||||
let [ptr, len, flags] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [ptr, len, flags] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let len = this.read_target_usize(len)?;
|
||||
let _flags = this.read_scalar(flags)?.to_i32()?;
|
||||
|
|
@ -1109,7 +1111,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// This function is non-standard but exists with the same signature and
|
||||
// same behavior (eg never fails) on FreeBSD and Solaris/Illumos.
|
||||
this.check_target_os(&["freebsd", "illumos", "solaris"], link_name)?;
|
||||
let [ptr, len] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [ptr, len] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let ptr = this.read_pointer(ptr)?;
|
||||
let len = this.read_target_usize(len)?;
|
||||
this.gen_random(ptr, len)?;
|
||||
|
|
@ -1133,12 +1135,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
link_name,
|
||||
)?;
|
||||
// This function looks and behaves excatly like miri_start_unwind.
|
||||
let [payload] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [payload] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.handle_miri_start_unwind(payload)?;
|
||||
return interp_ok(EmulateItemResult::NeedsUnwind);
|
||||
}
|
||||
"getuid" | "geteuid" => {
|
||||
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
// For now, just pretend we always have this fixed UID.
|
||||
this.write_int(UID, dest)?;
|
||||
}
|
||||
|
|
@ -1146,7 +1148,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Incomplete shims that we "stub out" just to get pre-main initialization code to work.
|
||||
// These shims are enabled only when the caller is in the standard library.
|
||||
"pthread_attr_getguardsize" if this.frame_in_std() => {
|
||||
let [_attr, guard_size] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [_attr, guard_size] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let guard_size_layout = this.machine.layouts.usize;
|
||||
let guard_size = this.deref_pointer_as(guard_size, guard_size_layout)?;
|
||||
this.write_scalar(
|
||||
|
|
@ -1159,11 +1161,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
|
||||
"pthread_attr_init" | "pthread_attr_destroy" if this.frame_in_std() => {
|
||||
let [_] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [_] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"pthread_attr_setstacksize" if this.frame_in_std() => {
|
||||
let [_, _] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [_, _] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
|
||||
|
|
@ -1171,7 +1173,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// We don't support "pthread_attr_setstack", so we just pretend all stacks have the same values here.
|
||||
// Hence we can mostly ignore the input `attr_place`.
|
||||
let [attr_place, addr_place, size_place] =
|
||||
this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let _attr_place =
|
||||
this.deref_pointer_as(attr_place, this.libc_ty_layout("pthread_attr_t"))?;
|
||||
let addr_place = this.deref_pointer_as(addr_place, this.machine.layouts.usize)?;
|
||||
|
|
@ -1191,18 +1193,18 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
|
||||
"signal" | "sigaltstack" if this.frame_in_std() => {
|
||||
let [_, _] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [_, _] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
"sigaction" | "mprotect" if this.frame_in_std() => {
|
||||
let [_, _, _] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [_, _, _] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
|
||||
"getpwuid_r" | "__posix_getpwuid_r" if this.frame_in_std() => {
|
||||
// getpwuid_r is the standard name, __posix_getpwuid_r is used on solarish
|
||||
let [uid, pwd, buf, buflen, result] =
|
||||
this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.check_no_isolation("`getpwuid_r`")?;
|
||||
|
||||
let uid = this.read_scalar(uid)?.to_u32()?;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use super::sync::EvalContextExt as _;
|
||||
use crate::shims::unix::*;
|
||||
|
|
@ -23,7 +24,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
match link_name.as_str() {
|
||||
// Threading
|
||||
"pthread_setname_np" => {
|
||||
let [thread, name] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [thread, name] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let max_len = u64::MAX; // FreeBSD does not seem to have a limit.
|
||||
let res = match this.pthread_setname_np(
|
||||
this.read_scalar(thread)?,
|
||||
|
|
@ -38,7 +39,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
"pthread_getname_np" => {
|
||||
let [thread, name, len] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [thread, name, len] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
// FreeBSD's pthread_getname_np uses strlcpy, which truncates the resulting value,
|
||||
// but always adds a null terminator (except for zero-sized buffers).
|
||||
// https://github.com/freebsd/freebsd-src/blob/c2d93a803acef634bd0eede6673aeea59e90c277/lib/libthr/thread/thr_info.c#L119-L144
|
||||
|
|
@ -59,7 +60,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
"cpuset_getaffinity" => {
|
||||
// The "same" kind of api as `sched_getaffinity` but more fine grained control for FreeBSD specifically.
|
||||
let [level, which, id, set_size, mask] =
|
||||
this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let level = this.read_scalar(level)?.to_i32()?;
|
||||
let which = this.read_scalar(which)?.to_i32()?;
|
||||
|
|
@ -123,7 +124,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Synchronization primitives
|
||||
"_umtx_op" => {
|
||||
let [obj, op, val, uaddr, uaddr2] =
|
||||
this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this._umtx_op(obj, op, val, uaddr, uaddr2, dest)?;
|
||||
}
|
||||
|
||||
|
|
@ -131,29 +132,29 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// For those, we both intercept `func` and `call@FBSD_1.0` symbols cases
|
||||
// since freebsd 12 the former form can be expected.
|
||||
"stat" | "stat@FBSD_1.0" => {
|
||||
let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [path, buf] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.macos_fbsd_solarish_stat(path, buf)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"lstat" | "lstat@FBSD_1.0" => {
|
||||
let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [path, buf] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.macos_fbsd_solarish_lstat(path, buf)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"fstat" | "fstat@FBSD_1.0" => {
|
||||
let [fd, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [fd, buf] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.macos_fbsd_solarish_fstat(fd, buf)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"readdir_r" | "readdir_r@FBSD_1.0" => {
|
||||
let [dirp, entry, result] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [dirp, entry, result] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let errno_place = this.last_error_place()?;
|
||||
this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
|
||||
}
|
||||
|
|
@ -161,7 +162,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Incomplete shims that we "stub out" just to get pre-main initialization code to work.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [_thread, _attr] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use self::shims::unix::linux::mem::EvalContextExt as _;
|
||||
use self::shims::unix::linux_like::epoll::EvalContextExt as _;
|
||||
|
|
@ -36,47 +37,48 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
match link_name.as_str() {
|
||||
// File related shims
|
||||
"readdir64" => {
|
||||
let [dirp] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [dirp] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.linux_solarish_readdir64("dirent64", dirp)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"sync_file_range" => {
|
||||
let [fd, offset, nbytes, flags] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [fd, offset, nbytes, flags] =
|
||||
this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [flag] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [epfd, op, fd, event] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.epoll_wait(epfd, events, maxevents, timeout, dest)?;
|
||||
}
|
||||
"eventfd" => {
|
||||
let [val, flag] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [val, flag] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [thread, name] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let res = match this.pthread_setname_np(
|
||||
this.read_scalar(thread)?,
|
||||
this.read_scalar(name)?,
|
||||
|
|
@ -91,7 +93,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
"pthread_getname_np" => {
|
||||
let [thread, name, len] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [thread, name, len] = this.check_shim(abi, CanonAbi::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.
|
||||
|
|
@ -114,7 +116,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
"gettid" => {
|
||||
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.linux_gettid()?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
|
@ -127,34 +129,34 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Miscellaneous
|
||||
"mmap64" => {
|
||||
let [addr, length, prot, flags, fd, offset] =
|
||||
this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::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_variadic(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim_variadic(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [errnum, buf, buflen] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.strerror_r(errnum, buf, buflen)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"__errno_location" => {
|
||||
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
this.write_int(SIGRTMIN, dest)?;
|
||||
}
|
||||
"__libc_current_sigrtmax" => {
|
||||
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
this.write_int(SIGRTMAX, dest)?;
|
||||
}
|
||||
|
|
@ -162,7 +164,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Incomplete shims that we "stub out" just to get pre-main initialization code to work.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [_thread, _attr] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.write_null(dest)?;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use crate::helpers::check_min_vararg_count;
|
||||
use crate::shims::unix::linux_like::eventfd::EvalContextExt as _;
|
||||
|
|
@ -14,7 +15,7 @@ pub fn syscall<'tcx>(
|
|||
args: &[OpTy<'tcx>],
|
||||
dest: &MPlaceTy<'tcx>,
|
||||
) -> InterpResult<'tcx> {
|
||||
let ([op], varargs) = ecx.check_shim_variadic(abi, Conv::C, link_name, args)?;
|
||||
let ([op], varargs) = ecx.check_shim_variadic(abi, CanonAbi::C, link_name, args)?;
|
||||
// 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
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use super::sync::{EvalContextExt as _, MacOsFutexTimeout};
|
||||
use crate::shims::unix::*;
|
||||
|
|
@ -34,64 +35,64 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
match link_name.as_str() {
|
||||
// errno
|
||||
"__error" => {
|
||||
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [result] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [path, buf] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.macos_fbsd_solarish_stat(path, buf)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"lstat" | "lstat64" | "lstat$INODE64" => {
|
||||
let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [path, buf] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.macos_fbsd_solarish_lstat(path, buf)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"fstat" | "fstat64" | "fstat$INODE64" => {
|
||||
let [fd, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [fd, buf] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.macos_fbsd_solarish_fstat(fd, buf)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"opendir$INODE64" => {
|
||||
let [name] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [name] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [dirp, entry, result] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [path, resolved_path] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.realpath(path, resolved_path)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"ioctl" => {
|
||||
let ([fd_num, cmd], varargs) =
|
||||
this.check_shim_variadic(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim_variadic(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.ioctl(fd_num, cmd, varargs)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
||||
// Environment related shims
|
||||
"_NSGetEnviron" => {
|
||||
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [bytes, count] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let bytes = this.read_pointer(bytes)?;
|
||||
let count = this.read_target_usize(count)?;
|
||||
let success = this.eval_libc_i32("kCCSuccess");
|
||||
|
|
@ -101,28 +102,28 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
// Time related shims
|
||||
"mach_absolute_time" => {
|
||||
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.mach_absolute_time()?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
||||
"mach_timebase_info" => {
|
||||
let [info] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [info] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.write_pointer(this.machine.argc.expect("machine must be initialized"), dest)?;
|
||||
}
|
||||
"_NSGetArgv" => {
|
||||
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.write_pointer(this.machine.argv.expect("machine must be initialized"), dest)?;
|
||||
}
|
||||
"_NSGetExecutablePath" => {
|
||||
let [buf, bufsize] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [buf, bufsize] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.check_no_isolation("`_NSGetExecutablePath`")?;
|
||||
|
||||
let buf_ptr = this.read_pointer(buf)?;
|
||||
|
|
@ -147,7 +148,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
// Thread-local storage
|
||||
"_tlv_atexit" => {
|
||||
let [dtor, data] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [dtor, data] = this.check_shim(abi, CanonAbi::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)?;
|
||||
|
|
@ -157,13 +158,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
// Querying system information
|
||||
"pthread_get_stackaddr_np" => {
|
||||
let [thread] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [thread] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [thread] = this.check_shim(abi, CanonAbi::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)?;
|
||||
|
|
@ -171,7 +172,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
// Threading
|
||||
"pthread_setname_np" => {
|
||||
let [name] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [name] = this.check_shim(abi, CanonAbi::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> {
|
|||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
"pthread_getname_np" => {
|
||||
let [thread, name, len] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [thread, name, len] = this.check_shim(abi, CanonAbi::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)
|
||||
|
|
@ -225,7 +226,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Synchronization primitives
|
||||
"os_sync_wait_on_address" => {
|
||||
let [addr_op, value_op, size_op, flags_op] =
|
||||
this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.os_sync_wait_on_address(
|
||||
addr_op,
|
||||
value_op,
|
||||
|
|
@ -237,7 +238,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
"os_sync_wait_on_address_with_deadline" => {
|
||||
let [addr_op, value_op, size_op, flags_op, clock_op, timeout_op] =
|
||||
this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.os_sync_wait_on_address(
|
||||
addr_op,
|
||||
value_op,
|
||||
|
|
@ -249,7 +250,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
"os_sync_wait_on_address_with_timeout" => {
|
||||
let [addr_op, value_op, size_op, flags_op, clock_op, timeout_op] =
|
||||
this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.os_sync_wait_on_address(
|
||||
addr_op,
|
||||
value_op,
|
||||
|
|
@ -261,36 +262,36 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
"os_sync_wake_by_address_any" => {
|
||||
let [addr_op, size_op, flags_op] =
|
||||
this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.os_sync_wake_by_address(
|
||||
addr_op, size_op, flags_op, /* all */ false, dest,
|
||||
)?;
|
||||
}
|
||||
"os_sync_wake_by_address_all" => {
|
||||
let [addr_op, size_op, flags_op] =
|
||||
this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.os_sync_wake_by_address(
|
||||
addr_op, size_op, flags_op, /* all */ true, dest,
|
||||
)?;
|
||||
}
|
||||
"os_unfair_lock_lock" => {
|
||||
let [lock_op] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [lock_op] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.os_unfair_lock_lock(lock_op)?;
|
||||
}
|
||||
"os_unfair_lock_trylock" => {
|
||||
let [lock_op] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [lock_op] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.os_unfair_lock_trylock(lock_op, dest)?;
|
||||
}
|
||||
"os_unfair_lock_unlock" => {
|
||||
let [lock_op] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [lock_op] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.os_unfair_lock_unlock(lock_op)?;
|
||||
}
|
||||
"os_unfair_lock_assert_owner" => {
|
||||
let [lock_op] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [lock_op] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [lock_op] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.os_unfair_lock_assert_not_owner(lock_op)?;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use crate::shims::unix::foreign_items::EvalContextExt as _;
|
||||
use crate::shims::unix::linux_like::epoll::EvalContextExt as _;
|
||||
|
|
@ -26,32 +27,32 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// epoll, eventfd (NOT available on Solaris!)
|
||||
"epoll_create1" => {
|
||||
this.assert_target_os("illumos", "epoll_create1");
|
||||
let [flag] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [flag] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.epoll_create1(flag)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"epoll_ctl" => {
|
||||
this.assert_target_os("illumos", "epoll_ctl");
|
||||
let [epfd, op, fd, event] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [epfd, op, fd, event] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.epoll_ctl(epfd, op, fd, event)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"epoll_wait" => {
|
||||
this.assert_target_os("illumos", "epoll_wait");
|
||||
let [epfd, events, maxevents, timeout] =
|
||||
this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.epoll_wait(epfd, events, maxevents, timeout, dest)?;
|
||||
}
|
||||
"eventfd" => {
|
||||
this.assert_target_os("illumos", "eventfd");
|
||||
let [val, flag] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [val, flag] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [thread, name] = this.check_shim(abi, CanonAbi::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;
|
||||
|
|
@ -69,7 +70,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
this.write_scalar(res, dest)?;
|
||||
}
|
||||
"pthread_getname_np" => {
|
||||
let [thread, name, len] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [thread, name, len] = this.check_shim(abi, CanonAbi::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)?,
|
||||
|
|
@ -86,22 +87,22 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
|
||||
// File related shims
|
||||
"stat" | "stat64" => {
|
||||
let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [path, buf] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.macos_fbsd_solarish_stat(path, buf)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"lstat" | "lstat64" => {
|
||||
let [path, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [path, buf] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.macos_fbsd_solarish_lstat(path, buf)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"fstat" | "fstat64" => {
|
||||
let [fd, buf] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [fd, buf] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.macos_fbsd_solarish_fstat(fd, buf)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
"readdir" => {
|
||||
let [dirp] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [dirp] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.linux_solarish_readdir64("dirent", dirp)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
|
@ -109,20 +110,20 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Sockets and pipes
|
||||
"__xnet_socketpair" => {
|
||||
let [domain, type_, protocol, sv] =
|
||||
this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.socketpair(domain, type_, protocol, sv)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
||||
// Miscellaneous
|
||||
"___errno" => {
|
||||
let [] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [stack] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let stack = this.deref_pointer_as(stack, this.libc_ty_layout("stack_t"))?;
|
||||
|
||||
this.write_int_fields_named(
|
||||
|
|
@ -140,7 +141,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
|
||||
"pset_info" => {
|
||||
let [pset, tpe, cpus, list] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [pset, tpe, cpus, list] = this.check_shim(abi, CanonAbi::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.
|
||||
|
|
@ -169,7 +170,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
}
|
||||
|
||||
"__sysconf_xpg7" => {
|
||||
let [val] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [val] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let result = this.sysconf(val)?;
|
||||
this.write_scalar(result, dest)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use crate::shims::alloc::EvalContextExt as _;
|
||||
use crate::*;
|
||||
|
|
@ -22,12 +23,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
match link_name.as_str() {
|
||||
// Allocation
|
||||
"posix_memalign" => {
|
||||
let [memptr, align, size] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [memptr, align, size] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [align, size] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let res = this.aligned_alloc(align, size)?;
|
||||
this.write_pointer(res, dest)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@ use std::ffi::OsStr;
|
|||
use std::path::{self, Path, PathBuf};
|
||||
use std::{io, iter, str};
|
||||
|
||||
use rustc_abi::{Align, Size};
|
||||
use rustc_abi::{Align, CanonAbi, Size, X86Call};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use self::shims::windows::handle::{Handle, PseudoHandle};
|
||||
use crate::shims::os_str::bytes_to_os_str;
|
||||
|
|
@ -140,7 +140,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// https://github.com/rust-lang/rust/blob/fb00adbdb69266f10df95a4527b767b0ad35ea48/compiler/rustc_target/src/spec/mod.rs#L2766-L2768,
|
||||
// x86-32 Windows uses a different calling convention than other Windows targets
|
||||
// for the "system" ABI.
|
||||
let sys_conv = if this.tcx.sess.target.arch == "x86" { Conv::X86Stdcall } else { Conv::C };
|
||||
let sys_conv = if this.tcx.sess.target.arch == "x86" {
|
||||
CanonAbi::X86(X86Call::Stdcall)
|
||||
} else {
|
||||
CanonAbi::C
|
||||
};
|
||||
|
||||
// See `fn emulate_foreign_item_inner` in `shims/foreign_items.rs` for the general pattern.
|
||||
|
||||
|
|
@ -834,7 +838,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
);
|
||||
}
|
||||
// This function looks and behaves excatly like miri_start_unwind.
|
||||
let [payload] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [payload] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
this.handle_miri_start_unwind(payload)?;
|
||||
return interp_ok(EmulateItemResult::NeedsUnwind);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_middle::ty::layout::LayoutOf as _;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use crate::*;
|
||||
|
||||
|
|
@ -26,7 +27,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// `state` with the corresponding 128-bit key of `key`.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [state, key] = this.check_shim(abi, CanonAbi::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());
|
||||
|
|
@ -42,7 +43,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// `state` with the corresponding 128-bit key of `key`.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [state, key] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
aes_round(this, state, key, dest, |state, key| {
|
||||
let mut state = aes::Block::from(state.to_le_bytes());
|
||||
|
|
@ -66,7 +67,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// `state` with the corresponding 128-bit key of `key`.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [state, key] = this.check_shim(abi, CanonAbi::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());
|
||||
|
|
@ -82,7 +83,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// `state` with the corresponding 128-bit key of `key`.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [state, key] = this.check_shim(abi, CanonAbi::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:
|
||||
|
|
@ -102,7 +103,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, Conv::C, link_name, args)?;
|
||||
let [op] = this.check_shim(abi, CanonAbi::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)?;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
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 rustc_target::callconv::FnAbi;
|
||||
|
||||
use super::{
|
||||
FloatBinOp, FloatUnaryOp, bin_op_simd_float_all, conditional_dot_product, convert_float_to_int,
|
||||
|
|
@ -33,7 +34,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// matches the IEEE min/max operations, while x86 has different
|
||||
// semantics.
|
||||
"min.ps.256" | "max.ps.256" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which = match unprefixed_name {
|
||||
"min.ps.256" => FloatBinOp::Min,
|
||||
|
|
@ -45,7 +46,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, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which = match unprefixed_name {
|
||||
"min.pd.256" => FloatBinOp::Min,
|
||||
|
|
@ -58,21 +59,21 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Used to implement the _mm256_round_ps function.
|
||||
// Rounds the elements of `op` according to `rounding`.
|
||||
"round.ps.256" => {
|
||||
let [op, rounding] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [op, rounding] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [op, rounding] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [op] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which = match unprefixed_name {
|
||||
"rcp.ps.256" => FloatUnaryOp::Rcp,
|
||||
|
|
@ -84,7 +85,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, Conv::C, link_name, args)?;
|
||||
let [left, right, imm] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
conditional_dot_product(this, left, right, imm, dest)?;
|
||||
}
|
||||
|
|
@ -92,7 +93,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Horizontally add/subtract adjacent floating point values
|
||||
// in `left` and `right`.
|
||||
"hadd.ps.256" | "hadd.pd.256" | "hsub.ps.256" | "hsub.pd.256" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which = match unprefixed_name {
|
||||
"hadd.ps.256" | "hadd.pd.256" => mir::BinOp::Add,
|
||||
|
|
@ -107,7 +108,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// and `right`. For each component, returns 0 if false or u32::MAX
|
||||
// if true.
|
||||
"cmp.ps.256" => {
|
||||
let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right, imm] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which =
|
||||
FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
|
||||
|
|
@ -119,7 +120,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// and `right`. For each component, returns 0 if false or u64::MAX
|
||||
// if true.
|
||||
"cmp.pd.256" => {
|
||||
let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right, imm] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which =
|
||||
FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
|
||||
|
|
@ -130,7 +131,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, Conv::C, link_name, args)?;
|
||||
let [op] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let rnd = match unprefixed_name {
|
||||
// "current SSE rounding mode", assume nearest
|
||||
|
|
@ -148,7 +149,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// sequence of 4-element arrays, and we shuffle each of these arrays, where
|
||||
// `control` determines which element of the current `data` array is written.
|
||||
"vpermilvar.ps" | "vpermilvar.ps.256" => {
|
||||
let [data, control] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [data, control] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (data, data_len) = this.project_to_simd(data)?;
|
||||
let (control, control_len) = this.project_to_simd(control)?;
|
||||
|
|
@ -181,7 +182,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// where `right` determines which element of the current `left` array is
|
||||
// written.
|
||||
"vpermilvar.pd" | "vpermilvar.pd.256" => {
|
||||
let [data, control] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [data, control] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (data, data_len) = this.project_to_simd(data)?;
|
||||
let (control, control_len) = this.project_to_simd(control)?;
|
||||
|
|
@ -213,7 +214,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// For each 128-bit element of `dest`, copies one from `left`, `right` or
|
||||
// zero, according to `imm`.
|
||||
"vperm2f128.ps.256" | "vperm2f128.pd.256" | "vperm2f128.si.256" => {
|
||||
let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right, imm] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
assert_eq!(dest.layout, left.layout);
|
||||
assert_eq!(dest.layout, right.layout);
|
||||
|
|
@ -256,7 +257,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// is one, it is loaded from `ptr.wrapping_add(i)`, otherwise zero is
|
||||
// loaded.
|
||||
"maskload.ps" | "maskload.pd" | "maskload.ps.256" | "maskload.pd.256" => {
|
||||
let [ptr, mask] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [ptr, mask] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
mask_load(this, ptr, mask, dest)?;
|
||||
}
|
||||
|
|
@ -266,7 +267,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// is one, it is stored into `ptr.wapping_add(i)`.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [ptr, mask, value] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
mask_store(this, ptr, mask, value)?;
|
||||
}
|
||||
|
|
@ -276,7 +277,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// the data crosses a cache line, but for Miri this is just a regular
|
||||
// unaligned read.
|
||||
"ldu.dq.256" => {
|
||||
let [src_ptr] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [src_ptr] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let src_ptr = this.read_pointer(src_ptr)?;
|
||||
let dest = dest.force_mplace(this)?;
|
||||
|
||||
|
|
@ -288,7 +289,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Tests `op & mask == 0`, `op & mask == mask` or
|
||||
// `op & mask != 0 && op & mask != mask`
|
||||
"ptestz.256" | "ptestc.256" | "ptestnzc.256" => {
|
||||
let [op, mask] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [op, mask] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (all_zero, masked_set) = test_bits_masked(this, op, mask)?;
|
||||
let res = match unprefixed_name {
|
||||
|
|
@ -311,7 +312,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
"vtestz.pd.256" | "vtestc.pd.256" | "vtestnzc.pd.256" | "vtestz.pd" | "vtestc.pd"
|
||||
| "vtestnzc.pd" | "vtestz.ps.256" | "vtestc.ps.256" | "vtestnzc.ps.256"
|
||||
| "vtestz.ps" | "vtestc.ps" | "vtestnzc.ps" => {
|
||||
let [op, mask] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [op, mask] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (direct, negated) = test_high_bits_masked(this, op, mask)?;
|
||||
let res = match unprefixed_name {
|
||||
|
|
@ -333,7 +334,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, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
}
|
||||
_ => return interp_ok(EmulateItemResult::NotSupported),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,9 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
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 rustc_target::callconv::FnAbi;
|
||||
|
||||
use super::{
|
||||
ShiftOp, horizontal_bin_op, int_abs, mask_load, mask_store, mpsadbw, packssdw, packsswb,
|
||||
|
|
@ -28,7 +29,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, Conv::C, link_name, args)?;
|
||||
let [op] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
int_abs(this, op, dest)?;
|
||||
}
|
||||
|
|
@ -36,7 +37,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Horizontally add / add with saturation / subtract adjacent 16/32-bit
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (which, saturating) = match unprefixed_name {
|
||||
"phadd.w" | "phadd.d" => (mir::BinOp::Add, false),
|
||||
|
|
@ -57,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, Conv::C, link_name, args)?;
|
||||
this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
assert_eq!(dest.layout, src.layout);
|
||||
|
||||
|
|
@ -114,7 +115,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// intermediate signed 32-bit integers. Horizontally add adjacent pairs of
|
||||
// intermediate 32-bit integers, and pack the results in `dest`.
|
||||
"pmadd.wd" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (right, right_len) = this.project_to_simd(right)?;
|
||||
|
|
@ -150,7 +151,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// the saturating sum of the products with indices `2*i` and `2*i+1`
|
||||
// produces the output at index `i`.
|
||||
"pmadd.ub.sw" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (right, right_len) = this.project_to_simd(right)?;
|
||||
|
|
@ -184,7 +185,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// is one, it is loaded from `ptr.wrapping_add(i)`, otherwise zero is
|
||||
// loaded.
|
||||
"maskload.d" | "maskload.q" | "maskload.d.256" | "maskload.q.256" => {
|
||||
let [ptr, mask] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [ptr, mask] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
mask_load(this, ptr, mask, dest)?;
|
||||
}
|
||||
|
|
@ -194,7 +195,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// is one, it is stored into `ptr.wapping_add(i)`.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [ptr, mask, value] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
mask_store(this, ptr, mask, value)?;
|
||||
}
|
||||
|
|
@ -205,7 +206,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// offsets specified in `imm`.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [left, right, imm] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
mpsadbw(this, left, right, imm, dest)?;
|
||||
}
|
||||
|
|
@ -216,7 +217,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// 1 and then taking the bits `1..=16`.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
pmulhrsw(this, left, right, dest)?;
|
||||
}
|
||||
|
|
@ -224,7 +225,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Converts two 16-bit integer vectors to a single 8-bit integer
|
||||
// vector with signed saturation.
|
||||
"packsswb" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
packsswb(this, left, right, dest)?;
|
||||
}
|
||||
|
|
@ -232,7 +233,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Converts two 32-bit integer vectors to a single 16-bit integer
|
||||
// vector with signed saturation.
|
||||
"packssdw" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
packssdw(this, left, right, dest)?;
|
||||
}
|
||||
|
|
@ -240,7 +241,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Converts two 16-bit signed integer vectors to a single 8-bit
|
||||
// unsigned integer vector with saturation.
|
||||
"packuswb" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
packuswb(this, left, right, dest)?;
|
||||
}
|
||||
|
|
@ -248,7 +249,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Concatenates two 32-bit signed integer vectors and converts
|
||||
// the result to a 16-bit unsigned integer vector with saturation.
|
||||
"packusdw" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
packusdw(this, left, right, dest)?;
|
||||
}
|
||||
|
|
@ -257,7 +258,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Shuffles `left` using the three low bits of each element of `right`
|
||||
// as indices.
|
||||
"permd" | "permps" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (right, right_len) = this.project_to_simd(right)?;
|
||||
|
|
@ -277,7 +278,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Used to implement the _mm256_permute2x128_si256 function.
|
||||
// Shuffles 128-bit blocks of `a` and `b` using `imm` as pattern.
|
||||
"vperm2i128" => {
|
||||
let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right, imm] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
assert_eq!(left.layout.size.bits(), 256);
|
||||
assert_eq!(right.layout.size.bits(), 256);
|
||||
|
|
@ -314,7 +315,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// in `dest`.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (right, right_len) = this.project_to_simd(right)?;
|
||||
|
|
@ -346,7 +347,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Shuffles bytes from `left` using `right` as pattern.
|
||||
// Each 128-bit block is shuffled independently.
|
||||
"pshuf.b" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (right, right_len) = this.project_to_simd(right)?;
|
||||
|
|
@ -377,7 +378,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// is writen to the corresponding output element.
|
||||
// Basically, we multiply `left` with `right.signum()`.
|
||||
"psign.b" | "psign.w" | "psign.d" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
psign(this, left, right, dest)?;
|
||||
}
|
||||
|
|
@ -391,7 +392,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// is copied to remaining bits.
|
||||
"psll.w" | "psrl.w" | "psra.w" | "psll.d" | "psrl.d" | "psra.d" | "psll.q"
|
||||
| "psrl.q" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which = match unprefixed_name {
|
||||
"psll.w" | "psll.d" | "psll.q" => ShiftOp::Left,
|
||||
|
|
@ -406,7 +407,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// (except _mm{,256}_srav_epi64, which are not available in AVX2).
|
||||
"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, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which = match unprefixed_name {
|
||||
"psllv.d" | "psllv.d.256" | "psllv.q" | "psllv.q.256" => ShiftOp::Left,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use crate::*;
|
||||
|
||||
|
|
@ -34,7 +35,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
return interp_ok(EmulateItemResult::NotSupported);
|
||||
}
|
||||
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let left = this.read_scalar(left)?;
|
||||
let right = this.read_scalar(right)?;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use crate::*;
|
||||
|
||||
|
|
@ -30,14 +31,14 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// See `affine_transform` for details.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [left, right, imm8] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [left, right, imm8] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
affine_transform(this, left, right, imm8, dest, /* inverse */ true)?;
|
||||
}
|
||||
// Used to implement the `_mm{, 256, 512}_gf2p8mul_epi8` functions.
|
||||
|
|
@ -46,7 +47,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// polynomial representation with the reduction polynomial x^8 + x^4 + x^3 + x + 1.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::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)?;
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
use rustc_abi::Size;
|
||||
use rustc_abi::{CanonAbi, 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 rustc_target::callconv::FnAbi;
|
||||
|
||||
use self::helpers::bool_to_simd_element;
|
||||
use crate::*;
|
||||
|
|
@ -46,7 +46,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
return interp_ok(EmulateItemResult::NotSupported);
|
||||
}
|
||||
|
||||
let [cb_in, a, b] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [cb_in, a, b] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let op = if unprefixed_name.starts_with("add") {
|
||||
mir::BinOp::AddWithOverflow
|
||||
} else {
|
||||
|
|
@ -68,7 +68,7 @@ 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, Conv::C, link_name, args)?;
|
||||
let [c_in, a, b, out] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let out = this.deref_pointer_as(
|
||||
out,
|
||||
if is_u64 { this.machine.layouts.u64 } else { this.machine.layouts.u32 },
|
||||
|
|
@ -85,7 +85,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, Conv::C, link_name, args)?;
|
||||
let [] = this.check_shim(abi, CanonAbi::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();
|
||||
|
|
@ -104,7 +104,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
len = 8;
|
||||
}
|
||||
|
||||
let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right, imm] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
pclmulqdq(this, left, right, imm, dest, len)?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@
|
|||
//!
|
||||
//! [RustCrypto's sha256 module]: https://github.com/RustCrypto/hashes/blob/6be8466247e936c415d8aafb848697f39894a386/sha2/src/sha256/soft.rs
|
||||
|
||||
use rustc_abi::CanonAbi;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use crate::*;
|
||||
|
||||
|
|
@ -52,7 +53,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
match unprefixed_name {
|
||||
// Used to implement the _mm_sha256rnds2_epu32 function.
|
||||
"256rnds2" => {
|
||||
let [a, b, k] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [a, b, k] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (a_reg, a_len) = this.project_to_simd(a)?;
|
||||
let (b_reg, b_len) = this.project_to_simd(b)?;
|
||||
|
|
@ -73,7 +74,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, Conv::C, link_name, args)?;
|
||||
let [a, b] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (a_reg, a_len) = this.project_to_simd(a)?;
|
||||
let (b_reg, b_len) = this.project_to_simd(b)?;
|
||||
|
|
@ -91,7 +92,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, Conv::C, link_name, args)?;
|
||||
let [a, b] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (a_reg, a_len) = this.project_to_simd(a)?;
|
||||
let (b_reg, b_len) = this.project_to_simd(b)?;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
use rustc_apfloat::ieee::Single;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use super::{
|
||||
FloatBinOp, FloatUnaryOp, bin_op_simd_float_all, bin_op_simd_float_first, unary_op_ps,
|
||||
|
|
@ -33,7 +34,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Performs the operations on the first component of `left` and
|
||||
// `right` and copies the remaining components from `left`.
|
||||
"min.ss" | "max.ss" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which = match unprefixed_name {
|
||||
"min.ss" => FloatBinOp::Min,
|
||||
|
|
@ -49,7 +50,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// matches the IEEE min/max operations, while x86 has different
|
||||
// semantics.
|
||||
"min.ps" | "max.ps" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which = match unprefixed_name {
|
||||
"min.ps" => FloatBinOp::Min,
|
||||
|
|
@ -63,7 +64,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, Conv::C, link_name, args)?;
|
||||
let [op] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which = match unprefixed_name {
|
||||
"rcp.ss" => FloatUnaryOp::Rcp,
|
||||
|
|
@ -76,7 +77,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, Conv::C, link_name, args)?;
|
||||
let [op] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which = match unprefixed_name {
|
||||
"rcp.ps" => FloatUnaryOp::Rcp,
|
||||
|
|
@ -95,7 +96,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// _mm_cmp{eq,lt,le,gt,ge,neq,nlt,nle,ngt,nge,ord,unord}_ss are SSE functions
|
||||
// with hard-coded operations.
|
||||
"cmp.ss" => {
|
||||
let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right, imm] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which =
|
||||
FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
|
||||
|
|
@ -111,7 +112,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// _mm_cmp{eq,lt,le,gt,ge,neq,nlt,nle,ngt,nge,ord,unord}_ps are SSE functions
|
||||
// with hard-coded operations.
|
||||
"cmp.ps" => {
|
||||
let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right, imm] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which =
|
||||
FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
|
||||
|
|
@ -124,7 +125,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
"comieq.ss" | "comilt.ss" | "comile.ss" | "comigt.ss" | "comige.ss" | "comineq.ss"
|
||||
| "ucomieq.ss" | "ucomilt.ss" | "ucomile.ss" | "ucomigt.ss" | "ucomige.ss"
|
||||
| "ucomineq.ss" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (right, right_len) = this.project_to_simd(right)?;
|
||||
|
|
@ -152,7 +153,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, Conv::C, link_name, args)?;
|
||||
let [op] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let (op, _) = this.project_to_simd(op)?;
|
||||
|
||||
let op = this.read_immediate(&this.project_index(&op, 0)?)?;
|
||||
|
|
@ -180,7 +181,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// are copied from `left`.
|
||||
// https://www.felixcloutier.com/x86/cvtsi2ss
|
||||
"cvtsi2ss" | "cvtsi642ss" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (dest, dest_len) = this.project_to_simd(dest)?;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
use rustc_apfloat::ieee::Double;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use super::{
|
||||
FloatBinOp, ShiftOp, bin_op_simd_float_all, bin_op_simd_float_first, convert_float_to_int,
|
||||
|
|
@ -40,7 +41,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// intermediate signed 32-bit integers. Horizontally add adjacent pairs of
|
||||
// intermediate 32-bit integers, and pack the results in `dest`.
|
||||
"pmadd.wd" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (right, right_len) = this.project_to_simd(right)?;
|
||||
|
|
@ -78,7 +79,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, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (right, right_len) = this.project_to_simd(right)?;
|
||||
|
|
@ -116,7 +117,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// is copied to remaining bits.
|
||||
"psll.w" | "psrl.w" | "psra.w" | "psll.d" | "psrl.d" | "psra.d" | "psll.q"
|
||||
| "psrl.q" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which = match unprefixed_name {
|
||||
"psll.w" | "psll.d" | "psll.q" => ShiftOp::Left,
|
||||
|
|
@ -131,7 +132,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, Conv::C, link_name, args)?;
|
||||
let [op] = this.check_shim(abi, CanonAbi::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);
|
||||
|
|
@ -168,7 +169,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Converts two 16-bit integer vectors to a single 8-bit integer
|
||||
// vector with signed saturation.
|
||||
"packsswb.128" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
packsswb(this, left, right, dest)?;
|
||||
}
|
||||
|
|
@ -176,7 +177,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Converts two 16-bit signed integer vectors to a single 8-bit
|
||||
// unsigned integer vector with saturation.
|
||||
"packuswb.128" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
packuswb(this, left, right, dest)?;
|
||||
}
|
||||
|
|
@ -184,7 +185,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Converts two 32-bit integer vectors to a single 16-bit integer
|
||||
// vector with signed saturation.
|
||||
"packssdw.128" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
packssdw(this, left, right, dest)?;
|
||||
}
|
||||
|
|
@ -194,7 +195,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// matches the IEEE min/max operations, while x86 has different
|
||||
// semantics.
|
||||
"min.sd" | "max.sd" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which = match unprefixed_name {
|
||||
"min.sd" => FloatBinOp::Min,
|
||||
|
|
@ -210,7 +211,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// matches the IEEE min/max operations, while x86 has different
|
||||
// semantics.
|
||||
"min.pd" | "max.pd" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which = match unprefixed_name {
|
||||
"min.pd" => FloatBinOp::Min,
|
||||
|
|
@ -229,7 +230,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// _mm_cmp{eq,lt,le,gt,ge,neq,nlt,nle,ngt,nge,ord,unord}_sd are SSE2 functions
|
||||
// with hard-coded operations.
|
||||
"cmp.sd" => {
|
||||
let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right, imm] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which =
|
||||
FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
|
||||
|
|
@ -245,7 +246,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// _mm_cmp{eq,lt,le,gt,ge,neq,nlt,nle,ngt,nge,ord,unord}_pd are SSE2 functions
|
||||
// with hard-coded operations.
|
||||
"cmp.pd" => {
|
||||
let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right, imm] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which =
|
||||
FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
|
||||
|
|
@ -258,7 +259,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
"comieq.sd" | "comilt.sd" | "comile.sd" | "comigt.sd" | "comige.sd" | "comineq.sd"
|
||||
| "ucomieq.sd" | "ucomilt.sd" | "ucomile.sd" | "ucomigt.sd" | "ucomige.sd"
|
||||
| "ucomineq.sd" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (right, right_len) = this.project_to_simd(right)?;
|
||||
|
|
@ -286,7 +287,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, Conv::C, link_name, args)?;
|
||||
let [op] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let (op, _) = this.project_to_simd(op)?;
|
||||
|
||||
let op = this.read_immediate(&this.project_index(&op, 0)?)?;
|
||||
|
|
@ -312,7 +313,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Converts the first f64/f32 from `right` to f32/f64 and copies
|
||||
// the remaining elements from `left`
|
||||
"cvtsd2ss" | "cvtss2sd" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (right, _) = this.project_to_simd(right)?;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use super::horizontal_bin_op;
|
||||
use crate::*;
|
||||
|
|
@ -25,7 +26,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Horizontally add/subtract adjacent floating point values
|
||||
// in `left` and `right`.
|
||||
"hadd.ps" | "hadd.pd" | "hsub.ps" | "hsub.pd" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let which = match unprefixed_name {
|
||||
"hadd.ps" | "hadd.pd" => mir::BinOp::Add,
|
||||
|
|
@ -41,7 +42,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// the data crosses a cache line, but for Miri this is just a regular
|
||||
// unaligned read.
|
||||
"ldu.dq" => {
|
||||
let [src_ptr] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [src_ptr] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let src_ptr = this.read_pointer(src_ptr)?;
|
||||
let dest = dest.force_mplace(this)?;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use super::{conditional_dot_product, mpsadbw, packusdw, round_all, round_first, test_bits_masked};
|
||||
use crate::*;
|
||||
|
|
@ -27,7 +28,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// bits `4..=5` if `imm`, and `i`th bit specifies whether element
|
||||
// `i` is zeroed.
|
||||
"insertps" => {
|
||||
let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right, imm] = this.check_shim(abi, CanonAbi::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> {
|
|||
// Concatenates two 32-bit signed integer vectors and converts
|
||||
// the result to a 16-bit unsigned integer vector with saturation.
|
||||
"packusdw" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
packusdw(this, left, right, dest)?;
|
||||
}
|
||||
|
|
@ -72,7 +73,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// products, and conditionally stores the sum in `dest` using the low
|
||||
// 4 bits of `imm`.
|
||||
"dpps" | "dppd" => {
|
||||
let [left, right, imm] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right, imm] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
conditional_dot_product(this, left, right, imm, dest)?;
|
||||
}
|
||||
|
|
@ -80,14 +81,14 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// functions. Rounds the first element of `right` according to `rounding`
|
||||
// and copies the remaining elements from `left`.
|
||||
"round.ss" => {
|
||||
let [left, right, rounding] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right, rounding] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [op, rounding] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
round_all::<rustc_apfloat::ieee::Single>(this, op, rounding, dest)?;
|
||||
}
|
||||
|
|
@ -95,14 +96,14 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// functions. Rounds the first element of `right` according to `rounding`
|
||||
// and copies the remaining elements from `left`.
|
||||
"round.sd" => {
|
||||
let [left, right, rounding] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right, rounding] = this.check_shim(abi, CanonAbi::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, Conv::C, link_name, args)?;
|
||||
let [op, rounding] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
round_all::<rustc_apfloat::ieee::Double>(this, op, rounding, dest)?;
|
||||
}
|
||||
|
|
@ -110,7 +111,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Find the minimum unsinged 16-bit integer in `op` and
|
||||
// returns its value and position.
|
||||
"phminposuw" => {
|
||||
let [op] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [op] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (op, op_len) = this.project_to_simd(op)?;
|
||||
let (dest, dest_len) = this.project_to_simd(dest)?;
|
||||
|
|
@ -144,7 +145,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// offsets specified in `imm`.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [left, right, imm] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
mpsadbw(this, left, right, imm, dest)?;
|
||||
}
|
||||
|
|
@ -153,7 +154,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Tests `(op & mask) == 0`, `(op & mask) == mask` or
|
||||
// `(op & mask) != 0 && (op & mask) != mask`
|
||||
"ptestz" | "ptestc" | "ptestnzc" => {
|
||||
let [op, mask] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [op, mask] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (all_zero, masked_set) = test_bits_masked(this, op, mask)?;
|
||||
let res = match unprefixed_name {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use rustc_abi::Size;
|
||||
use rustc_abi::{CanonAbi, 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 rustc_target::callconv::FnAbi;
|
||||
|
||||
use crate::*;
|
||||
|
||||
|
|
@ -223,7 +223,7 @@ fn deconstruct_args<'tcx>(
|
|||
};
|
||||
|
||||
if is_explicit {
|
||||
let [str1, len1, str2, len2, imm] = ecx.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [str1, len1, str2, len2, imm] = ecx.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let imm = ecx.read_scalar(imm)?.to_u8()?;
|
||||
|
||||
let default_len = default_len::<u32>(imm);
|
||||
|
|
@ -236,7 +236,7 @@ fn deconstruct_args<'tcx>(
|
|||
|
||||
interp_ok((str1, str2, Some((len1, len2)), imm))
|
||||
} else {
|
||||
let [str1, str2, imm] = ecx.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [str1, str2, imm] = ecx.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let imm = ecx.read_scalar(imm)?.to_u8()?;
|
||||
|
||||
let array_layout = array_layout_fn(ecx, imm)?;
|
||||
|
|
@ -386,7 +386,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// search for a null terminator (see `deconstruct_args` for more details).
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [str1, str2, imm] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let imm = this.read_scalar(imm)?.to_u8()?;
|
||||
|
||||
let str = if unprefixed_name == "pcmpistris128" { str1 } else { str2 };
|
||||
|
|
@ -406,7 +406,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// than 16 for byte-sized operands or 8 for word-sized operands.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [_, len1, _, len2, imm] = this.check_shim(abi, CanonAbi::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()?;
|
||||
|
|
@ -433,7 +433,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
return interp_ok(EmulateItemResult::NotSupported);
|
||||
}
|
||||
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
let left = this.read_scalar(left)?;
|
||||
let right = this.read_scalar(right)?;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
use rustc_abi::CanonAbi;
|
||||
use rustc_middle::mir;
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::Symbol;
|
||||
use rustc_target::callconv::{Conv, FnAbi};
|
||||
use rustc_target::callconv::FnAbi;
|
||||
|
||||
use super::{horizontal_bin_op, int_abs, pmulhrsw, psign};
|
||||
use crate::*;
|
||||
|
|
@ -24,7 +25,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, Conv::C, link_name, args)?;
|
||||
let [op] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
int_abs(this, op, dest)?;
|
||||
}
|
||||
|
|
@ -32,7 +33,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// Shuffles bytes from `left` using `right` as pattern.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (right, right_len) = this.project_to_simd(right)?;
|
||||
|
|
@ -61,7 +62,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// integer values in `left` and `right`.
|
||||
"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, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (which, saturating) = match unprefixed_name {
|
||||
"phadd.w.128" | "phadd.d.128" => (mir::BinOp::Add, false),
|
||||
|
|
@ -80,7 +81,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// produces the output at index `i`.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
let (left, left_len) = this.project_to_simd(left)?;
|
||||
let (right, right_len) = this.project_to_simd(right)?;
|
||||
|
|
@ -115,7 +116,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// 1 and then taking the bits `1..=16`.
|
||||
// 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, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
pmulhrsw(this, left, right, dest)?;
|
||||
}
|
||||
|
|
@ -125,7 +126,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
|||
// is writen to the corresponding output element.
|
||||
// Basically, we multiply `left` with `right.signum()`.
|
||||
"psign.b.128" | "psign.w.128" | "psign.d.128" => {
|
||||
let [left, right] = this.check_shim(abi, Conv::C, link_name, args)?;
|
||||
let [left, right] = this.check_shim(abi, CanonAbi::C, link_name, args)?;
|
||||
|
||||
psign(this, left, right, dest)?;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue