diff options
author | NAKAMURA Takumi <geek4civic@gmail.com> | 2011-01-17 22:56:31 +0000 |
---|---|---|
committer | NAKAMURA Takumi <geek4civic@gmail.com> | 2011-01-17 22:56:31 +0000 |
commit | a75732201b19059a0e56a88b0eb5a0e5dd3c6ca3 (patch) | |
tree | 13d9e7076b207f03eb589af6fdf4c4bfe793055d /lib/CodeGen/TargetInfo.cpp | |
parent | 79521990f774dfd1b8bcfd62179234a223c34d84 (diff) |
lib/CodeGen/TargetInfo.cpp: Add Win64 calling conversion.
FIXME: It would be incompatible to Microsoft's in one point.
On mingw64-gcc, {i128} is expanded for args and returned as {rax, rdx}.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@123692 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/TargetInfo.cpp')
-rw-r--r-- | lib/CodeGen/TargetInfo.cpp | 51 |
1 files changed, 49 insertions, 2 deletions
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index 9c606f0c89..71fe9078d1 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -859,9 +859,14 @@ public: }; /// WinX86_64ABIInfo - The Windows X86_64 ABI information. -class WinX86_64ABIInfo : public X86_64ABIInfo { +class WinX86_64ABIInfo : public ABIInfo { + + ABIArgInfo classify(QualType Ty) const; + public: - WinX86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : X86_64ABIInfo(CGT) {} + WinX86_64ABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {} + + virtual void computeInfo(CGFunctionInfo &FI) const; virtual llvm::Value *EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CGF) const; @@ -2063,6 +2068,48 @@ llvm::Value *X86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, return ResAddr; } +ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty) const { + + if (Ty->isVoidType()) + return ABIArgInfo::getIgnore(); + + if (const EnumType *EnumTy = Ty->getAs<EnumType>()) + Ty = EnumTy->getDecl()->getIntegerType(); + + uint64_t Size = getContext().getTypeSize(Ty); + + if (const RecordType *RT = Ty->getAs<RecordType>()) { + if (hasNonTrivialDestructorOrCopyConstructor(RT) + || RT->getDecl()->hasFlexibleArrayMember()) + return ABIArgInfo::getIndirect(0, /*ByVal=*/false); + + // FIXME: mingw64-gcc emits 128-bit struct as i128 + if (Size <= 128 + && (Size & (Size - 1)) == 0) + return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), + Size)); + + return ABIArgInfo::getIndirect(0, /*ByVal=*/false); + } + + if (Ty->isPromotableIntegerType()) + return ABIArgInfo::getExtend(); + + return ABIArgInfo::getDirect(); +} + +void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { + + QualType RetTy = FI.getReturnType(); + FI.getReturnInfo() = classify(RetTy); + + // AMD64-ABI 3.2.3p3: Once arguments are classified, the registers + // get assigned (in left-to-right order) for passing as follows... + for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); + it != ie; ++it) + it->info = classify(it->type); +} + llvm::Value *WinX86_64ABIInfo::EmitVAArg(llvm::Value *VAListAddr, QualType Ty, CodeGenFunction &CGF) const { const llvm::Type *BP = llvm::Type::getInt8PtrTy(CGF.getLLVMContext()); |