Skip to content

Commit 2daa140

Browse files
committed
Merge pull request #2541 from linux-on-ibm-z/master-s390x
Support Linux on z as a Swift platform
2 parents 38f7ec2 + bcc43c0 commit 2daa140

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+322
-99
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/Basic/LangOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,10 @@ namespace swift {
233233
/// a supported target architecture.
234234
static bool isPlatformConditionArchSupported(StringRef ArchName);
235235

236+
/// Returns true if the 'endian' platform condition argument represents
237+
/// a supported target endianness.
238+
static bool isPlatformConditionEndiannessSupported(StringRef endianness);
239+
236240
private:
237241
llvm::SmallVector<std::pair<std::string, std::string>, 3>
238242
PlatformConditionValues;

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: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,13 @@ static const StringRef SupportedConditionalCompilationArches[] = {
4040
"i386",
4141
"x86_64",
4242
"powerpc64",
43-
"powerpc64le"
43+
"powerpc64le",
44+
"s390x"
45+
};
46+
47+
static const StringRef SupportedConditionalCompilationEndianness[] = {
48+
"little",
49+
"big"
4450
};
4551

4652
bool LangOptions::isPlatformConditionOSSupported(StringRef OSName) {
@@ -58,6 +64,14 @@ LangOptions::isPlatformConditionArchSupported(StringRef ArchName) {
5864
return foundIt != std::end(SupportedConditionalCompilationArches);
5965
}
6066

67+
bool
68+
LangOptions::isPlatformConditionEndiannessSupported(StringRef Endianness) {
69+
auto foundIt = std::find(std::begin(SupportedConditionalCompilationEndianness),
70+
std::end(SupportedConditionalCompilationEndianness),
71+
Endianness);
72+
return foundIt != std::end(SupportedConditionalCompilationEndianness);
73+
}
74+
6175
StringRef
6276
LangOptions::getPlatformConditionValue(StringRef Name) const {
6377
// Last one wins.
@@ -141,13 +155,44 @@ std::pair<bool, bool> LangOptions::setTarget(llvm::Triple triple) {
141155
case llvm::Triple::ArchType::x86_64:
142156
addPlatformConditionValue("arch", "x86_64");
143157
break;
158+
case llvm::Triple::ArchType::systemz:
159+
addPlatformConditionValue("arch", "s390x");
160+
break;
144161
default:
145162
UnsupportedArch = true;
146163
}
147164

148165
if (UnsupportedOS || UnsupportedArch)
149166
return { UnsupportedOS, UnsupportedArch };
150167

168+
// Set the "_endian" platform condition.
169+
switch (Target.getArch()) {
170+
case llvm::Triple::ArchType::arm:
171+
case llvm::Triple::ArchType::thumb:
172+
addPlatformConditionValue("_endian", "little");
173+
break;
174+
case llvm::Triple::ArchType::aarch64:
175+
addPlatformConditionValue("_endian", "little");
176+
break;
177+
case llvm::Triple::ArchType::ppc64:
178+
addPlatformConditionValue("_endian", "big");
179+
break;
180+
case llvm::Triple::ArchType::ppc64le:
181+
addPlatformConditionValue("_endian", "little");
182+
break;
183+
case llvm::Triple::ArchType::x86:
184+
addPlatformConditionValue("_endian", "little");
185+
break;
186+
case llvm::Triple::ArchType::x86_64:
187+
addPlatformConditionValue("_endian", "little");
188+
break;
189+
case llvm::Triple::ArchType::systemz:
190+
addPlatformConditionValue("_endian", "big");
191+
break;
192+
default:
193+
llvm_unreachable("undefined architecture endianness");
194+
}
195+
151196
// Set the "runtime" platform condition.
152197
if (EnableObjCInterop)
153198
addPlatformConditionValue("_runtime", "_ObjC");

lib/IRGen/GenMeta.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4338,16 +4338,20 @@ irgen::emitClassResilientInstanceSizeAndAlignMask(IRGenFunction &IGF,
43384338
&& "didn't find size or alignment in metadata?!");
43394339
Address metadataAsBytes(IGF.Builder.CreateBitCast(metadata, IGF.IGM.Int8PtrTy),
43404340
IGF.IGM.getPointerAlignment());
4341-
auto loadZExtInt32AtOffset = [&](Size offset) {
4342-
Address slot = IGF.Builder.CreateConstByteArrayGEP(metadataAsBytes, offset);
4343-
slot = IGF.Builder.CreateBitCast(slot, IGF.IGM.Int32Ty->getPointerTo());
4344-
llvm::Value *result = IGF.Builder.CreateLoad(slot);
4345-
if (IGF.IGM.SizeTy != IGF.IGM.Int32Ty)
4346-
result = IGF.Builder.CreateZExt(result, IGF.IGM.SizeTy);
4347-
return result;
4348-
};
4349-
llvm::Value *size = loadZExtInt32AtOffset(scanner.InstanceSize);
4350-
llvm::Value *alignMask = loadZExtInt32AtOffset(scanner.InstanceAlignMask);
4341+
4342+
Address slot = IGF.Builder.CreateConstByteArrayGEP(metadataAsBytes,
4343+
scanner.InstanceSize);
4344+
slot = IGF.Builder.CreateBitCast(slot, IGF.IGM.Int32Ty->getPointerTo());
4345+
llvm::Value *size = IGF.Builder.CreateLoad(slot);
4346+
if (IGF.IGM.SizeTy != IGF.IGM.Int32Ty)
4347+
size = IGF.Builder.CreateZExt(size, IGF.IGM.SizeTy);
4348+
4349+
slot = IGF.Builder.CreateConstByteArrayGEP(metadataAsBytes,
4350+
scanner.InstanceAlignMask);
4351+
slot = IGF.Builder.CreateBitCast(slot, IGF.IGM.Int16Ty->getPointerTo());
4352+
llvm::Value *alignMask = IGF.Builder.CreateLoad(slot);
4353+
alignMask = IGF.Builder.CreateZExt(alignMask, IGF.IGM.SizeTy);
4354+
43514355
return {size, alignMask};
43524356
}
43534357

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;

0 commit comments

Comments
 (0)