Skip to content

Commit ac8890b

Browse files
committed
[stdlib][SR-2239][5.0] Implement AAPCS64 variable argument list support.
Use the already existing support for x86_64 and s390 to implement AAPCS64 __VaListBuilder. The parts where each implementation differ are the x86_64 header, and the order of the general and vector registers. This change brings in one commit the changes introduced in swiftlang#20862 and in swiftlang#21237.
1 parent 3ef4a2d commit ac8890b

File tree

3 files changed

+104
-14
lines changed

3 files changed

+104
-14
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,21 @@ getSwiftStdlibType(const clang::TypedefNameDecl *D,
322322
break;
323323

324324
case MappedCTypeKind::VaList:
325-
if (ClangTypeSize != ClangCtx.getTypeSize(ClangCtx.VoidPtrTy))
326-
return std::make_pair(Type(), "");
325+
switch (ClangCtx.getTargetInfo().getBuiltinVaListKind()) {
326+
case clang::TargetInfo::CharPtrBuiltinVaList:
327+
case clang::TargetInfo::VoidPtrBuiltinVaList:
328+
case clang::TargetInfo::PowerABIBuiltinVaList:
329+
case clang::TargetInfo::AAPCSABIBuiltinVaList:
330+
assert(ClangCtx.getTypeSize(ClangCtx.VoidPtrTy) == ClangTypeSize &&
331+
"expected va_list type to be sizeof(void *)");
332+
break;
333+
case clang::TargetInfo::AArch64ABIBuiltinVaList:
334+
break;
335+
case clang::TargetInfo::PNaClABIBuiltinVaList:
336+
case clang::TargetInfo::SystemZBuiltinVaList:
337+
case clang::TargetInfo::X86_64ABIBuiltinVaList:
338+
return std::make_pair(Type(), "");
339+
}
327340
break;
328341

329342
case MappedCTypeKind::ObjCBool:

stdlib/public/core/CTypes.swift

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,39 @@ extension UInt {
219219
}
220220

221221
/// A wrapper around a C `va_list` pointer.
222+
#if arch(arm64) && !(os(macOS) || os(iOS) || os(tvOS) || os(watchOS) || os(Windows))
223+
@_fixed_layout
224+
public struct CVaListPointer {
225+
@usableFromInline // unsafe-performance
226+
internal var _value: (__stack: UnsafeMutablePointer<Int>?,
227+
__gr_top: UnsafeMutablePointer<Int>?,
228+
__vr_top: UnsafeMutablePointer<Int>?,
229+
__gr_off: Int32,
230+
__vr_off: Int32)
231+
232+
@inlinable // unsafe-performance
233+
public // @testable
234+
init(__stack: UnsafeMutablePointer<Int>?,
235+
__gr_top: UnsafeMutablePointer<Int>?,
236+
__vr_top: UnsafeMutablePointer<Int>?,
237+
__gr_off: Int32,
238+
__vr_off: Int32) {
239+
_value = (__stack, __gr_top, __vr_top, __gr_off, __vr_off)
240+
}
241+
}
242+
243+
extension CVaListPointer : CustomDebugStringConvertible {
244+
public var debugDescription: String {
245+
return "(\(_value.__stack.debugDescription), " +
246+
"\(_value.__gr_top.debugDescription), " +
247+
"\(_value.__vr_top.debugDescription), " +
248+
"\(_value.__gr_off), " +
249+
"\(_value.__vr_off))"
250+
}
251+
}
252+
253+
#else
254+
222255
@_fixed_layout
223256
public struct CVaListPointer {
224257
@usableFromInline // unsafe-performance
@@ -238,6 +271,8 @@ extension CVaListPointer : CustomDebugStringConvertible {
238271
}
239272
}
240273

274+
#endif
275+
241276
@inlinable
242277
internal func _memcpy(
243278
dest destination: UnsafeMutableRawPointer,

stdlib/public/core/VarArgs.swift

Lines changed: 54 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,23 @@ internal let _registerSaveWords = _countGPRegisters + _countFPRegisters * _fpReg
9090
internal let _countGPRegisters = 16
9191
@usableFromInline
9292
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)
93110
#endif
94111

95112
#if arch(s390x)
@@ -391,7 +408,7 @@ extension Float80 : CVarArg, _CVarArgAligned {
391408
public var _cVarArgEncoding: [Int] {
392409
return _encodeBitsAsWords(self)
393410
}
394-
411+
395412
/// Returns the required alignment in bytes of
396413
/// the value returned by `_cVarArgEncoding`.
397414
@inlinable // FIXME(sil-serialize-all)
@@ -402,7 +419,7 @@ extension Float80 : CVarArg, _CVarArgAligned {
402419
}
403420
#endif
404421

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)))
406423

407424
/// An object that can manage the lifetime of storage backing a
408425
/// `CVaListPointer`.
@@ -412,6 +429,7 @@ extension Float80 : CVarArg, _CVarArgAligned {
412429
@_fixed_layout
413430
@usableFromInline // c-abi
414431
final internal class __VaListBuilder {
432+
#if arch(x86_64) || arch(s390x)
415433
@_fixed_layout // c-abi
416434
@usableFromInline
417435
internal struct Header {
@@ -428,15 +446,19 @@ final internal class __VaListBuilder {
428446
@usableFromInline // c-abi
429447
internal var reg_save_area: UnsafeMutablePointer<Int>?
430448
}
449+
#endif
431450

432451
@usableFromInline // c-abi
433452
internal var gpRegistersUsed = 0
434453
@usableFromInline // c-abi
435454
internal var fpRegistersUsed = 0
436455

456+
#if arch(x86_64) || arch(s390x)
437457
@usableFromInline // c-abi
438458
final // Property must be final since it is used by Builtin.addressof.
439459
internal var header = Header()
460+
#endif
461+
440462
@usableFromInline // c-abi
441463
internal var storage: ContiguousArray<Int>
442464

@@ -453,12 +475,16 @@ final internal class __VaListBuilder {
453475
internal func append(_ arg: CVarArg) {
454476
var encoded = arg._cVarArgEncoding
455477

456-
#if arch(x86_64)
478+
#if arch(x86_64) || arch(arm64)
457479
let isDouble = arg is _CVarArgPassedAsDouble
458480

459481
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
462488
for w in encoded {
463489
storage[startIndex] = w
464490
startIndex += 1
@@ -468,7 +494,12 @@ final internal class __VaListBuilder {
468494
else if encoded.count == 1
469495
&& !isDouble
470496
&& 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]
472503
gpRegistersUsed += 1
473504
}
474505
else {
@@ -493,12 +524,23 @@ final internal class __VaListBuilder {
493524

494525
@inlinable // c-abi
495526
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
502544
}
503545
}
504546

0 commit comments

Comments
 (0)