Skip to content

Commit 85fde8b

Browse files
committed
Add support for Linux s390x. LLVM's Swift calling convention support is used to ensure correct operations of C++ code in the runtime. This patch also includes some (incomplete) changes to enum handling to make enums work in most common cases.
1 parent bb3486d commit 85fde8b

File tree

32 files changed

+189
-49
lines changed

32 files changed

+189
-49
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,8 @@ else()
439439
set(SWIFT_HOST_VARIANT_ARCH_default "powerpc64")
440440
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "ppc64le")
441441
set(SWIFT_HOST_VARIANT_ARCH_default "powerpc64le")
442+
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "s390x")
443+
set(SWIFT_HOST_VARIANT_ARCH_default "s390x")
442444
# FIXME: Only matches v6l/v7l - by far the most common variants
443445
elseif("${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "armv6l")
444446
set(SWIFT_HOST_VARIANT_ARCH_default "armv6")
@@ -507,6 +509,8 @@ if("${SWIFT_HOST_VARIANT_SDK}" STREQUAL "LINUX")
507509
set(SWIFT_HOST_TRIPLE "aarch64-unknown-linux-gnu")
508510
elseif("${SWIFT_HOST_VARIANT_ARCH}" MATCHES "(powerpc64|powerpc64le)")
509511
set(SWIFT_HOST_TRIPLE "${SWIFT_HOST_VARIANT_ARCH}-unknown-linux-gnu")
512+
elseif("${SWIFT_HOST_VARIANT_ARCH}" MATCHES "s390x")
513+
set(SWIFT_HOST_TRIPLE "s390x-unknown-linux-gnu")
510514
elseif("${SWIFT_HOST_VARIANT_ARCH}" MATCHES "(armv6|armv7)")
511515
set(SWIFT_HOST_TRIPLE "${SWIFT_HOST_VARIANT_ARCH}-unknown-linux-gnueabihf")
512516
else()

cmake/modules/SwiftSetIfArchBitness.cmake

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ function(set_if_arch_bitness var_name)
1616
"${SIA_ARCH}" STREQUAL "arm64" OR
1717
"${SIA_ARCH}" STREQUAL "aarch64" OR
1818
"${SIA_ARCH}" STREQUAL "powerpc64" OR
19-
"${SIA_ARCH}" STREQUAL "powerpc64le")
19+
"${SIA_ARCH}" STREQUAL "powerpc64le" OR
20+
"${SIA_ARCH}" STREQUAL "s390x")
2021
set("${var_name}" "${SIA_CASE_64_BIT}" PARENT_SCOPE)
2122
else()
2223
message(FATAL_ERROR "Unknown architecture: ${SIA_ARCH}")

include/swift/ABI/System.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,9 @@
9797
// Heap objects are pointer-aligned, so the low three bits are unused.
9898
#define SWIFT_ABI_POWERPC64_SWIFT_SPARE_BITS_MASK 0x0000000000000007ULL
9999

100+
/*********************************** s390x ************************************/
101+
102+
// Top byte of pointers is unused, and heap objects are eight-byte aligned.
103+
#define SWIFT_ABI_S390X_SWIFT_SPARE_BITS_MASK 0x0000000000000007ULL
104+
100105
#endif /* SWIFT_ABI_SYSTEM_H */

include/swift/Runtime/Config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,12 @@
3333
/// Does the current Swift platform use LLVM's intrinsic "swiftcall"
3434
/// calling convention for Swift functions?
3535
#ifndef SWIFT_USE_SWIFTCALL
36+
#ifdef __s390x__
37+
#define SWIFT_USE_SWIFTCALL 1
38+
#else
3639
#define SWIFT_USE_SWIFTCALL 0
3740
#endif
41+
#endif
3842

3943
/// Does the current Swift platform allow information other than the
4044
/// class pointer to be stored in the isa field? If so, when deriving

include/swift/Runtime/HeapObject.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,12 @@ using BoxPair = TwoWordPair<HeapObject *, OpaqueValue *>;
157157
/// The heap object has an initial retain count of 1, and its metadata is set
158158
/// such that destroying the heap object destroys the contained value.
159159
SWIFT_RUNTIME_EXPORT
160-
extern "C" BoxPair::Return swift_allocBox(Metadata const *type);
160+
extern "C" BoxPair::Return swift_allocBox(Metadata const *type)
161+
SWIFT_CC(swift);
161162

162163
SWIFT_RUNTIME_EXPORT
163-
extern "C" BoxPair::Return (*_swift_allocBox)(Metadata const *type);
164+
extern "C" BoxPair::Return (*_swift_allocBox)(Metadata const *type)
165+
SWIFT_CC(swift);
164166

165167

166168
// Allocate plain old memory. This is the generalized entry point

