@@ -60,7 +60,7 @@ protocol _CVarArgAligned : CVarArg {
60
60
61
61
#if arch(x86_64)
62
62
@_versioned
63
- internal let _x86_64CountGPRegisters = 6
63
+ internal let _countGPRegisters = 6
64
64
// Note to future visitors concerning the following SSE register count.
65
65
//
66
66
// AMD64-ABI section 3.5.7 says -- as recently as v0.99.7, Nov 2014 -- to make
@@ -75,11 +75,24 @@ internal let _x86_64CountGPRegisters = 6
75
75
// from 8 to 16 based on reading the spec, probably the bug you're looking for
76
76
// is elsewhere.
77
77
@_versioned
78
- internal let _x86_64CountSSERegisters = 8
78
+ internal let _countSSERegisters = 8
79
79
@_versioned
80
- internal let _x86_64SSERegisterWords = 2
80
+ internal let _sseRegisterWords = 2
81
81
@_versioned
82
- internal let _x86_64RegisterSaveWords = _x86_64CountGPRegisters + _x86_64CountSSERegisters * _x86_64SSERegisterWords
82
+ internal let _registerSaveWords = _countGPRegisters + _countSSERegisters * _sseRegisterWords
83
+ #elseif arch(s390x)
84
+ @_versioned
85
+ internal let _countGPRegisters = 16
86
+ @_versioned
87
+ internal let _registerSaveWords = _countGPRegisters
88
+ #endif
89
+
90
+ #if arch(s390x)
91
+ internal typealias _VAUInt = CUnsignedLongLong
92
+ internal typealias _VAInt = Int64
93
+ #else
94
+ internal typealias _VAUInt = CUnsignedInt
95
+ internal typealias _VAInt = Int32
83
96
#endif
84
97
85
98
/// Invokes the given closure with a C `va_list` argument derived from the
@@ -178,7 +191,7 @@ extension Int : CVarArg {
178
191
179
192
extension Bool : CVarArg {
180
193
public var _cVarArgEncoding : [ Int ] {
181
- return _encodeBitsAsWords ( Int32 ( self ? 1 : 0 ) )
194
+ return _encodeBitsAsWords ( _VAInt ( self ? 1 : 0 ) )
182
195
}
183
196
}
184
197
@@ -204,7 +217,7 @@ extension Int32 : CVarArg {
204
217
/// appropriately interpreted by C varargs.
205
218
@_inlineable // FIXME(sil-serialize-all)
206
219
public var _cVarArgEncoding : [ Int ] {
207
- return _encodeBitsAsWords ( self )
220
+ return _encodeBitsAsWords ( _VAInt ( self ) )
208
221
}
209
222
}
210
223
@@ -213,7 +226,7 @@ extension Int16 : CVarArg {
213
226
/// appropriately interpreted by C varargs.
214
227
@_inlineable // FIXME(sil-serialize-all)
215
228
public var _cVarArgEncoding : [ Int ] {
216
- return _encodeBitsAsWords ( Int32 ( self ) )
229
+ return _encodeBitsAsWords ( _VAInt ( self ) )
217
230
}
218
231
}
219
232
@@ -222,7 +235,7 @@ extension Int8 : CVarArg {
222
235
/// appropriately interpreted by C varargs.
223
236
@_inlineable // FIXME(sil-serialize-all)
224
237
public var _cVarArgEncoding : [ Int ] {
225
- return _encodeBitsAsWords ( Int32 ( self ) )
238
+ return _encodeBitsAsWords ( _VAInt ( self ) )
226
239
}
227
240
}
228
241
@@ -258,7 +271,7 @@ extension UInt32 : CVarArg {
258
271
/// appropriately interpreted by C varargs.
259
272
@_inlineable // FIXME(sil-serialize-all)
260
273
public var _cVarArgEncoding : [ Int ] {
261
- return _encodeBitsAsWords ( self )
274
+ return _encodeBitsAsWords ( _VAUInt ( self ) )
262
275
}
263
276
}
264
277
@@ -267,7 +280,7 @@ extension UInt16 : CVarArg {
267
280
/// appropriately interpreted by C varargs.
268
281
@_inlineable // FIXME(sil-serialize-all)
269
282
public var _cVarArgEncoding : [ Int ] {
270
- return _encodeBitsAsWords ( CUnsignedInt ( self ) )
283
+ return _encodeBitsAsWords ( _VAUInt ( self ) )
271
284
}
272
285
}
273
286
@@ -276,7 +289,7 @@ extension UInt8 : CVarArg {
276
289
/// appropriately interpreted by C varargs.
277
290
@_inlineable // FIXME(sil-serialize-all)
278
291
public var _cVarArgEncoding : [ Int ] {
279
- return _encodeBitsAsWords ( CUnsignedInt ( self ) )
292
+ return _encodeBitsAsWords ( _VAUInt ( self ) )
280
293
}
281
294
}
282
295
@@ -352,7 +365,7 @@ extension Double : _CVarArgPassedAsDouble, _CVarArgAligned {
352
365
}
353
366
}
354
367
355
- #if arch(x86_64)
368
+ #if arch(x86_64) || arch(s390x)
356
369
357
370
/// An object that can manage the lifetime of storage backing a
358
371
/// `CVaListPointer`.
@@ -371,7 +384,7 @@ final internal class _VaListBuilder {
371
384
internal var gp_offset = CUnsignedInt ( 0 )
372
385
@_versioned // FIXME(sil-serialize-all)
373
386
internal var fp_offset =
374
- CUnsignedInt ( _x86_64CountGPRegisters * MemoryLayout< Int> . stride)
387
+ CUnsignedInt ( _countGPRegisters * MemoryLayout< Int> . stride)
375
388
@_versioned // FIXME(sil-serialize-all)
376
389
internal var overflow_arg_area : UnsafeMutablePointer < Int > ?
377
390
@_versioned // FIXME(sil-serialize-all)
@@ -382,7 +395,7 @@ final internal class _VaListBuilder {
382
395
@_versioned // FIXME(sil-serialize-all)
383
396
internal init ( ) {
384
397
// prepare the register save area
385
- storage = ContiguousArray ( repeating: 0 , count: _x86_64RegisterSaveWords )
398
+ storage = ContiguousArray ( repeating: 0 , count: _registerSaveWords )
386
399
}
387
400
388
401
@_inlineable // FIXME(sil-serialize-all)
@@ -394,10 +407,11 @@ final internal class _VaListBuilder {
394
407
internal func append( _ arg: CVarArg ) {
395
408
var encoded = arg. _cVarArgEncoding
396
409
410
+ #if arch(x86_64)
397
411
if arg is _CVarArgPassedAsDouble
398
- && sseRegistersUsed < _x86_64CountSSERegisters {
399
- var startIndex = _x86_64CountGPRegisters
400
- + ( sseRegistersUsed * _x86_64SSERegisterWords )
412
+ && sseRegistersUsed < _countSSERegisters {
413
+ var startIndex = _countGPRegisters
414
+ + ( sseRegistersUsed * _sseRegisterWords )
401
415
for w in encoded {
402
416
storage [ startIndex] = w
403
417
startIndex += 1
@@ -406,7 +420,7 @@ final internal class _VaListBuilder {
406
420
}
407
421
else if encoded. count == 1
408
422
&& !( arg is _CVarArgPassedAsDouble )
409
- && gpRegistersUsed < _x86_64CountGPRegisters {
423
+ && gpRegistersUsed < _countGPRegisters {
410
424
storage [ gpRegistersUsed] = encoded [ 0 ]
411
425
gpRegistersUsed += 1
412
426
}
@@ -415,14 +429,27 @@ final internal class _VaListBuilder {
415
429
storage. append ( w)
416
430
}
417
431
}
432
+ #elseif arch(s390x)
433
+ if gpRegistersUsed < _countGPRegisters {
434
+ for w in encoded {
435
+ storage [ gpRegistersUsed] = w
436
+ gpRegistersUsed += 1
437
+ }
438
+ } else {
439
+ for w in encoded {
440
+ storage. append ( w)
441
+ }
442
+ }
443
+ #endif
444
+
418
445
}
419
446
420
447
@_inlineable // FIXME(sil-serialize-all)
421
448
@_versioned // FIXME(sil-serialize-all)
422
449
internal func va_list( ) -> CVaListPointer {
423
450
header. reg_save_area = storage. _baseAddress
424
451
header. overflow_arg_area
425
- = storage. _baseAddress + _x86_64RegisterSaveWords
452
+ = storage. _baseAddress + _registerSaveWords
426
453
return CVaListPointer (
427
454
_fromUnsafeMutablePointer: UnsafeMutableRawPointer (
428
455
Builtin . addressof ( & self . header) ) )
0 commit comments