@@ -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(Linux)
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)
@@ -498,6 +515,129 @@ final internal class _VaListBuilder {
498
515
Builtin . addressof ( & self . header) ) )
499
516
}
500
517
}
518
+ #elseif arch(arm64) && os(Linux)
519
+
520
+ @_fixed_layout // FIXME(sil-serialize-all)
521
+ @usableFromInline // FIXME(sil-serialize-all)
522
+ final internal class _VaListBuilder {
523
+ @usableFromInline // FIXME(sil-serialize-all)
524
+ internal init ( ) {
525
+ // Prepare the register save area.
526
+ allocated = _registerSaveWords
527
+ storage = allocStorage ( wordCount: allocated)
528
+ // Append stack arguments after register save area.
529
+ count = allocated
530
+ }
531
+
532
+ @usableFromInline // FIXME(sil-serialize-all)
533
+ deinit {
534
+ if let allocatedStorage = storage {
535
+ deallocStorage ( wordCount: allocated, storage: allocatedStorage)
536
+ }
537
+ }
538
+
539
+ @usableFromInline // FIXME(sil-serialize-all)
540
+ internal func append( _ arg: CVarArg ) {
541
+ var encoded = arg. _cVarArgEncoding
542
+
543
+ if arg is _CVarArgPassedAsDouble
544
+ && fpRegistersUsed < _countFPRegisters {
545
+ var startIndex = ( fpRegistersUsed * _fpRegisterWords)
546
+ for w in encoded {
547
+ storage [ startIndex] = w
548
+ startIndex += 1
549
+ }
550
+ fpRegistersUsed += 1
551
+ } else if encoded. count == 1
552
+ && !( arg is _CVarArgPassedAsDouble )
553
+ && gpRegistersUsed < _countGPRegisters {
554
+ var startIndex = ( _fpRegisterWords * _countFPRegisters) + gpRegistersUsed
555
+ storage [ startIndex] = encoded [ 0 ]
556
+ gpRegistersUsed += 1
557
+ } else {
558
+ // Arguments in stack slot.
559
+ appendWords ( encoded)
560
+ }
561
+ }
562
+
563
+ @usableFromInline // FIXME(sil-serialize-all)
564
+ internal func va_list( ) -> CVaListPointer {
565
+ let vr_top = storage + ( _fpRegisterWords * _countFPRegisters)
566
+ let gr_top = vr_top + _countGPRegisters
567
+
568
+ return CVaListPointer ( __stack: gr_top, __gr_top: gr_top,
569
+ __vr_top: vr_top, __gr_off: - 64 , __vr_off: - 128 )
570
+ }
571
+
572
+ @usableFromInline // FIXME(sil-serialize-all)
573
+ internal func appendWords( _ words: [ Int ] ) {
574
+ let newCount = count + words. count
575
+ if newCount > allocated {
576
+ let oldAllocated = allocated
577
+ let oldStorage = storage
578
+ let oldCount = count
579
+
580
+ allocated = max ( newCount, allocated * 2 )
581
+ let newStorage = allocStorage ( wordCount: allocated)
582
+ storage = newStorage
583
+ // Count is updated below.
584
+ if let allocatedOldStorage = oldStorage {
585
+ newStorage. moveInitialize ( from: allocatedOldStorage, count: oldCount)
586
+ deallocStorage ( wordCount: oldAllocated, storage: allocatedOldStorage)
587
+ }
588
+ }
589
+
590
+ let allocatedStorage = storage!
591
+ for word in words {
592
+ allocatedStorage [ count] = word
593
+ count += 1
594
+ }
595
+ }
596
+
597
+ @usableFromInline // FIXME(sil-serialize-all)
598
+ internal func rawSizeAndAlignment(
599
+ _ wordCount: Int
600
+ ) -> ( Builtin . Word , Builtin . Word ) {
601
+ return ( ( wordCount * MemoryLayout < Int > . stride) . _builtinWordValue,
602
+ requiredAlignmentInBytes. _builtinWordValue)
603
+ }
604
+
605
+ @usableFromInline // FIXME(sil-serialize-all)
606
+ internal func allocStorage( wordCount: Int ) -> UnsafeMutablePointer < Int > {
607
+ let ( rawSize, rawAlignment) = rawSizeAndAlignment ( wordCount)
608
+ let rawStorage = Builtin . allocRaw ( rawSize, rawAlignment)
609
+ return UnsafeMutablePointer < Int > ( rawStorage)
610
+ }
611
+
612
+ @usableFromInline // FIXME(sil-serialize-all)
613
+ internal func deallocStorage(
614
+ wordCount: Int , storage: UnsafeMutablePointer < Int >
615
+ ) {
616
+ let ( rawSize, rawAlignment) = rawSizeAndAlignment ( wordCount)
617
+ Builtin . deallocRaw ( storage. _rawValue, rawSize, rawAlignment)
618
+ }
619
+
620
+ @usableFromInline // FIXME(sil-serialize-all)
621
+ internal let requiredAlignmentInBytes = MemoryLayout< Double> . alignment
622
+
623
+ @usableFromInline // FIXME(sil-serialize-all)
624
+ internal var count = 0
625
+
626
+ @usableFromInline // FIXME(sil-serialize-all)
627
+ internal var allocated = 0
628
+
629
+ @usableFromInline // FIXME(sil-serialize-all)
630
+ internal var storage : UnsafeMutablePointer < Int > !
631
+
632
+ @usableFromInline // FIXME(sil-serialize-all)
633
+ internal var gpRegistersUsed = 0
634
+
635
+ @usableFromInline // FIXME(sil-serialize-all)
636
+ internal var fpRegistersUsed = 0
637
+
638
+ @usableFromInline // FIXME(sil-serialize-all)
639
+ internal var overflowWordsUsed = 0
640
+ }
501
641
502
642
#else
503
643
0 commit comments