Skip to content

Commit ab2dd10

Browse files
rpostsmilseman
authored andcommitted
Towards s390x support (#19822)
* Towards s390x support * Fix case index on Big Endian
1 parent 526081c commit ab2dd10

File tree

5 files changed

+41
-11
lines changed

5 files changed

+41
-11
lines changed

stdlib/public/SwiftShims/HeapObject.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,9 +171,9 @@ static_assert(alignof(HeapObject) == alignof(void*),
171171
#define _swift_abi_SwiftSpareBitsMask \
172172
(__swift_uintptr_t) SWIFT_ABI_S390X_SWIFT_SPARE_BITS_MASK
173173
#define _swift_abi_ObjCReservedBitsMask \
174-
(__swift_uintptr_t) SWIFT_ABI_DEFAULT_OBJC_RESERVED_BITS_MASK
174+
(__swift_uintptr_t) SWIFT_ABI_S390X_OBJC_RESERVED_BITS_MASK
175175
#define _swift_abi_ObjCReservedLowBits \
176-
(unsigned) SWIFT_ABI_DEFAULT_OBJC_NUM_RESERVED_LOW_BITS
176+
(unsigned) SWIFT_ABI_S390X_OBJC_NUM_RESERVED_LOW_BITS
177177
#define _swift_BridgeObject_TaggedPointerBits \
178178
(__swift_uintptr_t) SWIFT_ABI_DEFAULT_BRIDGEOBJECT_TAG_64
179179

stdlib/public/SwiftShims/System.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,24 @@
164164
/*********************************** s390x ************************************/
165165

166166
// Top byte of pointers is unused, and heap objects are eight-byte aligned.
167-
#define SWIFT_ABI_S390X_SWIFT_SPARE_BITS_MASK 0x0000000000000007ULL
167+
// On s390x it is theoretically possible to have high bit set but in practice
168+
// it is unlikely.
169+
#define SWIFT_ABI_S390X_SWIFT_SPARE_BITS_MASK 0xFF00000000000007ULL
170+
171+
// Objective-C reserves just the high bit for tagged pointers.
172+
#define SWIFT_ABI_S390X_OBJC_RESERVED_BITS_MASK 0x8000000000000000ULL
173+
#define SWIFT_ABI_S390X_OBJC_NUM_RESERVED_LOW_BITS 0
174+
175+
// BridgeObject uses this bit to indicate whether it holds an ObjC object or
176+
// not.
177+
#define SWIFT_ABI_S390X_IS_OBJC_BIT 0x4000000000000000ULL
178+
179+
// ObjC weak reference discriminator is the high bit
180+
// reserved for ObjC tagged pointers plus the LSB.
181+
#define SWIFT_ABI_S390X_OBJC_WEAK_REFERENCE_MARKER_MASK \
182+
(SWIFT_ABI_S390X_OBJC_RESERVED_BITS_MASK | \
183+
1<<SWIFT_ABI_S390X_OBJC_NUM_RESERVED_LOW_BITS)
184+
#define SWIFT_ABI_S390X_OBJC_WEAK_REFERENCE_MARKER_VALUE \
185+
(1<<SWIFT_ABI_S390X_OBJC_NUM_RESERVED_LOW_BITS)
168186

169187
#endif /* SWIFT_ABI_SYSTEM_H */

stdlib/public/core/CTypes.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,11 @@ public typealias CLongDouble = Double
8282
public typealias CLongDouble = Float80
8383
#endif
8484
// TODO: Fill in definitions for other OSes.
85+
#if arch(s390x)
86+
// On s390x '-mlong-double-64' option with size of 64-bits makes the
87+
// Long Double type equivalent to Double type.
88+
public typealias CLongDouble = Double
89+
#endif
8590
#endif
8691

8792
// FIXME: Is it actually UTF-32 on Darwin?

stdlib/public/runtime/EnumImpl.h

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,16 +110,19 @@ inline unsigned getEnumTagSinglePayloadImpl(
110110
unsigned caseIndexFromExtraTagBits =
111111
payloadSize >= 4 ? 0 : (extraTagBits - 1U) << (payloadSize * 8U);
112112

113+
#if defined(__BIG_ENDIAN__)
114+
// On BE high order bytes contain the index
115+
unsigned long caseIndexFromValue = 0;
116+
unsigned numPayloadTagBytes = std::min(size_t(8), payloadSize);
117+
if (numPayloadTagBytes)
118+
memcpy(reinterpret_cast<uint8_t *>(&caseIndexFromValue) + 8 -
119+
numPayloadTagBytes,
120+
valueAddr, numPayloadTagBytes);
121+
#else
113122
// In practice we should need no more than four bytes from the payload
114123
// area.
115124
unsigned caseIndexFromValue = 0;
116125
unsigned numPayloadTagBytes = std::min(size_t(4), payloadSize);
117-
#if defined(__BIG_ENDIAN__)
118-
if (numPayloadTagBytes)
119-
small_memcpy(reinterpret_cast<uint8_t *>(&caseIndexFromValue) + 4 -
120-
numPayloadTagBytes,
121-
valueAddr, numPayloadTagBytes, true);
122-
#else
123126
if (numPayloadTagBytes)
124127
small_memcpy(&caseIndexFromValue, valueAddr,
125128
numPayloadTagBytes, true);
@@ -192,6 +195,8 @@ inline void storeEnumTagSinglePayloadImpl(
192195
reinterpret_cast<uint8_t *>(&payloadIndex) + 4 -
193196
numPayloadTagBytes,
194197
numPayloadTagBytes, true);
198+
if (payloadSize > 4)
199+
memset(valueAddr + 4, 0, payloadSize - 4);
195200
if (numExtraTagBytes)
196201
small_memcpy(extraTagBitAddr,
197202
reinterpret_cast<uint8_t *>(&extraTagIndex) + 4 -

stdlib/public/runtime/HeapObject.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,11 @@ using namespace swift;
6161
/// Returns true if the pointer passed to a native retain or release is valid.
6262
/// If false, the operation should immediately return.
6363
static inline bool isValidPointerForNativeRetain(const void *p) {
64-
#if defined(__x86_64__) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64)
65-
// On these platforms, the upper half of address space is reserved for the
64+
#if defined(__x86_64__) || defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64) || defined(__s390x__)
65+
// On these platforms, except s390x, the upper half of address space is reserved for the
6666
// kernel, so we can assume that pointer values in this range are invalid.
67+
// On s390x it is theoretically possible to have high bit set but in practice
68+
// it is unlikely.
6769
return (intptr_t)p > 0;
6870
#else
6971
return p != nullptr;

0 commit comments

Comments
 (0)