summaryrefslogtreecommitdiffstats
path: root/aarch64-new-master-VarArgs.patch
diff options
context:
space:
mode:
Diffstat (limited to 'aarch64-new-master-VarArgs.patch')
-rw-r--r--aarch64-new-master-VarArgs.patch219
1 files changed, 219 insertions, 0 deletions
diff --git a/aarch64-new-master-VarArgs.patch b/aarch64-new-master-VarArgs.patch
new file mode 100644
index 0000000..c07cef0
--- /dev/null
+++ b/aarch64-new-master-VarArgs.patch
@@ -0,0 +1,219 @@
+diff --git a/lib/ClangImporter/ImportDecl.cpp b/lib/ClangImporter/ImportDecl.cpp
+index ff503bf..c601288 100644
+--- swift/lib/ClangImporter/ImportDecl.cpp
++++ swift/lib/ClangImporter/ImportDecl.cpp
+@@ -322,8 +322,11 @@ getSwiftStdlibType(const clang::TypedefNameDecl *D,
+ break;
+
+ case MappedCTypeKind::VaList:
+- if (ClangTypeSize != ClangCtx.getTypeSize(ClangCtx.VoidPtrTy))
+- return std::make_pair(Type(), "");
++ if (ClangTypeSize != ClangCtx.getTypeSize(ClangCtx.VoidPtrTy)) {
++ if (ClangCtx.getTargetInfo().getBuiltinVaListKind() !=
++ clang::TargetInfo::AArch64ABIBuiltinVaList)
++ return std::make_pair(Type(), "");
++ }
+ break;
+
+ case MappedCTypeKind::ObjCBool:
+diff --git a/stdlib/public/core/CTypes.swift b/stdlib/public/core/CTypes.swift
+index b46fa89..bdbe228 100644
+--- swift/stdlib/public/core/CTypes.swift
++++ swift/stdlib/public/core/CTypes.swift
+@@ -219,6 +219,29 @@ extension UInt {
+ }
+
+ /// A wrapper around a C `va_list` pointer.
++#if arch(arm64) && os(Linux)
++@_fixed_layout
++public struct CVaListPointer {
++ @usableFromInline // unsafe-performance
++ internal var value: (__stack: UnsafeMutablePointer<Int>?,
++ __gr_top: UnsafeMutablePointer<Int>?,
++ __vr_top: UnsafeMutablePointer<Int>?,
++ __gr_off: Int32,
++ __vr_off: Int32)
++
++ @inlinable // unsafe-performance
++ public // @testable
++ init(__stack: UnsafeMutablePointer<Int>?,
++ __gr_top: UnsafeMutablePointer<Int>?,
++ __vr_top: UnsafeMutablePointer<Int>?,
++ __gr_off: Int32,
++ __vr_off: Int32) {
++ value = (__stack, __gr_top, __vr_top, __gr_off, __vr_off)
++ }
++}
++
++#else
++
+ @_fixed_layout
+ public struct CVaListPointer {
+ @usableFromInline // unsafe-performance
+@@ -238,6 +261,8 @@ extension CVaListPointer : CustomDebugStringConvertible {
+ }
+ }
+
++#endif
++
+ @inlinable
+ internal func _memcpy(
+ dest destination: UnsafeMutableRawPointer,
+diff --git a/stdlib/public/core/VarArgs.swift b/stdlib/public/core/VarArgs.swift
+index 5d42c58..859d987 100644
+--- swift/stdlib/public/core/VarArgs.swift
++++ swift/stdlib/public/core/VarArgs.swift
+@@ -90,6 +90,23 @@ internal let _registerSaveWords = _countGPRegisters + _countFPRegisters * _fpReg
+ internal let _countGPRegisters = 16
+ @usableFromInline
+ internal let _registerSaveWords = _countGPRegisters
++
++#elseif arch(arm64) && os(Linux)
++// ARM Procedure Call Standard for aarch64. (IHI0055B)
++// The va_list type may refer to any parameter in a parameter list may be in one
++// of three memory locations depending on its type and position in the argument
++// list :
++// 1. GP register save area x0 - x7
++// 2. 128-bit FP/SIMD register save area q0 - q7
++// 3. Stack argument area
++@usableFromInline
++internal let _countGPRegisters = 8
++@usableFromInline
++internal let _countFPRegisters = 8
++@usableFromInline
++internal let _fpRegisterWords = 16 / MemoryLayout<Int>.size
++@usableFromInline
++internal let _registerSaveWords = _countGPRegisters + (_countFPRegisters * _fpRegisterWords)
+ #endif
+
+ #if arch(s390x)
+@@ -498,6 +515,129 @@ final internal class _VaListBuilder {
+ Builtin.addressof(&self.header)))
+ }
+ }
++#elseif arch(arm64) && os(Linux)
++
++@_fixed_layout // FIXME(sil-serialize-all)
++@usableFromInline // FIXME(sil-serialize-all)
++final internal class __VaListBuilder {
++ @usableFromInline // FIXME(sil-serialize-all)
++ internal init() {
++ // Prepare the register save area.
++ allocated = _registerSaveWords
++ storage = allocStorage(wordCount: allocated)
++ // Append stack arguments after register save area.
++ count = allocated
++ }
++
++ @usableFromInline // FIXME(sil-serialize-all)
++ deinit {
++ if let allocatedStorage = storage {
++ deallocStorage(wordCount: allocated, storage: allocatedStorage)
++ }
++ }
++
++ @usableFromInline // FIXME(sil-serialize-all)
++ internal func append(_ arg: CVarArg) {
++ var encoded = arg._cVarArgEncoding
++
++ if arg is _CVarArgPassedAsDouble
++ && fpRegistersUsed < _countFPRegisters {
++ var startIndex = (fpRegistersUsed * _fpRegisterWords)
++ for w in encoded {
++ storage[startIndex] = w
++ startIndex += 1
++ }
++ fpRegistersUsed += 1
++ } else if encoded.count == 1
++ && !(arg is _CVarArgPassedAsDouble)
++ && gpRegistersUsed < _countGPRegisters {
++ var startIndex = ( _fpRegisterWords * _countFPRegisters) + gpRegistersUsed
++ storage[startIndex] = encoded[0]
++ gpRegistersUsed += 1
++ } else {
++ // Arguments in stack slot.
++ appendWords(encoded)
++ }
++ }
++
++ @usableFromInline // FIXME(sil-serialize-all)
++ internal func va_list() -> CVaListPointer {
++ let vr_top = storage + (_fpRegisterWords * _countFPRegisters)
++ let gr_top = vr_top + _countGPRegisters
++
++ return CVaListPointer(__stack: gr_top, __gr_top: gr_top,
++ __vr_top: vr_top, __gr_off: -64, __vr_off: -128)
++ }
++
++ @usableFromInline // FIXME(sil-serialize-all)
++ internal func appendWords(_ words: [Int]) {
++ let newCount = count + words.count
++ if newCount > allocated {
++ let oldAllocated = allocated
++ let oldStorage = storage
++ let oldCount = count
++
++ allocated = max(newCount, allocated * 2)
++ let newStorage = allocStorage(wordCount: allocated)
++ storage = newStorage
++ // Count is updated below.
++ if let allocatedOldStorage = oldStorage {
++ newStorage.moveInitialize(from: allocatedOldStorage, count: oldCount)
++ deallocStorage(wordCount: oldAllocated, storage: allocatedOldStorage)
++ }
++ }
++
++ let allocatedStorage = storage!
++ for word in words {
++ allocatedStorage[count] = word
++ count += 1
++ }
++ }
++
++ @usableFromInline // FIXME(sil-serialize-all)
++ internal func rawSizeAndAlignment(
++ _ wordCount: Int
++ ) -> (Builtin.Word, Builtin.Word) {
++ return ((wordCount * MemoryLayout<Int>.stride)._builtinWordValue,
++ requiredAlignmentInBytes._builtinWordValue)
++ }
++
++ @usableFromInline // FIXME(sil-serialize-all)
++ internal func allocStorage(wordCount: Int) -> UnsafeMutablePointer<Int> {
++ let (rawSize, rawAlignment) = rawSizeAndAlignment(wordCount)
++ let rawStorage = Builtin.allocRaw(rawSize, rawAlignment)
++ return UnsafeMutablePointer<Int>(rawStorage)
++ }
++
++ @usableFromInline // FIXME(sil-serialize-all)
++ internal func deallocStorage(
++ wordCount: Int, storage: UnsafeMutablePointer<Int>
++ ) {
++ let (rawSize, rawAlignment) = rawSizeAndAlignment(wordCount)
++ Builtin.deallocRaw(storage._rawValue, rawSize, rawAlignment)
++ }
++
++ @usableFromInline // FIXME(sil-serialize-all)
++ internal let requiredAlignmentInBytes = MemoryLayout<Double>.alignment
++
++ @usableFromInline // FIXME(sil-serialize-all)
++ internal var count = 0
++
++ @usableFromInline // FIXME(sil-serialize-all)
++ internal var allocated = 0
++
++ @usableFromInline // FIXME(sil-serialize-all)
++ internal var storage: UnsafeMutablePointer<Int>!
++
++ @usableFromInline // FIXME(sil-serialize-all)
++ internal var gpRegistersUsed = 0
++
++ @usableFromInline // FIXME(sil-serialize-all)
++ internal var fpRegistersUsed = 0
++
++ @usableFromInline // FIXME(sil-serialize-all)
++ internal var overflowWordsUsed = 0
++}
+
+ #else
+