Skip to content

Commit 8ae5a55

Browse files
committed
fix issue 97463 using change suggested by nbdd0121.
parameterized on target details to decide value-extension policy on calls, in order to address how Apple's aarch64 ABI differs from that on Linux and Windows. Updated to incorporate review feedback: adjust comment on new enum specifying param extension policy. Updated to incorporate review feedback: shorten enum names and those of its variants to make it less unwieldy. placate tidy.
1 parent b2777ab commit 8ae5a55

File tree

3 files changed

+44
-8
lines changed

3 files changed

+44
-8
lines changed

compiler/rustc_target/src/abi/call/aarch64.rs

+34-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,27 @@
11
use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
22
use crate::abi::{HasDataLayout, TyAbiInterface};
33

4+
/// Given integer-types M and register width N (e.g. M=u16 and N=32 bits), the
5+
/// `ParamExtension` policy specifies how a uM value should be treated when
6+
/// passed via register or stack-slot of width N. See also rust-lang/rust#97463.
7+
#[derive(Copy, Clone, PartialEq)]
8+
pub enum ParamExtension {
9+
/// Indicates that when passing an i8/i16, either as a function argument or
10+
/// as a return value, it must be sign-extended to 32 bits, and likewise a
11+
/// u8/u16 must be zero-extended to 32-bits. (This variant is here to
12+
/// accommodate Apple's deviation from the usual AArch64 ABI as defined by
13+
/// ARM.)
14+
///
15+
/// See also: https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms#Pass-Arguments-to-Functions-Correctly
16+
ExtendTo32Bits,
17+
18+
/// Indicates that no sign- nor zero-extension is performed: if a value of
19+
/// type with bitwidth M is passed as function argument or return value,
20+
/// then M bits are copied into the least significant M bits, and the
21+
/// remaining bits of the register (or word of memory) are untouched.
22+
NoExtension,
23+
}
24+
425
fn is_homogeneous_aggregate<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>) -> Option<Uniform>
526
where
627
Ty: TyAbiInterface<'a, C> + Copy,
@@ -24,13 +45,16 @@ where
2445
})
2546
}
2647

27-
fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>)
48+
fn classify_ret<'a, Ty, C>(cx: &C, ret: &mut ArgAbi<'a, Ty>, param_policy: ParamExtension)
2849
where
2950
Ty: TyAbiInterface<'a, C> + Copy,
3051
C: HasDataLayout,
3152
{
3253
if !ret.layout.is_aggregate() {
33-
ret.extend_integer_width_to(32);
54+
match param_policy {
55+
ParamExtension::ExtendTo32Bits => ret.extend_integer_width_to(32),
56+
ParamExtension::NoExtension => {}
57+
}
3458
return;
3559
}
3660
if let Some(uniform) = is_homogeneous_aggregate(cx, ret) {
@@ -46,13 +70,16 @@ where
4670
ret.make_indirect();
4771
}
4872

49-
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>)
73+
fn classify_arg<'a, Ty, C>(cx: &C, arg: &mut ArgAbi<'a, Ty>, param_policy: ParamExtension)
5074
where
5175
Ty: TyAbiInterface<'a, C> + Copy,
5276
C: HasDataLayout,
5377
{
5478
if !arg.layout.is_aggregate() {
55-
arg.extend_integer_width_to(32);
79+
match param_policy {
80+
ParamExtension::ExtendTo32Bits => arg.extend_integer_width_to(32),
81+
ParamExtension::NoExtension => {}
82+
}
5683
return;
5784
}
5885
if let Some(uniform) = is_homogeneous_aggregate(cx, arg) {
@@ -68,19 +95,19 @@ where
6895
arg.make_indirect();
6996
}
7097

71-
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
98+
pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>, param_policy: ParamExtension)
7299
where
73100
Ty: TyAbiInterface<'a, C> + Copy,
74101
C: HasDataLayout,
75102
{
76103
if !fn_abi.ret.is_ignore() {
77-
classify_ret(cx, &mut fn_abi.ret);
104+
classify_ret(cx, &mut fn_abi.ret, param_policy);
78105
}
79106

80107
for arg in &mut fn_abi.args {
81108
if arg.is_ignore() {
82109
continue;
83110
}
84-
classify_arg(cx, arg);
111+
classify_arg(cx, arg, param_policy);
85112
}
86113
}

compiler/rustc_target/src/abi/call/mod.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,14 @@ impl<'a, Ty> FnAbi<'a, Ty> {
687687
}
688688
}
689689
},
690-
"aarch64" => aarch64::compute_abi_info(cx, self),
690+
"aarch64" => {
691+
let param_policy = if cx.target_spec().is_like_osx {
692+
aarch64::ParamExtension::ExtendTo32Bits
693+
} else {
694+
aarch64::ParamExtension::NoExtension
695+
};
696+
aarch64::compute_abi_info(cx, self, param_policy)
697+
}
691698
"amdgpu" => amdgpu::compute_abi_info(cx, self),
692699
"arm" => arm::compute_abi_info(cx, self),
693700
"avr" => avr::compute_abi_info(self),

compiler/rustc_target/src/spec/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1250,6 +1250,8 @@ pub struct TargetOptions {
12501250
pub abi_return_struct_as_int: bool,
12511251
/// Whether the target toolchain is like macOS's. Only useful for compiling against iOS/macOS,
12521252
/// in particular running dsymutil and some other stuff like `-dead_strip`. Defaults to false.
1253+
/// Also indiates whether to use Apple-specific ABI changes, such as extending function
1254+
/// parameters to 32-bits.
12531255
pub is_like_osx: bool,
12541256
/// Whether the target toolchain is like Solaris's.
12551257
/// Only useful for compiling against Illumos/Solaris,

0 commit comments

Comments
 (0)