@@ -90,6 +90,23 @@ internal let _registerSaveWords = _countGPRegisters + _countFPRegisters * _fpReg
90
90
internal let _countGPRegisters = 16
91
91
@usableFromInline
92
92
internal let _registerSaveWords = _countGPRegisters
93
+
94
+ #elseif arch(arm64) && !(os(macOS) || os(iOS) || os(tvOS) || os(watchOS) || os(Windows))
95
+ // ARM Procedure Call Standard for aarch64. (IHI0055B)
96
+ // The va_list type may refer to any parameter in a parameter list may be in one
97
+ // of three memory locations depending on its type and position in the argument
98
+ // list :
99
+ // 1. GP register save area x0 - x7
100
+ // 2. 128-bit FP/SIMD register save area q0 - q7
101
+ // 3. Stack argument area
102
+ @usableFromInline
103
+ internal let _countGPRegisters = 8
104
+ @usableFromInline
105
+ internal let _countFPRegisters = 8
106
+ @usableFromInline
107
+ internal let _fpRegisterWords = 16 / MemoryLayout< Int> . size
108
+ @usableFromInline
109
+ internal let _registerSaveWords = _countGPRegisters + ( _countFPRegisters * _fpRegisterWords)
93
110
#endif
94
111
95
112
#if arch(s390x)
@@ -391,7 +408,7 @@ extension Float80 : CVarArg, _CVarArgAligned {
391
408
public var _cVarArgEncoding : [ Int ] {
392
409
return _encodeBitsAsWords ( self )
393
410
}
394
-
411
+
395
412
/// Returns the required alignment in bytes of
396
413
/// the value returned by `_cVarArgEncoding`.
397
414
@inlinable // FIXME(sil-serialize-all)
@@ -402,7 +419,7 @@ extension Float80 : CVarArg, _CVarArgAligned {
402
419
}
403
420
#endif
404
421
405
- #if arch(x86_64) || arch(s390x)
422
+ #if arch(x86_64) || arch(s390x) || (arch(arm64) && !(os(macOS) || os(iOS) || os(tvOS) || os(watchOS) || os(Windows)))
406
423
407
424
/// An object that can manage the lifetime of storage backing a
408
425
/// `CVaListPointer`.
@@ -412,6 +429,7 @@ extension Float80 : CVarArg, _CVarArgAligned {
412
429
@_fixed_layout
413
430
@usableFromInline // c-abi
414
431
final internal class __VaListBuilder {
432
+ #if arch(x86_64) || arch(s390x)
415
433
@_fixed_layout // c-abi
416
434
@usableFromInline
417
435
internal struct Header {
@@ -428,15 +446,19 @@ final internal class __VaListBuilder {
428
446
@usableFromInline // c-abi
429
447
internal var reg_save_area : UnsafeMutablePointer < Int > ?
430
448
}
449
+ #endif
431
450
432
451
@usableFromInline // c-abi
433
452
internal var gpRegistersUsed = 0
434
453
@usableFromInline // c-abi
435
454
internal var fpRegistersUsed = 0
436
455
456
+ #if arch(x86_64) || arch(s390x)
437
457
@usableFromInline // c-abi
438
458
final // Property must be final since it is used by Builtin.addressof.
439
459
internal var header = Header ( )
460
+ #endif
461
+
440
462
@usableFromInline // c-abi
441
463
internal var storage : ContiguousArray < Int >
442
464
@@ -453,12 +475,16 @@ final internal class __VaListBuilder {
453
475
internal func append( _ arg: CVarArg ) {
454
476
var encoded = arg. _cVarArgEncoding
455
477
456
- #if arch(x86_64)
478
+ #if arch(x86_64) || arch(arm64)
457
479
let isDouble = arg is _CVarArgPassedAsDouble
458
480
459
481
if isDouble && fpRegistersUsed < _countFPRegisters {
460
- var startIndex = _countGPRegisters
461
- + ( fpRegistersUsed * _fpRegisterWords)
482
+ #if arch(arm64)
483
+ var startIndex = fpRegistersUsed * _fpRegisterWords
484
+ #else
485
+ var startIndex = _countGPRegisters
486
+ + ( fpRegistersUsed * _fpRegisterWords)
487
+ #endif
462
488
for w in encoded {
463
489
storage [ startIndex] = w
464
490
startIndex += 1
@@ -468,7 +494,12 @@ final internal class __VaListBuilder {
468
494
else if encoded. count == 1
469
495
&& !isDouble
470
496
&& gpRegistersUsed < _countGPRegisters {
471
- storage [ gpRegistersUsed] = encoded [ 0 ]
497
+ #if arch(arm64)
498
+ let startIndex = ( _fpRegisterWords * _countFPRegisters) + gpRegistersUsed
499
+ #else
500
+ let startIndex = gpRegistersUsed
501
+ #endif
502
+ storage [ startIndex] = encoded [ 0 ]
472
503
gpRegistersUsed += 1
473
504
}
474
505
else {
@@ -493,12 +524,23 @@ final internal class __VaListBuilder {
493
524
494
525
@inlinable // c-abi
495
526
internal func va_list( ) -> CVaListPointer {
496
- header. reg_save_area = storage. _baseAddress
497
- header. overflow_arg_area
498
- = storage. _baseAddress + _registerSaveWords
499
- return CVaListPointer (
500
- _fromUnsafeMutablePointer: UnsafeMutableRawPointer (
501
- Builtin . addressof ( & self . header) ) )
527
+ #if arch(x86_64) || arch(s390x)
528
+ header. reg_save_area = storage. _baseAddress
529
+ header. overflow_arg_area
530
+ = storage. _baseAddress + _registerSaveWords
531
+ return CVaListPointer (
532
+ _fromUnsafeMutablePointer: UnsafeMutableRawPointer (
533
+ Builtin . addressof ( & self . header) ) )
534
+ #elseif arch(arm64)
535
+ let vr_top = storage. _baseAddress + ( _fpRegisterWords * _countFPRegisters)
536
+ let gr_top = vr_top + _countGPRegisters
537
+
538
+ return CVaListPointer ( __stack: gr_top,
539
+ __gr_top: gr_top,
540
+ __vr_top: vr_top,
541
+ __gr_off: - 64 ,
542
+ __vr_off: - 128 )
543
+ #endif
502
544
}
503
545
}
504
546
0 commit comments