From e6f44d0c8980efd141319698cd3936d841960df6 Mon Sep 17 00:00:00 2001
From: Sergey Fedorov <vital.had@gmail.com>
Date: Mon, 15 Dec 2025 21:28:53 +0800
Subject: [PATCH] Add powerpc*-apple-darwin targets

---
 .../rustc_middle/src/dep_graph/dep_node.rs    |  6 ++++-
 .../rustc_target/src/abi/call/powerpc64.rs    | 11 ++++++++--
 compiler/rustc_target/src/spec/apple_base.rs  |  7 +++++-
 .../rustc_target/src/spec/apple_sdk_base.rs   |  6 ++++-
 compiler/rustc_target/src/spec/mod.rs         |  2 ++
 .../src/spec/powerpc64_apple_darwin.rs        | 22 +++++++++++++++++++
 .../src/spec/powerpc_apple_darwin.rs          | 22 +++++++++++++++++++
 src/tools/build-manifest/src/main.rs          |  4 ++++
 8 files changed, 75 insertions(+), 5 deletions(-)
 create mode 100644 compiler/rustc_target/src/spec/powerpc64_apple_darwin.rs
 create mode 100644 compiler/rustc_target/src/spec/powerpc_apple_darwin.rs

diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index 8476929eaec..46790bb393f 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -287,7 +287,11 @@ pub mod label_strs {
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
 static_assert_size!(DepNode, 18);
 
-#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
+// PowerPC 64-bit build is not tried out.
+#[cfg(any(target_arch = "powerpc", target_arch = "powerpc64"))]
+static_assert_size!(DepNode, 20);
+
+#[cfg(not(any(target_arch = "x86", target_arch = "x86_64", target_arch = "powerpc", target_arch = "powerpc64")))]
 static_assert_size!(DepNode, 24);
 
 pub trait DepNodeExt: Sized {
diff --git a/compiler/rustc_target/src/abi/call/powerpc64.rs b/compiler/rustc_target/src/abi/call/powerpc64.rs
index 8c2a9d09a3d..f883dc76010 100644
--- a/compiler/rustc_target/src/abi/call/powerpc64.rs
+++ b/compiler/rustc_target/src/abi/call/powerpc64.rs
@@ -1,6 +1,8 @@
 // FIXME:
 // Alignment of 128 bit types is not currently handled, this will
 // need to be fixed when PowerPC vector support is added.
+// FIXME:
+// PowerOpen ABI needs to be actually implemented and added to compute_abi_info below.
 
 use crate::abi::call::{ArgAbi, FnAbi, Reg, RegKind, Uniform};
 use crate::abi::{Endian, HasDataLayout, LayoutOf, TyAndLayout, TyAndLayoutMethods};
@@ -8,8 +10,9 @@
 
 #[derive(Debug, Clone, Copy, PartialEq)]
 enum ABI {
-    ELFv1, // original ABI used for powerpc64 (big-endian)
+    ELFv1, // ABI used for powerpc64 (big-endian) on Linux and *BSD
     ELFv2, // newer ABI used for powerpc64le and musl (both endians)
+    PowerOpen, // original AIX and macOS ABI
 }
 use ABI::*;
 
@@ -119,7 +122,11 @@ pub fn compute_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
     Ty: TyAndLayoutMethods<'a, C> + Copy,
     C: LayoutOf<Ty = Ty, TyAndLayout = TyAndLayout<'a, Ty>> + HasDataLayout + HasTargetSpec,
 {
-    let abi = if cx.target_spec().env == "musl" {
+    let abi = if cx.target_spec().is_like_osx {
+        // FIXME: PowerOpen ABI implementation is incomplete
+        // For now, use ELFv1 as a placeholder since it's similar
+        ELFv1
+    } else if cx.target_spec().env == "musl" {
         ELFv2
     } else {
         match cx.data_layout().endian {
diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs
index 8530db179d9..cc8f8e5dd4d 100644
--- a/compiler/rustc_target/src/spec/apple_base.rs
+++ b/compiler/rustc_target/src/spec/apple_base.rs
@@ -71,6 +71,11 @@ pub fn macos_llvm_target(arch: &str) -> String {
     format!("{}-apple-macosx{}.{}.0", arch, major, minor)
 }
 
+// This has to add darwin versions, for LLVM compatibility, but it does not atm.
+pub fn macos_llvm_target_ppc(arch: &str) -> String {
+    format!("{}-apple-darwin", arch)
+}
+
 pub fn macos_link_env_remove() -> Vec<String> {
     let mut env_remove = Vec::with_capacity(2);
     // Remove the `SDKROOT` environment variable if it's clearly set for the wrong platform, which
diff --git a/compiler/rustc_target/src/spec/apple_sdk_base.rs b/compiler/rustc_target/src/spec/apple_sdk_base.rs
index e7f7bb343d0..bd6023125cf 100644
--- a/compiler/rustc_target/src/spec/apple_sdk_base.rs
+++ b/compiler/rustc_target/src/spec/apple_sdk_base.rs
@@ -12,6 +12,8 @@ pub enum Arch {
     X86_64_macabi,
     Arm64_macabi,
     Arm64_sim,
+    PowerPc,
+    PowerPc64,
 }
 
 fn target_cpu(arch: Arch) -> String {
@@ -24,13 +26,15 @@ fn target_cpu(arch: Arch) -> String {
         X86_64_macabi => "core2",
         Arm64_macabi => "apple-a12",
         Arm64_sim => "apple-a12",
+        PowerPc => "ppc",
+        PowerPc64 => "ppc64",
     }
     .to_string()
 }
 
 fn link_env_remove(arch: Arch) -> Vec<String> {
     match arch {
-        Armv7 | Armv7s | Arm64 | I386 | X86_64 | Arm64_sim => {
+        Armv7 | Armv7s | Arm64 | I386 | X86_64 | Arm64_sim | PowerPc | PowerPc64 => {
             vec!["MACOSX_DEPLOYMENT_TARGET".to_string()]
         }
         X86_64_macabi | Arm64_macabi => vec!["IPHONEOS_DEPLOYMENT_TARGET".to_string()],
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 9cfd25600be..5cacc1d02f3 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -790,6 +790,8 @@ fn $module() {
     ("aarch64-apple-darwin", aarch64_apple_darwin),
     ("x86_64-apple-darwin", x86_64_apple_darwin),
     ("i686-apple-darwin", i686_apple_darwin),
+    ("powerpc-apple-darwin", powerpc_apple_darwin),
+    ("powerpc64-apple-darwin", powerpc64_apple_darwin),
 
     ("aarch64-fuchsia", aarch64_fuchsia),
     ("x86_64-fuchsia", x86_64_fuchsia),
diff --git a/compiler/rustc_target/src/spec/powerpc64_apple_darwin.rs b/compiler/rustc_target/src/spec/powerpc64_apple_darwin.rs
new file mode 100644
index 00000000000..8c0031e638f
--- /dev/null
+++ b/compiler/rustc_target/src/spec/powerpc64_apple_darwin.rs
@@ -0,0 +1,21 @@
+use crate::abi::Endian;
+use crate::spec::{LinkerFlavor, Target, TargetOptions};
+
+pub fn target() -> Target {
+    let mut base = super::apple_base::opts("macos");
+    base.cpu = "ppc64".to_string();
+    base.max_atomic_width = Some(64);
+    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "ppc64".to_string()]);
+    base.eliminate_frame_pointer = false;
+
+    let arch = "ppc64";
+    let llvm_target = super::apple_base::macos_llvm_target_ppc(&arch);
+
+    Target {
+        llvm_target,
+        pointer_width: 64,
+        data_layout: "E-m:o-i64:64-n32:64".to_string(),
+        arch: "powerpc64".to_string(),
+        options: TargetOptions { endian: Endian::Big, mcount: "\u{1}mcount".to_string(), ..base },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/powerpc_apple_darwin.rs b/compiler/rustc_target/src/spec/powerpc_apple_darwin.rs
new file mode 100644
index 00000000000..4760423dd8f
--- /dev/null
+++ b/compiler/rustc_target/src/spec/powerpc_apple_darwin.rs
@@ -0,0 +1,21 @@
+use crate::abi::Endian;
+use crate::spec::{LinkerFlavor, Target, TargetOptions};
+
+pub fn target() -> Target {
+    let mut base = super::apple_base::opts("macos");
+    base.cpu = "ppc".to_string();
+    base.max_atomic_width = Some(32);
+    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "ppc".to_string()]);
+    base.eliminate_frame_pointer = false;
+
+    let arch = "ppc";
+    let llvm_target = super::apple_base::macos_llvm_target_ppc(&arch);
+
+    Target {
+        llvm_target,
+        pointer_width: 32,
+        data_layout: "E-m:o-p:32:32-i64:64-n32".to_string(),
+        arch: "powerpc".to_string(),
+        options: TargetOptions { endian: Endian::Big, mcount: "\u{1}mcount".to_string(), ..base },
+    }
+}
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 1e19b7b21d8..7f9b7509680 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -36,7 +36,9 @@
     "mipsisa32r6el-unknown-linux-gnu",
     "mipsisa64r6-unknown-linux-gnuabi64",
     "mipsisa64r6el-unknown-linux-gnuabi64",
+    "powerpc-apple-darwin",
     "powerpc-unknown-linux-gnu",
+    "powerpc64-apple-darwin",
     "powerpc64-unknown-linux-gnu",
     "powerpc64le-unknown-linux-gnu",
     "riscv64gc-unknown-linux-gnu",
@@ -111,7 +113,9 @@
     "mipsel-unknown-linux-gnu",
     "mipsel-unknown-linux-musl",
     "nvptx64-nvidia-cuda",
+    "powerpc-apple-darwin",
     "powerpc-unknown-linux-gnu",
+    "powerpc64-apple-darwin",
     "powerpc64-unknown-linux-gnu",
     "powerpc64le-unknown-linux-gnu",
     "riscv32i-unknown-none-elf",


--- /dev/null
+++ b/vendor/rustc-ap-rustc_target/src/spec/powerpc_apple_darwin.rs
@@ -0,0 +1,21 @@
+use crate::abi::Endian;
+use crate::spec::{LinkerFlavor, Target, TargetOptions};
+
+pub fn target() -> Target {
+    let mut base = super::apple_base::opts("macos");
+    base.cpu = "ppc".to_string();
+    base.max_atomic_width = Some(32);
+    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "ppc".to_string()]);
+    base.eliminate_frame_pointer = false;
+
+    let arch = "ppc";
+    let llvm_target = super::apple_base::macos_llvm_target_ppc(&arch);
+
+    Target {
+        llvm_target,
+        pointer_width: 32,
+        data_layout: "E-m:o-p:32:32-i64:64-n32".to_string(),
+        arch: "powerpc".to_string(),
+        options: TargetOptions { endian: Endian::Big, mcount: "\u{1}mcount".to_string(), ..base },
+    }
+}

--- /dev/null
+++ b/vendor/rustc-ap-rustc_target/src/spec/powerpc64_apple_darwin.rs
@@ -0,0 +1,21 @@
+use crate::abi::Endian;
+use crate::spec::{LinkerFlavor, Target, TargetOptions};
+
+pub fn target() -> Target {
+    let mut base = super::apple_base::opts("macos");
+    base.cpu = "ppc64".to_string();
+    base.max_atomic_width = Some(64);
+    base.pre_link_args.insert(LinkerFlavor::Gcc, vec!["-arch".to_string(), "ppc64".to_string()]);
+    base.eliminate_frame_pointer = false;
+
+    let arch = "ppc64";
+    let llvm_target = super::apple_base::macos_llvm_target_ppc(&arch);
+
+    Target {
+        llvm_target,
+        pointer_width: 64,
+        data_layout: "E-m:o-i64:64-n32:64".to_string(),
+        arch: "powerpc64".to_string(),
+        options: TargetOptions { endian: Endian::Big, mcount: "\u{1}mcount".to_string(), ..base },
+    }
+}

--- a/vendor/rustc-ap-rustc_target/src/spec/mod.rs	2021-07-26 23:20:39.000000000 +0800
+++ b/vendor/rustc-ap-rustc_target/src/spec/mod.rs	2025-12-15 21:26:11.000000000 +0800
@@ -790,6 +790,8 @@
     ("aarch64-apple-darwin", aarch64_apple_darwin),
     ("x86_64-apple-darwin", x86_64_apple_darwin),
     ("i686-apple-darwin", i686_apple_darwin),
+    ("powerpc-apple-darwin", powerpc_apple_darwin),
+    ("powerpc64-apple-darwin", powerpc64_apple_darwin),

     ("aarch64-fuchsia", aarch64_fuchsia),
     ("x86_64-fuchsia", x86_64_fuchsia),

--- a/vendor/target-lexicon/src/targets.rs	2021-07-26 23:20:39.000000000 +0800
+++ b/vendor/target-lexicon/src/targets.rs	2025-12-16 06:46:49.000000000 +0800
@@ -1368,18 +1368,14 @@
             "mips-unknown-linux-uclibc",
             "msp430-none-elf",
             "nvptx64-nvidia-cuda",
-            "powerpc64le-unknown-linux-gnu",
-            "powerpc64le-unknown-linux-musl",
-            "powerpc64-unknown-freebsd",
-            "powerpc64-unknown-linux-gnu",
-            "powerpc64-unknown-linux-musl",
-            "powerpc64-wrs-vxworks",
+            "powerpc-apple-darwin",
             "powerpc-unknown-linux-gnu",
             "powerpc-unknown-linux-gnuspe",
             "powerpc-unknown-linux-musl",
             "powerpc-unknown-netbsd",
             "powerpc-wrs-vxworks",
             "powerpc-wrs-vxworks-spe",
+            "powerpc64-apple-darwin",
             "powerpc64-unknown-freebsd",
             "powerpc64-unknown-linux-gnu",
             "powerpc64-unknown-linux-musl",

--- a/vendor/crossbeam-epoch/no_atomic.rs	2021-07-26 23:20:38.000000000 +0800
+++ b/vendor/crossbeam-epoch/no_atomic.rs	2025-12-16 08:14:17.000000000 +0800
@@ -30,6 +30,7 @@
     "mipsel-unknown-none",
     "mipsisa32r6-unknown-linux-gnu",
     "mipsisa32r6el-unknown-linux-gnu",
+    "powerpc-apple-darwin",
     "powerpc-unknown-linux-gnu",
     "powerpc-unknown-linux-gnuspe",
     "powerpc-unknown-linux-musl",

--- a/vendor/crossbeam-utils/no_atomic.rs	2021-07-26 23:20:38.000000000 +0800
+++ b/vendor/crossbeam-utils/no_atomic.rs	2025-12-20 19:32:47.000000000 +0800
@@ -30,6 +30,7 @@
     "mipsel-unknown-none",
     "mipsisa32r6-unknown-linux-gnu",
     "mipsisa32r6el-unknown-linux-gnu",
+    "powerpc-apple-darwin",
     "powerpc-unknown-linux-gnu",
     "powerpc-unknown-linux-gnuspe",
     "powerpc-unknown-linux-musl",

--- a/vendor/openssl-src/src/lib.rs	2021-07-26 23:20:39.000000000 +0800
+++ b/vendor/openssl-src/src/lib.rs	2025-12-15 21:19:42.000000000 +0800
@@ -248,7 +248,9 @@
             "mips64el-unknown-linux-gnuabi64" => "linux64-mips64",
             "mipsel-unknown-linux-gnu" => "linux-mips32",
             "mipsel-unknown-linux-musl" => "linux-mips32",
+            "powerpc-apple-darwin" => "darwin-ppc-cc",
             "powerpc-unknown-linux-gnu" => "linux-ppc",
+            "powerpc64-apple-darwin" => "darwin-ppc64-cc",
             "powerpc64-unknown-freebsd" => "BSD-generic64",
             "powerpc64-unknown-linux-gnu" => "linux-ppc64",
             "powerpc64le-unknown-freebsd" => "BSD-generic64",

--- a/vendor/cc/src/lib.rs	2025-12-19 11:31:10.000000000 +0800
+++ b/vendor/cc/src/lib.rs	2025-12-19 11:32:05.000000000 +0800
@@ -3086,6 +3086,12 @@
         Some("arm64e")
     } else if target.contains("aarch64") {
         Some("arm64")
+    } else if target.contains("powerpc64") || target.contains("ppc64") {
+        Some("ppc64")
+    } else if target.contains("powerpc") || target.contains("ppc") {
+        Some("ppc")
+    } else if target.contains("i686") {
+        Some("i386")
     } else {
         None
     }
