@@ -85,6 +85,30 @@ internal let _registerSaveWords = _countGPRegisters + _countSSERegisters * _sseR
85
85
internal let _countGPRegisters = 16
86
86
@_versioned
87
87
internal let _registerSaveWords = _countGPRegisters
88
+
89
+ #elseif arch(arm64)
90
+
91
+ // ARM IHI 0055B
92
+ // va_list may refer to any paramenter may be in one of three memory locations:
93
+ // 1. GP register save area x0 - x7
94
+ // 2. FP/SIMD register save area q0 - q7
95
+ // 3. Stack argument area
96
+ //
97
+
98
+ @_versioned
99
+ internal let _countGPRegisters = 8
100
+
101
+ @_versioned
102
+ internal let _countFPRegisters = 8
103
+
104
+ //128bit, 2 64bit word
105
+ @_versioned
106
+ internal let _fpRegisterWords = 2
107
+
108
+ @_versioned
109
+ internal let _registerSaveWords = _countGPRegisters + ( _countFPRegisters * _fpRegisterWords)
110
+
111
+
88
112
#endif
89
113
90
114
#if arch(s390x)
@@ -467,6 +491,140 @@ final internal class _VaListBuilder {
467
491
internal var storage : ContiguousArray < Int >
468
492
}
469
493
494
+ #elseif arch(arm64) && !(os(macOS) || os(iOS) || os(tvOS) || os(watchOS))
495
+
496
+
497
+ @_fixed_layout // FIXME(sil-serialize-all)
498
+ @_versioned // FIXME(sil-serialize-all)
499
+ final internal class _VaListBuilder {
500
+
501
+ @_inlineable // FIXME(sil-serialize-all)
502
+ @_versioned // FIXME(sil-serialize-all)
503
+ internal init ( ) {
504
+ // prepare the register save area
505
+ allocated = _registerSaveWords
506
+ storage = allocStorage ( wordCount: allocated)
507
+ // append stack arguments after register save area
508
+ count = allocated
509
+ }
510
+
511
+ @_inlineable // FIXME(sil-serialize-all)
512
+ @_versioned // FIXME(sil-serialize-all)
513
+ deinit {
514
+ if let allocatedStorage = storage {
515
+ deallocStorage ( wordCount: allocated, storage: allocatedStorage)
516
+ }
517
+ }
518
+
519
+ @_inlineable // FIXME(sil-serialize-all)
520
+ @_versioned // FIXME(sil-serialize-all)
521
+ internal func append( _ arg: CVarArg ) {
522
+ var encoded = arg. _cVarArgEncoding
523
+
524
+ if arg is _CVarArgPassedAsDouble
525
+ && fpRegistersUsed < _countFPRegisters {
526
+ var startIndex = ( fpRegistersUsed * _fpRegisterWords)
527
+ for w in encoded {
528
+ storage [ startIndex] = w
529
+ startIndex += 1
530
+ }
531
+ fpRegistersUsed += 1
532
+ } else if encoded. count == 1
533
+ && !( arg is _CVarArgPassedAsDouble )
534
+ && gpRegistersUsed < _countGPRegisters {
535
+ var startIndex = ( _fpRegisterWords * _countFPRegisters) + gpRegistersUsed
536
+ storage [ startIndex] = encoded [ 0 ]
537
+ gpRegistersUsed += 1
538
+ } else {
539
+ //arguments in stack slot
540
+ appendWords ( encoded)
541
+ }
542
+ }
543
+
544
+ @_inlineable // FIXME(sil-serialize-all)
545
+ @_versioned // FIXME(sil-serialize-all)
546
+ internal func va_list( ) -> CVaListPointer {
547
+ let vr_top = storage + ( _fpRegisterWords * _countFPRegisters)
548
+ let gr_top = vr_top + _countGPRegisters
549
+
550
+ return CVaListPointer ( __stack: gr_top, __gr_top: gr_top,
551
+ __vr_top: vr_top, __gr_off: - 64 , __vr_off: - 128 )
552
+ }
553
+
554
+ @_inlineable // FIXME(sil-serialize-all)
555
+ @_versioned // FIXME(sil-serialize-all)
556
+ internal func appendWords( _ words: [ Int ] ) {
557
+ let newCount = count + words. count
558
+ if newCount > allocated {
559
+ let oldAllocated = allocated
560
+ let oldStorage = storage
561
+ let oldCount = count
562
+
563
+ allocated = max ( newCount, allocated * 2 )
564
+ let newStorage = allocStorage ( wordCount: allocated)
565
+ storage = newStorage
566
+ // count is updated below
567
+
568
+ if let allocatedOldStorage = oldStorage {
569
+ newStorage. moveInitialize ( from: allocatedOldStorage, count: oldCount)
570
+ deallocStorage ( wordCount: oldAllocated, storage: allocatedOldStorage)
571
+ }
572
+ }
573
+
574
+ let allocatedStorage = storage!
575
+ for word in words {
576
+ allocatedStorage [ count] = word
577
+ count += 1
578
+ }
579
+ }
580
+
581
+ @_inlineable // FIXME(sil-serialize-all)
582
+ @_versioned // FIXME(sil-serialize-all)
583
+ internal func rawSizeAndAlignment(
584
+ _ wordCount: Int
585
+ ) -> ( Builtin . Word , Builtin . Word ) {
586
+ return ( ( wordCount * MemoryLayout < Int > . stride) . _builtinWordValue,
587
+ requiredAlignmentInBytes. _builtinWordValue)
588
+ }
589
+
590
+ @_inlineable // FIXME(sil-serialize-all)
591
+ @_versioned // FIXME(sil-serialize-all)
592
+ internal func allocStorage( wordCount: Int ) -> UnsafeMutablePointer < Int > {
593
+ let ( rawSize, rawAlignment) = rawSizeAndAlignment ( wordCount)
594
+ let rawStorage = Builtin . allocRaw ( rawSize, rawAlignment)
595
+ return UnsafeMutablePointer < Int > ( rawStorage)
596
+ }
597
+
598
+ @_versioned // FIXME(sil-serialize-all)
599
+ internal func deallocStorage(
600
+ wordCount: Int , storage: UnsafeMutablePointer < Int >
601
+ ) {
602
+ let ( rawSize, rawAlignment) = rawSizeAndAlignment ( wordCount)
603
+ Builtin . deallocRaw ( storage. _rawValue, rawSize, rawAlignment)
604
+ }
605
+
606
+ @_versioned // FIXME(sil-serialize-all)
607
+ internal let requiredAlignmentInBytes = MemoryLayout< Double> . alignment
608
+
609
+ @_versioned // FIXME(sil-serialize-all)
610
+ internal var count = 0
611
+
612
+ @_versioned // FIXME(sil-serialize-all)
613
+ internal var allocated = 0
614
+
615
+ @_versioned // FIXME(sil-serialize-all)
616
+ internal var storage : UnsafeMutablePointer < Int > !
617
+
618
+ @_versioned // FIXME(sil-serialize-all)
619
+ internal var gpRegistersUsed = 0
620
+
621
+ @_versioned // FIXME(sil-serialize-all)
622
+ internal var fpRegistersUsed = 0
623
+
624
+ @_versioned // FIXME(sil-serialize-all)
625
+ internal var overflowWordsUsed = 0
626
+ }
627
+
470
628
#else
471
629
472
630
/// An object that can manage the lifetime of storage backing a
0 commit comments