Skip to content

Commit 20e0014

Browse files
Support f32/f64 in native function calls
1 parent 3c92cf1 commit 20e0014

File tree

3 files changed

+22
-2
lines changed

3 files changed

+22
-2
lines changed

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

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ use libffi::middle::Type as FfiType;
88
use rustc_abi::{HasDataLayout, Size};
99
use rustc_data_structures::either;
1010
use rustc_middle::ty::layout::{HasTypingEnv, TyAndLayout};
11-
use rustc_middle::ty::{self, IntTy, Ty, UintTy};
11+
use rustc_middle::ty::{self, FloatTy, IntTy, Ty, UintTy};
1212
use rustc_span::Symbol;
1313
use serde::{Deserialize, Serialize};
1414

15+
use self::helpers::ToSoft;
16+
1517
mod ffi;
1618

1719
#[cfg_attr(
@@ -138,6 +140,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
138140
let x = unsafe { ffi::call::<usize>(fun, libffi_args) };
139141
Scalar::from_target_usize(x.try_into().unwrap(), this)
140142
}
143+
ty::Float(FloatTy::F32) => {
144+
let x = unsafe { ffi::call::<f32>(fun, libffi_args) };
145+
Scalar::from_f32(x.to_soft())
146+
}
147+
ty::Float(FloatTy::F64) => {
148+
let x = unsafe { ffi::call::<f64>(fun, libffi_args) };
149+
Scalar::from_f64(x.to_soft())
150+
}
141151
// Functions with no declared return type (i.e., the default return)
142152
// have the output_type `Tuple([])`.
143153
ty::Tuple(t_list) if (*t_list).deref().is_empty() => {
@@ -396,7 +406,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
396406

397407
/// Gets the matching libffi type for a given Ty.
398408
fn ty_to_ffitype(&self, layout: TyAndLayout<'tcx>) -> InterpResult<'tcx, FfiType> {
399-
use rustc_abi::{AddressSpace, BackendRepr, Integer, Primitive};
409+
use rustc_abi::{AddressSpace, BackendRepr, Float, Integer, Primitive};
400410

401411
// `BackendRepr::Scalar` is also a signal to pass this type as a scalar in the ABI. This
402412
// matches what codegen does. This does mean that we support some types whose ABI is not
@@ -413,6 +423,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
413423
Primitive::Int(Integer::I16, /* signed */ false) => FfiType::u16(),
414424
Primitive::Int(Integer::I32, /* signed */ false) => FfiType::u32(),
415425
Primitive::Int(Integer::I64, /* signed */ false) => FfiType::u64(),
426+
Primitive::Float(Float::F32) => FfiType::f32(),
427+
Primitive::Float(Float::F64) => FfiType::f64(),
416428
Primitive::Pointer(AddressSpace::ZERO) => FfiType::pointer(),
417429
_ =>
418430
throw_unsup_format!(

src/tools/miri/tests/native-lib/pass/scalar_arguments.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ extern "C" {
1717
) -> i32;
1818
fn add_short_to_long(x: i16, y: i64) -> i64;
1919
fn get_unsigned_int() -> u32;
20+
fn add_float(x: f32) -> f32;
2021
fn printer();
2122
}
2223

@@ -37,6 +38,9 @@ fn main() {
3738
// test function that returns -10 as an unsigned int
3839
assert_eq!(get_unsigned_int(), (-10i32) as u32);
3940

41+
// test function that adds 1.5 to a f32
42+
assert_eq!(add_float(1.0f32), 2.5f32);
43+
4044
// test void function that prints from C
4145
printer();
4246
}

src/tools/miri/tests/native-lib/scalar_arguments.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ EXPORT int64_t add_short_to_long(int16_t x, int64_t y) {
3030
return x + y;
3131
}
3232

33+
EXPORT float add_float(float x) {
34+
return x + 1.5f;
35+
}
36+
3337
// To test that functions not marked with EXPORT cannot be called by Miri.
3438
int32_t not_exported(void) {
3539
return 0;

0 commit comments

Comments
 (0)