include/swift/Runtime/Metadata.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1046,6 +1046,17 @@ static const uintptr_t ObjCReservedBitsMask =
10461046
static const unsigned ObjCReservedLowBits =
10471047
SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS;
10481048

1049+
#elif defined(__s390x__)
1050+
1051+
static const uintptr_t LeastValidPointerValue =
1052+
SWIFT_ABI_DEFAULT_LEAST_VALID_POINTER;
1053+
static const uintptr_t SwiftSpareBitsMask =
1054+
SWIFT_ABI_S390X_SWIFT_SPARE_BITS_MASK;
1055+
static const uintptr_t ObjCReservedBitsMask =
1056+
SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK;
1057+
static const unsigned ObjCReservedLowBits =
1058+
SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS;
1059+
10491060
#else
10501061

10511062
static const uintptr_t LeastValidPointerValue =

lib/Basic/LangOptions.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ static const StringRef SupportedConditionalCompilationArches[] = {
4040
"i386",
4141
"x86_64",
4242
"powerpc64",
43-
"powerpc64le"
43+
"powerpc64le",
44+
"s390x"
4445
};
4546

4647
static const StringRef SupportedConditionalCompilationEndianness[] = {
@@ -154,6 +155,9 @@ std::pair<bool, bool> LangOptions::setTarget(llvm::Triple triple) {
154155
case llvm::Triple::ArchType::x86_64:
155156
addPlatformConditionValue("arch", "x86_64");
156157
break;
158+
case llvm::Triple::ArchType::systemz:
159+
addPlatformConditionValue("arch", "s390x");
160+
break;
157161
default:
158162
UnsupportedArch = true;
159163
}
@@ -182,6 +186,9 @@ std::pair<bool, bool> LangOptions::setTarget(llvm::Triple triple) {
182186
case llvm::Triple::ArchType::x86_64:
183187
addPlatformConditionValue("_endian", "little");
184188
break;
189+
case llvm::Triple::ArchType::systemz:
190+
addPlatformConditionValue("_endian", "big");
191+
break;
185192
default:
186193
llvm_unreachable("undefined architecture endianness");
187194
}

lib/IRGen/SwiftTargetInfo.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,13 @@ static void configurePowerPC64(IRGenModule &IGM, const llvm::Triple &triple,
103103
SWIFT_ABI_POWERPC64_SWIFT_SPARE_BITS_MASK);
104104
}
105105

106+
/// Configures target-specific information for SystemZ platforms.
107+
static void configureSystemZ(IRGenModule &IGM, const llvm::Triple &triple,
108+
SwiftTargetInfo &target) {
109+
setToMask(target.PointerSpareBits, 64,
110+
SWIFT_ABI_S390X_SWIFT_SPARE_BITS_MASK);
111+
}
112+
106113
/// Configure a default target.
107114
SwiftTargetInfo::SwiftTargetInfo(
108115
llvm::Triple::ObjectFormatType outputObjectFormat,
@@ -154,6 +161,10 @@ SwiftTargetInfo SwiftTargetInfo::get(IRGenModule &IGM) {
154161
configurePowerPC64(IGM, triple, target);
155162
break;
156163

164+
case llvm::Triple::systemz:
165+
configureSystemZ(IGM, triple, target);
166+
break;
167+
157168
default:
158169
// FIXME: Complain here? Default target info is unlikely to be correct.
159170
break;

stdlib/private/SwiftPrivate/PRNG.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public func rand64() -> UInt64 {
2929
public func randInt() -> Int {
3030
#if arch(i386) || arch(arm)
3131
return Int(Int32(bitPattern: rand32()))
32-
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le)
32+
#elseif arch(x86_64) || arch(arm64) || arch(powerpc64) || arch(powerpc64le) || arch(s390x)
3333
return Int(Int64(bitPattern: rand64()))
3434
#else
3535
fatalError("unimplemented")

stdlib/public/core/Builtin.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,19 @@ internal var _objectPointerLowSpareBitShift: UInt {
394394
internal var _objCTaggedPointerBits: UInt {
395395
@inline(__always) get { return 0 }
396396
}
397+
#elseif arch(s390x)
398+
internal var _objectPointerSpareBits: UInt {
399+
@inline(__always) get { return 0x0000_0000_0000_0007 }
400+
}
401+
internal var _objectPointerIsObjCBit: UInt {
402+
@inline(__always) get { return 0x0000_0000_0000_0002 }
403+
}
404+
internal var _objectPointerLowSpareBitShift: UInt {
405+
@inline(__always) get { return 0 }
406+
}
407+
internal var _objCTaggedPointerBits: UInt {
408+
@inline(__always) get { return 0 }
409+
}
397410
#endif
398411

399412
/// Extract the raw bits of `x`.

0 commit comments

Comments
 (0)