diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-10-11 15:36:51 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-11 15:36:51 +0200 |
| commit | fc81a7c1d58468e0380e6d396ffebed694e7bd56 (patch) | |
| tree | 37485aecf00f076d61b3670fce4cd83b44f8e9ce /compiler | |
| parent | 7c79621462e724d123fb5788e5d797067f5f1222 (diff) | |
| parent | e502a7f13a4605503e1b73cfdfb69d64d11ea722 (diff) | |
| download | rust-fc81a7c1d58468e0380e6d396ffebed694e7bd56.tar.gz rust-fc81a7c1d58468e0380e6d396ffebed694e7bd56.zip | |
Rollup merge of #131208 - mustartt:aix-call-abi, r=davidtwco
ABI: Pass aggregates by value on AIX On AIX we pass aggregates byval. Adds new ABI for AIX for powerpc64. https://github.com/llvm/llvm-project/blob/313ad85dfa40a18f2edefd7ce2edc0528d5a554a/clang/lib/CodeGen/Targets/PPC.cpp#L216 Fixes the following 2 testcases on AIX: ``` tests/ui/abi/extern/extern-pass-TwoU16s.rs tests/ui/abi/extern/extern-pass-TwoU8s.rs ```
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_target/src/abi/call/powerpc64.rs | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/compiler/rustc_target/src/abi/call/powerpc64.rs b/compiler/rustc_target/src/abi/call/powerpc64.rs index b9767bf906b..71e533b8cc5 100644 --- a/compiler/rustc_target/src/abi/call/powerpc64.rs +++ b/compiler/rustc_target/src/abi/call/powerpc64.rs @@ -10,6 +10,7 @@ use crate::spec::HasTargetSpec; enum ABI { ELFv1, // original ABI used for powerpc64 (big-endian) ELFv2, // newer ABI used for powerpc64le and musl (both endians) + AIX, // used by AIX OS, big-endian only } use ABI::*; @@ -23,9 +24,9 @@ where C: HasDataLayout, { arg.layout.homogeneous_aggregate(cx).ok().and_then(|ha| ha.unit()).and_then(|unit| { - // ELFv1 only passes one-member aggregates transparently. + // ELFv1 and AIX only passes one-member aggregates transparently. // ELFv2 passes up to eight uniquely addressable members. - if (abi == ELFv1 && arg.layout.size > unit.size) + if ((abi == ELFv1 || abi == AIX) && arg.layout.size > unit.size) || arg.layout.size > unit.size.checked_mul(8, cx).unwrap() { return None; @@ -55,8 +56,15 @@ where return; } + // The AIX ABI expect byval for aggregates + // See https://github.com/llvm/llvm-project/blob/main/clang/lib/CodeGen/Targets/PPC.cpp. + if !is_ret && abi == AIX { + arg.pass_by_stack_offset(None); + return; + } + // The ELFv1 ABI doesn't return aggregates in registers - if is_ret && abi == ELFv1 { + if is_ret && (abi == ELFv1 || abi == AIX) { arg.make_indirect(); return; } @@ -93,6 +101,8 @@ where { let abi = if cx.target_spec().env == "musl" { ELFv2 + } else if cx.target_spec().os == "aix" { + AIX } else { match cx.data_layout().endian { Endian::Big => ELFv1, |
