Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit d2a6139

Browse files
committedNov 16, 2024
aarch64 softfloat target: always pass floats in int registers
1 parent 46e8d20 commit d2a6139

File tree

4 files changed

+65
-3
lines changed

4 files changed

+65
-3
lines changed
 

‎compiler/rustc_target/src/callconv/aarch64.rs

+36-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
use std::iter;
2+
3+
use rustc_abi::{BackendRepr, Primitive};
4+
15
use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
26
use crate::abi::{HasDataLayout, TyAbiInterface};
7+
use crate::spec::{HasTargetSpec, Target};
38

49
/// Indicates the variant of the AArch64 ABI we are compiling for.
510
/// Used to accommodate Apple and Microsoft's deviations from the usual AAPCS ABI.
@@ -35,10 +40,25 @@ where
3540
})
3641
}
3742

43+
fn softfloat_float_abi<Ty>(target: &Target, arg: &mut ArgAbi<'_, Ty>) {
44+
if let BackendRepr::Scalar(s) = arg.layout.backend_repr
45+
&& let Primitive::Float(f) = s.primitive()
46+
{
47+
if target.abi == "softfloat" {
48+
// Do *not* use the floag registers for passing arguments, as that would make
49+
// the ABI depend on whether `neon` instructions are enabled.
50+
// Apparently there is no standard ABI here [1], so we can do whatever we want.
51+
// We choose to pass floats via equal-sized integer registers.
52+
// [1]: https://github.com/rust-lang/rust/issues/131058#issuecomment-2384960972
53+
arg.cast_to(Reg { kind: RegKind::Integer, size: f.size() });
54+
}
55+
}
56+
}
57+
3858
fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, kind: AbiKind)
3959
where
4060
Ty: TyAbiInterface<'a, C> + Copy,
41-
C: HasDataLayout,
61+
C: HasDataLayout + HasTargetSpec,
4262
{
4363
if !ret.layout.is_sized() {
4464
// Not touching this...
@@ -51,6 +71,7 @@ where
5171
// See also: <https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Pass-Arguments-to-Functions-Correctly>
5272
ret.extend_integer_width_to(32)
5373
}
74+
softfloat_float_abi(cx.target_spec(), ret);
5475
return;
5576
}
5677
if let Some(uniform) = is_homogeneous_aggregate(cx, ret) {
@@ -69,7 +90,7 @@ where
6990
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, kind: AbiKind)
7091
where
7192
Ty: TyAbiInterface<'a, C> + Copy,
72-
C: HasDataLayout,
93+
C: HasDataLayout + HasTargetSpec,
7394
{
7495
if !arg.layout.is_sized() {
7596
// Not touching this...
@@ -82,6 +103,8 @@ where
82103
// See also: <https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Pass-Arguments-to-Functions-Correctly>
83104
arg.extend_integer_width_to(32);
84105
}
106+
softfloat_float_abi(cx.target_spec(), arg);
107+
85108
return;
86109
}
87110
if let Some(uniform) = is_homogeneous_aggregate(cx, arg) {
@@ -112,7 +135,7 @@ where
112135
pub(crate) fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, kind: AbiKind)
113136
where
114137
Ty: TyAbiInterface<'a, C> + Copy,
115-
C: HasDataLayout,
138+
C: HasDataLayout + HasTargetSpec,
116139
{
117140
if !fn_abi.ret.is_ignore() {
118141
classify_ret(cx, &mut fn_abi.ret, kind);
@@ -125,3 +148,13 @@ where
125148
classify_arg(cx, arg, kind);
126149
}
127150
}
151+
152+
pub(crate) fn compute_rust_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
153+
where
154+
Ty: TyAbiInterface<'a, C> + Copy,
155+
C: HasDataLayout + HasTargetSpec,
156+
{
157+
for arg in fn_abi.args.iter_mut().chain(iter::once(&mut fn_abi.ret)) {
158+
softfloat_float_abi(cx.target_spec(), arg);
159+
}
160+
}

‎compiler/rustc_target/src/callconv/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
738738
"x86" => x86::compute_rust_abi_info(cx, self, abi),
739739
"riscv32" | "riscv64" => riscv::compute_rust_abi_info(cx, self, abi),
740740
"loongarch64" => loongarch::compute_rust_abi_info(cx, self, abi),
741+
"aarch64" => aarch64::compute_rust_abi_info(cx, self),
741742
_ => {}
742743
};
743744

‎tests/codegen/aarch64-softfloat.rs

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//@ compile-flags: --target aarch64-unknown-none-softfloat
2+
//@ needs-llvm-components: aarch64
3+
#![crate_type = "lib"]
4+
#![feature(no_core, lang_items)]
5+
#![no_core]
6+
7+
#[lang = "sized"]
8+
trait Sized {}
9+
#[lang = "copy"]
10+
trait Copy {}
11+
impl Copy for f64 {}
12+
13+
// CHECK: i64 @pass_f64_C(i64
14+
#[no_mangle]
15+
extern "C" fn pass_f64_C(x: f64) -> f64 {
16+
x
17+
}
18+
19+
// CHECK: i64 @pass_f64_Rust(i64
20+
#[no_mangle]
21+
fn pass_f64_Rust(x: f64, _y: f64) -> f64 {
22+
x
23+
}

‎tests/ui/abi/aarch64-softfloat.rs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
//@ compile-flags: --target aarch64-unknown-linux-gnu
2+
//@ needs-llvm-components: aarch64
3+
#![feature(no_core, lang_items)]
4+
#![no_core]
5+

0 commit comments

Comments
 (0)
Failed to load comments.