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;

lib/Parse/ParseStmt.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1608,7 +1608,7 @@ ParserResult<Stmt> Parser::parseStmtGuard() {
16081608
// "_compiler_version"), and whose argument is a named decl ref expression
16091609
ConditionalCompilationExprState
16101610
Parser::evaluateConditionalCompilationExpr(Expr *condition) {
1611-
// Evaluate a ParenExpr.
1611+
// Evaluate a ParenExpr.
16121612
if (auto *PE = dyn_cast<ParenExpr>(condition))
16131613
return evaluateConditionalCompilationExpr(PE->getSubExpr());
16141614

@@ -1709,6 +1709,7 @@ Parser::evaluateConditionalCompilationExpr(Expr *condition) {
17091709
}
17101710

17111711
if (!fnName.equals("arch") && !fnName.equals("os") &&
1712+
!fnName.equals("_endian") &&
17121713
!fnName.equals("_runtime") &&
17131714
!fnName.equals("swift") &&
17141715
!fnName.equals("_compiler_version")) {
@@ -1799,6 +1800,11 @@ Parser::evaluateConditionalCompilationExpr(Expr *condition) {
17991800
"architecture", fnName);
18001801
return ConditionalCompilationExprState::error();
18011802
}
1803+
} else if (fnName == "_endian") {
1804+
if (!LangOptions::isPlatformConditionEndiannessSupported(argument)) {
1805+
diagnose(UDRE->getLoc(), diag::unknown_platform_condition_argument,
1806+
"endianness", fnName);
1807+
}
18021808
}
18031809
auto target = Context.LangOpts.getPlatformConditionValue(fnName);
18041810
return {target == argument, ConditionalCompilationExprKind::DeclRef};

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/private/SwiftPrivateLibcExtras/SwiftPrivateLibcExtras.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ public var _stdlib_FD_SETSIZE: CInt {
3838
}
3939

4040
public struct _stdlib_fd_set {
41-
var _data: [UInt32]
41+
var _data: [UInt]
4242
static var _wordBits: Int {
43-
return sizeof(UInt32) * 8
43+
return sizeof(UInt) * 8
4444
}
4545

4646
public init() {
47-
_data = [UInt32](
47+
_data = [UInt](
4848
repeating: 0,
4949
count: Int(_stdlib_FD_SETSIZE) / _stdlib_fd_set._wordBits)
5050
}
@@ -53,20 +53,20 @@ public struct _stdlib_fd_set {
5353
let fdInt = Int(fd)
5454
return (
5555
_data[fdInt / _stdlib_fd_set._wordBits] &
56-
UInt32(1 << (fdInt % _stdlib_fd_set._wordBits))
56+
UInt(1 << (fdInt % _stdlib_fd_set._wordBits))
5757
) != 0
5858
}
5959

6060
public mutating func set(_ fd: CInt) {
6161
let fdInt = Int(fd)
6262
_data[fdInt / _stdlib_fd_set._wordBits] |=
63-
UInt32(1 << (fdInt % _stdlib_fd_set._wordBits))
63+
UInt(1 << (fdInt % _stdlib_fd_set._wordBits))
6464
}
6565

6666
public mutating func clear(_ fd: CInt) {
6767
let fdInt = Int(fd)
6868
_data[fdInt / _stdlib_fd_set._wordBits] &=
69-
~UInt32(1 << (fdInt % _stdlib_fd_set._wordBits))
69+
~UInt(1 << (fdInt % _stdlib_fd_set._wordBits))
7070
}
7171

7272
public mutating func zero() {

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`.

stdlib/public/core/FixedPoint.swift.gyb

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -265,25 +265,21 @@ public struct ${Self}
265265
/// byte order if necessary.
266266
@_transparent public
267267
init(bigEndian value: ${Self}) {
268-
#if arch(i386) || arch(x86_64) || arch(arm) || arch(arm64) || arch(powerpc64le)
269-
self = ${Self}(Builtin.int_bswap_${BuiltinName}(value._value) )
270-
#elseif arch(powerpc64)
268+
#if _endian(big)
271269
self = value
272270
#else
273-
_UnsupportedArchitectureError()
271+
self = ${Self}(Builtin.int_bswap_${BuiltinName}(value._value) )
274272
#endif
275273
}
276274

277275
/// Creates an integer from its little-endian representation, changing the
278276
/// byte order if necessary.
279277
@_transparent public
280278
init(littleEndian value: ${Self}) {
281-
#if arch(i386) || arch(x86_64) || arch(arm) || arch(arm64) || arch(powerpc64le)
279+
#if _endian(little)
282280
self = value
283-
#elseif arch(powerpc64)
284-
self = ${Self}(Builtin.int_bswap_${BuiltinName}(value._value) )
285281
#else
286-
_UnsupportedArchitectureError()
282+
self = ${Self}(Builtin.int_bswap_${BuiltinName}(value._value) )
287283
#endif
288284
}
289285
% end
@@ -303,23 +299,19 @@ public struct ${Self}
303299
/// Returns the big-endian representation of the integer, changing the
304300
/// byte order if necessary.
305301
public var bigEndian: ${Self} {
306-
#if arch(i386) || arch(x86_64) || arch(arm) || arch(arm64) || arch(powerpc64le)
307-
return ${Self}(Builtin.int_bswap_${BuiltinName}(_value))
308-
#elseif arch(powerpc64)
302+
#if _endian(big)
309303
return self
310304
#else
311-
_UnsupportedArchitectureError()
305+
return ${Self}(Builtin.int_bswap_${BuiltinName}(_value))
312306
#endif
313307
}
314308
/// Returns the little-endian representation of the integer, changing the
315309
/// byte order if necessary.
316310
public var littleEndian: ${Self} {
317-
#if arch(i386) || arch(x86_64) || arch(arm) || arch(arm64) || arch(powerpc64le)
311+
#if _endian(little)
318312
return self
319-
#elseif arch(powerpc64)
320-
return ${Self}(Builtin.int_bswap_${BuiltinName}(_value))
321313
#else
322-
_UnsupportedArchitectureError()
314+
return ${Self}(Builtin.int_bswap_${BuiltinName}(_value))
323315
#endif
324316
}
325317
% end

0 commit comments

Comments
 (0)