about summary refs log tree commit diff
path: root/compiler/rustc_target/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_target/src')
-rw-r--r--compiler/rustc_target/src/abi/call/powerpc64.rs16
-rw-r--r--compiler/rustc_target/src/target_features.rs4
2 files changed, 16 insertions, 4 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,
diff --git a/compiler/rustc_target/src/target_features.rs b/compiler/rustc_target/src/target_features.rs
index 0a98b363b1a..e92366d5c5c 100644
--- a/compiler/rustc_target/src/target_features.rs
+++ b/compiler/rustc_target/src/target_features.rs
@@ -191,6 +191,8 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     ("sm4", Stable, &["neon"]),
     // FEAT_SME
     ("sme", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
+    // FEAT_SME_B16B16
+    ("sme-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16", "sme2", "sve-b16b16"]),
     // FEAT_SME_F16F16
     ("sme-f16f16", Unstable(sym::aarch64_unstable_target_feature), &["sme2"]),
     // FEAT_SME_F64F64
@@ -227,7 +229,7 @@ const AARCH64_ALLOWED_FEATURES: &[(&str, Stability, ImpliedFeatures)] = &[
     //
     // "For backwards compatibility, Neon and VFP are required in the latest architectures."
     ("sve", Stable, &["neon"]),
-    // FEAT_SVE_B16B16 (SVE or SME Instructions)
+    // FEAT_SVE_B16B16 (SVE or SME Z-targeting instructions)
     ("sve-b16b16", Unstable(sym::aarch64_unstable_target_feature), &["bf16"]),
     // FEAT_SVE2
     ("sve2", Stable, &["sve"]),