Skip to content

Instantly share code, notes, and snippets.

@colemancda
Last active May 25, 2022 15:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save colemancda/6bc88cb7fb1f0a5c7853eb578c634461 to your computer and use it in GitHub Desktop.
Save colemancda/6bc88cb7fb1f0a5c7853eb578c634461 to your computer and use it in GitHub Desktop.
Swift 5.6 patched for PowerPC 32-bit
diff --git a/CMakeLists.txt b/CMakeLists.txt
index bc9b6790922..734d2dae23f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -709,6 +709,8 @@ else()
endif()
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64")
set(SWIFT_HOST_VARIANT_ARCH_default "powerpc64")
+ elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc")
+ set(SWIFT_HOST_VARIANT_ARCH_default "powerpc")
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64le")
set(SWIFT_HOST_VARIANT_ARCH_default "powerpc64le")
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "s390x")
diff --git a/cmake/modules/SwiftConfigureSDK.cmake b/cmake/modules/SwiftConfigureSDK.cmake
index 3c866f2e65c..da405660415 100644
--- a/cmake/modules/SwiftConfigureSDK.cmake
+++ b/cmake/modules/SwiftConfigureSDK.cmake
@@ -325,7 +325,7 @@ macro(configure_sdk_unix name architectures)
if("${prefix}" STREQUAL "LINUX")
if(arch MATCHES "(armv6|armv7)")
set(SWIFT_SDK_LINUX_ARCH_${arch}_TRIPLE "${arch}-unknown-linux-gnueabihf")
- elseif(arch MATCHES "(aarch64|i686|powerpc64|powerpc64le|s390x|x86_64)")
+ elseif(arch MATCHES "(aarch64|i686|powerpc|powerpc64|powerpc64le|s390x|x86_64)")
set(SWIFT_SDK_LINUX_ARCH_${arch}_TRIPLE "${arch}-unknown-linux-gnu")
else()
message(FATAL_ERROR "unknown arch for ${prefix}: ${arch}")
diff --git a/cmake/modules/SwiftSetIfArchBitness.cmake b/cmake/modules/SwiftSetIfArchBitness.cmake
index fa29d77fe26..8880828bfd1 100644
--- a/cmake/modules/SwiftSetIfArchBitness.cmake
+++ b/cmake/modules/SwiftSetIfArchBitness.cmake
@@ -14,7 +14,8 @@ function(set_if_arch_bitness var_name)
"${SIA_ARCH}" STREQUAL "armv7k" OR
"${SIA_ARCH}" STREQUAL "arm64_32" OR
"${SIA_ARCH}" STREQUAL "armv7s" OR
- "${SIA_ARCH}" STREQUAL "wasm32")
+ "${SIA_ARCH}" STREQUAL "wasm32" OR
+ "${SIA_ARCH}" STREQUAL "powerpc")
set("${var_name}" "${SIA_CASE_32_BIT}" PARENT_SCOPE)
elseif("${SIA_ARCH}" STREQUAL "x86_64" OR
"${SIA_ARCH}" STREQUAL "amd64" OR
diff --git a/lib/Basic/LangOptions.cpp b/lib/Basic/LangOptions.cpp
index b9e8b488d9c..5669fa746e1 100644
--- a/lib/Basic/LangOptions.cpp
+++ b/lib/Basic/LangOptions.cpp
@@ -62,6 +62,7 @@ static const SupportedConditionalValue SupportedConditionalCompilationArches[] =
"arm64_32",
"i386",
"x86_64",
+ "powerpc",
"powerpc64",
"powerpc64le",
"s390x",
@@ -312,6 +313,9 @@ std::pair<bool, bool> LangOptions::setTarget(llvm::Triple triple) {
addPlatformConditionValue(PlatformConditionKind::Arch, "arm64");
}
break;
+ case llvm::Triple::ArchType::ppc:
+ addPlatformConditionValue(PlatformConditionKind::Arch, "powerpc");
+ break;
case llvm::Triple::ArchType::ppc64:
addPlatformConditionValue(PlatformConditionKind::Arch, "powerpc64");
break;
@@ -350,6 +354,7 @@ std::pair<bool, bool> LangOptions::setTarget(llvm::Triple triple) {
case llvm::Triple::ArchType::x86_64:
addPlatformConditionValue(PlatformConditionKind::Endianness, "little");
break;
+ case llvm::Triple::ArchType::ppc:
case llvm::Triple::ArchType::ppc64:
case llvm::Triple::ArchType::systemz:
addPlatformConditionValue(PlatformConditionKind::Endianness, "big");
diff --git a/lib/IRGen/SwiftTargetInfo.cpp b/lib/IRGen/SwiftTargetInfo.cpp
index 81c0fce41bc..97b70d6d75c 100644
--- a/lib/IRGen/SwiftTargetInfo.cpp
+++ b/lib/IRGen/SwiftTargetInfo.cpp
@@ -144,6 +144,13 @@ static void configureARM(IRGenModule &IGM, const llvm::Triple &triple,
setToMask(target.IsObjCPointerBit, 32, SWIFT_ABI_ARM_IS_OBJC_BIT);
}
+/// Configures target-specific information for powerpc platforms.
+static void configurePowerPC(IRGenModule &IGM, const llvm::Triple &triple,
+ SwiftTargetInfo &target) {
+ setToMask(target.PointerSpareBits, 32,
+ SWIFT_ABI_POWERPC_SWIFT_SPARE_BITS_MASK);
+}
+
/// Configures target-specific information for powerpc64 platforms.
static void configurePowerPC64(IRGenModule &IGM, const llvm::Triple &triple,
SwiftTargetInfo &target) {
@@ -220,6 +227,10 @@ SwiftTargetInfo SwiftTargetInfo::get(IRGenModule &IGM) {
else
configureARM64(IGM, triple, target);
break;
+
+ case llvm::Triple::ppc:
+ configurePowerPC(IGM, triple, target);
+ break;
case llvm::Triple::ppc64:
case llvm::Triple::ppc64le:
diff --git a/stdlib/public/SwiftShims/HeapObject.h b/stdlib/public/SwiftShims/HeapObject.h
index 5e165fd3d4e..cea7477a31e 100644
--- a/stdlib/public/SwiftShims/HeapObject.h
+++ b/stdlib/public/SwiftShims/HeapObject.h
@@ -202,6 +202,9 @@ static_assert(alignof(HeapObject) == alignof(void*),
(defined(__arm64__) && (__POINTER_WIDTH__ == 32))
#define _swift_abi_SwiftSpareBitsMask \
(__swift_uintptr_t) SWIFT_ABI_ARM_SWIFT_SPARE_BITS_MASK
+#elif defined(__powerpc__)
+#define _swift_abi_SwiftSpareBitsMask \
+ (__swift_uintptr_t) SWIFT_ABI_POWERPC_SWIFT_SPARE_BITS_MASK
#else
#define _swift_abi_SwiftSpareBitsMask \
(__swift_uintptr_t) SWIFT_ABI_DEFAULT_SWIFT_SPARE_BITS_MASK
diff --git a/stdlib/public/SwiftShims/RefCount.h b/stdlib/public/SwiftShims/RefCount.h
index fc067f70f55..27a6d22cf47 100644
--- a/stdlib/public/SwiftShims/RefCount.h
+++ b/stdlib/public/SwiftShims/RefCount.h
@@ -1319,7 +1319,12 @@ class HeapObjectSideTableEntry {
public:
HeapObjectSideTableEntry(HeapObject *newObject)
- : object(newObject), refCounts()
+ : object(newObject),
+#if __arm__ || __powerpc__
+ refCounts(SideTableRefCounts::Initialized)
+#else
+ refCounts()
+#endif
{ }
#pragma clang diagnostic push
diff --git a/stdlib/public/SwiftShims/System.h b/stdlib/public/SwiftShims/System.h
index 8fe54f6bda5..978ec41f1ea 100644
--- a/stdlib/public/SwiftShims/System.h
+++ b/stdlib/public/SwiftShims/System.h
@@ -173,6 +173,11 @@
#define SWIFT_ABI_ARM64_OBJC_WEAK_REFERENCE_MARKER_VALUE \
(1<<SWIFT_ABI_ARM64_OBJC_NUM_RESERVED_LOW_BITS)
+/*********************************** powerpc ********************************/
+
+// Heap objects are pointer-aligned, so the low two bits are unused.
+#define SWIFT_ABI_POWERPC_SWIFT_SPARE_BITS_MASK 0x00000003U
+
/*********************************** powerpc64 ********************************/
// Heap objects are pointer-aligned, so the low three bits are unused.
diff --git a/stdlib/public/core/AtomicInt.swift.gyb b/stdlib/public/core/AtomicInt.swift.gyb
index a66212f4b35..56fed2cb117 100644
--- a/stdlib/public/core/AtomicInt.swift.gyb
+++ b/stdlib/public/core/AtomicInt.swift.gyb
@@ -65,7 +65,7 @@ internal func _swift_stdlib_atomicCompareExchangeStrongInt(
object target: UnsafeMutablePointer<Int>,
expected: UnsafeMutablePointer<Int>,
desired: Int) -> Bool {
-#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
+#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) || arch(powerpc)
let (oldValue, won) = Builtin.cmpxchg_seqcst_seqcst_Int32(
target._rawValue, expected.pointee._value, desired._value)
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
@@ -82,7 +82,7 @@ internal func _swift_stdlib_atomicCompareExchangeStrongInt(
public // Existing uses outside stdlib
func _swift_stdlib_atomicLoadInt(
object target: UnsafeMutablePointer<Int>) -> Int {
-#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
+#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) || arch(powerpc)
let value = Builtin.atomicload_seqcst_Int32(target._rawValue)
return Int(value)
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
@@ -95,7 +95,7 @@ func _swift_stdlib_atomicLoadInt(
internal func _swift_stdlib_atomicStoreInt(
object target: UnsafeMutablePointer<Int>,
desired: Int) {
-#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
+#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) || arch(powerpc)
Builtin.atomicstore_seqcst_Int32(target._rawValue, desired._value)
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
Builtin.atomicstore_seqcst_Int64(target._rawValue, desired._value)
@@ -111,7 +111,7 @@ func _swift_stdlib_atomicFetch${operation}Int(
object target: UnsafeMutablePointer<Int>,
operand: Int) -> Int {
let rawTarget = UnsafeMutableRawPointer(target)
-#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32)
+#if arch(i386) || arch(arm) || arch(arm64_32) || arch(wasm32) || arch(powerpc)
let value = _swift_stdlib_atomicFetch${operation}Int32(
object: rawTarget.assumingMemoryBound(to: Int32.self),
operand: Int32(operand))
diff --git a/stdlib/public/core/Builtin.swift b/stdlib/public/core/Builtin.swift
index 8a7bb33243a..b1675ee89fc 100644
--- a/stdlib/public/core/Builtin.swift
+++ b/stdlib/public/core/Builtin.swift
@@ -388,7 +388,7 @@ internal var _objectPointerLowSpareBitShift: UInt {
}
}
-#if arch(i386) || arch(arm) || arch(wasm32) || arch(powerpc64) || arch(
+#if arch(i386) || arch(arm) || arch(wasm32) || arch(powerpc) || arch(powerpc64) || arch(
powerpc64le) || arch(s390x) || arch(arm64_32)
@inlinable
internal var _objectPointerIsObjCBit: UInt {
diff --git a/stdlib/public/runtime/Float16Support.cpp b/stdlib/public/runtime/Float16Support.cpp
index 817739d4cdf..c55ed8b58f2 100644
--- a/stdlib/public/runtime/Float16Support.cpp
+++ b/stdlib/public/runtime/Float16Support.cpp
@@ -15,6 +15,7 @@
// __gnu_h2f_ieee
// __gnu_f2h_ieee
// __truncdfhf2
+// __multi3
//
// On Darwin platforms, these are provided by the host compiler-rt, but we
// can't depend on that everywhere, so we have to provide them in the Swift
@@ -27,12 +28,66 @@
//
//===----------------------------------------------------------------------===//
+#include "../SwiftShims/Visibility.h"
+#include <endian.h>
+#include <stdint.h>
+#include <climits>
+
+// PowerPC 32-bit Glibc does not provide __multi3
+#if defined(__powerpc__)
+
+typedef int int128_t __attribute__((mode(TI)));
+typedef unsigned int uint128_t __attribute__((mode(TI)));
+
+typedef union {
+ int128_t all;
+ struct {
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+ uint64_t low;
+ int64_t high;
+#else
+ int64_t high;
+ uint64_t low;
+#endif
+ } s;
+} twords;
+
+SWIFT_RUNTIME_EXPORT int64_t __mulddi3(uint64_t a, uint64_t b) {
+ twords r;
+ const int bits_in_dword_2 = (int)(sizeof(int64_t) * CHAR_BIT) / 2;
+ const uint64_t lower_mask = (uint64_t)~0 >> bits_in_dword_2;
+ r.s.low = (a & lower_mask) * (b & lower_mask);
+ uint64_t t = r.s.low >> bits_in_dword_2;
+ r.s.low &= lower_mask;
+ t += (a >> bits_in_dword_2) * (b & lower_mask);
+ r.s.low += (t & lower_mask) << bits_in_dword_2;
+ r.s.high = t >> bits_in_dword_2;
+ t = r.s.low >> bits_in_dword_2;
+ r.s.low &= lower_mask;
+ t += (b >> bits_in_dword_2) * (a & lower_mask);
+ r.s.low += (t & lower_mask) << bits_in_dword_2;
+ r.s.high += t >> bits_in_dword_2;
+ r.s.high += (a >> bits_in_dword_2) * (b >> bits_in_dword_2);
+ return r.all;
+}
+
+SWIFT_RUNTIME_EXPORT int64_t __multi3(int128_t a, int128_t b) {
+ twords x;
+ x.all = a;
+ twords y;
+ y.all = b;
+ twords r;
+ r.all = __mulddi3(x.s.low, y.s.low);
+ r.s.high += x.s.high * y.s.low + x.s.low * y.s.high;
+ return r.all;
+}
+
+#endif
+
// Android NDK <r21 do not provide `__aeabi_d2h` in the compiler runtime,
// provide shims in that case.
#if (defined(__ANDROID__) && defined(__ARM_ARCH_7A__) && defined(__ARM_EABI__)) || \
- ((defined(__i386__) || defined(__i686__) || defined(__x86_64__)) && !defined(__APPLE__))
-
-#include "../SwiftShims/Visibility.h"
+ ((defined(__i386__) || defined(__i686__) || defined(__x86_64__)|| defined(__powerpc__)) && !defined(__APPLE__))
static unsigned toEncoding(float f) {
unsigned e;
diff --git a/stdlib/public/stubs/MathStubs.cpp b/stdlib/public/stubs/MathStubs.cpp
index 8d0617089ca..1f0c8693c29 100644
--- a/stdlib/public/stubs/MathStubs.cpp
+++ b/stdlib/public/stubs/MathStubs.cpp
@@ -112,7 +112,7 @@ __muloti4(ti_int a, ti_int b, int* overflow)
// lowered to instructions as though MSVC had generated. There does not seem to
// be a MSVC provided multiply with overflow detection that I can see, but this
// avoids an unnecessary dependency on compiler-rt for a single function.
-#if (defined(__linux__) && (defined(__arm__) || defined(__i386__))) || defined(_WIN32)
+#if (defined(__linux__) && (defined(__arm__) || defined(__i386__) || defined(__powerpc__))) || defined(_WIN32)
// Similar to above, but with mulodi4. Perhaps this is
// something that shouldn't be done, and is a bandaid over
diff --git a/test/Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift b/test/Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
index dbb14cebc2a..dbb0ccc70c7 100644
--- a/test/Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
+++ b/test/Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
@@ -6,7 +6,7 @@ public func == (lhs: CGPoint, rhs: CGPoint) -> Bool {
}
public struct CGFloat {
-#if arch(i386) || arch(arm) || arch(arm64_32)
+#if arch(i386) || arch(arm) || arch(arm64_32) || arch(powerpc)
public typealias UnderlyingType = Float
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64le) || arch(s390x)
public typealias UnderlyingType = Double
diff --git a/test/Interpreter/builtin_bridge_object.swift b/test/Interpreter/builtin_bridge_object.swift
index c6ee1908252..a33c1fb1ed8 100644
--- a/test/Interpreter/builtin_bridge_object.swift
+++ b/test/Interpreter/builtin_bridge_object.swift
@@ -13,7 +13,7 @@ class C {
deinit { print("deallocated") }
}
-#if arch(i386) || arch(arm) || arch(arm64_32)
+#if arch(i386) || arch(arm) || arch(arm64_32) || arch(powerpc)
// We have no ObjC tagged pointers, and two low spare bits due to alignment.
let NATIVE_SPARE_BITS: UInt = 0x0000_0003
diff --git a/test/stdlib/Inputs/FloatingPointConversion.swift.gyb b/test/stdlib/Inputs/FloatingPointConversion.swift.gyb
index e95d1ca5b5f..433c2327338 100644
--- a/test/stdlib/Inputs/FloatingPointConversion.swift.gyb
+++ b/test/stdlib/Inputs/FloatingPointConversion.swift.gyb
@@ -134,7 +134,7 @@ FloatingPointConversionFailures.test("${OtherFloat}To${Self}Conversion/AlwaysSuc
% end # for in all_floating_point_types (Other)
-#if arch(i386) || arch(arm) || arch(arm64_32)
+#if arch(i386) || arch(arm) || arch(arm64_32) || arch(powerpc)
% int_types = all_integer_types(32)
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
% int_types = all_integer_types(64)
diff --git a/test/stdlib/Runtime.swift.gyb b/test/stdlib/Runtime.swift.gyb
index ee04dfc4082..0df1e6398e2 100644
--- a/test/stdlib/Runtime.swift.gyb
+++ b/test/stdlib/Runtime.swift.gyb
@@ -684,7 +684,7 @@ Reflection.test("multiprotocolTypes") {
var BitTwiddlingTestSuite = TestSuite("BitTwiddling")
BitTwiddlingTestSuite.test("_pointerSize") {
-#if arch(i386) || arch(arm) || arch(arm64_32)
+#if arch(i386) || arch(arm) || arch(arm64_32) || arch(powerpc)
expectEqual(4, MemoryLayout<Optional<AnyObject>>.size)
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
expectEqual(8, MemoryLayout<Optional<AnyObject>>.size)
@@ -708,7 +708,7 @@ BitTwiddlingTestSuite.test("_isPowerOf2/Int") {
expectTrue(_isPowerOf2(asInt(2)))
expectFalse(_isPowerOf2(asInt(3)))
expectTrue(_isPowerOf2(asInt(1024)))
-#if arch(i386) || arch(arm) || arch(arm64_32)
+#if arch(i386) || arch(arm) || arch(arm64_32) || arch(powerpc)
// Not applicable to 32-bit architectures.
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
expectTrue(_isPowerOf2(asInt(0x8000_0000)))
diff --git a/test/stdlib/UnsafePointer.swift.gyb b/test/stdlib/UnsafePointer.swift.gyb
index 4820dd87f94..ecb953e6c0f 100644
--- a/test/stdlib/UnsafePointer.swift.gyb
+++ b/test/stdlib/UnsafePointer.swift.gyb
@@ -401,7 +401,7 @@ ${SelfName}TestSuite.test("customMirror") {
let ptr = ${SelfType}(bitPattern: reallyBigInt)!
let mirror = ptr.customMirror
expectEqual(1, mirror.children.count)
-#if arch(i386) || arch(arm) || arch(arm64_32)
+#if arch(i386) || arch(arm) || arch(arm64_32) || arch(powerpc)
expectEqual("18446744071562067968", String(describing: mirror.children.first!.1))
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
expectEqual("9223372036854775808", String(describing: mirror.children.first!.1))
@@ -416,7 +416,7 @@ ${SelfName}TestSuite.test("customPlaygroundQuickLook") {
let reallyBigInt: UInt = UInt(Int.max) + 1
let ptr = ${SelfType}(bitPattern: reallyBigInt)!
if case let .text(desc) = ptr.customPlaygroundQuickLook {
-#if arch(i386) || arch(arm) || arch(arm64_32)
+#if arch(i386) || arch(arm) || arch(arm64_32) || arch(powerpc)
expectEqual("${SelfName}(0xFFFFFFFF80000000)", desc)
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
expectEqual("${SelfName}(0x8000000000000000)", desc)
diff --git a/utils/build-script-impl b/utils/build-script-impl
index 074e6f6cad2..0d0da49f3b2 100755
--- a/utils/build-script-impl
+++ b/utils/build-script-impl
@@ -455,6 +455,7 @@ function verify_host_is_supported() {
| linux-armv6 \
| linux-armv7 \
| linux-aarch64 \
+ | linux-powerpc \
| linux-powerpc64 \
| linux-powerpc64le \
| linux-s390x \
diff --git a/utils/swift-bench.py b/utils/swift-bench.py
index 0ec7343c7eb..a61b1de0c81 100644
--- a/utils/swift-bench.py
+++ b/utils/swift-bench.py
@@ -146,7 +146,7 @@ func _opaqueGetInt64(x: Int) -> Int
@inline(never)
public func getInt(x: Int) -> Int {
-#if arch(i386) || arch(arm) || arch(arm64_32)
+#if arch(i386) || arch(arm) || arch(arm64_32)|| arch(powerpc)
return _opaqueGetInt32(x)
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || \
arch(powerpc64le) || arch(s390x)
diff --git a/utils/swift_build_support/swift_build_support/targets.py b/utils/swift_build_support/swift_build_support/targets.py
index 05966defe28..b85f1dd4ffe 100644
--- a/utils/swift_build_support/swift_build_support/targets.py
+++ b/utils/swift_build_support/swift_build_support/targets.py
@@ -227,6 +227,7 @@ class StdlibDeploymentTarget(object):
"armv6",
"armv7",
"aarch64",
+ "powerpc",
"powerpc64",
"powerpc64le",
"s390x"])
@@ -306,6 +307,8 @@ class StdlibDeploymentTarget(object):
return StdlibDeploymentTarget.Linux.armv6
elif machine == 'aarch64':
return StdlibDeploymentTarget.Linux.aarch64
+ elif machine == 'ppc':
+ return StdlibDeploymentTarget.Linux.powerpc
elif machine == 'ppc64':
return StdlibDeploymentTarget.Linux.powerpc64
elif machine == 'ppc64le':
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment