1992cb984SSergei Barannikov //===- X86.cpp ------------------------------------------------------------===// 2992cb984SSergei Barannikov // 3992cb984SSergei Barannikov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4992cb984SSergei Barannikov // See https://llvm.org/LICENSE.txt for license information. 5992cb984SSergei Barannikov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6992cb984SSergei Barannikov // 7992cb984SSergei Barannikov //===----------------------------------------------------------------------===// 8992cb984SSergei Barannikov 9992cb984SSergei Barannikov #include "ABIInfoImpl.h" 10992cb984SSergei Barannikov #include "TargetInfo.h" 11992cb984SSergei Barannikov #include "clang/Basic/DiagnosticFrontend.h" 12992cb984SSergei Barannikov #include "llvm/ADT/SmallBitVector.h" 13992cb984SSergei Barannikov 14992cb984SSergei Barannikov using namespace clang; 15992cb984SSergei Barannikov using namespace clang::CodeGen; 16992cb984SSergei Barannikov 17992cb984SSergei Barannikov namespace { 18992cb984SSergei Barannikov 19992cb984SSergei Barannikov /// IsX86_MMXType - Return true if this is an MMX type. 20992cb984SSergei Barannikov bool IsX86_MMXType(llvm::Type *IRType) { 21992cb984SSergei Barannikov // Return true if the type is an MMX type <2 x i32>, <4 x i16>, or <8 x i8>. 22992cb984SSergei Barannikov return IRType->isVectorTy() && IRType->getPrimitiveSizeInBits() == 64 && 23992cb984SSergei Barannikov cast<llvm::VectorType>(IRType)->getElementType()->isIntegerTy() && 24992cb984SSergei Barannikov IRType->getScalarSizeInBits() != 64; 25992cb984SSergei Barannikov } 26992cb984SSergei Barannikov 27992cb984SSergei Barannikov static llvm::Type *X86AdjustInlineAsmType(CodeGen::CodeGenFunction &CGF, 28992cb984SSergei Barannikov StringRef Constraint, 29992cb984SSergei Barannikov llvm::Type *Ty) { 308d6e82d5SPhoebe Wang if (Constraint == "k") { 318d6e82d5SPhoebe Wang llvm::Type *Int1Ty = llvm::Type::getInt1Ty(CGF.getLLVMContext()); 328d6e82d5SPhoebe Wang return llvm::FixedVectorType::get(Int1Ty, Ty->getScalarSizeInBits()); 338d6e82d5SPhoebe Wang } 348d6e82d5SPhoebe Wang 35992cb984SSergei Barannikov // No operation needed 36992cb984SSergei Barannikov return Ty; 37992cb984SSergei Barannikov } 38992cb984SSergei Barannikov 39992cb984SSergei Barannikov /// Returns true if this type can be passed in SSE registers with the 40992cb984SSergei Barannikov /// X86_VectorCall calling convention. Shared between x86_32 and x86_64. 41992cb984SSergei Barannikov static bool isX86VectorTypeForVectorCall(ASTContext &Context, QualType Ty) { 42992cb984SSergei Barannikov if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) { 43992cb984SSergei Barannikov if (BT->isFloatingPoint() && BT->getKind() != BuiltinType::Half) { 44992cb984SSergei Barannikov if (BT->getKind() == BuiltinType::LongDouble) { 45992cb984SSergei Barannikov if (&Context.getTargetInfo().getLongDoubleFormat() == 46992cb984SSergei Barannikov &llvm::APFloat::x87DoubleExtended()) 47992cb984SSergei Barannikov return false; 48992cb984SSergei Barannikov } 49992cb984SSergei Barannikov return true; 50992cb984SSergei Barannikov } 51992cb984SSergei Barannikov } else if (const VectorType *VT = Ty->getAs<VectorType>()) { 52992cb984SSergei Barannikov // vectorcall can pass XMM, YMM, and ZMM vectors. We don't pass SSE1 MMX 53992cb984SSergei Barannikov // registers specially. 54992cb984SSergei Barannikov unsigned VecSize = Context.getTypeSize(VT); 55992cb984SSergei Barannikov if (VecSize == 128 || VecSize == 256 || VecSize == 512) 56992cb984SSergei Barannikov return true; 57992cb984SSergei Barannikov } 58992cb984SSergei Barannikov return false; 59992cb984SSergei Barannikov } 60992cb984SSergei Barannikov 61992cb984SSergei Barannikov /// Returns true if this aggregate is small enough to be passed in SSE registers 62992cb984SSergei Barannikov /// in the X86_VectorCall calling convention. Shared between x86_32 and x86_64. 63992cb984SSergei Barannikov static bool isX86VectorCallAggregateSmallEnough(uint64_t NumMembers) { 64992cb984SSergei Barannikov return NumMembers <= 4; 65992cb984SSergei Barannikov } 66992cb984SSergei Barannikov 67992cb984SSergei Barannikov /// Returns a Homogeneous Vector Aggregate ABIArgInfo, used in X86. 68992cb984SSergei Barannikov static ABIArgInfo getDirectX86Hva(llvm::Type* T = nullptr) { 69992cb984SSergei Barannikov auto AI = ABIArgInfo::getDirect(T); 70992cb984SSergei Barannikov AI.setInReg(true); 71992cb984SSergei Barannikov AI.setCanBeFlattened(false); 72992cb984SSergei Barannikov return AI; 73992cb984SSergei Barannikov } 74992cb984SSergei Barannikov 75992cb984SSergei Barannikov //===----------------------------------------------------------------------===// 76992cb984SSergei Barannikov // X86-32 ABI Implementation 77992cb984SSergei Barannikov //===----------------------------------------------------------------------===// 78992cb984SSergei Barannikov 79992cb984SSergei Barannikov /// Similar to llvm::CCState, but for Clang. 80992cb984SSergei Barannikov struct CCState { 81992cb984SSergei Barannikov CCState(CGFunctionInfo &FI) 82c8c075e8SReid Kleckner : IsPreassigned(FI.arg_size()), CC(FI.getCallingConvention()), 83c8c075e8SReid Kleckner Required(FI.getRequiredArgs()), IsDelegateCall(FI.isDelegateCall()) {} 84992cb984SSergei Barannikov 85992cb984SSergei Barannikov llvm::SmallBitVector IsPreassigned; 86992cb984SSergei Barannikov unsigned CC = CallingConv::CC_C; 87992cb984SSergei Barannikov unsigned FreeRegs = 0; 88992cb984SSergei Barannikov unsigned FreeSSERegs = 0; 89c8c075e8SReid Kleckner RequiredArgs Required; 90c8c075e8SReid Kleckner bool IsDelegateCall = false; 91992cb984SSergei Barannikov }; 92992cb984SSergei Barannikov 93992cb984SSergei Barannikov /// X86_32ABIInfo - The X86-32 ABI information. 94992cb984SSergei Barannikov class X86_32ABIInfo : public ABIInfo { 95992cb984SSergei Barannikov enum Class { 96992cb984SSergei Barannikov Integer, 97992cb984SSergei Barannikov Float 98992cb984SSergei Barannikov }; 99992cb984SSergei Barannikov 100992cb984SSergei Barannikov static const unsigned MinABIStackAlignInBytes = 4; 101992cb984SSergei Barannikov 102992cb984SSergei Barannikov bool IsDarwinVectorABI; 103992cb984SSergei Barannikov bool IsRetSmallStructInRegABI; 104992cb984SSergei Barannikov bool IsWin32StructABI; 105992cb984SSergei Barannikov bool IsSoftFloatABI; 106992cb984SSergei Barannikov bool IsMCUABI; 107992cb984SSergei Barannikov bool IsLinuxABI; 108992cb984SSergei Barannikov unsigned DefaultNumRegisterParameters; 109992cb984SSergei Barannikov 110992cb984SSergei Barannikov static bool isRegisterSize(unsigned Size) { 111992cb984SSergei Barannikov return (Size == 8 || Size == 16 || Size == 32 || Size == 64); 112992cb984SSergei Barannikov } 113992cb984SSergei Barannikov 114992cb984SSergei Barannikov bool isHomogeneousAggregateBaseType(QualType Ty) const override { 115992cb984SSergei Barannikov // FIXME: Assumes vectorcall is in use. 116992cb984SSergei Barannikov return isX86VectorTypeForVectorCall(getContext(), Ty); 117992cb984SSergei Barannikov } 118992cb984SSergei Barannikov 119992cb984SSergei Barannikov bool isHomogeneousAggregateSmallEnough(const Type *Ty, 120992cb984SSergei Barannikov uint64_t NumMembers) const override { 121992cb984SSergei Barannikov // FIXME: Assumes vectorcall is in use. 122992cb984SSergei Barannikov return isX86VectorCallAggregateSmallEnough(NumMembers); 123992cb984SSergei Barannikov } 124992cb984SSergei Barannikov 125992cb984SSergei Barannikov bool shouldReturnTypeInRegister(QualType Ty, ASTContext &Context) const; 126992cb984SSergei Barannikov 127992cb984SSergei Barannikov /// getIndirectResult - Give a source type \arg Ty, return a suitable result 128992cb984SSergei Barannikov /// such that the argument will be passed in memory. 129992cb984SSergei Barannikov ABIArgInfo getIndirectResult(QualType Ty, bool ByVal, CCState &State) const; 130992cb984SSergei Barannikov 131992cb984SSergei Barannikov ABIArgInfo getIndirectReturnResult(QualType Ty, CCState &State) const; 132992cb984SSergei Barannikov 133992cb984SSergei Barannikov /// Return the alignment to use for the given type on the stack. 134992cb984SSergei Barannikov unsigned getTypeStackAlignInBytes(QualType Ty, unsigned Align) const; 135992cb984SSergei Barannikov 136992cb984SSergei Barannikov Class classify(QualType Ty) const; 137992cb984SSergei Barannikov ABIArgInfo classifyReturnType(QualType RetTy, CCState &State) const; 13827dab4d3SAmy Huang ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State, 139c8c075e8SReid Kleckner unsigned ArgIndex) const; 140992cb984SSergei Barannikov 141992cb984SSergei Barannikov /// Updates the number of available free registers, returns 142992cb984SSergei Barannikov /// true if any registers were allocated. 143992cb984SSergei Barannikov bool updateFreeRegs(QualType Ty, CCState &State) const; 144992cb984SSergei Barannikov 145992cb984SSergei Barannikov bool shouldAggregateUseDirect(QualType Ty, CCState &State, bool &InReg, 146992cb984SSergei Barannikov bool &NeedsPadding) const; 147992cb984SSergei Barannikov bool shouldPrimitiveUseInReg(QualType Ty, CCState &State) const; 148992cb984SSergei Barannikov 149992cb984SSergei Barannikov bool canExpandIndirectArgument(QualType Ty) const; 150992cb984SSergei Barannikov 151992cb984SSergei Barannikov /// Rewrite the function info so that all memory arguments use 152992cb984SSergei Barannikov /// inalloca. 153992cb984SSergei Barannikov void rewriteWithInAlloca(CGFunctionInfo &FI) const; 154992cb984SSergei Barannikov 155992cb984SSergei Barannikov void addFieldToArgStruct(SmallVector<llvm::Type *, 6> &FrameFields, 156992cb984SSergei Barannikov CharUnits &StackOffset, ABIArgInfo &Info, 157992cb984SSergei Barannikov QualType Type) const; 158992cb984SSergei Barannikov void runVectorCallFirstPass(CGFunctionInfo &FI, CCState &State) const; 159992cb984SSergei Barannikov 160992cb984SSergei Barannikov public: 161992cb984SSergei Barannikov 162992cb984SSergei Barannikov void computeInfo(CGFunctionInfo &FI) const override; 1636d973b45SMariya Podchishchaeva RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, 1646d973b45SMariya Podchishchaeva AggValueSlot Slot) const override; 165992cb984SSergei Barannikov 166992cb984SSergei Barannikov X86_32ABIInfo(CodeGen::CodeGenTypes &CGT, bool DarwinVectorABI, 167992cb984SSergei Barannikov bool RetSmallStructInRegABI, bool Win32StructABI, 168992cb984SSergei Barannikov unsigned NumRegisterParameters, bool SoftFloatABI) 169992cb984SSergei Barannikov : ABIInfo(CGT), IsDarwinVectorABI(DarwinVectorABI), 170992cb984SSergei Barannikov IsRetSmallStructInRegABI(RetSmallStructInRegABI), 171992cb984SSergei Barannikov IsWin32StructABI(Win32StructABI), IsSoftFloatABI(SoftFloatABI), 172992cb984SSergei Barannikov IsMCUABI(CGT.getTarget().getTriple().isOSIAMCU()), 173992cb984SSergei Barannikov IsLinuxABI(CGT.getTarget().getTriple().isOSLinux() || 174992cb984SSergei Barannikov CGT.getTarget().getTriple().isOSCygMing()), 175992cb984SSergei Barannikov DefaultNumRegisterParameters(NumRegisterParameters) {} 176992cb984SSergei Barannikov }; 177992cb984SSergei Barannikov 178992cb984SSergei Barannikov class X86_32SwiftABIInfo : public SwiftABIInfo { 179992cb984SSergei Barannikov public: 180992cb984SSergei Barannikov explicit X86_32SwiftABIInfo(CodeGenTypes &CGT) 181992cb984SSergei Barannikov : SwiftABIInfo(CGT, /*SwiftErrorInRegister=*/false) {} 182992cb984SSergei Barannikov 183992cb984SSergei Barannikov bool shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys, 184992cb984SSergei Barannikov bool AsReturnValue) const override { 185992cb984SSergei Barannikov // LLVM's x86-32 lowering currently only assigns up to three 186992cb984SSergei Barannikov // integer registers and three fp registers. Oddly, it'll use up to 187992cb984SSergei Barannikov // four vector registers for vectors, but those can overlap with the 188992cb984SSergei Barannikov // scalar registers. 189992cb984SSergei Barannikov return occupiesMoreThan(ComponentTys, /*total=*/3); 190992cb984SSergei Barannikov } 191992cb984SSergei Barannikov }; 192992cb984SSergei Barannikov 193992cb984SSergei Barannikov class X86_32TargetCodeGenInfo : public TargetCodeGenInfo { 194992cb984SSergei Barannikov public: 195992cb984SSergei Barannikov X86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, bool DarwinVectorABI, 196992cb984SSergei Barannikov bool RetSmallStructInRegABI, bool Win32StructABI, 197992cb984SSergei Barannikov unsigned NumRegisterParameters, bool SoftFloatABI) 198992cb984SSergei Barannikov : TargetCodeGenInfo(std::make_unique<X86_32ABIInfo>( 199992cb984SSergei Barannikov CGT, DarwinVectorABI, RetSmallStructInRegABI, Win32StructABI, 200992cb984SSergei Barannikov NumRegisterParameters, SoftFloatABI)) { 201992cb984SSergei Barannikov SwiftInfo = std::make_unique<X86_32SwiftABIInfo>(CGT); 202992cb984SSergei Barannikov } 203992cb984SSergei Barannikov 204992cb984SSergei Barannikov static bool isStructReturnInRegABI( 205992cb984SSergei Barannikov const llvm::Triple &Triple, const CodeGenOptions &Opts); 206992cb984SSergei Barannikov 207992cb984SSergei Barannikov void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, 208992cb984SSergei Barannikov CodeGen::CodeGenModule &CGM) const override; 209992cb984SSergei Barannikov 210992cb984SSergei Barannikov int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override { 211992cb984SSergei Barannikov // Darwin uses different dwarf register numbers for EH. 212992cb984SSergei Barannikov if (CGM.getTarget().getTriple().isOSDarwin()) return 5; 213992cb984SSergei Barannikov return 4; 214992cb984SSergei Barannikov } 215992cb984SSergei Barannikov 216992cb984SSergei Barannikov bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 217992cb984SSergei Barannikov llvm::Value *Address) const override; 218992cb984SSergei Barannikov 219992cb984SSergei Barannikov llvm::Type* adjustInlineAsmType(CodeGen::CodeGenFunction &CGF, 220992cb984SSergei Barannikov StringRef Constraint, 221992cb984SSergei Barannikov llvm::Type* Ty) const override { 222992cb984SSergei Barannikov return X86AdjustInlineAsmType(CGF, Constraint, Ty); 223992cb984SSergei Barannikov } 224992cb984SSergei Barannikov 225992cb984SSergei Barannikov void addReturnRegisterOutputs(CodeGenFunction &CGF, LValue ReturnValue, 226992cb984SSergei Barannikov std::string &Constraints, 227992cb984SSergei Barannikov std::vector<llvm::Type *> &ResultRegTypes, 228992cb984SSergei Barannikov std::vector<llvm::Type *> &ResultTruncRegTypes, 229992cb984SSergei Barannikov std::vector<LValue> &ResultRegDests, 230992cb984SSergei Barannikov std::string &AsmString, 231992cb984SSergei Barannikov unsigned NumOutputs) const override; 232992cb984SSergei Barannikov 233992cb984SSergei Barannikov StringRef getARCRetainAutoreleasedReturnValueMarker() const override { 234992cb984SSergei Barannikov return "movl\t%ebp, %ebp" 235992cb984SSergei Barannikov "\t\t// marker for objc_retainAutoreleaseReturnValue"; 236992cb984SSergei Barannikov } 237992cb984SSergei Barannikov }; 238992cb984SSergei Barannikov 239992cb984SSergei Barannikov } 240992cb984SSergei Barannikov 241992cb984SSergei Barannikov /// Rewrite input constraint references after adding some output constraints. 242992cb984SSergei Barannikov /// In the case where there is one output and one input and we add one output, 243992cb984SSergei Barannikov /// we need to replace all operand references greater than or equal to 1: 244992cb984SSergei Barannikov /// mov $0, $1 245992cb984SSergei Barannikov /// mov eax, $1 246992cb984SSergei Barannikov /// The result will be: 247992cb984SSergei Barannikov /// mov $0, $2 248992cb984SSergei Barannikov /// mov eax, $2 249992cb984SSergei Barannikov static void rewriteInputConstraintReferences(unsigned FirstIn, 250992cb984SSergei Barannikov unsigned NumNewOuts, 251992cb984SSergei Barannikov std::string &AsmString) { 252992cb984SSergei Barannikov std::string Buf; 253992cb984SSergei Barannikov llvm::raw_string_ostream OS(Buf); 254992cb984SSergei Barannikov size_t Pos = 0; 255992cb984SSergei Barannikov while (Pos < AsmString.size()) { 256992cb984SSergei Barannikov size_t DollarStart = AsmString.find('$', Pos); 257992cb984SSergei Barannikov if (DollarStart == std::string::npos) 258992cb984SSergei Barannikov DollarStart = AsmString.size(); 259992cb984SSergei Barannikov size_t DollarEnd = AsmString.find_first_not_of('$', DollarStart); 260992cb984SSergei Barannikov if (DollarEnd == std::string::npos) 261992cb984SSergei Barannikov DollarEnd = AsmString.size(); 262992cb984SSergei Barannikov OS << StringRef(&AsmString[Pos], DollarEnd - Pos); 263992cb984SSergei Barannikov Pos = DollarEnd; 264992cb984SSergei Barannikov size_t NumDollars = DollarEnd - DollarStart; 265992cb984SSergei Barannikov if (NumDollars % 2 != 0 && Pos < AsmString.size()) { 266992cb984SSergei Barannikov // We have an operand reference. 267992cb984SSergei Barannikov size_t DigitStart = Pos; 268992cb984SSergei Barannikov if (AsmString[DigitStart] == '{') { 269992cb984SSergei Barannikov OS << '{'; 270992cb984SSergei Barannikov ++DigitStart; 271992cb984SSergei Barannikov } 272992cb984SSergei Barannikov size_t DigitEnd = AsmString.find_first_not_of("0123456789", DigitStart); 273992cb984SSergei Barannikov if (DigitEnd == std::string::npos) 274992cb984SSergei Barannikov DigitEnd = AsmString.size(); 275992cb984SSergei Barannikov StringRef OperandStr(&AsmString[DigitStart], DigitEnd - DigitStart); 276992cb984SSergei Barannikov unsigned OperandIndex; 277992cb984SSergei Barannikov if (!OperandStr.getAsInteger(10, OperandIndex)) { 278992cb984SSergei Barannikov if (OperandIndex >= FirstIn) 279992cb984SSergei Barannikov OperandIndex += NumNewOuts; 280992cb984SSergei Barannikov OS << OperandIndex; 281992cb984SSergei Barannikov } else { 282992cb984SSergei Barannikov OS << OperandStr; 283992cb984SSergei Barannikov } 284992cb984SSergei Barannikov Pos = DigitEnd; 285992cb984SSergei Barannikov } 286992cb984SSergei Barannikov } 2871b913cdeSJOE1994 AsmString = std::move(Buf); 288992cb984SSergei Barannikov } 289992cb984SSergei Barannikov 290992cb984SSergei Barannikov /// Add output constraints for EAX:EDX because they are return registers. 291992cb984SSergei Barannikov void X86_32TargetCodeGenInfo::addReturnRegisterOutputs( 292992cb984SSergei Barannikov CodeGenFunction &CGF, LValue ReturnSlot, std::string &Constraints, 293992cb984SSergei Barannikov std::vector<llvm::Type *> &ResultRegTypes, 294992cb984SSergei Barannikov std::vector<llvm::Type *> &ResultTruncRegTypes, 295992cb984SSergei Barannikov std::vector<LValue> &ResultRegDests, std::string &AsmString, 296992cb984SSergei Barannikov unsigned NumOutputs) const { 297992cb984SSergei Barannikov uint64_t RetWidth = CGF.getContext().getTypeSize(ReturnSlot.getType()); 298992cb984SSergei Barannikov 299992cb984SSergei Barannikov // Use the EAX constraint if the width is 32 or smaller and EAX:EDX if it is 300992cb984SSergei Barannikov // larger. 301992cb984SSergei Barannikov if (!Constraints.empty()) 302992cb984SSergei Barannikov Constraints += ','; 303992cb984SSergei Barannikov if (RetWidth <= 32) { 304992cb984SSergei Barannikov Constraints += "={eax}"; 305992cb984SSergei Barannikov ResultRegTypes.push_back(CGF.Int32Ty); 306992cb984SSergei Barannikov } else { 307992cb984SSergei Barannikov // Use the 'A' constraint for EAX:EDX. 308992cb984SSergei Barannikov Constraints += "=A"; 309992cb984SSergei Barannikov ResultRegTypes.push_back(CGF.Int64Ty); 310992cb984SSergei Barannikov } 311992cb984SSergei Barannikov 312992cb984SSergei Barannikov // Truncate EAX or EAX:EDX to an integer of the appropriate size. 313992cb984SSergei Barannikov llvm::Type *CoerceTy = llvm::IntegerType::get(CGF.getLLVMContext(), RetWidth); 314992cb984SSergei Barannikov ResultTruncRegTypes.push_back(CoerceTy); 315992cb984SSergei Barannikov 316992cb984SSergei Barannikov // Coerce the integer by bitcasting the return slot pointer. 3173575d23cSAhmed Bougacha ReturnSlot.setAddress(ReturnSlot.getAddress().withElementType(CoerceTy)); 318992cb984SSergei Barannikov ResultRegDests.push_back(ReturnSlot); 319992cb984SSergei Barannikov 320992cb984SSergei Barannikov rewriteInputConstraintReferences(NumOutputs, 1, AsmString); 321992cb984SSergei Barannikov } 322992cb984SSergei Barannikov 323992cb984SSergei Barannikov /// shouldReturnTypeInRegister - Determine if the given type should be 324992cb984SSergei Barannikov /// returned in a register (for the Darwin and MCU ABI). 325992cb984SSergei Barannikov bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty, 326992cb984SSergei Barannikov ASTContext &Context) const { 327992cb984SSergei Barannikov uint64_t Size = Context.getTypeSize(Ty); 328992cb984SSergei Barannikov 329992cb984SSergei Barannikov // For i386, type must be register sized. 330992cb984SSergei Barannikov // For the MCU ABI, it only needs to be <= 8-byte 331992cb984SSergei Barannikov if ((IsMCUABI && Size > 64) || (!IsMCUABI && !isRegisterSize(Size))) 332992cb984SSergei Barannikov return false; 333992cb984SSergei Barannikov 334992cb984SSergei Barannikov if (Ty->isVectorType()) { 335992cb984SSergei Barannikov // 64- and 128- bit vectors inside structures are not returned in 336992cb984SSergei Barannikov // registers. 337992cb984SSergei Barannikov if (Size == 64 || Size == 128) 338992cb984SSergei Barannikov return false; 339992cb984SSergei Barannikov 340992cb984SSergei Barannikov return true; 341992cb984SSergei Barannikov } 342992cb984SSergei Barannikov 343992cb984SSergei Barannikov // If this is a builtin, pointer, enum, complex type, member pointer, or 344992cb984SSergei Barannikov // member function pointer it is ok. 345992cb984SSergei Barannikov if (Ty->getAs<BuiltinType>() || Ty->hasPointerRepresentation() || 346992cb984SSergei Barannikov Ty->isAnyComplexType() || Ty->isEnumeralType() || 347992cb984SSergei Barannikov Ty->isBlockPointerType() || Ty->isMemberPointerType()) 348992cb984SSergei Barannikov return true; 349992cb984SSergei Barannikov 350992cb984SSergei Barannikov // Arrays are treated like records. 351992cb984SSergei Barannikov if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) 352992cb984SSergei Barannikov return shouldReturnTypeInRegister(AT->getElementType(), Context); 353992cb984SSergei Barannikov 354992cb984SSergei Barannikov // Otherwise, it must be a record type. 355992cb984SSergei Barannikov const RecordType *RT = Ty->getAs<RecordType>(); 356992cb984SSergei Barannikov if (!RT) return false; 357992cb984SSergei Barannikov 358992cb984SSergei Barannikov // FIXME: Traverse bases here too. 359992cb984SSergei Barannikov 360992cb984SSergei Barannikov // Structure types are passed in register if all fields would be 361992cb984SSergei Barannikov // passed in a register. 362992cb984SSergei Barannikov for (const auto *FD : RT->getDecl()->fields()) { 363992cb984SSergei Barannikov // Empty fields are ignored. 364992cb984SSergei Barannikov if (isEmptyField(Context, FD, true)) 365992cb984SSergei Barannikov continue; 366992cb984SSergei Barannikov 367992cb984SSergei Barannikov // Check fields recursively. 368992cb984SSergei Barannikov if (!shouldReturnTypeInRegister(FD->getType(), Context)) 369992cb984SSergei Barannikov return false; 370992cb984SSergei Barannikov } 371992cb984SSergei Barannikov return true; 372992cb984SSergei Barannikov } 373992cb984SSergei Barannikov 374992cb984SSergei Barannikov static bool is32Or64BitBasicType(QualType Ty, ASTContext &Context) { 375992cb984SSergei Barannikov // Treat complex types as the element type. 376992cb984SSergei Barannikov if (const ComplexType *CTy = Ty->getAs<ComplexType>()) 377992cb984SSergei Barannikov Ty = CTy->getElementType(); 378992cb984SSergei Barannikov 379992cb984SSergei Barannikov // Check for a type which we know has a simple scalar argument-passing 380992cb984SSergei Barannikov // convention without any padding. (We're specifically looking for 32 381992cb984SSergei Barannikov // and 64-bit integer and integer-equivalents, float, and double.) 382992cb984SSergei Barannikov if (!Ty->getAs<BuiltinType>() && !Ty->hasPointerRepresentation() && 383992cb984SSergei Barannikov !Ty->isEnumeralType() && !Ty->isBlockPointerType()) 384992cb984SSergei Barannikov return false; 385992cb984SSergei Barannikov 386992cb984SSergei Barannikov uint64_t Size = Context.getTypeSize(Ty); 387992cb984SSergei Barannikov return Size == 32 || Size == 64; 388992cb984SSergei Barannikov } 389992cb984SSergei Barannikov 390992cb984SSergei Barannikov static bool addFieldSizes(ASTContext &Context, const RecordDecl *RD, 391992cb984SSergei Barannikov uint64_t &Size) { 392992cb984SSergei Barannikov for (const auto *FD : RD->fields()) { 393992cb984SSergei Barannikov // Scalar arguments on the stack get 4 byte alignment on x86. If the 394992cb984SSergei Barannikov // argument is smaller than 32-bits, expanding the struct will create 395992cb984SSergei Barannikov // alignment padding. 396992cb984SSergei Barannikov if (!is32Or64BitBasicType(FD->getType(), Context)) 397992cb984SSergei Barannikov return false; 398992cb984SSergei Barannikov 399992cb984SSergei Barannikov // FIXME: Reject bit-fields wholesale; there are two problems, we don't know 400992cb984SSergei Barannikov // how to expand them yet, and the predicate for telling if a bitfield still 401992cb984SSergei Barannikov // counts as "basic" is more complicated than what we were doing previously. 402992cb984SSergei Barannikov if (FD->isBitField()) 403992cb984SSergei Barannikov return false; 404992cb984SSergei Barannikov 405992cb984SSergei Barannikov Size += Context.getTypeSize(FD->getType()); 406992cb984SSergei Barannikov } 407992cb984SSergei Barannikov return true; 408992cb984SSergei Barannikov } 409992cb984SSergei Barannikov 410992cb984SSergei Barannikov static bool addBaseAndFieldSizes(ASTContext &Context, const CXXRecordDecl *RD, 411992cb984SSergei Barannikov uint64_t &Size) { 412992cb984SSergei Barannikov // Don't do this if there are any non-empty bases. 413992cb984SSergei Barannikov for (const CXXBaseSpecifier &Base : RD->bases()) { 414992cb984SSergei Barannikov if (!addBaseAndFieldSizes(Context, Base.getType()->getAsCXXRecordDecl(), 415992cb984SSergei Barannikov Size)) 416992cb984SSergei Barannikov return false; 417992cb984SSergei Barannikov } 418992cb984SSergei Barannikov if (!addFieldSizes(Context, RD, Size)) 419992cb984SSergei Barannikov return false; 420992cb984SSergei Barannikov return true; 421992cb984SSergei Barannikov } 422992cb984SSergei Barannikov 423992cb984SSergei Barannikov /// Test whether an argument type which is to be passed indirectly (on the 424992cb984SSergei Barannikov /// stack) would have the equivalent layout if it was expanded into separate 425992cb984SSergei Barannikov /// arguments. If so, we prefer to do the latter to avoid inhibiting 426992cb984SSergei Barannikov /// optimizations. 427992cb984SSergei Barannikov bool X86_32ABIInfo::canExpandIndirectArgument(QualType Ty) const { 428992cb984SSergei Barannikov // We can only expand structure types. 429992cb984SSergei Barannikov const RecordType *RT = Ty->getAs<RecordType>(); 430992cb984SSergei Barannikov if (!RT) 431992cb984SSergei Barannikov return false; 432992cb984SSergei Barannikov const RecordDecl *RD = RT->getDecl(); 433992cb984SSergei Barannikov uint64_t Size = 0; 434992cb984SSergei Barannikov if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { 435992cb984SSergei Barannikov if (!IsWin32StructABI) { 436992cb984SSergei Barannikov // On non-Windows, we have to conservatively match our old bitcode 437992cb984SSergei Barannikov // prototypes in order to be ABI-compatible at the bitcode level. 438992cb984SSergei Barannikov if (!CXXRD->isCLike()) 439992cb984SSergei Barannikov return false; 440992cb984SSergei Barannikov } else { 441992cb984SSergei Barannikov // Don't do this for dynamic classes. 442992cb984SSergei Barannikov if (CXXRD->isDynamicClass()) 443992cb984SSergei Barannikov return false; 444992cb984SSergei Barannikov } 445992cb984SSergei Barannikov if (!addBaseAndFieldSizes(getContext(), CXXRD, Size)) 446992cb984SSergei Barannikov return false; 447992cb984SSergei Barannikov } else { 448992cb984SSergei Barannikov if (!addFieldSizes(getContext(), RD, Size)) 449992cb984SSergei Barannikov return false; 450992cb984SSergei Barannikov } 451992cb984SSergei Barannikov 452992cb984SSergei Barannikov // We can do this if there was no alignment padding. 453992cb984SSergei Barannikov return Size == getContext().getTypeSize(Ty); 454992cb984SSergei Barannikov } 455992cb984SSergei Barannikov 456992cb984SSergei Barannikov ABIArgInfo X86_32ABIInfo::getIndirectReturnResult(QualType RetTy, CCState &State) const { 457992cb984SSergei Barannikov // If the return value is indirect, then the hidden argument is consuming one 458992cb984SSergei Barannikov // integer register. 4597e01e647SPhoebe Wang if (State.CC != llvm::CallingConv::X86_FastCall && 4607e01e647SPhoebe Wang State.CC != llvm::CallingConv::X86_VectorCall && State.FreeRegs) { 461992cb984SSergei Barannikov --State.FreeRegs; 462992cb984SSergei Barannikov if (!IsMCUABI) 463992cb984SSergei Barannikov return getNaturalAlignIndirectInReg(RetTy); 464992cb984SSergei Barannikov } 465992cb984SSergei Barannikov return getNaturalAlignIndirect(RetTy, /*ByVal=*/false); 466992cb984SSergei Barannikov } 467992cb984SSergei Barannikov 468992cb984SSergei Barannikov ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, 469992cb984SSergei Barannikov CCState &State) const { 470992cb984SSergei Barannikov if (RetTy->isVoidType()) 471992cb984SSergei Barannikov return ABIArgInfo::getIgnore(); 472992cb984SSergei Barannikov 473992cb984SSergei Barannikov const Type *Base = nullptr; 474992cb984SSergei Barannikov uint64_t NumElts = 0; 475992cb984SSergei Barannikov if ((State.CC == llvm::CallingConv::X86_VectorCall || 476992cb984SSergei Barannikov State.CC == llvm::CallingConv::X86_RegCall) && 477992cb984SSergei Barannikov isHomogeneousAggregate(RetTy, Base, NumElts)) { 478992cb984SSergei Barannikov // The LLVM struct type for such an aggregate should lower properly. 479992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 480992cb984SSergei Barannikov } 481992cb984SSergei Barannikov 482992cb984SSergei Barannikov if (const VectorType *VT = RetTy->getAs<VectorType>()) { 483992cb984SSergei Barannikov // On Darwin, some vectors are returned in registers. 484992cb984SSergei Barannikov if (IsDarwinVectorABI) { 485992cb984SSergei Barannikov uint64_t Size = getContext().getTypeSize(RetTy); 486992cb984SSergei Barannikov 487992cb984SSergei Barannikov // 128-bit vectors are a special case; they are returned in 488992cb984SSergei Barannikov // registers and we need to make sure to pick a type the LLVM 489992cb984SSergei Barannikov // backend will like. 490992cb984SSergei Barannikov if (Size == 128) 491992cb984SSergei Barannikov return ABIArgInfo::getDirect(llvm::FixedVectorType::get( 492992cb984SSergei Barannikov llvm::Type::getInt64Ty(getVMContext()), 2)); 493992cb984SSergei Barannikov 494992cb984SSergei Barannikov // Always return in register if it fits in a general purpose 495992cb984SSergei Barannikov // register, or if it is 64 bits and has a single element. 496992cb984SSergei Barannikov if ((Size == 8 || Size == 16 || Size == 32) || 497992cb984SSergei Barannikov (Size == 64 && VT->getNumElements() == 1)) 498992cb984SSergei Barannikov return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), 499992cb984SSergei Barannikov Size)); 500992cb984SSergei Barannikov 501992cb984SSergei Barannikov return getIndirectReturnResult(RetTy, State); 502992cb984SSergei Barannikov } 503992cb984SSergei Barannikov 504992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 505992cb984SSergei Barannikov } 506992cb984SSergei Barannikov 507992cb984SSergei Barannikov if (isAggregateTypeForABI(RetTy)) { 508992cb984SSergei Barannikov if (const RecordType *RT = RetTy->getAs<RecordType>()) { 509992cb984SSergei Barannikov // Structures with flexible arrays are always indirect. 510992cb984SSergei Barannikov if (RT->getDecl()->hasFlexibleArrayMember()) 511992cb984SSergei Barannikov return getIndirectReturnResult(RetTy, State); 512992cb984SSergei Barannikov } 513992cb984SSergei Barannikov 514992cb984SSergei Barannikov // If specified, structs and unions are always indirect. 515992cb984SSergei Barannikov if (!IsRetSmallStructInRegABI && !RetTy->isAnyComplexType()) 516992cb984SSergei Barannikov return getIndirectReturnResult(RetTy, State); 517992cb984SSergei Barannikov 518992cb984SSergei Barannikov // Ignore empty structs/unions. 519992cb984SSergei Barannikov if (isEmptyRecord(getContext(), RetTy, true)) 520992cb984SSergei Barannikov return ABIArgInfo::getIgnore(); 521992cb984SSergei Barannikov 522992cb984SSergei Barannikov // Return complex of _Float16 as <2 x half> so the backend will use xmm0. 523992cb984SSergei Barannikov if (const ComplexType *CT = RetTy->getAs<ComplexType>()) { 524992cb984SSergei Barannikov QualType ET = getContext().getCanonicalType(CT->getElementType()); 525992cb984SSergei Barannikov if (ET->isFloat16Type()) 526992cb984SSergei Barannikov return ABIArgInfo::getDirect(llvm::FixedVectorType::get( 527992cb984SSergei Barannikov llvm::Type::getHalfTy(getVMContext()), 2)); 528992cb984SSergei Barannikov } 529992cb984SSergei Barannikov 530992cb984SSergei Barannikov // Small structures which are register sized are generally returned 531992cb984SSergei Barannikov // in a register. 532992cb984SSergei Barannikov if (shouldReturnTypeInRegister(RetTy, getContext())) { 533992cb984SSergei Barannikov uint64_t Size = getContext().getTypeSize(RetTy); 534992cb984SSergei Barannikov 535992cb984SSergei Barannikov // As a special-case, if the struct is a "single-element" struct, and 536992cb984SSergei Barannikov // the field is of type "float" or "double", return it in a 537992cb984SSergei Barannikov // floating-point register. (MSVC does not apply this special case.) 538992cb984SSergei Barannikov // We apply a similar transformation for pointer types to improve the 539992cb984SSergei Barannikov // quality of the generated IR. 540992cb984SSergei Barannikov if (const Type *SeltTy = isSingleElementStruct(RetTy, getContext())) 541992cb984SSergei Barannikov if ((!IsWin32StructABI && SeltTy->isRealFloatingType()) 542992cb984SSergei Barannikov || SeltTy->hasPointerRepresentation()) 543992cb984SSergei Barannikov return ABIArgInfo::getDirect(CGT.ConvertType(QualType(SeltTy, 0))); 544992cb984SSergei Barannikov 545992cb984SSergei Barannikov // FIXME: We should be able to narrow this integer in cases with dead 546992cb984SSergei Barannikov // padding. 547992cb984SSergei Barannikov return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(),Size)); 548992cb984SSergei Barannikov } 549992cb984SSergei Barannikov 550992cb984SSergei Barannikov return getIndirectReturnResult(RetTy, State); 551992cb984SSergei Barannikov } 552992cb984SSergei Barannikov 553992cb984SSergei Barannikov // Treat an enum type as its underlying type. 554992cb984SSergei Barannikov if (const EnumType *EnumTy = RetTy->getAs<EnumType>()) 555992cb984SSergei Barannikov RetTy = EnumTy->getDecl()->getIntegerType(); 556992cb984SSergei Barannikov 557992cb984SSergei Barannikov if (const auto *EIT = RetTy->getAs<BitIntType>()) 558992cb984SSergei Barannikov if (EIT->getNumBits() > 64) 559992cb984SSergei Barannikov return getIndirectReturnResult(RetTy, State); 560992cb984SSergei Barannikov 561992cb984SSergei Barannikov return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy) 562992cb984SSergei Barannikov : ABIArgInfo::getDirect()); 563992cb984SSergei Barannikov } 564992cb984SSergei Barannikov 565992cb984SSergei Barannikov unsigned X86_32ABIInfo::getTypeStackAlignInBytes(QualType Ty, 566992cb984SSergei Barannikov unsigned Align) const { 567992cb984SSergei Barannikov // Otherwise, if the alignment is less than or equal to the minimum ABI 568992cb984SSergei Barannikov // alignment, just use the default; the backend will handle this. 569992cb984SSergei Barannikov if (Align <= MinABIStackAlignInBytes) 570992cb984SSergei Barannikov return 0; // Use default alignment. 571992cb984SSergei Barannikov 572992cb984SSergei Barannikov if (IsLinuxABI) { 573992cb984SSergei Barannikov // Exclude other System V OS (e.g Darwin, PS4 and FreeBSD) since we don't 574992cb984SSergei Barannikov // want to spend any effort dealing with the ramifications of ABI breaks. 575992cb984SSergei Barannikov // 576992cb984SSergei Barannikov // If the vector type is __m128/__m256/__m512, return the default alignment. 577992cb984SSergei Barannikov if (Ty->isVectorType() && (Align == 16 || Align == 32 || Align == 64)) 578992cb984SSergei Barannikov return Align; 579992cb984SSergei Barannikov } 580992cb984SSergei Barannikov // On non-Darwin, the stack type alignment is always 4. 581992cb984SSergei Barannikov if (!IsDarwinVectorABI) { 582992cb984SSergei Barannikov // Set explicit alignment, since we may need to realign the top. 583992cb984SSergei Barannikov return MinABIStackAlignInBytes; 584992cb984SSergei Barannikov } 585992cb984SSergei Barannikov 586992cb984SSergei Barannikov // Otherwise, if the type contains an SSE vector type, the alignment is 16. 587992cb984SSergei Barannikov if (Align >= 16 && (isSIMDVectorType(getContext(), Ty) || 588992cb984SSergei Barannikov isRecordWithSIMDVectorType(getContext(), Ty))) 589992cb984SSergei Barannikov return 16; 590992cb984SSergei Barannikov 591992cb984SSergei Barannikov return MinABIStackAlignInBytes; 592992cb984SSergei Barannikov } 593992cb984SSergei Barannikov 594992cb984SSergei Barannikov ABIArgInfo X86_32ABIInfo::getIndirectResult(QualType Ty, bool ByVal, 595992cb984SSergei Barannikov CCState &State) const { 596992cb984SSergei Barannikov if (!ByVal) { 597992cb984SSergei Barannikov if (State.FreeRegs) { 598992cb984SSergei Barannikov --State.FreeRegs; // Non-byval indirects just use one pointer. 599992cb984SSergei Barannikov if (!IsMCUABI) 600992cb984SSergei Barannikov return getNaturalAlignIndirectInReg(Ty); 601992cb984SSergei Barannikov } 602992cb984SSergei Barannikov return getNaturalAlignIndirect(Ty, false); 603992cb984SSergei Barannikov } 604992cb984SSergei Barannikov 605992cb984SSergei Barannikov // Compute the byval alignment. 606992cb984SSergei Barannikov unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8; 607992cb984SSergei Barannikov unsigned StackAlign = getTypeStackAlignInBytes(Ty, TypeAlign); 608992cb984SSergei Barannikov if (StackAlign == 0) 609992cb984SSergei Barannikov return ABIArgInfo::getIndirect(CharUnits::fromQuantity(4), /*ByVal=*/true); 610992cb984SSergei Barannikov 611992cb984SSergei Barannikov // If the stack alignment is less than the type alignment, realign the 612992cb984SSergei Barannikov // argument. 613992cb984SSergei Barannikov bool Realign = TypeAlign > StackAlign; 614992cb984SSergei Barannikov return ABIArgInfo::getIndirect(CharUnits::fromQuantity(StackAlign), 615992cb984SSergei Barannikov /*ByVal=*/true, Realign); 616992cb984SSergei Barannikov } 617992cb984SSergei Barannikov 618992cb984SSergei Barannikov X86_32ABIInfo::Class X86_32ABIInfo::classify(QualType Ty) const { 619992cb984SSergei Barannikov const Type *T = isSingleElementStruct(Ty, getContext()); 620992cb984SSergei Barannikov if (!T) 621992cb984SSergei Barannikov T = Ty.getTypePtr(); 622992cb984SSergei Barannikov 623992cb984SSergei Barannikov if (const BuiltinType *BT = T->getAs<BuiltinType>()) { 624992cb984SSergei Barannikov BuiltinType::Kind K = BT->getKind(); 625992cb984SSergei Barannikov if (K == BuiltinType::Float || K == BuiltinType::Double) 626992cb984SSergei Barannikov return Float; 627992cb984SSergei Barannikov } 628992cb984SSergei Barannikov return Integer; 629992cb984SSergei Barannikov } 630992cb984SSergei Barannikov 631992cb984SSergei Barannikov bool X86_32ABIInfo::updateFreeRegs(QualType Ty, CCState &State) const { 632992cb984SSergei Barannikov if (!IsSoftFloatABI) { 633992cb984SSergei Barannikov Class C = classify(Ty); 634992cb984SSergei Barannikov if (C == Float) 635992cb984SSergei Barannikov return false; 636992cb984SSergei Barannikov } 637992cb984SSergei Barannikov 638992cb984SSergei Barannikov unsigned Size = getContext().getTypeSize(Ty); 639992cb984SSergei Barannikov unsigned SizeInRegs = (Size + 31) / 32; 640992cb984SSergei Barannikov 641992cb984SSergei Barannikov if (SizeInRegs == 0) 642992cb984SSergei Barannikov return false; 643992cb984SSergei Barannikov 644992cb984SSergei Barannikov if (!IsMCUABI) { 645992cb984SSergei Barannikov if (SizeInRegs > State.FreeRegs) { 646992cb984SSergei Barannikov State.FreeRegs = 0; 647992cb984SSergei Barannikov return false; 648992cb984SSergei Barannikov } 649992cb984SSergei Barannikov } else { 650992cb984SSergei Barannikov // The MCU psABI allows passing parameters in-reg even if there are 651992cb984SSergei Barannikov // earlier parameters that are passed on the stack. Also, 652992cb984SSergei Barannikov // it does not allow passing >8-byte structs in-register, 653992cb984SSergei Barannikov // even if there are 3 free registers available. 654992cb984SSergei Barannikov if (SizeInRegs > State.FreeRegs || SizeInRegs > 2) 655992cb984SSergei Barannikov return false; 656992cb984SSergei Barannikov } 657992cb984SSergei Barannikov 658992cb984SSergei Barannikov State.FreeRegs -= SizeInRegs; 659992cb984SSergei Barannikov return true; 660992cb984SSergei Barannikov } 661992cb984SSergei Barannikov 662992cb984SSergei Barannikov bool X86_32ABIInfo::shouldAggregateUseDirect(QualType Ty, CCState &State, 663992cb984SSergei Barannikov bool &InReg, 664992cb984SSergei Barannikov bool &NeedsPadding) const { 665992cb984SSergei Barannikov // On Windows, aggregates other than HFAs are never passed in registers, and 666992cb984SSergei Barannikov // they do not consume register slots. Homogenous floating-point aggregates 667992cb984SSergei Barannikov // (HFAs) have already been dealt with at this point. 668992cb984SSergei Barannikov if (IsWin32StructABI && isAggregateTypeForABI(Ty)) 669992cb984SSergei Barannikov return false; 670992cb984SSergei Barannikov 671992cb984SSergei Barannikov NeedsPadding = false; 672992cb984SSergei Barannikov InReg = !IsMCUABI; 673992cb984SSergei Barannikov 674992cb984SSergei Barannikov if (!updateFreeRegs(Ty, State)) 675992cb984SSergei Barannikov return false; 676992cb984SSergei Barannikov 677992cb984SSergei Barannikov if (IsMCUABI) 678992cb984SSergei Barannikov return true; 679992cb984SSergei Barannikov 680992cb984SSergei Barannikov if (State.CC == llvm::CallingConv::X86_FastCall || 681992cb984SSergei Barannikov State.CC == llvm::CallingConv::X86_VectorCall || 682992cb984SSergei Barannikov State.CC == llvm::CallingConv::X86_RegCall) { 683992cb984SSergei Barannikov if (getContext().getTypeSize(Ty) <= 32 && State.FreeRegs) 684992cb984SSergei Barannikov NeedsPadding = true; 685992cb984SSergei Barannikov 686992cb984SSergei Barannikov return false; 687992cb984SSergei Barannikov } 688992cb984SSergei Barannikov 689992cb984SSergei Barannikov return true; 690992cb984SSergei Barannikov } 691992cb984SSergei Barannikov 692992cb984SSergei Barannikov bool X86_32ABIInfo::shouldPrimitiveUseInReg(QualType Ty, CCState &State) const { 693992cb984SSergei Barannikov bool IsPtrOrInt = (getContext().getTypeSize(Ty) <= 32) && 694992cb984SSergei Barannikov (Ty->isIntegralOrEnumerationType() || Ty->isPointerType() || 695992cb984SSergei Barannikov Ty->isReferenceType()); 696992cb984SSergei Barannikov 697992cb984SSergei Barannikov if (!IsPtrOrInt && (State.CC == llvm::CallingConv::X86_FastCall || 698992cb984SSergei Barannikov State.CC == llvm::CallingConv::X86_VectorCall)) 699992cb984SSergei Barannikov return false; 700992cb984SSergei Barannikov 701992cb984SSergei Barannikov if (!updateFreeRegs(Ty, State)) 702992cb984SSergei Barannikov return false; 703992cb984SSergei Barannikov 704992cb984SSergei Barannikov if (!IsPtrOrInt && State.CC == llvm::CallingConv::X86_RegCall) 705992cb984SSergei Barannikov return false; 706992cb984SSergei Barannikov 707992cb984SSergei Barannikov // Return true to apply inreg to all legal parameters except for MCU targets. 708992cb984SSergei Barannikov return !IsMCUABI; 709992cb984SSergei Barannikov } 710992cb984SSergei Barannikov 711992cb984SSergei Barannikov void X86_32ABIInfo::runVectorCallFirstPass(CGFunctionInfo &FI, CCState &State) const { 712992cb984SSergei Barannikov // Vectorcall x86 works subtly different than in x64, so the format is 713992cb984SSergei Barannikov // a bit different than the x64 version. First, all vector types (not HVAs) 714992cb984SSergei Barannikov // are assigned, with the first 6 ending up in the [XYZ]MM0-5 registers. 715992cb984SSergei Barannikov // This differs from the x64 implementation, where the first 6 by INDEX get 716992cb984SSergei Barannikov // registers. 717992cb984SSergei Barannikov // In the second pass over the arguments, HVAs are passed in the remaining 718992cb984SSergei Barannikov // vector registers if possible, or indirectly by address. The address will be 719992cb984SSergei Barannikov // passed in ECX/EDX if available. Any other arguments are passed according to 720992cb984SSergei Barannikov // the usual fastcall rules. 721992cb984SSergei Barannikov MutableArrayRef<CGFunctionInfoArgInfo> Args = FI.arguments(); 722992cb984SSergei Barannikov for (int I = 0, E = Args.size(); I < E; ++I) { 723992cb984SSergei Barannikov const Type *Base = nullptr; 724992cb984SSergei Barannikov uint64_t NumElts = 0; 725992cb984SSergei Barannikov const QualType &Ty = Args[I].type; 726992cb984SSergei Barannikov if ((Ty->isVectorType() || Ty->isBuiltinType()) && 727992cb984SSergei Barannikov isHomogeneousAggregate(Ty, Base, NumElts)) { 728992cb984SSergei Barannikov if (State.FreeSSERegs >= NumElts) { 729992cb984SSergei Barannikov State.FreeSSERegs -= NumElts; 730992cb984SSergei Barannikov Args[I].info = ABIArgInfo::getDirectInReg(); 731992cb984SSergei Barannikov State.IsPreassigned.set(I); 732992cb984SSergei Barannikov } 733992cb984SSergei Barannikov } 734992cb984SSergei Barannikov } 735992cb984SSergei Barannikov } 736992cb984SSergei Barannikov 73727dab4d3SAmy Huang ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State, 738c8c075e8SReid Kleckner unsigned ArgIndex) const { 739992cb984SSergei Barannikov // FIXME: Set alignment on indirect arguments. 740992cb984SSergei Barannikov bool IsFastCall = State.CC == llvm::CallingConv::X86_FastCall; 741992cb984SSergei Barannikov bool IsRegCall = State.CC == llvm::CallingConv::X86_RegCall; 742992cb984SSergei Barannikov bool IsVectorCall = State.CC == llvm::CallingConv::X86_VectorCall; 743992cb984SSergei Barannikov 744992cb984SSergei Barannikov Ty = useFirstFieldIfTransparentUnion(Ty); 745992cb984SSergei Barannikov TypeInfo TI = getContext().getTypeInfo(Ty); 746992cb984SSergei Barannikov 747992cb984SSergei Barannikov // Check with the C++ ABI first. 748992cb984SSergei Barannikov const RecordType *RT = Ty->getAs<RecordType>(); 749992cb984SSergei Barannikov if (RT) { 750992cb984SSergei Barannikov CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI()); 7518ed7aa59SAmy Huang if (RAA == CGCXXABI::RAA_Indirect) { 752992cb984SSergei Barannikov return getIndirectResult(Ty, false, State); 753c8c075e8SReid Kleckner } else if (State.IsDelegateCall) { 75427dab4d3SAmy Huang // Avoid having different alignments on delegate call args by always 75527dab4d3SAmy Huang // setting the alignment to 4, which is what we do for inallocas. 75627dab4d3SAmy Huang ABIArgInfo Res = getIndirectResult(Ty, false, State); 75727dab4d3SAmy Huang Res.setIndirectAlign(CharUnits::fromQuantity(4)); 75827dab4d3SAmy Huang return Res; 759992cb984SSergei Barannikov } else if (RAA == CGCXXABI::RAA_DirectInMemory) { 760992cb984SSergei Barannikov // The field index doesn't matter, we'll fix it up later. 761992cb984SSergei Barannikov return ABIArgInfo::getInAlloca(/*FieldIndex=*/0); 762992cb984SSergei Barannikov } 763992cb984SSergei Barannikov } 764992cb984SSergei Barannikov 765992cb984SSergei Barannikov // Regcall uses the concept of a homogenous vector aggregate, similar 766992cb984SSergei Barannikov // to other targets. 767992cb984SSergei Barannikov const Type *Base = nullptr; 768992cb984SSergei Barannikov uint64_t NumElts = 0; 769992cb984SSergei Barannikov if ((IsRegCall || IsVectorCall) && 770992cb984SSergei Barannikov isHomogeneousAggregate(Ty, Base, NumElts)) { 771992cb984SSergei Barannikov if (State.FreeSSERegs >= NumElts) { 772992cb984SSergei Barannikov State.FreeSSERegs -= NumElts; 773992cb984SSergei Barannikov 774992cb984SSergei Barannikov // Vectorcall passes HVAs directly and does not flatten them, but regcall 775992cb984SSergei Barannikov // does. 776992cb984SSergei Barannikov if (IsVectorCall) 777992cb984SSergei Barannikov return getDirectX86Hva(); 778992cb984SSergei Barannikov 779992cb984SSergei Barannikov if (Ty->isBuiltinType() || Ty->isVectorType()) 780992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 781992cb984SSergei Barannikov return ABIArgInfo::getExpand(); 782992cb984SSergei Barannikov } 7835bde8017SPhoebe Wang if (IsVectorCall && Ty->isBuiltinType()) 7845bde8017SPhoebe Wang return ABIArgInfo::getDirect(); 785992cb984SSergei Barannikov return getIndirectResult(Ty, /*ByVal=*/false, State); 786992cb984SSergei Barannikov } 787992cb984SSergei Barannikov 788992cb984SSergei Barannikov if (isAggregateTypeForABI(Ty)) { 789992cb984SSergei Barannikov // Structures with flexible arrays are always indirect. 790992cb984SSergei Barannikov // FIXME: This should not be byval! 791992cb984SSergei Barannikov if (RT && RT->getDecl()->hasFlexibleArrayMember()) 792992cb984SSergei Barannikov return getIndirectResult(Ty, true, State); 793992cb984SSergei Barannikov 794992cb984SSergei Barannikov // Ignore empty structs/unions on non-Windows. 795992cb984SSergei Barannikov if (!IsWin32StructABI && isEmptyRecord(getContext(), Ty, true)) 796992cb984SSergei Barannikov return ABIArgInfo::getIgnore(); 797992cb984SSergei Barannikov 7984461b690SLongsheng Mou // Ignore 0 sized structs. 7994461b690SLongsheng Mou if (TI.Width == 0) 8004461b690SLongsheng Mou return ABIArgInfo::getIgnore(); 8014461b690SLongsheng Mou 802992cb984SSergei Barannikov llvm::LLVMContext &LLVMContext = getVMContext(); 803992cb984SSergei Barannikov llvm::IntegerType *Int32 = llvm::Type::getInt32Ty(LLVMContext); 804992cb984SSergei Barannikov bool NeedsPadding = false; 805992cb984SSergei Barannikov bool InReg; 806992cb984SSergei Barannikov if (shouldAggregateUseDirect(Ty, State, InReg, NeedsPadding)) { 807992cb984SSergei Barannikov unsigned SizeInRegs = (TI.Width + 31) / 32; 808992cb984SSergei Barannikov SmallVector<llvm::Type*, 3> Elements(SizeInRegs, Int32); 809992cb984SSergei Barannikov llvm::Type *Result = llvm::StructType::get(LLVMContext, Elements); 810992cb984SSergei Barannikov if (InReg) 811992cb984SSergei Barannikov return ABIArgInfo::getDirectInReg(Result); 812992cb984SSergei Barannikov else 813992cb984SSergei Barannikov return ABIArgInfo::getDirect(Result); 814992cb984SSergei Barannikov } 815992cb984SSergei Barannikov llvm::IntegerType *PaddingType = NeedsPadding ? Int32 : nullptr; 816992cb984SSergei Barannikov 817c8c075e8SReid Kleckner // Pass over-aligned aggregates to non-variadic functions on Windows 818c8c075e8SReid Kleckner // indirectly. This behavior was added in MSVC 2015. Use the required 819c8c075e8SReid Kleckner // alignment from the record layout, since that may be less than the 820c8c075e8SReid Kleckner // regular type alignment, and types with required alignment of less than 4 821c8c075e8SReid Kleckner // bytes are not passed indirectly. 822c8c075e8SReid Kleckner if (IsWin32StructABI && State.Required.isRequiredArg(ArgIndex)) { 823992cb984SSergei Barannikov unsigned AlignInBits = 0; 824992cb984SSergei Barannikov if (RT) { 825992cb984SSergei Barannikov const ASTRecordLayout &Layout = 826992cb984SSergei Barannikov getContext().getASTRecordLayout(RT->getDecl()); 827992cb984SSergei Barannikov AlignInBits = getContext().toBits(Layout.getRequiredAlignment()); 828992cb984SSergei Barannikov } else if (TI.isAlignRequired()) { 829992cb984SSergei Barannikov AlignInBits = TI.Align; 830992cb984SSergei Barannikov } 831992cb984SSergei Barannikov if (AlignInBits > 32) 832992cb984SSergei Barannikov return getIndirectResult(Ty, /*ByVal=*/false, State); 833992cb984SSergei Barannikov } 834992cb984SSergei Barannikov 835992cb984SSergei Barannikov // Expand small (<= 128-bit) record types when we know that the stack layout 836992cb984SSergei Barannikov // of those arguments will match the struct. This is important because the 837992cb984SSergei Barannikov // LLVM backend isn't smart enough to remove byval, which inhibits many 838992cb984SSergei Barannikov // optimizations. 839992cb984SSergei Barannikov // Don't do this for the MCU if there are still free integer registers 840992cb984SSergei Barannikov // (see X86_64 ABI for full explanation). 841992cb984SSergei Barannikov if (TI.Width <= 4 * 32 && (!IsMCUABI || State.FreeRegs == 0) && 842992cb984SSergei Barannikov canExpandIndirectArgument(Ty)) 843992cb984SSergei Barannikov return ABIArgInfo::getExpandWithPadding( 844992cb984SSergei Barannikov IsFastCall || IsVectorCall || IsRegCall, PaddingType); 845992cb984SSergei Barannikov 846992cb984SSergei Barannikov return getIndirectResult(Ty, true, State); 847992cb984SSergei Barannikov } 848992cb984SSergei Barannikov 849992cb984SSergei Barannikov if (const VectorType *VT = Ty->getAs<VectorType>()) { 850992cb984SSergei Barannikov // On Windows, vectors are passed directly if registers are available, or 851992cb984SSergei Barannikov // indirectly if not. This avoids the need to align argument memory. Pass 852992cb984SSergei Barannikov // user-defined vector types larger than 512 bits indirectly for simplicity. 853992cb984SSergei Barannikov if (IsWin32StructABI) { 854992cb984SSergei Barannikov if (TI.Width <= 512 && State.FreeSSERegs > 0) { 855992cb984SSergei Barannikov --State.FreeSSERegs; 856992cb984SSergei Barannikov return ABIArgInfo::getDirectInReg(); 857992cb984SSergei Barannikov } 858992cb984SSergei Barannikov return getIndirectResult(Ty, /*ByVal=*/false, State); 859992cb984SSergei Barannikov } 860992cb984SSergei Barannikov 861992cb984SSergei Barannikov // On Darwin, some vectors are passed in memory, we handle this by passing 862992cb984SSergei Barannikov // it as an i8/i16/i32/i64. 863992cb984SSergei Barannikov if (IsDarwinVectorABI) { 864992cb984SSergei Barannikov if ((TI.Width == 8 || TI.Width == 16 || TI.Width == 32) || 865992cb984SSergei Barannikov (TI.Width == 64 && VT->getNumElements() == 1)) 866992cb984SSergei Barannikov return ABIArgInfo::getDirect( 867992cb984SSergei Barannikov llvm::IntegerType::get(getVMContext(), TI.Width)); 868992cb984SSergei Barannikov } 869992cb984SSergei Barannikov 870992cb984SSergei Barannikov if (IsX86_MMXType(CGT.ConvertType(Ty))) 871992cb984SSergei Barannikov return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), 64)); 872992cb984SSergei Barannikov 873992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 874992cb984SSergei Barannikov } 875992cb984SSergei Barannikov 876992cb984SSergei Barannikov 877992cb984SSergei Barannikov if (const EnumType *EnumTy = Ty->getAs<EnumType>()) 878992cb984SSergei Barannikov Ty = EnumTy->getDecl()->getIntegerType(); 879992cb984SSergei Barannikov 880992cb984SSergei Barannikov bool InReg = shouldPrimitiveUseInReg(Ty, State); 881992cb984SSergei Barannikov 882992cb984SSergei Barannikov if (isPromotableIntegerTypeForABI(Ty)) { 883992cb984SSergei Barannikov if (InReg) 884ea920450SLei Huang return ABIArgInfo::getExtendInReg(Ty, CGT.ConvertType(Ty)); 885ea920450SLei Huang return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)); 886992cb984SSergei Barannikov } 887992cb984SSergei Barannikov 888992cb984SSergei Barannikov if (const auto *EIT = Ty->getAs<BitIntType>()) { 889992cb984SSergei Barannikov if (EIT->getNumBits() <= 64) { 890992cb984SSergei Barannikov if (InReg) 891992cb984SSergei Barannikov return ABIArgInfo::getDirectInReg(); 892992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 893992cb984SSergei Barannikov } 894992cb984SSergei Barannikov return getIndirectResult(Ty, /*ByVal=*/false, State); 895992cb984SSergei Barannikov } 896992cb984SSergei Barannikov 897992cb984SSergei Barannikov if (InReg) 898992cb984SSergei Barannikov return ABIArgInfo::getDirectInReg(); 899992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 900992cb984SSergei Barannikov } 901992cb984SSergei Barannikov 902992cb984SSergei Barannikov void X86_32ABIInfo::computeInfo(CGFunctionInfo &FI) const { 903992cb984SSergei Barannikov CCState State(FI); 904992cb984SSergei Barannikov if (IsMCUABI) 905992cb984SSergei Barannikov State.FreeRegs = 3; 906992cb984SSergei Barannikov else if (State.CC == llvm::CallingConv::X86_FastCall) { 907992cb984SSergei Barannikov State.FreeRegs = 2; 908992cb984SSergei Barannikov State.FreeSSERegs = 3; 909992cb984SSergei Barannikov } else if (State.CC == llvm::CallingConv::X86_VectorCall) { 910992cb984SSergei Barannikov State.FreeRegs = 2; 911992cb984SSergei Barannikov State.FreeSSERegs = 6; 912992cb984SSergei Barannikov } else if (FI.getHasRegParm()) 913992cb984SSergei Barannikov State.FreeRegs = FI.getRegParm(); 914992cb984SSergei Barannikov else if (State.CC == llvm::CallingConv::X86_RegCall) { 915992cb984SSergei Barannikov State.FreeRegs = 5; 916992cb984SSergei Barannikov State.FreeSSERegs = 8; 917992cb984SSergei Barannikov } else if (IsWin32StructABI) { 918992cb984SSergei Barannikov // Since MSVC 2015, the first three SSE vectors have been passed in 919992cb984SSergei Barannikov // registers. The rest are passed indirectly. 920992cb984SSergei Barannikov State.FreeRegs = DefaultNumRegisterParameters; 921992cb984SSergei Barannikov State.FreeSSERegs = 3; 922992cb984SSergei Barannikov } else 923992cb984SSergei Barannikov State.FreeRegs = DefaultNumRegisterParameters; 924992cb984SSergei Barannikov 925992cb984SSergei Barannikov if (!::classifyReturnType(getCXXABI(), FI, *this)) { 926992cb984SSergei Barannikov FI.getReturnInfo() = classifyReturnType(FI.getReturnType(), State); 927992cb984SSergei Barannikov } else if (FI.getReturnInfo().isIndirect()) { 928992cb984SSergei Barannikov // The C++ ABI is not aware of register usage, so we have to check if the 929992cb984SSergei Barannikov // return value was sret and put it in a register ourselves if appropriate. 930992cb984SSergei Barannikov if (State.FreeRegs) { 931992cb984SSergei Barannikov --State.FreeRegs; // The sret parameter consumes a register. 932992cb984SSergei Barannikov if (!IsMCUABI) 933992cb984SSergei Barannikov FI.getReturnInfo().setInReg(true); 934992cb984SSergei Barannikov } 935992cb984SSergei Barannikov } 936992cb984SSergei Barannikov 937992cb984SSergei Barannikov // The chain argument effectively gives us another free register. 938992cb984SSergei Barannikov if (FI.isChainCall()) 939992cb984SSergei Barannikov ++State.FreeRegs; 940992cb984SSergei Barannikov 941992cb984SSergei Barannikov // For vectorcall, do a first pass over the arguments, assigning FP and vector 942992cb984SSergei Barannikov // arguments to XMM registers as available. 943992cb984SSergei Barannikov if (State.CC == llvm::CallingConv::X86_VectorCall) 944992cb984SSergei Barannikov runVectorCallFirstPass(FI, State); 945992cb984SSergei Barannikov 946992cb984SSergei Barannikov bool UsedInAlloca = false; 947992cb984SSergei Barannikov MutableArrayRef<CGFunctionInfoArgInfo> Args = FI.arguments(); 948c8c075e8SReid Kleckner for (unsigned I = 0, E = Args.size(); I < E; ++I) { 949992cb984SSergei Barannikov // Skip arguments that have already been assigned. 950992cb984SSergei Barannikov if (State.IsPreassigned.test(I)) 951992cb984SSergei Barannikov continue; 952992cb984SSergei Barannikov 95327dab4d3SAmy Huang Args[I].info = 954c8c075e8SReid Kleckner classifyArgumentType(Args[I].type, State, I); 955992cb984SSergei Barannikov UsedInAlloca |= (Args[I].info.getKind() == ABIArgInfo::InAlloca); 956992cb984SSergei Barannikov } 957992cb984SSergei Barannikov 958992cb984SSergei Barannikov // If we needed to use inalloca for any argument, do a second pass and rewrite 959992cb984SSergei Barannikov // all the memory arguments to use inalloca. 960992cb984SSergei Barannikov if (UsedInAlloca) 961992cb984SSergei Barannikov rewriteWithInAlloca(FI); 962992cb984SSergei Barannikov } 963992cb984SSergei Barannikov 964992cb984SSergei Barannikov void 965992cb984SSergei Barannikov X86_32ABIInfo::addFieldToArgStruct(SmallVector<llvm::Type *, 6> &FrameFields, 966992cb984SSergei Barannikov CharUnits &StackOffset, ABIArgInfo &Info, 967992cb984SSergei Barannikov QualType Type) const { 968992cb984SSergei Barannikov // Arguments are always 4-byte-aligned. 969992cb984SSergei Barannikov CharUnits WordSize = CharUnits::fromQuantity(4); 970992cb984SSergei Barannikov assert(StackOffset.isMultipleOf(WordSize) && "unaligned inalloca struct"); 971992cb984SSergei Barannikov 972992cb984SSergei Barannikov // sret pointers and indirect things will require an extra pointer 973992cb984SSergei Barannikov // indirection, unless they are byval. Most things are byval, and will not 974992cb984SSergei Barannikov // require this indirection. 975992cb984SSergei Barannikov bool IsIndirect = false; 976992cb984SSergei Barannikov if (Info.isIndirect() && !Info.getIndirectByVal()) 977992cb984SSergei Barannikov IsIndirect = true; 978992cb984SSergei Barannikov Info = ABIArgInfo::getInAlloca(FrameFields.size(), IsIndirect); 979992cb984SSergei Barannikov llvm::Type *LLTy = CGT.ConvertTypeForMem(Type); 980992cb984SSergei Barannikov if (IsIndirect) 981992cb984SSergei Barannikov LLTy = llvm::PointerType::getUnqual(getVMContext()); 982992cb984SSergei Barannikov FrameFields.push_back(LLTy); 983992cb984SSergei Barannikov StackOffset += IsIndirect ? WordSize : getContext().getTypeSizeInChars(Type); 984992cb984SSergei Barannikov 985992cb984SSergei Barannikov // Insert padding bytes to respect alignment. 986992cb984SSergei Barannikov CharUnits FieldEnd = StackOffset; 987992cb984SSergei Barannikov StackOffset = FieldEnd.alignTo(WordSize); 988992cb984SSergei Barannikov if (StackOffset != FieldEnd) { 989992cb984SSergei Barannikov CharUnits NumBytes = StackOffset - FieldEnd; 990992cb984SSergei Barannikov llvm::Type *Ty = llvm::Type::getInt8Ty(getVMContext()); 991992cb984SSergei Barannikov Ty = llvm::ArrayType::get(Ty, NumBytes.getQuantity()); 992992cb984SSergei Barannikov FrameFields.push_back(Ty); 993992cb984SSergei Barannikov } 994992cb984SSergei Barannikov } 995992cb984SSergei Barannikov 996992cb984SSergei Barannikov static bool isArgInAlloca(const ABIArgInfo &Info) { 997992cb984SSergei Barannikov // Leave ignored and inreg arguments alone. 998992cb984SSergei Barannikov switch (Info.getKind()) { 999992cb984SSergei Barannikov case ABIArgInfo::InAlloca: 1000992cb984SSergei Barannikov return true; 1001992cb984SSergei Barannikov case ABIArgInfo::Ignore: 1002992cb984SSergei Barannikov case ABIArgInfo::IndirectAliased: 1003992cb984SSergei Barannikov return false; 1004992cb984SSergei Barannikov case ABIArgInfo::Indirect: 1005992cb984SSergei Barannikov case ABIArgInfo::Direct: 1006992cb984SSergei Barannikov case ABIArgInfo::Extend: 1007992cb984SSergei Barannikov return !Info.getInReg(); 1008992cb984SSergei Barannikov case ABIArgInfo::Expand: 1009992cb984SSergei Barannikov case ABIArgInfo::CoerceAndExpand: 1010992cb984SSergei Barannikov // These are aggregate types which are never passed in registers when 1011992cb984SSergei Barannikov // inalloca is involved. 1012992cb984SSergei Barannikov return true; 1013992cb984SSergei Barannikov } 1014992cb984SSergei Barannikov llvm_unreachable("invalid enum"); 1015992cb984SSergei Barannikov } 1016992cb984SSergei Barannikov 1017992cb984SSergei Barannikov void X86_32ABIInfo::rewriteWithInAlloca(CGFunctionInfo &FI) const { 1018992cb984SSergei Barannikov assert(IsWin32StructABI && "inalloca only supported on win32"); 1019992cb984SSergei Barannikov 1020992cb984SSergei Barannikov // Build a packed struct type for all of the arguments in memory. 1021992cb984SSergei Barannikov SmallVector<llvm::Type *, 6> FrameFields; 1022992cb984SSergei Barannikov 1023992cb984SSergei Barannikov // The stack alignment is always 4. 1024992cb984SSergei Barannikov CharUnits StackAlign = CharUnits::fromQuantity(4); 1025992cb984SSergei Barannikov 1026992cb984SSergei Barannikov CharUnits StackOffset; 1027992cb984SSergei Barannikov CGFunctionInfo::arg_iterator I = FI.arg_begin(), E = FI.arg_end(); 1028992cb984SSergei Barannikov 1029992cb984SSergei Barannikov // Put 'this' into the struct before 'sret', if necessary. 1030992cb984SSergei Barannikov bool IsThisCall = 1031992cb984SSergei Barannikov FI.getCallingConvention() == llvm::CallingConv::X86_ThisCall; 1032992cb984SSergei Barannikov ABIArgInfo &Ret = FI.getReturnInfo(); 1033992cb984SSergei Barannikov if (Ret.isIndirect() && Ret.isSRetAfterThis() && !IsThisCall && 1034992cb984SSergei Barannikov isArgInAlloca(I->info)) { 1035992cb984SSergei Barannikov addFieldToArgStruct(FrameFields, StackOffset, I->info, I->type); 1036992cb984SSergei Barannikov ++I; 1037992cb984SSergei Barannikov } 1038992cb984SSergei Barannikov 1039992cb984SSergei Barannikov // Put the sret parameter into the inalloca struct if it's in memory. 1040992cb984SSergei Barannikov if (Ret.isIndirect() && !Ret.getInReg()) { 1041992cb984SSergei Barannikov addFieldToArgStruct(FrameFields, StackOffset, Ret, FI.getReturnType()); 1042992cb984SSergei Barannikov // On Windows, the hidden sret parameter is always returned in eax. 1043992cb984SSergei Barannikov Ret.setInAllocaSRet(IsWin32StructABI); 1044992cb984SSergei Barannikov } 1045992cb984SSergei Barannikov 1046992cb984SSergei Barannikov // Skip the 'this' parameter in ecx. 1047992cb984SSergei Barannikov if (IsThisCall) 1048992cb984SSergei Barannikov ++I; 1049992cb984SSergei Barannikov 1050992cb984SSergei Barannikov // Put arguments passed in memory into the struct. 1051992cb984SSergei Barannikov for (; I != E; ++I) { 1052992cb984SSergei Barannikov if (isArgInAlloca(I->info)) 1053992cb984SSergei Barannikov addFieldToArgStruct(FrameFields, StackOffset, I->info, I->type); 1054992cb984SSergei Barannikov } 1055992cb984SSergei Barannikov 1056992cb984SSergei Barannikov FI.setArgStruct(llvm::StructType::get(getVMContext(), FrameFields, 1057992cb984SSergei Barannikov /*isPacked=*/true), 1058992cb984SSergei Barannikov StackAlign); 1059992cb984SSergei Barannikov } 1060992cb984SSergei Barannikov 10616d973b45SMariya Podchishchaeva RValue X86_32ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 10626d973b45SMariya Podchishchaeva QualType Ty, AggValueSlot Slot) const { 1063992cb984SSergei Barannikov 1064992cb984SSergei Barannikov auto TypeInfo = getContext().getTypeInfoInChars(Ty); 1065992cb984SSergei Barannikov 1066956b47b4SLongsheng Mou CCState State(*const_cast<CGFunctionInfo *>(CGF.CurFnInfo)); 1067956b47b4SLongsheng Mou ABIArgInfo AI = classifyArgumentType(Ty, State, /*ArgIndex*/ 0); 1068956b47b4SLongsheng Mou // Empty records are ignored for parameter passing purposes. 1069956b47b4SLongsheng Mou if (AI.isIgnore()) 10706d973b45SMariya Podchishchaeva return Slot.asRValue(); 1071956b47b4SLongsheng Mou 1072992cb984SSergei Barannikov // x86-32 changes the alignment of certain arguments on the stack. 1073992cb984SSergei Barannikov // 1074992cb984SSergei Barannikov // Just messing with TypeInfo like this works because we never pass 1075992cb984SSergei Barannikov // anything indirectly. 1076992cb984SSergei Barannikov TypeInfo.Align = CharUnits::fromQuantity( 1077992cb984SSergei Barannikov getTypeStackAlignInBytes(Ty, TypeInfo.Align.getQuantity())); 1078992cb984SSergei Barannikov 10796d973b45SMariya Podchishchaeva return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*Indirect*/ false, TypeInfo, 10806d973b45SMariya Podchishchaeva CharUnits::fromQuantity(4), 10816d973b45SMariya Podchishchaeva /*AllowHigherAlign*/ true, Slot); 1082992cb984SSergei Barannikov } 1083992cb984SSergei Barannikov 1084992cb984SSergei Barannikov bool X86_32TargetCodeGenInfo::isStructReturnInRegABI( 1085992cb984SSergei Barannikov const llvm::Triple &Triple, const CodeGenOptions &Opts) { 1086992cb984SSergei Barannikov assert(Triple.getArch() == llvm::Triple::x86); 1087992cb984SSergei Barannikov 1088992cb984SSergei Barannikov switch (Opts.getStructReturnConvention()) { 1089992cb984SSergei Barannikov case CodeGenOptions::SRCK_Default: 1090992cb984SSergei Barannikov break; 1091992cb984SSergei Barannikov case CodeGenOptions::SRCK_OnStack: // -fpcc-struct-return 1092992cb984SSergei Barannikov return false; 1093992cb984SSergei Barannikov case CodeGenOptions::SRCK_InRegs: // -freg-struct-return 1094992cb984SSergei Barannikov return true; 1095992cb984SSergei Barannikov } 1096992cb984SSergei Barannikov 1097992cb984SSergei Barannikov if (Triple.isOSDarwin() || Triple.isOSIAMCU()) 1098992cb984SSergei Barannikov return true; 1099992cb984SSergei Barannikov 1100992cb984SSergei Barannikov switch (Triple.getOS()) { 1101992cb984SSergei Barannikov case llvm::Triple::DragonFly: 1102992cb984SSergei Barannikov case llvm::Triple::FreeBSD: 1103992cb984SSergei Barannikov case llvm::Triple::OpenBSD: 1104992cb984SSergei Barannikov case llvm::Triple::Win32: 1105992cb984SSergei Barannikov return true; 1106992cb984SSergei Barannikov default: 1107992cb984SSergei Barannikov return false; 1108992cb984SSergei Barannikov } 1109992cb984SSergei Barannikov } 1110992cb984SSergei Barannikov 1111992cb984SSergei Barannikov static void addX86InterruptAttrs(const FunctionDecl *FD, llvm::GlobalValue *GV, 1112992cb984SSergei Barannikov CodeGen::CodeGenModule &CGM) { 1113992cb984SSergei Barannikov if (!FD->hasAttr<AnyX86InterruptAttr>()) 1114992cb984SSergei Barannikov return; 1115992cb984SSergei Barannikov 1116992cb984SSergei Barannikov llvm::Function *Fn = cast<llvm::Function>(GV); 1117992cb984SSergei Barannikov Fn->setCallingConv(llvm::CallingConv::X86_INTR); 1118992cb984SSergei Barannikov if (FD->getNumParams() == 0) 1119992cb984SSergei Barannikov return; 1120992cb984SSergei Barannikov 1121992cb984SSergei Barannikov auto PtrTy = cast<PointerType>(FD->getParamDecl(0)->getType()); 1122992cb984SSergei Barannikov llvm::Type *ByValTy = CGM.getTypes().ConvertType(PtrTy->getPointeeType()); 1123992cb984SSergei Barannikov llvm::Attribute NewAttr = llvm::Attribute::getWithByValType( 1124992cb984SSergei Barannikov Fn->getContext(), ByValTy); 1125992cb984SSergei Barannikov Fn->addParamAttr(0, NewAttr); 1126992cb984SSergei Barannikov } 1127992cb984SSergei Barannikov 1128992cb984SSergei Barannikov void X86_32TargetCodeGenInfo::setTargetAttributes( 1129992cb984SSergei Barannikov const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const { 1130992cb984SSergei Barannikov if (GV->isDeclaration()) 1131992cb984SSergei Barannikov return; 1132992cb984SSergei Barannikov if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) { 1133992cb984SSergei Barannikov if (FD->hasAttr<X86ForceAlignArgPointerAttr>()) { 1134992cb984SSergei Barannikov llvm::Function *Fn = cast<llvm::Function>(GV); 1135992cb984SSergei Barannikov Fn->addFnAttr("stackrealign"); 1136992cb984SSergei Barannikov } 1137992cb984SSergei Barannikov 1138992cb984SSergei Barannikov addX86InterruptAttrs(FD, GV, CGM); 1139992cb984SSergei Barannikov } 1140992cb984SSergei Barannikov } 1141992cb984SSergei Barannikov 1142992cb984SSergei Barannikov bool X86_32TargetCodeGenInfo::initDwarfEHRegSizeTable( 1143992cb984SSergei Barannikov CodeGen::CodeGenFunction &CGF, 1144992cb984SSergei Barannikov llvm::Value *Address) const { 1145992cb984SSergei Barannikov CodeGen::CGBuilderTy &Builder = CGF.Builder; 1146992cb984SSergei Barannikov 1147992cb984SSergei Barannikov llvm::Value *Four8 = llvm::ConstantInt::get(CGF.Int8Ty, 4); 1148992cb984SSergei Barannikov 1149992cb984SSergei Barannikov // 0-7 are the eight integer registers; the order is different 1150992cb984SSergei Barannikov // on Darwin (for EH), but the range is the same. 1151992cb984SSergei Barannikov // 8 is %eip. 1152992cb984SSergei Barannikov AssignToArrayRange(Builder, Address, Four8, 0, 8); 1153992cb984SSergei Barannikov 1154992cb984SSergei Barannikov if (CGF.CGM.getTarget().getTriple().isOSDarwin()) { 1155992cb984SSergei Barannikov // 12-16 are st(0..4). Not sure why we stop at 4. 1156992cb984SSergei Barannikov // These have size 16, which is sizeof(long double) on 1157992cb984SSergei Barannikov // platforms with 8-byte alignment for that type. 1158992cb984SSergei Barannikov llvm::Value *Sixteen8 = llvm::ConstantInt::get(CGF.Int8Ty, 16); 1159992cb984SSergei Barannikov AssignToArrayRange(Builder, Address, Sixteen8, 12, 16); 1160992cb984SSergei Barannikov 1161992cb984SSergei Barannikov } else { 1162992cb984SSergei Barannikov // 9 is %eflags, which doesn't get a size on Darwin for some 1163992cb984SSergei Barannikov // reason. 1164992cb984SSergei Barannikov Builder.CreateAlignedStore( 1165992cb984SSergei Barannikov Four8, Builder.CreateConstInBoundsGEP1_32(CGF.Int8Ty, Address, 9), 1166992cb984SSergei Barannikov CharUnits::One()); 1167992cb984SSergei Barannikov 1168992cb984SSergei Barannikov // 11-16 are st(0..5). Not sure why we stop at 5. 1169992cb984SSergei Barannikov // These have size 12, which is sizeof(long double) on 1170992cb984SSergei Barannikov // platforms with 4-byte alignment for that type. 1171992cb984SSergei Barannikov llvm::Value *Twelve8 = llvm::ConstantInt::get(CGF.Int8Ty, 12); 1172992cb984SSergei Barannikov AssignToArrayRange(Builder, Address, Twelve8, 11, 16); 1173992cb984SSergei Barannikov } 1174992cb984SSergei Barannikov 1175992cb984SSergei Barannikov return false; 1176992cb984SSergei Barannikov } 1177992cb984SSergei Barannikov 1178992cb984SSergei Barannikov //===----------------------------------------------------------------------===// 1179992cb984SSergei Barannikov // X86-64 ABI Implementation 1180992cb984SSergei Barannikov //===----------------------------------------------------------------------===// 1181992cb984SSergei Barannikov 1182992cb984SSergei Barannikov 1183992cb984SSergei Barannikov namespace { 1184992cb984SSergei Barannikov 1185992cb984SSergei Barannikov /// \p returns the size in bits of the largest (native) vector for \p AVXLevel. 1186992cb984SSergei Barannikov static unsigned getNativeVectorSizeForAVXABI(X86AVXABILevel AVXLevel) { 1187992cb984SSergei Barannikov switch (AVXLevel) { 1188992cb984SSergei Barannikov case X86AVXABILevel::AVX512: 1189992cb984SSergei Barannikov return 512; 1190992cb984SSergei Barannikov case X86AVXABILevel::AVX: 1191992cb984SSergei Barannikov return 256; 1192992cb984SSergei Barannikov case X86AVXABILevel::None: 1193992cb984SSergei Barannikov return 128; 1194992cb984SSergei Barannikov } 1195992cb984SSergei Barannikov llvm_unreachable("Unknown AVXLevel"); 1196992cb984SSergei Barannikov } 1197992cb984SSergei Barannikov 1198992cb984SSergei Barannikov /// X86_64ABIInfo - The X86_64 ABI information. 1199992cb984SSergei Barannikov class X86_64ABIInfo : public ABIInfo { 1200992cb984SSergei Barannikov enum Class { 1201992cb984SSergei Barannikov Integer = 0, 1202992cb984SSergei Barannikov SSE, 1203992cb984SSergei Barannikov SSEUp, 1204992cb984SSergei Barannikov X87, 1205992cb984SSergei Barannikov X87Up, 1206992cb984SSergei Barannikov ComplexX87, 1207992cb984SSergei Barannikov NoClass, 1208992cb984SSergei Barannikov Memory 1209992cb984SSergei Barannikov }; 1210992cb984SSergei Barannikov 1211992cb984SSergei Barannikov /// merge - Implement the X86_64 ABI merging algorithm. 1212992cb984SSergei Barannikov /// 1213992cb984SSergei Barannikov /// Merge an accumulating classification \arg Accum with a field 1214992cb984SSergei Barannikov /// classification \arg Field. 1215992cb984SSergei Barannikov /// 1216992cb984SSergei Barannikov /// \param Accum - The accumulating classification. This should 1217992cb984SSergei Barannikov /// always be either NoClass or the result of a previous merge 1218992cb984SSergei Barannikov /// call. In addition, this should never be Memory (the caller 1219992cb984SSergei Barannikov /// should just return Memory for the aggregate). 1220992cb984SSergei Barannikov static Class merge(Class Accum, Class Field); 1221992cb984SSergei Barannikov 1222992cb984SSergei Barannikov /// postMerge - Implement the X86_64 ABI post merging algorithm. 1223992cb984SSergei Barannikov /// 1224992cb984SSergei Barannikov /// Post merger cleanup, reduces a malformed Hi and Lo pair to 1225992cb984SSergei Barannikov /// final MEMORY or SSE classes when necessary. 1226992cb984SSergei Barannikov /// 1227992cb984SSergei Barannikov /// \param AggregateSize - The size of the current aggregate in 1228992cb984SSergei Barannikov /// the classification process. 1229992cb984SSergei Barannikov /// 1230992cb984SSergei Barannikov /// \param Lo - The classification for the parts of the type 1231992cb984SSergei Barannikov /// residing in the low word of the containing object. 1232992cb984SSergei Barannikov /// 1233992cb984SSergei Barannikov /// \param Hi - The classification for the parts of the type 1234992cb984SSergei Barannikov /// residing in the higher words of the containing object. 1235992cb984SSergei Barannikov /// 1236992cb984SSergei Barannikov void postMerge(unsigned AggregateSize, Class &Lo, Class &Hi) const; 1237992cb984SSergei Barannikov 1238992cb984SSergei Barannikov /// classify - Determine the x86_64 register classes in which the 1239992cb984SSergei Barannikov /// given type T should be passed. 1240992cb984SSergei Barannikov /// 1241992cb984SSergei Barannikov /// \param Lo - The classification for the parts of the type 1242992cb984SSergei Barannikov /// residing in the low word of the containing object. 1243992cb984SSergei Barannikov /// 1244992cb984SSergei Barannikov /// \param Hi - The classification for the parts of the type 1245992cb984SSergei Barannikov /// residing in the high word of the containing object. 1246992cb984SSergei Barannikov /// 1247992cb984SSergei Barannikov /// \param OffsetBase - The bit offset of this type in the 1248992cb984SSergei Barannikov /// containing object. Some parameters are classified different 1249992cb984SSergei Barannikov /// depending on whether they straddle an eightbyte boundary. 1250992cb984SSergei Barannikov /// 1251992cb984SSergei Barannikov /// \param isNamedArg - Whether the argument in question is a "named" 1252992cb984SSergei Barannikov /// argument, as used in AMD64-ABI 3.5.7. 1253992cb984SSergei Barannikov /// 1254992cb984SSergei Barannikov /// \param IsRegCall - Whether the calling conversion is regcall. 1255992cb984SSergei Barannikov /// 1256992cb984SSergei Barannikov /// If a word is unused its result will be NoClass; if a type should 1257992cb984SSergei Barannikov /// be passed in Memory then at least the classification of \arg Lo 1258992cb984SSergei Barannikov /// will be Memory. 1259992cb984SSergei Barannikov /// 1260992cb984SSergei Barannikov /// The \arg Lo class will be NoClass iff the argument is ignored. 1261992cb984SSergei Barannikov /// 1262992cb984SSergei Barannikov /// If the \arg Lo class is ComplexX87, then the \arg Hi class will 1263992cb984SSergei Barannikov /// also be ComplexX87. 1264992cb984SSergei Barannikov void classify(QualType T, uint64_t OffsetBase, Class &Lo, Class &Hi, 1265992cb984SSergei Barannikov bool isNamedArg, bool IsRegCall = false) const; 1266992cb984SSergei Barannikov 1267992cb984SSergei Barannikov llvm::Type *GetByteVectorType(QualType Ty) const; 1268992cb984SSergei Barannikov llvm::Type *GetSSETypeAtOffset(llvm::Type *IRType, 1269992cb984SSergei Barannikov unsigned IROffset, QualType SourceTy, 1270992cb984SSergei Barannikov unsigned SourceOffset) const; 1271992cb984SSergei Barannikov llvm::Type *GetINTEGERTypeAtOffset(llvm::Type *IRType, 1272992cb984SSergei Barannikov unsigned IROffset, QualType SourceTy, 1273992cb984SSergei Barannikov unsigned SourceOffset) const; 1274992cb984SSergei Barannikov 1275992cb984SSergei Barannikov /// getIndirectResult - Give a source type \arg Ty, return a suitable result 1276992cb984SSergei Barannikov /// such that the argument will be returned in memory. 1277992cb984SSergei Barannikov ABIArgInfo getIndirectReturnResult(QualType Ty) const; 1278992cb984SSergei Barannikov 1279992cb984SSergei Barannikov /// getIndirectResult - Give a source type \arg Ty, return a suitable result 1280992cb984SSergei Barannikov /// such that the argument will be passed in memory. 1281992cb984SSergei Barannikov /// 1282992cb984SSergei Barannikov /// \param freeIntRegs - The number of free integer registers remaining 1283992cb984SSergei Barannikov /// available. 1284992cb984SSergei Barannikov ABIArgInfo getIndirectResult(QualType Ty, unsigned freeIntRegs) const; 1285992cb984SSergei Barannikov 1286992cb984SSergei Barannikov ABIArgInfo classifyReturnType(QualType RetTy) const; 1287992cb984SSergei Barannikov 1288992cb984SSergei Barannikov ABIArgInfo classifyArgumentType(QualType Ty, unsigned freeIntRegs, 1289992cb984SSergei Barannikov unsigned &neededInt, unsigned &neededSSE, 1290992cb984SSergei Barannikov bool isNamedArg, 1291992cb984SSergei Barannikov bool IsRegCall = false) const; 1292992cb984SSergei Barannikov 1293992cb984SSergei Barannikov ABIArgInfo classifyRegCallStructType(QualType Ty, unsigned &NeededInt, 1294992cb984SSergei Barannikov unsigned &NeededSSE, 1295992cb984SSergei Barannikov unsigned &MaxVectorWidth) const; 1296992cb984SSergei Barannikov 1297992cb984SSergei Barannikov ABIArgInfo classifyRegCallStructTypeImpl(QualType Ty, unsigned &NeededInt, 1298992cb984SSergei Barannikov unsigned &NeededSSE, 1299992cb984SSergei Barannikov unsigned &MaxVectorWidth) const; 1300992cb984SSergei Barannikov 1301992cb984SSergei Barannikov bool IsIllegalVectorType(QualType Ty) const; 1302992cb984SSergei Barannikov 1303992cb984SSergei Barannikov /// The 0.98 ABI revision clarified a lot of ambiguities, 1304992cb984SSergei Barannikov /// unfortunately in ways that were not always consistent with 1305992cb984SSergei Barannikov /// certain previous compilers. In particular, platforms which 1306992cb984SSergei Barannikov /// required strict binary compatibility with older versions of GCC 1307992cb984SSergei Barannikov /// may need to exempt themselves. 1308992cb984SSergei Barannikov bool honorsRevision0_98() const { 1309992cb984SSergei Barannikov return !getTarget().getTriple().isOSDarwin(); 1310992cb984SSergei Barannikov } 1311992cb984SSergei Barannikov 1312992cb984SSergei Barannikov /// GCC classifies <1 x long long> as SSE but some platform ABIs choose to 1313992cb984SSergei Barannikov /// classify it as INTEGER (for compatibility with older clang compilers). 1314992cb984SSergei Barannikov bool classifyIntegerMMXAsSSE() const { 1315992cb984SSergei Barannikov // Clang <= 3.8 did not do this. 1316992cb984SSergei Barannikov if (getContext().getLangOpts().getClangABICompat() <= 1317992cb984SSergei Barannikov LangOptions::ClangABI::Ver3_8) 1318992cb984SSergei Barannikov return false; 1319992cb984SSergei Barannikov 1320992cb984SSergei Barannikov const llvm::Triple &Triple = getTarget().getTriple(); 1321992cb984SSergei Barannikov if (Triple.isOSDarwin() || Triple.isPS() || Triple.isOSFreeBSD()) 1322992cb984SSergei Barannikov return false; 1323992cb984SSergei Barannikov return true; 1324992cb984SSergei Barannikov } 1325992cb984SSergei Barannikov 1326992cb984SSergei Barannikov // GCC classifies vectors of __int128 as memory. 1327992cb984SSergei Barannikov bool passInt128VectorsInMem() const { 1328992cb984SSergei Barannikov // Clang <= 9.0 did not do this. 1329992cb984SSergei Barannikov if (getContext().getLangOpts().getClangABICompat() <= 1330992cb984SSergei Barannikov LangOptions::ClangABI::Ver9) 1331992cb984SSergei Barannikov return false; 1332992cb984SSergei Barannikov 1333992cb984SSergei Barannikov const llvm::Triple &T = getTarget().getTriple(); 1334992cb984SSergei Barannikov return T.isOSLinux() || T.isOSNetBSD(); 1335992cb984SSergei Barannikov } 1336992cb984SSergei Barannikov 1337992cb984SSergei Barannikov X86AVXABILevel AVXLevel; 1338992cb984SSergei Barannikov // Some ABIs (e.g. X32 ABI and Native Client OS) use 32 bit pointers on 1339992cb984SSergei Barannikov // 64-bit hardware. 1340992cb984SSergei Barannikov bool Has64BitPointers; 1341992cb984SSergei Barannikov 1342992cb984SSergei Barannikov public: 1343992cb984SSergei Barannikov X86_64ABIInfo(CodeGen::CodeGenTypes &CGT, X86AVXABILevel AVXLevel) 1344992cb984SSergei Barannikov : ABIInfo(CGT), AVXLevel(AVXLevel), 1345992cb984SSergei Barannikov Has64BitPointers(CGT.getDataLayout().getPointerSize(0) == 8) {} 1346992cb984SSergei Barannikov 1347992cb984SSergei Barannikov bool isPassedUsingAVXType(QualType type) const { 1348992cb984SSergei Barannikov unsigned neededInt, neededSSE; 1349992cb984SSergei Barannikov // The freeIntRegs argument doesn't matter here. 1350992cb984SSergei Barannikov ABIArgInfo info = classifyArgumentType(type, 0, neededInt, neededSSE, 1351992cb984SSergei Barannikov /*isNamedArg*/true); 1352992cb984SSergei Barannikov if (info.isDirect()) { 1353992cb984SSergei Barannikov llvm::Type *ty = info.getCoerceToType(); 1354992cb984SSergei Barannikov if (llvm::VectorType *vectorTy = dyn_cast_or_null<llvm::VectorType>(ty)) 1355992cb984SSergei Barannikov return vectorTy->getPrimitiveSizeInBits().getFixedValue() > 128; 1356992cb984SSergei Barannikov } 1357992cb984SSergei Barannikov return false; 1358992cb984SSergei Barannikov } 1359992cb984SSergei Barannikov 1360992cb984SSergei Barannikov void computeInfo(CGFunctionInfo &FI) const override; 1361992cb984SSergei Barannikov 13626d973b45SMariya Podchishchaeva RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, 13636d973b45SMariya Podchishchaeva AggValueSlot Slot) const override; 13646d973b45SMariya Podchishchaeva RValue EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, 13656d973b45SMariya Podchishchaeva AggValueSlot Slot) const override; 1366992cb984SSergei Barannikov 1367992cb984SSergei Barannikov bool has64BitPointers() const { 1368992cb984SSergei Barannikov return Has64BitPointers; 1369992cb984SSergei Barannikov } 1370992cb984SSergei Barannikov }; 1371992cb984SSergei Barannikov 1372992cb984SSergei Barannikov /// WinX86_64ABIInfo - The Windows X86_64 ABI information. 1373992cb984SSergei Barannikov class WinX86_64ABIInfo : public ABIInfo { 1374992cb984SSergei Barannikov public: 1375992cb984SSergei Barannikov WinX86_64ABIInfo(CodeGen::CodeGenTypes &CGT, X86AVXABILevel AVXLevel) 1376992cb984SSergei Barannikov : ABIInfo(CGT), AVXLevel(AVXLevel), 1377992cb984SSergei Barannikov IsMingw64(getTarget().getTriple().isWindowsGNUEnvironment()) {} 1378992cb984SSergei Barannikov 1379992cb984SSergei Barannikov void computeInfo(CGFunctionInfo &FI) const override; 1380992cb984SSergei Barannikov 13816d973b45SMariya Podchishchaeva RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, 13826d973b45SMariya Podchishchaeva AggValueSlot Slot) const override; 1383992cb984SSergei Barannikov 1384992cb984SSergei Barannikov bool isHomogeneousAggregateBaseType(QualType Ty) const override { 1385992cb984SSergei Barannikov // FIXME: Assumes vectorcall is in use. 1386992cb984SSergei Barannikov return isX86VectorTypeForVectorCall(getContext(), Ty); 1387992cb984SSergei Barannikov } 1388992cb984SSergei Barannikov 1389992cb984SSergei Barannikov bool isHomogeneousAggregateSmallEnough(const Type *Ty, 1390992cb984SSergei Barannikov uint64_t NumMembers) const override { 1391992cb984SSergei Barannikov // FIXME: Assumes vectorcall is in use. 1392992cb984SSergei Barannikov return isX86VectorCallAggregateSmallEnough(NumMembers); 1393992cb984SSergei Barannikov } 1394992cb984SSergei Barannikov 1395992cb984SSergei Barannikov private: 1396992cb984SSergei Barannikov ABIArgInfo classify(QualType Ty, unsigned &FreeSSERegs, bool IsReturnType, 1397992cb984SSergei Barannikov bool IsVectorCall, bool IsRegCall) const; 1398992cb984SSergei Barannikov ABIArgInfo reclassifyHvaArgForVectorCall(QualType Ty, unsigned &FreeSSERegs, 1399992cb984SSergei Barannikov const ABIArgInfo ¤t) const; 1400992cb984SSergei Barannikov 1401992cb984SSergei Barannikov X86AVXABILevel AVXLevel; 1402992cb984SSergei Barannikov 1403992cb984SSergei Barannikov bool IsMingw64; 1404992cb984SSergei Barannikov }; 1405992cb984SSergei Barannikov 1406992cb984SSergei Barannikov class X86_64TargetCodeGenInfo : public TargetCodeGenInfo { 1407992cb984SSergei Barannikov public: 1408992cb984SSergei Barannikov X86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, X86AVXABILevel AVXLevel) 1409992cb984SSergei Barannikov : TargetCodeGenInfo(std::make_unique<X86_64ABIInfo>(CGT, AVXLevel)) { 1410992cb984SSergei Barannikov SwiftInfo = 1411992cb984SSergei Barannikov std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/true); 1412992cb984SSergei Barannikov } 1413992cb984SSergei Barannikov 1414992cb984SSergei Barannikov /// Disable tail call on x86-64. The epilogue code before the tail jump blocks 1415992cb984SSergei Barannikov /// autoreleaseRV/retainRV and autoreleaseRV/unsafeClaimRV optimizations. 1416992cb984SSergei Barannikov bool markARCOptimizedReturnCallsAsNoTail() const override { return true; } 1417992cb984SSergei Barannikov 1418992cb984SSergei Barannikov int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override { 1419992cb984SSergei Barannikov return 7; 1420992cb984SSergei Barannikov } 1421992cb984SSergei Barannikov 1422992cb984SSergei Barannikov bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 1423992cb984SSergei Barannikov llvm::Value *Address) const override { 1424992cb984SSergei Barannikov llvm::Value *Eight8 = llvm::ConstantInt::get(CGF.Int8Ty, 8); 1425992cb984SSergei Barannikov 1426992cb984SSergei Barannikov // 0-15 are the 16 integer registers. 1427992cb984SSergei Barannikov // 16 is %rip. 1428992cb984SSergei Barannikov AssignToArrayRange(CGF.Builder, Address, Eight8, 0, 16); 1429992cb984SSergei Barannikov return false; 1430992cb984SSergei Barannikov } 1431992cb984SSergei Barannikov 1432992cb984SSergei Barannikov llvm::Type* adjustInlineAsmType(CodeGen::CodeGenFunction &CGF, 1433992cb984SSergei Barannikov StringRef Constraint, 1434992cb984SSergei Barannikov llvm::Type* Ty) const override { 1435992cb984SSergei Barannikov return X86AdjustInlineAsmType(CGF, Constraint, Ty); 1436992cb984SSergei Barannikov } 1437992cb984SSergei Barannikov 1438992cb984SSergei Barannikov bool isNoProtoCallVariadic(const CallArgList &args, 1439992cb984SSergei Barannikov const FunctionNoProtoType *fnType) const override { 1440992cb984SSergei Barannikov // The default CC on x86-64 sets %al to the number of SSA 1441992cb984SSergei Barannikov // registers used, and GCC sets this when calling an unprototyped 1442992cb984SSergei Barannikov // function, so we override the default behavior. However, don't do 1443992cb984SSergei Barannikov // that when AVX types are involved: the ABI explicitly states it is 1444992cb984SSergei Barannikov // undefined, and it doesn't work in practice because of how the ABI 1445992cb984SSergei Barannikov // defines varargs anyway. 1446992cb984SSergei Barannikov if (fnType->getCallConv() == CC_C) { 1447992cb984SSergei Barannikov bool HasAVXType = false; 1448992cb984SSergei Barannikov for (CallArgList::const_iterator 1449992cb984SSergei Barannikov it = args.begin(), ie = args.end(); it != ie; ++it) { 1450992cb984SSergei Barannikov if (getABIInfo<X86_64ABIInfo>().isPassedUsingAVXType(it->Ty)) { 1451992cb984SSergei Barannikov HasAVXType = true; 1452992cb984SSergei Barannikov break; 1453992cb984SSergei Barannikov } 1454992cb984SSergei Barannikov } 1455992cb984SSergei Barannikov 1456992cb984SSergei Barannikov if (!HasAVXType) 1457992cb984SSergei Barannikov return true; 1458992cb984SSergei Barannikov } 1459992cb984SSergei Barannikov 1460992cb984SSergei Barannikov return TargetCodeGenInfo::isNoProtoCallVariadic(args, fnType); 1461992cb984SSergei Barannikov } 1462992cb984SSergei Barannikov 1463992cb984SSergei Barannikov void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, 1464992cb984SSergei Barannikov CodeGen::CodeGenModule &CGM) const override { 1465992cb984SSergei Barannikov if (GV->isDeclaration()) 1466992cb984SSergei Barannikov return; 1467992cb984SSergei Barannikov if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) { 1468992cb984SSergei Barannikov if (FD->hasAttr<X86ForceAlignArgPointerAttr>()) { 1469992cb984SSergei Barannikov llvm::Function *Fn = cast<llvm::Function>(GV); 1470992cb984SSergei Barannikov Fn->addFnAttr("stackrealign"); 1471992cb984SSergei Barannikov } 1472992cb984SSergei Barannikov 1473992cb984SSergei Barannikov addX86InterruptAttrs(FD, GV, CGM); 1474992cb984SSergei Barannikov } 1475992cb984SSergei Barannikov } 1476992cb984SSergei Barannikov 1477992cb984SSergei Barannikov void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, 1478992cb984SSergei Barannikov const FunctionDecl *Caller, 14791fd196c8Sostannard const FunctionDecl *Callee, const CallArgList &Args, 14801fd196c8Sostannard QualType ReturnType) const override; 1481992cb984SSergei Barannikov }; 1482992cb984SSergei Barannikov } // namespace 1483992cb984SSergei Barannikov 1484992cb984SSergei Barannikov static void initFeatureMaps(const ASTContext &Ctx, 1485992cb984SSergei Barannikov llvm::StringMap<bool> &CallerMap, 1486992cb984SSergei Barannikov const FunctionDecl *Caller, 1487992cb984SSergei Barannikov llvm::StringMap<bool> &CalleeMap, 1488992cb984SSergei Barannikov const FunctionDecl *Callee) { 1489992cb984SSergei Barannikov if (CalleeMap.empty() && CallerMap.empty()) { 1490992cb984SSergei Barannikov // The caller is potentially nullptr in the case where the call isn't in a 1491992cb984SSergei Barannikov // function. In this case, the getFunctionFeatureMap ensures we just get 1492992cb984SSergei Barannikov // the TU level setting (since it cannot be modified by 'target'.. 1493992cb984SSergei Barannikov Ctx.getFunctionFeatureMap(CallerMap, Caller); 1494992cb984SSergei Barannikov Ctx.getFunctionFeatureMap(CalleeMap, Callee); 1495992cb984SSergei Barannikov } 1496992cb984SSergei Barannikov } 1497992cb984SSergei Barannikov 1498992cb984SSergei Barannikov static bool checkAVXParamFeature(DiagnosticsEngine &Diag, 1499992cb984SSergei Barannikov SourceLocation CallLoc, 1500992cb984SSergei Barannikov const llvm::StringMap<bool> &CallerMap, 1501992cb984SSergei Barannikov const llvm::StringMap<bool> &CalleeMap, 1502992cb984SSergei Barannikov QualType Ty, StringRef Feature, 1503992cb984SSergei Barannikov bool IsArgument) { 1504992cb984SSergei Barannikov bool CallerHasFeat = CallerMap.lookup(Feature); 1505992cb984SSergei Barannikov bool CalleeHasFeat = CalleeMap.lookup(Feature); 1506992cb984SSergei Barannikov if (!CallerHasFeat && !CalleeHasFeat) 1507992cb984SSergei Barannikov return Diag.Report(CallLoc, diag::warn_avx_calling_convention) 1508992cb984SSergei Barannikov << IsArgument << Ty << Feature; 1509992cb984SSergei Barannikov 1510992cb984SSergei Barannikov // Mixing calling conventions here is very clearly an error. 1511992cb984SSergei Barannikov if (!CallerHasFeat || !CalleeHasFeat) 1512992cb984SSergei Barannikov return Diag.Report(CallLoc, diag::err_avx_calling_convention) 1513992cb984SSergei Barannikov << IsArgument << Ty << Feature; 1514992cb984SSergei Barannikov 1515992cb984SSergei Barannikov // Else, both caller and callee have the required feature, so there is no need 1516992cb984SSergei Barannikov // to diagnose. 1517992cb984SSergei Barannikov return false; 1518992cb984SSergei Barannikov } 1519992cb984SSergei Barannikov 152024194090SPhoebe Wang static bool checkAVX512ParamFeature(DiagnosticsEngine &Diag, 152124194090SPhoebe Wang SourceLocation CallLoc, 152224194090SPhoebe Wang const llvm::StringMap<bool> &CallerMap, 152324194090SPhoebe Wang const llvm::StringMap<bool> &CalleeMap, 152424194090SPhoebe Wang QualType Ty, bool IsArgument) { 152524194090SPhoebe Wang bool Caller256 = CallerMap.lookup("avx512f") && !CallerMap.lookup("evex512"); 152624194090SPhoebe Wang bool Callee256 = CalleeMap.lookup("avx512f") && !CalleeMap.lookup("evex512"); 152724194090SPhoebe Wang 152824194090SPhoebe Wang // Forbid 512-bit or larger vector pass or return when we disabled ZMM 152924194090SPhoebe Wang // instructions. 153024194090SPhoebe Wang if (Caller256 || Callee256) 153124194090SPhoebe Wang return Diag.Report(CallLoc, diag::err_avx_calling_convention) 153224194090SPhoebe Wang << IsArgument << Ty << "evex512"; 153324194090SPhoebe Wang 153424194090SPhoebe Wang return checkAVXParamFeature(Diag, CallLoc, CallerMap, CalleeMap, Ty, 153524194090SPhoebe Wang "avx512f", IsArgument); 153624194090SPhoebe Wang } 153724194090SPhoebe Wang 1538992cb984SSergei Barannikov static bool checkAVXParam(DiagnosticsEngine &Diag, ASTContext &Ctx, 1539992cb984SSergei Barannikov SourceLocation CallLoc, 1540992cb984SSergei Barannikov const llvm::StringMap<bool> &CallerMap, 1541992cb984SSergei Barannikov const llvm::StringMap<bool> &CalleeMap, QualType Ty, 1542992cb984SSergei Barannikov bool IsArgument) { 1543992cb984SSergei Barannikov uint64_t Size = Ctx.getTypeSize(Ty); 1544992cb984SSergei Barannikov if (Size > 256) 154524194090SPhoebe Wang return checkAVX512ParamFeature(Diag, CallLoc, CallerMap, CalleeMap, Ty, 154624194090SPhoebe Wang IsArgument); 1547992cb984SSergei Barannikov 1548992cb984SSergei Barannikov if (Size > 128) 1549992cb984SSergei Barannikov return checkAVXParamFeature(Diag, CallLoc, CallerMap, CalleeMap, Ty, "avx", 1550992cb984SSergei Barannikov IsArgument); 1551992cb984SSergei Barannikov 1552992cb984SSergei Barannikov return false; 1553992cb984SSergei Barannikov } 1554992cb984SSergei Barannikov 15551fd196c8Sostannard void X86_64TargetCodeGenInfo::checkFunctionCallABI(CodeGenModule &CGM, 15561fd196c8Sostannard SourceLocation CallLoc, 15571fd196c8Sostannard const FunctionDecl *Caller, 15581fd196c8Sostannard const FunctionDecl *Callee, 15591fd196c8Sostannard const CallArgList &Args, 15601fd196c8Sostannard QualType ReturnType) const { 15611fd196c8Sostannard if (!Callee) 15621fd196c8Sostannard return; 15631fd196c8Sostannard 1564992cb984SSergei Barannikov llvm::StringMap<bool> CallerMap; 1565992cb984SSergei Barannikov llvm::StringMap<bool> CalleeMap; 1566992cb984SSergei Barannikov unsigned ArgIndex = 0; 1567992cb984SSergei Barannikov 1568992cb984SSergei Barannikov // We need to loop through the actual call arguments rather than the 1569992cb984SSergei Barannikov // function's parameters, in case this variadic. 1570992cb984SSergei Barannikov for (const CallArg &Arg : Args) { 1571992cb984SSergei Barannikov // The "avx" feature changes how vectors >128 in size are passed. "avx512f" 1572992cb984SSergei Barannikov // additionally changes how vectors >256 in size are passed. Like GCC, we 1573992cb984SSergei Barannikov // warn when a function is called with an argument where this will change. 1574992cb984SSergei Barannikov // Unlike GCC, we also error when it is an obvious ABI mismatch, that is, 1575992cb984SSergei Barannikov // the caller and callee features are mismatched. 1576992cb984SSergei Barannikov // Unfortunately, we cannot do this diagnostic in SEMA, since the callee can 1577992cb984SSergei Barannikov // change its ABI with attribute-target after this call. 1578992cb984SSergei Barannikov if (Arg.getType()->isVectorType() && 1579992cb984SSergei Barannikov CGM.getContext().getTypeSize(Arg.getType()) > 128) { 1580992cb984SSergei Barannikov initFeatureMaps(CGM.getContext(), CallerMap, Caller, CalleeMap, Callee); 1581992cb984SSergei Barannikov QualType Ty = Arg.getType(); 1582992cb984SSergei Barannikov // The CallArg seems to have desugared the type already, so for clearer 1583992cb984SSergei Barannikov // diagnostics, replace it with the type in the FunctionDecl if possible. 1584992cb984SSergei Barannikov if (ArgIndex < Callee->getNumParams()) 1585992cb984SSergei Barannikov Ty = Callee->getParamDecl(ArgIndex)->getType(); 1586992cb984SSergei Barannikov 1587992cb984SSergei Barannikov if (checkAVXParam(CGM.getDiags(), CGM.getContext(), CallLoc, CallerMap, 1588992cb984SSergei Barannikov CalleeMap, Ty, /*IsArgument*/ true)) 1589992cb984SSergei Barannikov return; 1590992cb984SSergei Barannikov } 1591992cb984SSergei Barannikov ++ArgIndex; 1592992cb984SSergei Barannikov } 1593992cb984SSergei Barannikov 1594992cb984SSergei Barannikov // Check return always, as we don't have a good way of knowing in codegen 1595992cb984SSergei Barannikov // whether this value is used, tail-called, etc. 1596992cb984SSergei Barannikov if (Callee->getReturnType()->isVectorType() && 1597992cb984SSergei Barannikov CGM.getContext().getTypeSize(Callee->getReturnType()) > 128) { 1598992cb984SSergei Barannikov initFeatureMaps(CGM.getContext(), CallerMap, Caller, CalleeMap, Callee); 1599992cb984SSergei Barannikov checkAVXParam(CGM.getDiags(), CGM.getContext(), CallLoc, CallerMap, 1600992cb984SSergei Barannikov CalleeMap, Callee->getReturnType(), 1601992cb984SSergei Barannikov /*IsArgument*/ false); 1602992cb984SSergei Barannikov } 1603992cb984SSergei Barannikov } 1604992cb984SSergei Barannikov 1605992cb984SSergei Barannikov std::string TargetCodeGenInfo::qualifyWindowsLibrary(StringRef Lib) { 1606992cb984SSergei Barannikov // If the argument does not end in .lib, automatically add the suffix. 1607992cb984SSergei Barannikov // If the argument contains a space, enclose it in quotes. 1608992cb984SSergei Barannikov // This matches the behavior of MSVC. 1609992cb984SSergei Barannikov bool Quote = Lib.contains(' '); 1610992cb984SSergei Barannikov std::string ArgStr = Quote ? "\"" : ""; 1611992cb984SSergei Barannikov ArgStr += Lib; 1612992cb984SSergei Barannikov if (!Lib.ends_with_insensitive(".lib") && !Lib.ends_with_insensitive(".a")) 1613992cb984SSergei Barannikov ArgStr += ".lib"; 1614992cb984SSergei Barannikov ArgStr += Quote ? "\"" : ""; 1615992cb984SSergei Barannikov return ArgStr; 1616992cb984SSergei Barannikov } 1617992cb984SSergei Barannikov 1618992cb984SSergei Barannikov namespace { 1619992cb984SSergei Barannikov class WinX86_32TargetCodeGenInfo : public X86_32TargetCodeGenInfo { 1620992cb984SSergei Barannikov public: 1621992cb984SSergei Barannikov WinX86_32TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, 1622992cb984SSergei Barannikov bool DarwinVectorABI, bool RetSmallStructInRegABI, bool Win32StructABI, 1623992cb984SSergei Barannikov unsigned NumRegisterParameters) 1624992cb984SSergei Barannikov : X86_32TargetCodeGenInfo(CGT, DarwinVectorABI, RetSmallStructInRegABI, 1625992cb984SSergei Barannikov Win32StructABI, NumRegisterParameters, false) {} 1626992cb984SSergei Barannikov 1627992cb984SSergei Barannikov void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, 1628992cb984SSergei Barannikov CodeGen::CodeGenModule &CGM) const override; 1629992cb984SSergei Barannikov 1630992cb984SSergei Barannikov void getDependentLibraryOption(llvm::StringRef Lib, 1631992cb984SSergei Barannikov llvm::SmallString<24> &Opt) const override { 1632992cb984SSergei Barannikov Opt = "/DEFAULTLIB:"; 1633992cb984SSergei Barannikov Opt += qualifyWindowsLibrary(Lib); 1634992cb984SSergei Barannikov } 1635992cb984SSergei Barannikov 1636992cb984SSergei Barannikov void getDetectMismatchOption(llvm::StringRef Name, 1637992cb984SSergei Barannikov llvm::StringRef Value, 1638992cb984SSergei Barannikov llvm::SmallString<32> &Opt) const override { 1639992cb984SSergei Barannikov Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\""; 1640992cb984SSergei Barannikov } 1641992cb984SSergei Barannikov }; 1642992cb984SSergei Barannikov } // namespace 1643992cb984SSergei Barannikov 1644992cb984SSergei Barannikov void WinX86_32TargetCodeGenInfo::setTargetAttributes( 1645992cb984SSergei Barannikov const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const { 1646992cb984SSergei Barannikov X86_32TargetCodeGenInfo::setTargetAttributes(D, GV, CGM); 1647992cb984SSergei Barannikov if (GV->isDeclaration()) 1648992cb984SSergei Barannikov return; 1649992cb984SSergei Barannikov addStackProbeTargetAttributes(D, GV, CGM); 1650992cb984SSergei Barannikov } 1651992cb984SSergei Barannikov 1652992cb984SSergei Barannikov namespace { 1653992cb984SSergei Barannikov class WinX86_64TargetCodeGenInfo : public TargetCodeGenInfo { 1654992cb984SSergei Barannikov public: 1655992cb984SSergei Barannikov WinX86_64TargetCodeGenInfo(CodeGen::CodeGenTypes &CGT, 1656992cb984SSergei Barannikov X86AVXABILevel AVXLevel) 1657992cb984SSergei Barannikov : TargetCodeGenInfo(std::make_unique<WinX86_64ABIInfo>(CGT, AVXLevel)) { 1658992cb984SSergei Barannikov SwiftInfo = 1659992cb984SSergei Barannikov std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/true); 1660992cb984SSergei Barannikov } 1661992cb984SSergei Barannikov 1662992cb984SSergei Barannikov void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, 1663992cb984SSergei Barannikov CodeGen::CodeGenModule &CGM) const override; 1664992cb984SSergei Barannikov 1665992cb984SSergei Barannikov int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override { 1666992cb984SSergei Barannikov return 7; 1667992cb984SSergei Barannikov } 1668992cb984SSergei Barannikov 1669992cb984SSergei Barannikov bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF, 1670992cb984SSergei Barannikov llvm::Value *Address) const override { 1671992cb984SSergei Barannikov llvm::Value *Eight8 = llvm::ConstantInt::get(CGF.Int8Ty, 8); 1672992cb984SSergei Barannikov 1673992cb984SSergei Barannikov // 0-15 are the 16 integer registers. 1674992cb984SSergei Barannikov // 16 is %rip. 1675992cb984SSergei Barannikov AssignToArrayRange(CGF.Builder, Address, Eight8, 0, 16); 1676992cb984SSergei Barannikov return false; 1677992cb984SSergei Barannikov } 1678992cb984SSergei Barannikov 1679992cb984SSergei Barannikov void getDependentLibraryOption(llvm::StringRef Lib, 1680992cb984SSergei Barannikov llvm::SmallString<24> &Opt) const override { 1681992cb984SSergei Barannikov Opt = "/DEFAULTLIB:"; 1682992cb984SSergei Barannikov Opt += qualifyWindowsLibrary(Lib); 1683992cb984SSergei Barannikov } 1684992cb984SSergei Barannikov 1685992cb984SSergei Barannikov void getDetectMismatchOption(llvm::StringRef Name, 1686992cb984SSergei Barannikov llvm::StringRef Value, 1687992cb984SSergei Barannikov llvm::SmallString<32> &Opt) const override { 1688992cb984SSergei Barannikov Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\""; 1689992cb984SSergei Barannikov } 1690992cb984SSergei Barannikov }; 1691992cb984SSergei Barannikov } // namespace 1692992cb984SSergei Barannikov 1693992cb984SSergei Barannikov void WinX86_64TargetCodeGenInfo::setTargetAttributes( 1694992cb984SSergei Barannikov const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const { 1695992cb984SSergei Barannikov TargetCodeGenInfo::setTargetAttributes(D, GV, CGM); 1696992cb984SSergei Barannikov if (GV->isDeclaration()) 1697992cb984SSergei Barannikov return; 1698992cb984SSergei Barannikov if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) { 1699992cb984SSergei Barannikov if (FD->hasAttr<X86ForceAlignArgPointerAttr>()) { 1700992cb984SSergei Barannikov llvm::Function *Fn = cast<llvm::Function>(GV); 1701992cb984SSergei Barannikov Fn->addFnAttr("stackrealign"); 1702992cb984SSergei Barannikov } 1703992cb984SSergei Barannikov 1704992cb984SSergei Barannikov addX86InterruptAttrs(FD, GV, CGM); 1705992cb984SSergei Barannikov } 1706992cb984SSergei Barannikov 1707992cb984SSergei Barannikov addStackProbeTargetAttributes(D, GV, CGM); 1708992cb984SSergei Barannikov } 1709992cb984SSergei Barannikov 1710992cb984SSergei Barannikov void X86_64ABIInfo::postMerge(unsigned AggregateSize, Class &Lo, 1711992cb984SSergei Barannikov Class &Hi) const { 1712992cb984SSergei Barannikov // AMD64-ABI 3.2.3p2: Rule 5. Then a post merger cleanup is done: 1713992cb984SSergei Barannikov // 1714992cb984SSergei Barannikov // (a) If one of the classes is Memory, the whole argument is passed in 1715992cb984SSergei Barannikov // memory. 1716992cb984SSergei Barannikov // 1717992cb984SSergei Barannikov // (b) If X87UP is not preceded by X87, the whole argument is passed in 1718992cb984SSergei Barannikov // memory. 1719992cb984SSergei Barannikov // 1720992cb984SSergei Barannikov // (c) If the size of the aggregate exceeds two eightbytes and the first 1721992cb984SSergei Barannikov // eightbyte isn't SSE or any other eightbyte isn't SSEUP, the whole 1722992cb984SSergei Barannikov // argument is passed in memory. NOTE: This is necessary to keep the 1723992cb984SSergei Barannikov // ABI working for processors that don't support the __m256 type. 1724992cb984SSergei Barannikov // 1725992cb984SSergei Barannikov // (d) If SSEUP is not preceded by SSE or SSEUP, it is converted to SSE. 1726992cb984SSergei Barannikov // 1727992cb984SSergei Barannikov // Some of these are enforced by the merging logic. Others can arise 1728992cb984SSergei Barannikov // only with unions; for example: 1729992cb984SSergei Barannikov // union { _Complex double; unsigned; } 1730992cb984SSergei Barannikov // 1731992cb984SSergei Barannikov // Note that clauses (b) and (c) were added in 0.98. 1732992cb984SSergei Barannikov // 1733992cb984SSergei Barannikov if (Hi == Memory) 1734992cb984SSergei Barannikov Lo = Memory; 1735992cb984SSergei Barannikov if (Hi == X87Up && Lo != X87 && honorsRevision0_98()) 1736992cb984SSergei Barannikov Lo = Memory; 1737992cb984SSergei Barannikov if (AggregateSize > 128 && (Lo != SSE || Hi != SSEUp)) 1738992cb984SSergei Barannikov Lo = Memory; 1739992cb984SSergei Barannikov if (Hi == SSEUp && Lo != SSE) 1740992cb984SSergei Barannikov Hi = SSE; 1741992cb984SSergei Barannikov } 1742992cb984SSergei Barannikov 1743992cb984SSergei Barannikov X86_64ABIInfo::Class X86_64ABIInfo::merge(Class Accum, Class Field) { 1744992cb984SSergei Barannikov // AMD64-ABI 3.2.3p2: Rule 4. Each field of an object is 1745992cb984SSergei Barannikov // classified recursively so that always two fields are 1746992cb984SSergei Barannikov // considered. The resulting class is calculated according to 1747992cb984SSergei Barannikov // the classes of the fields in the eightbyte: 1748992cb984SSergei Barannikov // 1749992cb984SSergei Barannikov // (a) If both classes are equal, this is the resulting class. 1750992cb984SSergei Barannikov // 1751992cb984SSergei Barannikov // (b) If one of the classes is NO_CLASS, the resulting class is 1752992cb984SSergei Barannikov // the other class. 1753992cb984SSergei Barannikov // 1754992cb984SSergei Barannikov // (c) If one of the classes is MEMORY, the result is the MEMORY 1755992cb984SSergei Barannikov // class. 1756992cb984SSergei Barannikov // 1757992cb984SSergei Barannikov // (d) If one of the classes is INTEGER, the result is the 1758992cb984SSergei Barannikov // INTEGER. 1759992cb984SSergei Barannikov // 1760992cb984SSergei Barannikov // (e) If one of the classes is X87, X87UP, COMPLEX_X87 class, 1761992cb984SSergei Barannikov // MEMORY is used as class. 1762992cb984SSergei Barannikov // 1763992cb984SSergei Barannikov // (f) Otherwise class SSE is used. 1764992cb984SSergei Barannikov 1765992cb984SSergei Barannikov // Accum should never be memory (we should have returned) or 1766992cb984SSergei Barannikov // ComplexX87 (because this cannot be passed in a structure). 1767992cb984SSergei Barannikov assert((Accum != Memory && Accum != ComplexX87) && 1768992cb984SSergei Barannikov "Invalid accumulated classification during merge."); 1769992cb984SSergei Barannikov if (Accum == Field || Field == NoClass) 1770992cb984SSergei Barannikov return Accum; 1771992cb984SSergei Barannikov if (Field == Memory) 1772992cb984SSergei Barannikov return Memory; 1773992cb984SSergei Barannikov if (Accum == NoClass) 1774992cb984SSergei Barannikov return Field; 1775992cb984SSergei Barannikov if (Accum == Integer || Field == Integer) 1776992cb984SSergei Barannikov return Integer; 1777992cb984SSergei Barannikov if (Field == X87 || Field == X87Up || Field == ComplexX87 || 1778992cb984SSergei Barannikov Accum == X87 || Accum == X87Up) 1779992cb984SSergei Barannikov return Memory; 1780992cb984SSergei Barannikov return SSE; 1781992cb984SSergei Barannikov } 1782992cb984SSergei Barannikov 1783992cb984SSergei Barannikov void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo, 1784992cb984SSergei Barannikov Class &Hi, bool isNamedArg, bool IsRegCall) const { 1785992cb984SSergei Barannikov // FIXME: This code can be simplified by introducing a simple value class for 1786992cb984SSergei Barannikov // Class pairs with appropriate constructor methods for the various 1787992cb984SSergei Barannikov // situations. 1788992cb984SSergei Barannikov 1789992cb984SSergei Barannikov // FIXME: Some of the split computations are wrong; unaligned vectors 1790992cb984SSergei Barannikov // shouldn't be passed in registers for example, so there is no chance they 1791992cb984SSergei Barannikov // can straddle an eightbyte. Verify & simplify. 1792992cb984SSergei Barannikov 1793992cb984SSergei Barannikov Lo = Hi = NoClass; 1794992cb984SSergei Barannikov 1795992cb984SSergei Barannikov Class &Current = OffsetBase < 64 ? Lo : Hi; 1796992cb984SSergei Barannikov Current = Memory; 1797992cb984SSergei Barannikov 1798992cb984SSergei Barannikov if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) { 1799992cb984SSergei Barannikov BuiltinType::Kind k = BT->getKind(); 1800992cb984SSergei Barannikov 1801992cb984SSergei Barannikov if (k == BuiltinType::Void) { 1802992cb984SSergei Barannikov Current = NoClass; 1803992cb984SSergei Barannikov } else if (k == BuiltinType::Int128 || k == BuiltinType::UInt128) { 1804992cb984SSergei Barannikov Lo = Integer; 1805992cb984SSergei Barannikov Hi = Integer; 1806992cb984SSergei Barannikov } else if (k >= BuiltinType::Bool && k <= BuiltinType::LongLong) { 1807992cb984SSergei Barannikov Current = Integer; 1808992cb984SSergei Barannikov } else if (k == BuiltinType::Float || k == BuiltinType::Double || 1809992cb984SSergei Barannikov k == BuiltinType::Float16 || k == BuiltinType::BFloat16) { 1810992cb984SSergei Barannikov Current = SSE; 1811f07aba4bSPhoebe Wang } else if (k == BuiltinType::Float128) { 1812f07aba4bSPhoebe Wang Lo = SSE; 1813f07aba4bSPhoebe Wang Hi = SSEUp; 1814992cb984SSergei Barannikov } else if (k == BuiltinType::LongDouble) { 1815992cb984SSergei Barannikov const llvm::fltSemantics *LDF = &getTarget().getLongDoubleFormat(); 1816992cb984SSergei Barannikov if (LDF == &llvm::APFloat::IEEEquad()) { 1817992cb984SSergei Barannikov Lo = SSE; 1818992cb984SSergei Barannikov Hi = SSEUp; 1819992cb984SSergei Barannikov } else if (LDF == &llvm::APFloat::x87DoubleExtended()) { 1820992cb984SSergei Barannikov Lo = X87; 1821992cb984SSergei Barannikov Hi = X87Up; 1822992cb984SSergei Barannikov } else if (LDF == &llvm::APFloat::IEEEdouble()) { 1823992cb984SSergei Barannikov Current = SSE; 1824992cb984SSergei Barannikov } else 1825992cb984SSergei Barannikov llvm_unreachable("unexpected long double representation!"); 1826992cb984SSergei Barannikov } 1827992cb984SSergei Barannikov // FIXME: _Decimal32 and _Decimal64 are SSE. 1828992cb984SSergei Barannikov // FIXME: _float128 and _Decimal128 are (SSE, SSEUp). 1829992cb984SSergei Barannikov return; 1830992cb984SSergei Barannikov } 1831992cb984SSergei Barannikov 1832992cb984SSergei Barannikov if (const EnumType *ET = Ty->getAs<EnumType>()) { 1833992cb984SSergei Barannikov // Classify the underlying integer type. 1834992cb984SSergei Barannikov classify(ET->getDecl()->getIntegerType(), OffsetBase, Lo, Hi, isNamedArg); 1835992cb984SSergei Barannikov return; 1836992cb984SSergei Barannikov } 1837992cb984SSergei Barannikov 1838992cb984SSergei Barannikov if (Ty->hasPointerRepresentation()) { 1839992cb984SSergei Barannikov Current = Integer; 1840992cb984SSergei Barannikov return; 1841992cb984SSergei Barannikov } 1842992cb984SSergei Barannikov 1843992cb984SSergei Barannikov if (Ty->isMemberPointerType()) { 1844992cb984SSergei Barannikov if (Ty->isMemberFunctionPointerType()) { 1845992cb984SSergei Barannikov if (Has64BitPointers) { 1846992cb984SSergei Barannikov // If Has64BitPointers, this is an {i64, i64}, so classify both 1847992cb984SSergei Barannikov // Lo and Hi now. 1848992cb984SSergei Barannikov Lo = Hi = Integer; 1849992cb984SSergei Barannikov } else { 1850992cb984SSergei Barannikov // Otherwise, with 32-bit pointers, this is an {i32, i32}. If that 1851992cb984SSergei Barannikov // straddles an eightbyte boundary, Hi should be classified as well. 1852992cb984SSergei Barannikov uint64_t EB_FuncPtr = (OffsetBase) / 64; 1853992cb984SSergei Barannikov uint64_t EB_ThisAdj = (OffsetBase + 64 - 1) / 64; 1854992cb984SSergei Barannikov if (EB_FuncPtr != EB_ThisAdj) { 1855992cb984SSergei Barannikov Lo = Hi = Integer; 1856992cb984SSergei Barannikov } else { 1857992cb984SSergei Barannikov Current = Integer; 1858992cb984SSergei Barannikov } 1859992cb984SSergei Barannikov } 1860992cb984SSergei Barannikov } else { 1861992cb984SSergei Barannikov Current = Integer; 1862992cb984SSergei Barannikov } 1863992cb984SSergei Barannikov return; 1864992cb984SSergei Barannikov } 1865992cb984SSergei Barannikov 1866992cb984SSergei Barannikov if (const VectorType *VT = Ty->getAs<VectorType>()) { 1867992cb984SSergei Barannikov uint64_t Size = getContext().getTypeSize(VT); 1868992cb984SSergei Barannikov if (Size == 1 || Size == 8 || Size == 16 || Size == 32) { 1869992cb984SSergei Barannikov // gcc passes the following as integer: 1870992cb984SSergei Barannikov // 4 bytes - <4 x char>, <2 x short>, <1 x int>, <1 x float> 1871992cb984SSergei Barannikov // 2 bytes - <2 x char>, <1 x short> 1872992cb984SSergei Barannikov // 1 byte - <1 x char> 1873992cb984SSergei Barannikov Current = Integer; 1874992cb984SSergei Barannikov 1875992cb984SSergei Barannikov // If this type crosses an eightbyte boundary, it should be 1876992cb984SSergei Barannikov // split. 1877992cb984SSergei Barannikov uint64_t EB_Lo = (OffsetBase) / 64; 1878992cb984SSergei Barannikov uint64_t EB_Hi = (OffsetBase + Size - 1) / 64; 1879992cb984SSergei Barannikov if (EB_Lo != EB_Hi) 1880992cb984SSergei Barannikov Hi = Lo; 1881992cb984SSergei Barannikov } else if (Size == 64) { 1882992cb984SSergei Barannikov QualType ElementType = VT->getElementType(); 1883992cb984SSergei Barannikov 1884992cb984SSergei Barannikov // gcc passes <1 x double> in memory. :( 1885992cb984SSergei Barannikov if (ElementType->isSpecificBuiltinType(BuiltinType::Double)) 1886992cb984SSergei Barannikov return; 1887992cb984SSergei Barannikov 1888992cb984SSergei Barannikov // gcc passes <1 x long long> as SSE but clang used to unconditionally 1889992cb984SSergei Barannikov // pass them as integer. For platforms where clang is the de facto 1890992cb984SSergei Barannikov // platform compiler, we must continue to use integer. 1891992cb984SSergei Barannikov if (!classifyIntegerMMXAsSSE() && 1892992cb984SSergei Barannikov (ElementType->isSpecificBuiltinType(BuiltinType::LongLong) || 1893992cb984SSergei Barannikov ElementType->isSpecificBuiltinType(BuiltinType::ULongLong) || 1894992cb984SSergei Barannikov ElementType->isSpecificBuiltinType(BuiltinType::Long) || 1895992cb984SSergei Barannikov ElementType->isSpecificBuiltinType(BuiltinType::ULong))) 1896992cb984SSergei Barannikov Current = Integer; 1897992cb984SSergei Barannikov else 1898992cb984SSergei Barannikov Current = SSE; 1899992cb984SSergei Barannikov 1900992cb984SSergei Barannikov // If this type crosses an eightbyte boundary, it should be 1901992cb984SSergei Barannikov // split. 1902992cb984SSergei Barannikov if (OffsetBase && OffsetBase != 64) 1903992cb984SSergei Barannikov Hi = Lo; 1904992cb984SSergei Barannikov } else if (Size == 128 || 1905992cb984SSergei Barannikov (isNamedArg && Size <= getNativeVectorSizeForAVXABI(AVXLevel))) { 1906992cb984SSergei Barannikov QualType ElementType = VT->getElementType(); 1907992cb984SSergei Barannikov 1908992cb984SSergei Barannikov // gcc passes 256 and 512 bit <X x __int128> vectors in memory. :( 1909992cb984SSergei Barannikov if (passInt128VectorsInMem() && Size != 128 && 1910992cb984SSergei Barannikov (ElementType->isSpecificBuiltinType(BuiltinType::Int128) || 1911992cb984SSergei Barannikov ElementType->isSpecificBuiltinType(BuiltinType::UInt128))) 1912992cb984SSergei Barannikov return; 1913992cb984SSergei Barannikov 1914992cb984SSergei Barannikov // Arguments of 256-bits are split into four eightbyte chunks. The 1915992cb984SSergei Barannikov // least significant one belongs to class SSE and all the others to class 1916992cb984SSergei Barannikov // SSEUP. The original Lo and Hi design considers that types can't be 1917992cb984SSergei Barannikov // greater than 128-bits, so a 64-bit split in Hi and Lo makes sense. 1918992cb984SSergei Barannikov // This design isn't correct for 256-bits, but since there're no cases 1919992cb984SSergei Barannikov // where the upper parts would need to be inspected, avoid adding 1920992cb984SSergei Barannikov // complexity and just consider Hi to match the 64-256 part. 1921992cb984SSergei Barannikov // 1922992cb984SSergei Barannikov // Note that per 3.5.7 of AMD64-ABI, 256-bit args are only passed in 1923992cb984SSergei Barannikov // registers if they are "named", i.e. not part of the "..." of a 1924992cb984SSergei Barannikov // variadic function. 1925992cb984SSergei Barannikov // 1926992cb984SSergei Barannikov // Similarly, per 3.2.3. of the AVX512 draft, 512-bits ("named") args are 1927992cb984SSergei Barannikov // split into eight eightbyte chunks, one SSE and seven SSEUP. 1928992cb984SSergei Barannikov Lo = SSE; 1929992cb984SSergei Barannikov Hi = SSEUp; 1930992cb984SSergei Barannikov } 1931992cb984SSergei Barannikov return; 1932992cb984SSergei Barannikov } 1933992cb984SSergei Barannikov 1934992cb984SSergei Barannikov if (const ComplexType *CT = Ty->getAs<ComplexType>()) { 1935992cb984SSergei Barannikov QualType ET = getContext().getCanonicalType(CT->getElementType()); 1936992cb984SSergei Barannikov 1937992cb984SSergei Barannikov uint64_t Size = getContext().getTypeSize(Ty); 1938992cb984SSergei Barannikov if (ET->isIntegralOrEnumerationType()) { 1939992cb984SSergei Barannikov if (Size <= 64) 1940992cb984SSergei Barannikov Current = Integer; 1941992cb984SSergei Barannikov else if (Size <= 128) 1942992cb984SSergei Barannikov Lo = Hi = Integer; 1943992cb984SSergei Barannikov } else if (ET->isFloat16Type() || ET == getContext().FloatTy || 1944992cb984SSergei Barannikov ET->isBFloat16Type()) { 1945992cb984SSergei Barannikov Current = SSE; 1946992cb984SSergei Barannikov } else if (ET == getContext().DoubleTy) { 1947992cb984SSergei Barannikov Lo = Hi = SSE; 1948992cb984SSergei Barannikov } else if (ET == getContext().LongDoubleTy) { 1949992cb984SSergei Barannikov const llvm::fltSemantics *LDF = &getTarget().getLongDoubleFormat(); 1950992cb984SSergei Barannikov if (LDF == &llvm::APFloat::IEEEquad()) 1951992cb984SSergei Barannikov Current = Memory; 1952992cb984SSergei Barannikov else if (LDF == &llvm::APFloat::x87DoubleExtended()) 1953992cb984SSergei Barannikov Current = ComplexX87; 1954992cb984SSergei Barannikov else if (LDF == &llvm::APFloat::IEEEdouble()) 1955992cb984SSergei Barannikov Lo = Hi = SSE; 1956992cb984SSergei Barannikov else 1957992cb984SSergei Barannikov llvm_unreachable("unexpected long double representation!"); 1958992cb984SSergei Barannikov } 1959992cb984SSergei Barannikov 1960992cb984SSergei Barannikov // If this complex type crosses an eightbyte boundary then it 1961992cb984SSergei Barannikov // should be split. 1962992cb984SSergei Barannikov uint64_t EB_Real = (OffsetBase) / 64; 1963992cb984SSergei Barannikov uint64_t EB_Imag = (OffsetBase + getContext().getTypeSize(ET)) / 64; 1964992cb984SSergei Barannikov if (Hi == NoClass && EB_Real != EB_Imag) 1965992cb984SSergei Barannikov Hi = Lo; 1966992cb984SSergei Barannikov 1967992cb984SSergei Barannikov return; 1968992cb984SSergei Barannikov } 1969992cb984SSergei Barannikov 1970992cb984SSergei Barannikov if (const auto *EITy = Ty->getAs<BitIntType>()) { 1971992cb984SSergei Barannikov if (EITy->getNumBits() <= 64) 1972992cb984SSergei Barannikov Current = Integer; 1973992cb984SSergei Barannikov else if (EITy->getNumBits() <= 128) 1974992cb984SSergei Barannikov Lo = Hi = Integer; 1975992cb984SSergei Barannikov // Larger values need to get passed in memory. 1976992cb984SSergei Barannikov return; 1977992cb984SSergei Barannikov } 1978992cb984SSergei Barannikov 1979992cb984SSergei Barannikov if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) { 1980992cb984SSergei Barannikov // Arrays are treated like structures. 1981992cb984SSergei Barannikov 1982992cb984SSergei Barannikov uint64_t Size = getContext().getTypeSize(Ty); 1983992cb984SSergei Barannikov 1984992cb984SSergei Barannikov // AMD64-ABI 3.2.3p2: Rule 1. If the size of an object is larger 1985992cb984SSergei Barannikov // than eight eightbytes, ..., it has class MEMORY. 1986992cb984SSergei Barannikov // regcall ABI doesn't have limitation to an object. The only limitation 1987992cb984SSergei Barannikov // is the free registers, which will be checked in computeInfo. 1988992cb984SSergei Barannikov if (!IsRegCall && Size > 512) 1989992cb984SSergei Barannikov return; 1990992cb984SSergei Barannikov 1991992cb984SSergei Barannikov // AMD64-ABI 3.2.3p2: Rule 1. If ..., or it contains unaligned 1992992cb984SSergei Barannikov // fields, it has class MEMORY. 1993992cb984SSergei Barannikov // 1994992cb984SSergei Barannikov // Only need to check alignment of array base. 1995992cb984SSergei Barannikov if (OffsetBase % getContext().getTypeAlign(AT->getElementType())) 1996992cb984SSergei Barannikov return; 1997992cb984SSergei Barannikov 1998992cb984SSergei Barannikov // Otherwise implement simplified merge. We could be smarter about 1999992cb984SSergei Barannikov // this, but it isn't worth it and would be harder to verify. 2000992cb984SSergei Barannikov Current = NoClass; 2001992cb984SSergei Barannikov uint64_t EltSize = getContext().getTypeSize(AT->getElementType()); 200228ddbd4aSChris B uint64_t ArraySize = AT->getZExtSize(); 2003992cb984SSergei Barannikov 2004992cb984SSergei Barannikov // The only case a 256-bit wide vector could be used is when the array 2005992cb984SSergei Barannikov // contains a single 256-bit element. Since Lo and Hi logic isn't extended 2006992cb984SSergei Barannikov // to work for sizes wider than 128, early check and fallback to memory. 2007992cb984SSergei Barannikov // 2008992cb984SSergei Barannikov if (Size > 128 && 2009992cb984SSergei Barannikov (Size != EltSize || Size > getNativeVectorSizeForAVXABI(AVXLevel))) 2010992cb984SSergei Barannikov return; 2011992cb984SSergei Barannikov 2012992cb984SSergei Barannikov for (uint64_t i=0, Offset=OffsetBase; i<ArraySize; ++i, Offset += EltSize) { 2013992cb984SSergei Barannikov Class FieldLo, FieldHi; 2014992cb984SSergei Barannikov classify(AT->getElementType(), Offset, FieldLo, FieldHi, isNamedArg); 2015992cb984SSergei Barannikov Lo = merge(Lo, FieldLo); 2016992cb984SSergei Barannikov Hi = merge(Hi, FieldHi); 2017992cb984SSergei Barannikov if (Lo == Memory || Hi == Memory) 2018992cb984SSergei Barannikov break; 2019992cb984SSergei Barannikov } 2020992cb984SSergei Barannikov 2021992cb984SSergei Barannikov postMerge(Size, Lo, Hi); 2022992cb984SSergei Barannikov assert((Hi != SSEUp || Lo == SSE) && "Invalid SSEUp array classification."); 2023992cb984SSergei Barannikov return; 2024992cb984SSergei Barannikov } 2025992cb984SSergei Barannikov 2026992cb984SSergei Barannikov if (const RecordType *RT = Ty->getAs<RecordType>()) { 2027992cb984SSergei Barannikov uint64_t Size = getContext().getTypeSize(Ty); 2028992cb984SSergei Barannikov 2029992cb984SSergei Barannikov // AMD64-ABI 3.2.3p2: Rule 1. If the size of an object is larger 2030992cb984SSergei Barannikov // than eight eightbytes, ..., it has class MEMORY. 2031992cb984SSergei Barannikov if (Size > 512) 2032992cb984SSergei Barannikov return; 2033992cb984SSergei Barannikov 2034992cb984SSergei Barannikov // AMD64-ABI 3.2.3p2: Rule 2. If a C++ object has either a non-trivial 2035992cb984SSergei Barannikov // copy constructor or a non-trivial destructor, it is passed by invisible 2036992cb984SSergei Barannikov // reference. 2037992cb984SSergei Barannikov if (getRecordArgABI(RT, getCXXABI())) 2038992cb984SSergei Barannikov return; 2039992cb984SSergei Barannikov 2040992cb984SSergei Barannikov const RecordDecl *RD = RT->getDecl(); 2041992cb984SSergei Barannikov 2042992cb984SSergei Barannikov // Assume variable sized types are passed in memory. 2043992cb984SSergei Barannikov if (RD->hasFlexibleArrayMember()) 2044992cb984SSergei Barannikov return; 2045992cb984SSergei Barannikov 2046992cb984SSergei Barannikov const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD); 2047992cb984SSergei Barannikov 2048992cb984SSergei Barannikov // Reset Lo class, this will be recomputed. 2049992cb984SSergei Barannikov Current = NoClass; 2050992cb984SSergei Barannikov 2051992cb984SSergei Barannikov // If this is a C++ record, classify the bases first. 2052992cb984SSergei Barannikov if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { 2053992cb984SSergei Barannikov for (const auto &I : CXXRD->bases()) { 2054992cb984SSergei Barannikov assert(!I.isVirtual() && !I.getType()->isDependentType() && 2055992cb984SSergei Barannikov "Unexpected base class!"); 2056992cb984SSergei Barannikov const auto *Base = 2057992cb984SSergei Barannikov cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 2058992cb984SSergei Barannikov 2059992cb984SSergei Barannikov // Classify this field. 2060992cb984SSergei Barannikov // 2061992cb984SSergei Barannikov // AMD64-ABI 3.2.3p2: Rule 3. If the size of the aggregate exceeds a 2062992cb984SSergei Barannikov // single eightbyte, each is classified separately. Each eightbyte gets 2063992cb984SSergei Barannikov // initialized to class NO_CLASS. 2064992cb984SSergei Barannikov Class FieldLo, FieldHi; 2065992cb984SSergei Barannikov uint64_t Offset = 2066992cb984SSergei Barannikov OffsetBase + getContext().toBits(Layout.getBaseClassOffset(Base)); 2067992cb984SSergei Barannikov classify(I.getType(), Offset, FieldLo, FieldHi, isNamedArg); 2068992cb984SSergei Barannikov Lo = merge(Lo, FieldLo); 2069992cb984SSergei Barannikov Hi = merge(Hi, FieldHi); 2070992cb984SSergei Barannikov if (Lo == Memory || Hi == Memory) { 2071992cb984SSergei Barannikov postMerge(Size, Lo, Hi); 2072992cb984SSergei Barannikov return; 2073992cb984SSergei Barannikov } 2074992cb984SSergei Barannikov } 2075992cb984SSergei Barannikov } 2076992cb984SSergei Barannikov 2077992cb984SSergei Barannikov // Classify the fields one at a time, merging the results. 2078992cb984SSergei Barannikov unsigned idx = 0; 2079992cb984SSergei Barannikov bool UseClang11Compat = getContext().getLangOpts().getClangABICompat() <= 2080992cb984SSergei Barannikov LangOptions::ClangABI::Ver11 || 2081992cb984SSergei Barannikov getContext().getTargetInfo().getTriple().isPS(); 2082992cb984SSergei Barannikov bool IsUnion = RT->isUnionType() && !UseClang11Compat; 2083992cb984SSergei Barannikov 2084992cb984SSergei Barannikov for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); 2085992cb984SSergei Barannikov i != e; ++i, ++idx) { 2086992cb984SSergei Barannikov uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx); 2087992cb984SSergei Barannikov bool BitField = i->isBitField(); 2088992cb984SSergei Barannikov 2089992cb984SSergei Barannikov // Ignore padding bit-fields. 20903d56ea05STimm Baeder if (BitField && i->isUnnamedBitField()) 2091992cb984SSergei Barannikov continue; 2092992cb984SSergei Barannikov 2093992cb984SSergei Barannikov // AMD64-ABI 3.2.3p2: Rule 1. If the size of an object is larger than 2094992cb984SSergei Barannikov // eight eightbytes, or it contains unaligned fields, it has class MEMORY. 2095992cb984SSergei Barannikov // 2096992cb984SSergei Barannikov // The only case a 256-bit or a 512-bit wide vector could be used is when 2097992cb984SSergei Barannikov // the struct contains a single 256-bit or 512-bit element. Early check 2098992cb984SSergei Barannikov // and fallback to memory. 2099992cb984SSergei Barannikov // 2100992cb984SSergei Barannikov // FIXME: Extended the Lo and Hi logic properly to work for size wider 2101992cb984SSergei Barannikov // than 128. 2102992cb984SSergei Barannikov if (Size > 128 && 2103992cb984SSergei Barannikov ((!IsUnion && Size != getContext().getTypeSize(i->getType())) || 2104992cb984SSergei Barannikov Size > getNativeVectorSizeForAVXABI(AVXLevel))) { 2105992cb984SSergei Barannikov Lo = Memory; 2106992cb984SSergei Barannikov postMerge(Size, Lo, Hi); 2107992cb984SSergei Barannikov return; 2108992cb984SSergei Barannikov } 2109000f2b51SLongsheng Mou 2110000f2b51SLongsheng Mou bool IsInMemory = 2111000f2b51SLongsheng Mou Offset % getContext().getTypeAlign(i->getType().getCanonicalType()); 2112992cb984SSergei Barannikov // Note, skip this test for bit-fields, see below. 2113000f2b51SLongsheng Mou if (!BitField && IsInMemory) { 2114992cb984SSergei Barannikov Lo = Memory; 2115992cb984SSergei Barannikov postMerge(Size, Lo, Hi); 2116992cb984SSergei Barannikov return; 2117992cb984SSergei Barannikov } 2118992cb984SSergei Barannikov 2119992cb984SSergei Barannikov // Classify this field. 2120992cb984SSergei Barannikov // 2121992cb984SSergei Barannikov // AMD64-ABI 3.2.3p2: Rule 3. If the size of the aggregate 2122992cb984SSergei Barannikov // exceeds a single eightbyte, each is classified 2123992cb984SSergei Barannikov // separately. Each eightbyte gets initialized to class 2124992cb984SSergei Barannikov // NO_CLASS. 2125992cb984SSergei Barannikov Class FieldLo, FieldHi; 2126992cb984SSergei Barannikov 2127992cb984SSergei Barannikov // Bit-fields require special handling, they do not force the 2128992cb984SSergei Barannikov // structure to be passed in memory even if unaligned, and 2129992cb984SSergei Barannikov // therefore they can straddle an eightbyte. 2130992cb984SSergei Barannikov if (BitField) { 21313d56ea05STimm Baeder assert(!i->isUnnamedBitField()); 2132992cb984SSergei Barannikov uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx); 2133*cfe26358STimm Baeder uint64_t Size = i->getBitWidthValue(); 2134992cb984SSergei Barannikov 2135992cb984SSergei Barannikov uint64_t EB_Lo = Offset / 64; 2136992cb984SSergei Barannikov uint64_t EB_Hi = (Offset + Size - 1) / 64; 2137992cb984SSergei Barannikov 2138992cb984SSergei Barannikov if (EB_Lo) { 2139992cb984SSergei Barannikov assert(EB_Hi == EB_Lo && "Invalid classification, type > 16 bytes."); 2140992cb984SSergei Barannikov FieldLo = NoClass; 2141992cb984SSergei Barannikov FieldHi = Integer; 2142992cb984SSergei Barannikov } else { 2143992cb984SSergei Barannikov FieldLo = Integer; 2144992cb984SSergei Barannikov FieldHi = EB_Hi ? Integer : NoClass; 2145992cb984SSergei Barannikov } 2146992cb984SSergei Barannikov } else 2147992cb984SSergei Barannikov classify(i->getType(), Offset, FieldLo, FieldHi, isNamedArg); 2148992cb984SSergei Barannikov Lo = merge(Lo, FieldLo); 2149992cb984SSergei Barannikov Hi = merge(Hi, FieldHi); 2150992cb984SSergei Barannikov if (Lo == Memory || Hi == Memory) 2151992cb984SSergei Barannikov break; 2152992cb984SSergei Barannikov } 2153992cb984SSergei Barannikov 2154992cb984SSergei Barannikov postMerge(Size, Lo, Hi); 2155992cb984SSergei Barannikov } 2156992cb984SSergei Barannikov } 2157992cb984SSergei Barannikov 2158992cb984SSergei Barannikov ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty) const { 2159992cb984SSergei Barannikov // If this is a scalar LLVM value then assume LLVM will pass it in the right 2160992cb984SSergei Barannikov // place naturally. 2161992cb984SSergei Barannikov if (!isAggregateTypeForABI(Ty)) { 2162992cb984SSergei Barannikov // Treat an enum type as its underlying type. 2163992cb984SSergei Barannikov if (const EnumType *EnumTy = Ty->getAs<EnumType>()) 2164992cb984SSergei Barannikov Ty = EnumTy->getDecl()->getIntegerType(); 2165992cb984SSergei Barannikov 2166992cb984SSergei Barannikov if (Ty->isBitIntType()) 2167992cb984SSergei Barannikov return getNaturalAlignIndirect(Ty); 2168992cb984SSergei Barannikov 2169992cb984SSergei Barannikov return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) 2170992cb984SSergei Barannikov : ABIArgInfo::getDirect()); 2171992cb984SSergei Barannikov } 2172992cb984SSergei Barannikov 2173992cb984SSergei Barannikov return getNaturalAlignIndirect(Ty); 2174992cb984SSergei Barannikov } 2175992cb984SSergei Barannikov 2176992cb984SSergei Barannikov bool X86_64ABIInfo::IsIllegalVectorType(QualType Ty) const { 2177992cb984SSergei Barannikov if (const VectorType *VecTy = Ty->getAs<VectorType>()) { 2178992cb984SSergei Barannikov uint64_t Size = getContext().getTypeSize(VecTy); 2179992cb984SSergei Barannikov unsigned LargestVector = getNativeVectorSizeForAVXABI(AVXLevel); 2180992cb984SSergei Barannikov if (Size <= 64 || Size > LargestVector) 2181992cb984SSergei Barannikov return true; 2182992cb984SSergei Barannikov QualType EltTy = VecTy->getElementType(); 2183992cb984SSergei Barannikov if (passInt128VectorsInMem() && 2184992cb984SSergei Barannikov (EltTy->isSpecificBuiltinType(BuiltinType::Int128) || 2185992cb984SSergei Barannikov EltTy->isSpecificBuiltinType(BuiltinType::UInt128))) 2186992cb984SSergei Barannikov return true; 2187992cb984SSergei Barannikov } 2188992cb984SSergei Barannikov 2189992cb984SSergei Barannikov return false; 2190992cb984SSergei Barannikov } 2191992cb984SSergei Barannikov 2192992cb984SSergei Barannikov ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty, 2193992cb984SSergei Barannikov unsigned freeIntRegs) const { 2194992cb984SSergei Barannikov // If this is a scalar LLVM value then assume LLVM will pass it in the right 2195992cb984SSergei Barannikov // place naturally. 2196992cb984SSergei Barannikov // 2197992cb984SSergei Barannikov // This assumption is optimistic, as there could be free registers available 2198992cb984SSergei Barannikov // when we need to pass this argument in memory, and LLVM could try to pass 2199992cb984SSergei Barannikov // the argument in the free register. This does not seem to happen currently, 2200992cb984SSergei Barannikov // but this code would be much safer if we could mark the argument with 2201992cb984SSergei Barannikov // 'onstack'. See PR12193. 2202992cb984SSergei Barannikov if (!isAggregateTypeForABI(Ty) && !IsIllegalVectorType(Ty) && 2203992cb984SSergei Barannikov !Ty->isBitIntType()) { 2204992cb984SSergei Barannikov // Treat an enum type as its underlying type. 2205992cb984SSergei Barannikov if (const EnumType *EnumTy = Ty->getAs<EnumType>()) 2206992cb984SSergei Barannikov Ty = EnumTy->getDecl()->getIntegerType(); 2207992cb984SSergei Barannikov 2208992cb984SSergei Barannikov return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) 2209992cb984SSergei Barannikov : ABIArgInfo::getDirect()); 2210992cb984SSergei Barannikov } 2211992cb984SSergei Barannikov 2212992cb984SSergei Barannikov if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) 2213992cb984SSergei Barannikov return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); 2214992cb984SSergei Barannikov 2215992cb984SSergei Barannikov // Compute the byval alignment. We specify the alignment of the byval in all 2216992cb984SSergei Barannikov // cases so that the mid-level optimizer knows the alignment of the byval. 2217992cb984SSergei Barannikov unsigned Align = std::max(getContext().getTypeAlign(Ty) / 8, 8U); 2218992cb984SSergei Barannikov 2219992cb984SSergei Barannikov // Attempt to avoid passing indirect results using byval when possible. This 2220992cb984SSergei Barannikov // is important for good codegen. 2221992cb984SSergei Barannikov // 2222992cb984SSergei Barannikov // We do this by coercing the value into a scalar type which the backend can 2223992cb984SSergei Barannikov // handle naturally (i.e., without using byval). 2224992cb984SSergei Barannikov // 2225992cb984SSergei Barannikov // For simplicity, we currently only do this when we have exhausted all of the 2226992cb984SSergei Barannikov // free integer registers. Doing this when there are free integer registers 2227992cb984SSergei Barannikov // would require more care, as we would have to ensure that the coerced value 2228992cb984SSergei Barannikov // did not claim the unused register. That would require either reording the 2229992cb984SSergei Barannikov // arguments to the function (so that any subsequent inreg values came first), 2230992cb984SSergei Barannikov // or only doing this optimization when there were no following arguments that 2231992cb984SSergei Barannikov // might be inreg. 2232992cb984SSergei Barannikov // 2233992cb984SSergei Barannikov // We currently expect it to be rare (particularly in well written code) for 2234992cb984SSergei Barannikov // arguments to be passed on the stack when there are still free integer 2235992cb984SSergei Barannikov // registers available (this would typically imply large structs being passed 2236992cb984SSergei Barannikov // by value), so this seems like a fair tradeoff for now. 2237992cb984SSergei Barannikov // 2238992cb984SSergei Barannikov // We can revisit this if the backend grows support for 'onstack' parameter 2239992cb984SSergei Barannikov // attributes. See PR12193. 2240992cb984SSergei Barannikov if (freeIntRegs == 0) { 2241992cb984SSergei Barannikov uint64_t Size = getContext().getTypeSize(Ty); 2242992cb984SSergei Barannikov 2243992cb984SSergei Barannikov // If this type fits in an eightbyte, coerce it into the matching integral 2244992cb984SSergei Barannikov // type, which will end up on the stack (with alignment 8). 2245992cb984SSergei Barannikov if (Align == 8 && Size <= 64) 2246992cb984SSergei Barannikov return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), 2247992cb984SSergei Barannikov Size)); 2248992cb984SSergei Barannikov } 2249992cb984SSergei Barannikov 2250992cb984SSergei Barannikov return ABIArgInfo::getIndirect(CharUnits::fromQuantity(Align)); 2251992cb984SSergei Barannikov } 2252992cb984SSergei Barannikov 2253992cb984SSergei Barannikov /// The ABI specifies that a value should be passed in a full vector XMM/YMM 2254992cb984SSergei Barannikov /// register. Pick an LLVM IR type that will be passed as a vector register. 2255992cb984SSergei Barannikov llvm::Type *X86_64ABIInfo::GetByteVectorType(QualType Ty) const { 2256992cb984SSergei Barannikov // Wrapper structs/arrays that only contain vectors are passed just like 2257992cb984SSergei Barannikov // vectors; strip them off if present. 2258992cb984SSergei Barannikov if (const Type *InnerTy = isSingleElementStruct(Ty, getContext())) 2259992cb984SSergei Barannikov Ty = QualType(InnerTy, 0); 2260992cb984SSergei Barannikov 2261992cb984SSergei Barannikov llvm::Type *IRType = CGT.ConvertType(Ty); 2262992cb984SSergei Barannikov if (isa<llvm::VectorType>(IRType)) { 2263992cb984SSergei Barannikov // Don't pass vXi128 vectors in their native type, the backend can't 2264992cb984SSergei Barannikov // legalize them. 2265992cb984SSergei Barannikov if (passInt128VectorsInMem() && 2266992cb984SSergei Barannikov cast<llvm::VectorType>(IRType)->getElementType()->isIntegerTy(128)) { 2267992cb984SSergei Barannikov // Use a vXi64 vector. 2268992cb984SSergei Barannikov uint64_t Size = getContext().getTypeSize(Ty); 2269992cb984SSergei Barannikov return llvm::FixedVectorType::get(llvm::Type::getInt64Ty(getVMContext()), 2270992cb984SSergei Barannikov Size / 64); 2271992cb984SSergei Barannikov } 2272992cb984SSergei Barannikov 2273992cb984SSergei Barannikov return IRType; 2274992cb984SSergei Barannikov } 2275992cb984SSergei Barannikov 2276992cb984SSergei Barannikov if (IRType->getTypeID() == llvm::Type::FP128TyID) 2277992cb984SSergei Barannikov return IRType; 2278992cb984SSergei Barannikov 2279992cb984SSergei Barannikov // We couldn't find the preferred IR vector type for 'Ty'. 2280992cb984SSergei Barannikov uint64_t Size = getContext().getTypeSize(Ty); 2281992cb984SSergei Barannikov assert((Size == 128 || Size == 256 || Size == 512) && "Invalid type found!"); 2282992cb984SSergei Barannikov 2283992cb984SSergei Barannikov 2284992cb984SSergei Barannikov // Return a LLVM IR vector type based on the size of 'Ty'. 2285992cb984SSergei Barannikov return llvm::FixedVectorType::get(llvm::Type::getDoubleTy(getVMContext()), 2286992cb984SSergei Barannikov Size / 64); 2287992cb984SSergei Barannikov } 2288992cb984SSergei Barannikov 2289992cb984SSergei Barannikov /// BitsContainNoUserData - Return true if the specified [start,end) bit range 2290992cb984SSergei Barannikov /// is known to either be off the end of the specified type or being in 2291992cb984SSergei Barannikov /// alignment padding. The user type specified is known to be at most 128 bits 2292992cb984SSergei Barannikov /// in size, and have passed through X86_64ABIInfo::classify with a successful 2293992cb984SSergei Barannikov /// classification that put one of the two halves in the INTEGER class. 2294992cb984SSergei Barannikov /// 2295992cb984SSergei Barannikov /// It is conservatively correct to return false. 2296992cb984SSergei Barannikov static bool BitsContainNoUserData(QualType Ty, unsigned StartBit, 2297992cb984SSergei Barannikov unsigned EndBit, ASTContext &Context) { 2298992cb984SSergei Barannikov // If the bytes being queried are off the end of the type, there is no user 2299992cb984SSergei Barannikov // data hiding here. This handles analysis of builtins, vectors and other 2300992cb984SSergei Barannikov // types that don't contain interesting padding. 2301992cb984SSergei Barannikov unsigned TySize = (unsigned)Context.getTypeSize(Ty); 2302992cb984SSergei Barannikov if (TySize <= StartBit) 2303992cb984SSergei Barannikov return true; 2304992cb984SSergei Barannikov 2305992cb984SSergei Barannikov if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) { 2306992cb984SSergei Barannikov unsigned EltSize = (unsigned)Context.getTypeSize(AT->getElementType()); 230728ddbd4aSChris B unsigned NumElts = (unsigned)AT->getZExtSize(); 2308992cb984SSergei Barannikov 2309992cb984SSergei Barannikov // Check each element to see if the element overlaps with the queried range. 2310992cb984SSergei Barannikov for (unsigned i = 0; i != NumElts; ++i) { 2311992cb984SSergei Barannikov // If the element is after the span we care about, then we're done.. 2312992cb984SSergei Barannikov unsigned EltOffset = i*EltSize; 2313992cb984SSergei Barannikov if (EltOffset >= EndBit) break; 2314992cb984SSergei Barannikov 2315992cb984SSergei Barannikov unsigned EltStart = EltOffset < StartBit ? StartBit-EltOffset :0; 2316992cb984SSergei Barannikov if (!BitsContainNoUserData(AT->getElementType(), EltStart, 2317992cb984SSergei Barannikov EndBit-EltOffset, Context)) 2318992cb984SSergei Barannikov return false; 2319992cb984SSergei Barannikov } 2320992cb984SSergei Barannikov // If it overlaps no elements, then it is safe to process as padding. 2321992cb984SSergei Barannikov return true; 2322992cb984SSergei Barannikov } 2323992cb984SSergei Barannikov 2324992cb984SSergei Barannikov if (const RecordType *RT = Ty->getAs<RecordType>()) { 2325992cb984SSergei Barannikov const RecordDecl *RD = RT->getDecl(); 2326992cb984SSergei Barannikov const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 2327992cb984SSergei Barannikov 2328992cb984SSergei Barannikov // If this is a C++ record, check the bases first. 2329992cb984SSergei Barannikov if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { 2330992cb984SSergei Barannikov for (const auto &I : CXXRD->bases()) { 2331992cb984SSergei Barannikov assert(!I.isVirtual() && !I.getType()->isDependentType() && 2332992cb984SSergei Barannikov "Unexpected base class!"); 2333992cb984SSergei Barannikov const auto *Base = 2334992cb984SSergei Barannikov cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl()); 2335992cb984SSergei Barannikov 2336992cb984SSergei Barannikov // If the base is after the span we care about, ignore it. 2337992cb984SSergei Barannikov unsigned BaseOffset = Context.toBits(Layout.getBaseClassOffset(Base)); 2338992cb984SSergei Barannikov if (BaseOffset >= EndBit) continue; 2339992cb984SSergei Barannikov 2340992cb984SSergei Barannikov unsigned BaseStart = BaseOffset < StartBit ? StartBit-BaseOffset :0; 2341992cb984SSergei Barannikov if (!BitsContainNoUserData(I.getType(), BaseStart, 2342992cb984SSergei Barannikov EndBit-BaseOffset, Context)) 2343992cb984SSergei Barannikov return false; 2344992cb984SSergei Barannikov } 2345992cb984SSergei Barannikov } 2346992cb984SSergei Barannikov 2347992cb984SSergei Barannikov // Verify that no field has data that overlaps the region of interest. Yes 2348992cb984SSergei Barannikov // this could be sped up a lot by being smarter about queried fields, 2349992cb984SSergei Barannikov // however we're only looking at structs up to 16 bytes, so we don't care 2350992cb984SSergei Barannikov // much. 2351992cb984SSergei Barannikov unsigned idx = 0; 2352992cb984SSergei Barannikov for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); 2353992cb984SSergei Barannikov i != e; ++i, ++idx) { 2354992cb984SSergei Barannikov unsigned FieldOffset = (unsigned)Layout.getFieldOffset(idx); 2355992cb984SSergei Barannikov 2356992cb984SSergei Barannikov // If we found a field after the region we care about, then we're done. 2357992cb984SSergei Barannikov if (FieldOffset >= EndBit) break; 2358992cb984SSergei Barannikov 2359992cb984SSergei Barannikov unsigned FieldStart = FieldOffset < StartBit ? StartBit-FieldOffset :0; 2360992cb984SSergei Barannikov if (!BitsContainNoUserData(i->getType(), FieldStart, EndBit-FieldOffset, 2361992cb984SSergei Barannikov Context)) 2362992cb984SSergei Barannikov return false; 2363992cb984SSergei Barannikov } 2364992cb984SSergei Barannikov 2365992cb984SSergei Barannikov // If nothing in this record overlapped the area of interest, then we're 2366992cb984SSergei Barannikov // clean. 2367992cb984SSergei Barannikov return true; 2368992cb984SSergei Barannikov } 2369992cb984SSergei Barannikov 2370992cb984SSergei Barannikov return false; 2371992cb984SSergei Barannikov } 2372992cb984SSergei Barannikov 2373992cb984SSergei Barannikov /// getFPTypeAtOffset - Return a floating point type at the specified offset. 2374992cb984SSergei Barannikov static llvm::Type *getFPTypeAtOffset(llvm::Type *IRType, unsigned IROffset, 2375992cb984SSergei Barannikov const llvm::DataLayout &TD) { 2376992cb984SSergei Barannikov if (IROffset == 0 && IRType->isFloatingPointTy()) 2377992cb984SSergei Barannikov return IRType; 2378992cb984SSergei Barannikov 2379992cb984SSergei Barannikov // If this is a struct, recurse into the field at the specified offset. 2380992cb984SSergei Barannikov if (llvm::StructType *STy = dyn_cast<llvm::StructType>(IRType)) { 2381992cb984SSergei Barannikov if (!STy->getNumContainedTypes()) 2382992cb984SSergei Barannikov return nullptr; 2383992cb984SSergei Barannikov 2384992cb984SSergei Barannikov const llvm::StructLayout *SL = TD.getStructLayout(STy); 2385992cb984SSergei Barannikov unsigned Elt = SL->getElementContainingOffset(IROffset); 2386992cb984SSergei Barannikov IROffset -= SL->getElementOffset(Elt); 2387992cb984SSergei Barannikov return getFPTypeAtOffset(STy->getElementType(Elt), IROffset, TD); 2388992cb984SSergei Barannikov } 2389992cb984SSergei Barannikov 2390992cb984SSergei Barannikov // If this is an array, recurse into the field at the specified offset. 2391992cb984SSergei Barannikov if (llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(IRType)) { 2392992cb984SSergei Barannikov llvm::Type *EltTy = ATy->getElementType(); 2393992cb984SSergei Barannikov unsigned EltSize = TD.getTypeAllocSize(EltTy); 2394992cb984SSergei Barannikov IROffset -= IROffset / EltSize * EltSize; 2395992cb984SSergei Barannikov return getFPTypeAtOffset(EltTy, IROffset, TD); 2396992cb984SSergei Barannikov } 2397992cb984SSergei Barannikov 2398992cb984SSergei Barannikov return nullptr; 2399992cb984SSergei Barannikov } 2400992cb984SSergei Barannikov 2401992cb984SSergei Barannikov /// GetSSETypeAtOffset - Return a type that will be passed by the backend in the 2402992cb984SSergei Barannikov /// low 8 bytes of an XMM register, corresponding to the SSE class. 2403992cb984SSergei Barannikov llvm::Type *X86_64ABIInfo:: 2404992cb984SSergei Barannikov GetSSETypeAtOffset(llvm::Type *IRType, unsigned IROffset, 2405992cb984SSergei Barannikov QualType SourceTy, unsigned SourceOffset) const { 2406992cb984SSergei Barannikov const llvm::DataLayout &TD = getDataLayout(); 2407992cb984SSergei Barannikov unsigned SourceSize = 2408992cb984SSergei Barannikov (unsigned)getContext().getTypeSize(SourceTy) / 8 - SourceOffset; 2409992cb984SSergei Barannikov llvm::Type *T0 = getFPTypeAtOffset(IRType, IROffset, TD); 2410992cb984SSergei Barannikov if (!T0 || T0->isDoubleTy()) 2411992cb984SSergei Barannikov return llvm::Type::getDoubleTy(getVMContext()); 2412992cb984SSergei Barannikov 2413992cb984SSergei Barannikov // Get the adjacent FP type. 2414992cb984SSergei Barannikov llvm::Type *T1 = nullptr; 2415992cb984SSergei Barannikov unsigned T0Size = TD.getTypeAllocSize(T0); 2416992cb984SSergei Barannikov if (SourceSize > T0Size) 2417992cb984SSergei Barannikov T1 = getFPTypeAtOffset(IRType, IROffset + T0Size, TD); 2418992cb984SSergei Barannikov if (T1 == nullptr) { 2419992cb984SSergei Barannikov // Check if IRType is a half/bfloat + float. float type will be in IROffset+4 due 2420992cb984SSergei Barannikov // to its alignment. 2421992cb984SSergei Barannikov if (T0->is16bitFPTy() && SourceSize > 4) 2422992cb984SSergei Barannikov T1 = getFPTypeAtOffset(IRType, IROffset + 4, TD); 2423992cb984SSergei Barannikov // If we can't get a second FP type, return a simple half or float. 2424992cb984SSergei Barannikov // avx512fp16-abi.c:pr51813_2 shows it works to return float for 2425992cb984SSergei Barannikov // {float, i8} too. 2426992cb984SSergei Barannikov if (T1 == nullptr) 2427992cb984SSergei Barannikov return T0; 2428992cb984SSergei Barannikov } 2429992cb984SSergei Barannikov 2430992cb984SSergei Barannikov if (T0->isFloatTy() && T1->isFloatTy()) 2431992cb984SSergei Barannikov return llvm::FixedVectorType::get(T0, 2); 2432992cb984SSergei Barannikov 2433992cb984SSergei Barannikov if (T0->is16bitFPTy() && T1->is16bitFPTy()) { 2434992cb984SSergei Barannikov llvm::Type *T2 = nullptr; 2435992cb984SSergei Barannikov if (SourceSize > 4) 2436992cb984SSergei Barannikov T2 = getFPTypeAtOffset(IRType, IROffset + 4, TD); 2437992cb984SSergei Barannikov if (T2 == nullptr) 2438992cb984SSergei Barannikov return llvm::FixedVectorType::get(T0, 2); 2439992cb984SSergei Barannikov return llvm::FixedVectorType::get(T0, 4); 2440992cb984SSergei Barannikov } 2441992cb984SSergei Barannikov 2442992cb984SSergei Barannikov if (T0->is16bitFPTy() || T1->is16bitFPTy()) 2443992cb984SSergei Barannikov return llvm::FixedVectorType::get(llvm::Type::getHalfTy(getVMContext()), 4); 2444992cb984SSergei Barannikov 2445992cb984SSergei Barannikov return llvm::Type::getDoubleTy(getVMContext()); 2446992cb984SSergei Barannikov } 2447992cb984SSergei Barannikov 2448992cb984SSergei Barannikov 2449992cb984SSergei Barannikov /// GetINTEGERTypeAtOffset - The ABI specifies that a value should be passed in 2450992cb984SSergei Barannikov /// an 8-byte GPR. This means that we either have a scalar or we are talking 2451992cb984SSergei Barannikov /// about the high or low part of an up-to-16-byte struct. This routine picks 2452992cb984SSergei Barannikov /// the best LLVM IR type to represent this, which may be i64 or may be anything 2453992cb984SSergei Barannikov /// else that the backend will pass in a GPR that works better (e.g. i8, %foo*, 2454992cb984SSergei Barannikov /// etc). 2455992cb984SSergei Barannikov /// 2456992cb984SSergei Barannikov /// PrefType is an LLVM IR type that corresponds to (part of) the IR type for 2457992cb984SSergei Barannikov /// the source type. IROffset is an offset in bytes into the LLVM IR type that 2458992cb984SSergei Barannikov /// the 8-byte value references. PrefType may be null. 2459992cb984SSergei Barannikov /// 2460992cb984SSergei Barannikov /// SourceTy is the source-level type for the entire argument. SourceOffset is 2461992cb984SSergei Barannikov /// an offset into this that we're processing (which is always either 0 or 8). 2462992cb984SSergei Barannikov /// 2463992cb984SSergei Barannikov llvm::Type *X86_64ABIInfo:: 2464992cb984SSergei Barannikov GetINTEGERTypeAtOffset(llvm::Type *IRType, unsigned IROffset, 2465992cb984SSergei Barannikov QualType SourceTy, unsigned SourceOffset) const { 2466992cb984SSergei Barannikov // If we're dealing with an un-offset LLVM IR type, then it means that we're 2467992cb984SSergei Barannikov // returning an 8-byte unit starting with it. See if we can safely use it. 2468992cb984SSergei Barannikov if (IROffset == 0) { 2469992cb984SSergei Barannikov // Pointers and int64's always fill the 8-byte unit. 2470992cb984SSergei Barannikov if ((isa<llvm::PointerType>(IRType) && Has64BitPointers) || 2471992cb984SSergei Barannikov IRType->isIntegerTy(64)) 2472992cb984SSergei Barannikov return IRType; 2473992cb984SSergei Barannikov 2474992cb984SSergei Barannikov // If we have a 1/2/4-byte integer, we can use it only if the rest of the 2475992cb984SSergei Barannikov // goodness in the source type is just tail padding. This is allowed to 2476992cb984SSergei Barannikov // kick in for struct {double,int} on the int, but not on 2477992cb984SSergei Barannikov // struct{double,int,int} because we wouldn't return the second int. We 2478992cb984SSergei Barannikov // have to do this analysis on the source type because we can't depend on 2479992cb984SSergei Barannikov // unions being lowered a specific way etc. 2480992cb984SSergei Barannikov if (IRType->isIntegerTy(8) || IRType->isIntegerTy(16) || 2481992cb984SSergei Barannikov IRType->isIntegerTy(32) || 2482992cb984SSergei Barannikov (isa<llvm::PointerType>(IRType) && !Has64BitPointers)) { 2483992cb984SSergei Barannikov unsigned BitWidth = isa<llvm::PointerType>(IRType) ? 32 : 2484992cb984SSergei Barannikov cast<llvm::IntegerType>(IRType)->getBitWidth(); 2485992cb984SSergei Barannikov 2486992cb984SSergei Barannikov if (BitsContainNoUserData(SourceTy, SourceOffset*8+BitWidth, 2487992cb984SSergei Barannikov SourceOffset*8+64, getContext())) 2488992cb984SSergei Barannikov return IRType; 2489992cb984SSergei Barannikov } 2490992cb984SSergei Barannikov } 2491992cb984SSergei Barannikov 2492992cb984SSergei Barannikov if (llvm::StructType *STy = dyn_cast<llvm::StructType>(IRType)) { 2493992cb984SSergei Barannikov // If this is a struct, recurse into the field at the specified offset. 2494992cb984SSergei Barannikov const llvm::StructLayout *SL = getDataLayout().getStructLayout(STy); 2495992cb984SSergei Barannikov if (IROffset < SL->getSizeInBytes()) { 2496992cb984SSergei Barannikov unsigned FieldIdx = SL->getElementContainingOffset(IROffset); 2497992cb984SSergei Barannikov IROffset -= SL->getElementOffset(FieldIdx); 2498992cb984SSergei Barannikov 2499992cb984SSergei Barannikov return GetINTEGERTypeAtOffset(STy->getElementType(FieldIdx), IROffset, 2500992cb984SSergei Barannikov SourceTy, SourceOffset); 2501992cb984SSergei Barannikov } 2502992cb984SSergei Barannikov } 2503992cb984SSergei Barannikov 2504992cb984SSergei Barannikov if (llvm::ArrayType *ATy = dyn_cast<llvm::ArrayType>(IRType)) { 2505992cb984SSergei Barannikov llvm::Type *EltTy = ATy->getElementType(); 2506992cb984SSergei Barannikov unsigned EltSize = getDataLayout().getTypeAllocSize(EltTy); 2507992cb984SSergei Barannikov unsigned EltOffset = IROffset/EltSize*EltSize; 2508992cb984SSergei Barannikov return GetINTEGERTypeAtOffset(EltTy, IROffset-EltOffset, SourceTy, 2509992cb984SSergei Barannikov SourceOffset); 2510992cb984SSergei Barannikov } 2511992cb984SSergei Barannikov 2512992cb984SSergei Barannikov // Okay, we don't have any better idea of what to pass, so we pass this in an 2513992cb984SSergei Barannikov // integer register that isn't too big to fit the rest of the struct. 2514992cb984SSergei Barannikov unsigned TySizeInBytes = 2515992cb984SSergei Barannikov (unsigned)getContext().getTypeSizeInChars(SourceTy).getQuantity(); 2516992cb984SSergei Barannikov 2517992cb984SSergei Barannikov assert(TySizeInBytes != SourceOffset && "Empty field?"); 2518992cb984SSergei Barannikov 2519992cb984SSergei Barannikov // It is always safe to classify this as an integer type up to i64 that 2520992cb984SSergei Barannikov // isn't larger than the structure. 2521992cb984SSergei Barannikov return llvm::IntegerType::get(getVMContext(), 2522992cb984SSergei Barannikov std::min(TySizeInBytes-SourceOffset, 8U)*8); 2523992cb984SSergei Barannikov } 2524992cb984SSergei Barannikov 2525992cb984SSergei Barannikov 2526992cb984SSergei Barannikov /// GetX86_64ByValArgumentPair - Given a high and low type that can ideally 2527992cb984SSergei Barannikov /// be used as elements of a two register pair to pass or return, return a 2528992cb984SSergei Barannikov /// first class aggregate to represent them. For example, if the low part of 2529992cb984SSergei Barannikov /// a by-value argument should be passed as i32* and the high part as float, 2530992cb984SSergei Barannikov /// return {i32*, float}. 2531992cb984SSergei Barannikov static llvm::Type * 2532992cb984SSergei Barannikov GetX86_64ByValArgumentPair(llvm::Type *Lo, llvm::Type *Hi, 2533992cb984SSergei Barannikov const llvm::DataLayout &TD) { 2534992cb984SSergei Barannikov // In order to correctly satisfy the ABI, we need to the high part to start 2535992cb984SSergei Barannikov // at offset 8. If the high and low parts we inferred are both 4-byte types 2536992cb984SSergei Barannikov // (e.g. i32 and i32) then the resultant struct type ({i32,i32}) won't have 2537992cb984SSergei Barannikov // the second element at offset 8. Check for this: 2538992cb984SSergei Barannikov unsigned LoSize = (unsigned)TD.getTypeAllocSize(Lo); 2539992cb984SSergei Barannikov llvm::Align HiAlign = TD.getABITypeAlign(Hi); 2540992cb984SSergei Barannikov unsigned HiStart = llvm::alignTo(LoSize, HiAlign); 2541992cb984SSergei Barannikov assert(HiStart != 0 && HiStart <= 8 && "Invalid x86-64 argument pair!"); 2542992cb984SSergei Barannikov 2543992cb984SSergei Barannikov // To handle this, we have to increase the size of the low part so that the 2544992cb984SSergei Barannikov // second element will start at an 8 byte offset. We can't increase the size 2545992cb984SSergei Barannikov // of the second element because it might make us access off the end of the 2546992cb984SSergei Barannikov // struct. 2547992cb984SSergei Barannikov if (HiStart != 8) { 2548992cb984SSergei Barannikov // There are usually two sorts of types the ABI generation code can produce 2549992cb984SSergei Barannikov // for the low part of a pair that aren't 8 bytes in size: half, float or 2550992cb984SSergei Barannikov // i8/i16/i32. This can also include pointers when they are 32-bit (X32 and 2551992cb984SSergei Barannikov // NaCl). 2552992cb984SSergei Barannikov // Promote these to a larger type. 2553992cb984SSergei Barannikov if (Lo->isHalfTy() || Lo->isFloatTy()) 2554992cb984SSergei Barannikov Lo = llvm::Type::getDoubleTy(Lo->getContext()); 2555992cb984SSergei Barannikov else { 2556992cb984SSergei Barannikov assert((Lo->isIntegerTy() || Lo->isPointerTy()) 2557992cb984SSergei Barannikov && "Invalid/unknown lo type"); 2558992cb984SSergei Barannikov Lo = llvm::Type::getInt64Ty(Lo->getContext()); 2559992cb984SSergei Barannikov } 2560992cb984SSergei Barannikov } 2561992cb984SSergei Barannikov 2562992cb984SSergei Barannikov llvm::StructType *Result = llvm::StructType::get(Lo, Hi); 2563992cb984SSergei Barannikov 2564992cb984SSergei Barannikov // Verify that the second element is at an 8-byte offset. 2565992cb984SSergei Barannikov assert(TD.getStructLayout(Result)->getElementOffset(1) == 8 && 2566992cb984SSergei Barannikov "Invalid x86-64 argument pair!"); 2567992cb984SSergei Barannikov return Result; 2568992cb984SSergei Barannikov } 2569992cb984SSergei Barannikov 2570992cb984SSergei Barannikov ABIArgInfo X86_64ABIInfo:: 2571992cb984SSergei Barannikov classifyReturnType(QualType RetTy) const { 2572992cb984SSergei Barannikov // AMD64-ABI 3.2.3p4: Rule 1. Classify the return type with the 2573992cb984SSergei Barannikov // classification algorithm. 2574992cb984SSergei Barannikov X86_64ABIInfo::Class Lo, Hi; 2575992cb984SSergei Barannikov classify(RetTy, 0, Lo, Hi, /*isNamedArg*/ true); 2576992cb984SSergei Barannikov 2577992cb984SSergei Barannikov // Check some invariants. 2578992cb984SSergei Barannikov assert((Hi != Memory || Lo == Memory) && "Invalid memory classification."); 2579992cb984SSergei Barannikov assert((Hi != SSEUp || Lo == SSE) && "Invalid SSEUp classification."); 2580992cb984SSergei Barannikov 2581992cb984SSergei Barannikov llvm::Type *ResType = nullptr; 2582992cb984SSergei Barannikov switch (Lo) { 2583992cb984SSergei Barannikov case NoClass: 2584992cb984SSergei Barannikov if (Hi == NoClass) 2585992cb984SSergei Barannikov return ABIArgInfo::getIgnore(); 2586992cb984SSergei Barannikov // If the low part is just padding, it takes no register, leave ResType 2587992cb984SSergei Barannikov // null. 2588992cb984SSergei Barannikov assert((Hi == SSE || Hi == Integer || Hi == X87Up) && 2589992cb984SSergei Barannikov "Unknown missing lo part"); 2590992cb984SSergei Barannikov break; 2591992cb984SSergei Barannikov 2592992cb984SSergei Barannikov case SSEUp: 2593992cb984SSergei Barannikov case X87Up: 2594992cb984SSergei Barannikov llvm_unreachable("Invalid classification for lo word."); 2595992cb984SSergei Barannikov 2596992cb984SSergei Barannikov // AMD64-ABI 3.2.3p4: Rule 2. Types of class memory are returned via 2597992cb984SSergei Barannikov // hidden argument. 2598992cb984SSergei Barannikov case Memory: 2599992cb984SSergei Barannikov return getIndirectReturnResult(RetTy); 2600992cb984SSergei Barannikov 2601992cb984SSergei Barannikov // AMD64-ABI 3.2.3p4: Rule 3. If the class is INTEGER, the next 2602992cb984SSergei Barannikov // available register of the sequence %rax, %rdx is used. 2603992cb984SSergei Barannikov case Integer: 2604992cb984SSergei Barannikov ResType = GetINTEGERTypeAtOffset(CGT.ConvertType(RetTy), 0, RetTy, 0); 2605992cb984SSergei Barannikov 2606992cb984SSergei Barannikov // If we have a sign or zero extended integer, make sure to return Extend 2607992cb984SSergei Barannikov // so that the parameter gets the right LLVM IR attributes. 2608992cb984SSergei Barannikov if (Hi == NoClass && isa<llvm::IntegerType>(ResType)) { 2609992cb984SSergei Barannikov // Treat an enum type as its underlying type. 2610992cb984SSergei Barannikov if (const EnumType *EnumTy = RetTy->getAs<EnumType>()) 2611992cb984SSergei Barannikov RetTy = EnumTy->getDecl()->getIntegerType(); 2612992cb984SSergei Barannikov 2613992cb984SSergei Barannikov if (RetTy->isIntegralOrEnumerationType() && 2614992cb984SSergei Barannikov isPromotableIntegerTypeForABI(RetTy)) 2615992cb984SSergei Barannikov return ABIArgInfo::getExtend(RetTy); 2616992cb984SSergei Barannikov } 2617992cb984SSergei Barannikov break; 2618992cb984SSergei Barannikov 2619992cb984SSergei Barannikov // AMD64-ABI 3.2.3p4: Rule 4. If the class is SSE, the next 2620992cb984SSergei Barannikov // available SSE register of the sequence %xmm0, %xmm1 is used. 2621992cb984SSergei Barannikov case SSE: 2622992cb984SSergei Barannikov ResType = GetSSETypeAtOffset(CGT.ConvertType(RetTy), 0, RetTy, 0); 2623992cb984SSergei Barannikov break; 2624992cb984SSergei Barannikov 2625992cb984SSergei Barannikov // AMD64-ABI 3.2.3p4: Rule 6. If the class is X87, the value is 2626992cb984SSergei Barannikov // returned on the X87 stack in %st0 as 80-bit x87 number. 2627992cb984SSergei Barannikov case X87: 2628992cb984SSergei Barannikov ResType = llvm::Type::getX86_FP80Ty(getVMContext()); 2629992cb984SSergei Barannikov break; 2630992cb984SSergei Barannikov 2631992cb984SSergei Barannikov // AMD64-ABI 3.2.3p4: Rule 8. If the class is COMPLEX_X87, the real 2632992cb984SSergei Barannikov // part of the value is returned in %st0 and the imaginary part in 2633992cb984SSergei Barannikov // %st1. 2634992cb984SSergei Barannikov case ComplexX87: 2635992cb984SSergei Barannikov assert(Hi == ComplexX87 && "Unexpected ComplexX87 classification."); 2636992cb984SSergei Barannikov ResType = llvm::StructType::get(llvm::Type::getX86_FP80Ty(getVMContext()), 2637992cb984SSergei Barannikov llvm::Type::getX86_FP80Ty(getVMContext())); 2638992cb984SSergei Barannikov break; 2639992cb984SSergei Barannikov } 2640992cb984SSergei Barannikov 2641992cb984SSergei Barannikov llvm::Type *HighPart = nullptr; 2642992cb984SSergei Barannikov switch (Hi) { 2643992cb984SSergei Barannikov // Memory was handled previously and X87 should 2644992cb984SSergei Barannikov // never occur as a hi class. 2645992cb984SSergei Barannikov case Memory: 2646992cb984SSergei Barannikov case X87: 2647992cb984SSergei Barannikov llvm_unreachable("Invalid classification for hi word."); 2648992cb984SSergei Barannikov 2649992cb984SSergei Barannikov case ComplexX87: // Previously handled. 2650992cb984SSergei Barannikov case NoClass: 2651992cb984SSergei Barannikov break; 2652992cb984SSergei Barannikov 2653992cb984SSergei Barannikov case Integer: 2654992cb984SSergei Barannikov HighPart = GetINTEGERTypeAtOffset(CGT.ConvertType(RetTy), 8, RetTy, 8); 2655992cb984SSergei Barannikov if (Lo == NoClass) // Return HighPart at offset 8 in memory. 2656992cb984SSergei Barannikov return ABIArgInfo::getDirect(HighPart, 8); 2657992cb984SSergei Barannikov break; 2658992cb984SSergei Barannikov case SSE: 2659992cb984SSergei Barannikov HighPart = GetSSETypeAtOffset(CGT.ConvertType(RetTy), 8, RetTy, 8); 2660992cb984SSergei Barannikov if (Lo == NoClass) // Return HighPart at offset 8 in memory. 2661992cb984SSergei Barannikov return ABIArgInfo::getDirect(HighPart, 8); 2662992cb984SSergei Barannikov break; 2663992cb984SSergei Barannikov 2664992cb984SSergei Barannikov // AMD64-ABI 3.2.3p4: Rule 5. If the class is SSEUP, the eightbyte 2665992cb984SSergei Barannikov // is passed in the next available eightbyte chunk if the last used 2666992cb984SSergei Barannikov // vector register. 2667992cb984SSergei Barannikov // 2668992cb984SSergei Barannikov // SSEUP should always be preceded by SSE, just widen. 2669992cb984SSergei Barannikov case SSEUp: 2670992cb984SSergei Barannikov assert(Lo == SSE && "Unexpected SSEUp classification."); 2671992cb984SSergei Barannikov ResType = GetByteVectorType(RetTy); 2672992cb984SSergei Barannikov break; 2673992cb984SSergei Barannikov 2674992cb984SSergei Barannikov // AMD64-ABI 3.2.3p4: Rule 7. If the class is X87UP, the value is 2675992cb984SSergei Barannikov // returned together with the previous X87 value in %st0. 2676992cb984SSergei Barannikov case X87Up: 2677992cb984SSergei Barannikov // If X87Up is preceded by X87, we don't need to do 2678992cb984SSergei Barannikov // anything. However, in some cases with unions it may not be 2679992cb984SSergei Barannikov // preceded by X87. In such situations we follow gcc and pass the 2680992cb984SSergei Barannikov // extra bits in an SSE reg. 2681992cb984SSergei Barannikov if (Lo != X87) { 2682992cb984SSergei Barannikov HighPart = GetSSETypeAtOffset(CGT.ConvertType(RetTy), 8, RetTy, 8); 2683992cb984SSergei Barannikov if (Lo == NoClass) // Return HighPart at offset 8 in memory. 2684992cb984SSergei Barannikov return ABIArgInfo::getDirect(HighPart, 8); 2685992cb984SSergei Barannikov } 2686992cb984SSergei Barannikov break; 2687992cb984SSergei Barannikov } 2688992cb984SSergei Barannikov 2689992cb984SSergei Barannikov // If a high part was specified, merge it together with the low part. It is 2690992cb984SSergei Barannikov // known to pass in the high eightbyte of the result. We do this by forming a 2691992cb984SSergei Barannikov // first class struct aggregate with the high and low part: {low, high} 2692992cb984SSergei Barannikov if (HighPart) 2693992cb984SSergei Barannikov ResType = GetX86_64ByValArgumentPair(ResType, HighPart, getDataLayout()); 2694992cb984SSergei Barannikov 2695992cb984SSergei Barannikov return ABIArgInfo::getDirect(ResType); 2696992cb984SSergei Barannikov } 2697992cb984SSergei Barannikov 2698992cb984SSergei Barannikov ABIArgInfo 2699992cb984SSergei Barannikov X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned freeIntRegs, 2700992cb984SSergei Barannikov unsigned &neededInt, unsigned &neededSSE, 2701992cb984SSergei Barannikov bool isNamedArg, bool IsRegCall) const { 2702992cb984SSergei Barannikov Ty = useFirstFieldIfTransparentUnion(Ty); 2703992cb984SSergei Barannikov 2704992cb984SSergei Barannikov X86_64ABIInfo::Class Lo, Hi; 2705992cb984SSergei Barannikov classify(Ty, 0, Lo, Hi, isNamedArg, IsRegCall); 2706992cb984SSergei Barannikov 2707992cb984SSergei Barannikov // Check some invariants. 2708992cb984SSergei Barannikov // FIXME: Enforce these by construction. 2709992cb984SSergei Barannikov assert((Hi != Memory || Lo == Memory) && "Invalid memory classification."); 2710992cb984SSergei Barannikov assert((Hi != SSEUp || Lo == SSE) && "Invalid SSEUp classification."); 2711992cb984SSergei Barannikov 2712992cb984SSergei Barannikov neededInt = 0; 2713992cb984SSergei Barannikov neededSSE = 0; 2714992cb984SSergei Barannikov llvm::Type *ResType = nullptr; 2715992cb984SSergei Barannikov switch (Lo) { 2716992cb984SSergei Barannikov case NoClass: 2717992cb984SSergei Barannikov if (Hi == NoClass) 2718992cb984SSergei Barannikov return ABIArgInfo::getIgnore(); 2719992cb984SSergei Barannikov // If the low part is just padding, it takes no register, leave ResType 2720992cb984SSergei Barannikov // null. 2721992cb984SSergei Barannikov assert((Hi == SSE || Hi == Integer || Hi == X87Up) && 2722992cb984SSergei Barannikov "Unknown missing lo part"); 2723992cb984SSergei Barannikov break; 2724992cb984SSergei Barannikov 2725992cb984SSergei Barannikov // AMD64-ABI 3.2.3p3: Rule 1. If the class is MEMORY, pass the argument 2726992cb984SSergei Barannikov // on the stack. 2727992cb984SSergei Barannikov case Memory: 2728992cb984SSergei Barannikov 2729992cb984SSergei Barannikov // AMD64-ABI 3.2.3p3: Rule 5. If the class is X87, X87UP or 2730992cb984SSergei Barannikov // COMPLEX_X87, it is passed in memory. 2731992cb984SSergei Barannikov case X87: 2732992cb984SSergei Barannikov case ComplexX87: 2733992cb984SSergei Barannikov if (getRecordArgABI(Ty, getCXXABI()) == CGCXXABI::RAA_Indirect) 2734992cb984SSergei Barannikov ++neededInt; 2735992cb984SSergei Barannikov return getIndirectResult(Ty, freeIntRegs); 2736992cb984SSergei Barannikov 2737992cb984SSergei Barannikov case SSEUp: 2738992cb984SSergei Barannikov case X87Up: 2739992cb984SSergei Barannikov llvm_unreachable("Invalid classification for lo word."); 2740992cb984SSergei Barannikov 2741992cb984SSergei Barannikov // AMD64-ABI 3.2.3p3: Rule 2. If the class is INTEGER, the next 2742992cb984SSergei Barannikov // available register of the sequence %rdi, %rsi, %rdx, %rcx, %r8 2743992cb984SSergei Barannikov // and %r9 is used. 2744992cb984SSergei Barannikov case Integer: 2745992cb984SSergei Barannikov ++neededInt; 2746992cb984SSergei Barannikov 2747992cb984SSergei Barannikov // Pick an 8-byte type based on the preferred type. 2748992cb984SSergei Barannikov ResType = GetINTEGERTypeAtOffset(CGT.ConvertType(Ty), 0, Ty, 0); 2749992cb984SSergei Barannikov 2750992cb984SSergei Barannikov // If we have a sign or zero extended integer, make sure to return Extend 2751992cb984SSergei Barannikov // so that the parameter gets the right LLVM IR attributes. 2752992cb984SSergei Barannikov if (Hi == NoClass && isa<llvm::IntegerType>(ResType)) { 2753992cb984SSergei Barannikov // Treat an enum type as its underlying type. 2754992cb984SSergei Barannikov if (const EnumType *EnumTy = Ty->getAs<EnumType>()) 2755992cb984SSergei Barannikov Ty = EnumTy->getDecl()->getIntegerType(); 2756992cb984SSergei Barannikov 2757992cb984SSergei Barannikov if (Ty->isIntegralOrEnumerationType() && 2758992cb984SSergei Barannikov isPromotableIntegerTypeForABI(Ty)) 2759ea920450SLei Huang return ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty)); 2760992cb984SSergei Barannikov } 2761992cb984SSergei Barannikov 2762992cb984SSergei Barannikov break; 2763992cb984SSergei Barannikov 2764992cb984SSergei Barannikov // AMD64-ABI 3.2.3p3: Rule 3. If the class is SSE, the next 2765992cb984SSergei Barannikov // available SSE register is used, the registers are taken in the 2766992cb984SSergei Barannikov // order from %xmm0 to %xmm7. 2767992cb984SSergei Barannikov case SSE: { 2768992cb984SSergei Barannikov llvm::Type *IRType = CGT.ConvertType(Ty); 2769992cb984SSergei Barannikov ResType = GetSSETypeAtOffset(IRType, 0, Ty, 0); 2770992cb984SSergei Barannikov ++neededSSE; 2771992cb984SSergei Barannikov break; 2772992cb984SSergei Barannikov } 2773992cb984SSergei Barannikov } 2774992cb984SSergei Barannikov 2775992cb984SSergei Barannikov llvm::Type *HighPart = nullptr; 2776992cb984SSergei Barannikov switch (Hi) { 2777992cb984SSergei Barannikov // Memory was handled previously, ComplexX87 and X87 should 2778992cb984SSergei Barannikov // never occur as hi classes, and X87Up must be preceded by X87, 2779992cb984SSergei Barannikov // which is passed in memory. 2780992cb984SSergei Barannikov case Memory: 2781992cb984SSergei Barannikov case X87: 2782992cb984SSergei Barannikov case ComplexX87: 2783992cb984SSergei Barannikov llvm_unreachable("Invalid classification for hi word."); 2784992cb984SSergei Barannikov 2785992cb984SSergei Barannikov case NoClass: break; 2786992cb984SSergei Barannikov 2787992cb984SSergei Barannikov case Integer: 2788992cb984SSergei Barannikov ++neededInt; 2789992cb984SSergei Barannikov // Pick an 8-byte type based on the preferred type. 2790992cb984SSergei Barannikov HighPart = GetINTEGERTypeAtOffset(CGT.ConvertType(Ty), 8, Ty, 8); 2791992cb984SSergei Barannikov 2792992cb984SSergei Barannikov if (Lo == NoClass) // Pass HighPart at offset 8 in memory. 2793992cb984SSergei Barannikov return ABIArgInfo::getDirect(HighPart, 8); 2794992cb984SSergei Barannikov break; 2795992cb984SSergei Barannikov 2796992cb984SSergei Barannikov // X87Up generally doesn't occur here (long double is passed in 2797992cb984SSergei Barannikov // memory), except in situations involving unions. 2798992cb984SSergei Barannikov case X87Up: 2799992cb984SSergei Barannikov case SSE: 28009c8dd5e6SLongsheng Mou ++neededSSE; 2801992cb984SSergei Barannikov HighPart = GetSSETypeAtOffset(CGT.ConvertType(Ty), 8, Ty, 8); 2802992cb984SSergei Barannikov 2803992cb984SSergei Barannikov if (Lo == NoClass) // Pass HighPart at offset 8 in memory. 2804992cb984SSergei Barannikov return ABIArgInfo::getDirect(HighPart, 8); 2805992cb984SSergei Barannikov break; 2806992cb984SSergei Barannikov 2807992cb984SSergei Barannikov // AMD64-ABI 3.2.3p3: Rule 4. If the class is SSEUP, the 2808992cb984SSergei Barannikov // eightbyte is passed in the upper half of the last used SSE 2809992cb984SSergei Barannikov // register. This only happens when 128-bit vectors are passed. 2810992cb984SSergei Barannikov case SSEUp: 2811992cb984SSergei Barannikov assert(Lo == SSE && "Unexpected SSEUp classification"); 2812992cb984SSergei Barannikov ResType = GetByteVectorType(Ty); 2813992cb984SSergei Barannikov break; 2814992cb984SSergei Barannikov } 2815992cb984SSergei Barannikov 2816992cb984SSergei Barannikov // If a high part was specified, merge it together with the low part. It is 2817992cb984SSergei Barannikov // known to pass in the high eightbyte of the result. We do this by forming a 2818992cb984SSergei Barannikov // first class struct aggregate with the high and low part: {low, high} 2819992cb984SSergei Barannikov if (HighPart) 2820992cb984SSergei Barannikov ResType = GetX86_64ByValArgumentPair(ResType, HighPart, getDataLayout()); 2821992cb984SSergei Barannikov 2822992cb984SSergei Barannikov return ABIArgInfo::getDirect(ResType); 2823992cb984SSergei Barannikov } 2824992cb984SSergei Barannikov 2825992cb984SSergei Barannikov ABIArgInfo 2826992cb984SSergei Barannikov X86_64ABIInfo::classifyRegCallStructTypeImpl(QualType Ty, unsigned &NeededInt, 2827992cb984SSergei Barannikov unsigned &NeededSSE, 2828992cb984SSergei Barannikov unsigned &MaxVectorWidth) const { 2829992cb984SSergei Barannikov auto RT = Ty->getAs<RecordType>(); 2830992cb984SSergei Barannikov assert(RT && "classifyRegCallStructType only valid with struct types"); 2831992cb984SSergei Barannikov 2832992cb984SSergei Barannikov if (RT->getDecl()->hasFlexibleArrayMember()) 2833992cb984SSergei Barannikov return getIndirectReturnResult(Ty); 2834992cb984SSergei Barannikov 2835992cb984SSergei Barannikov // Sum up bases 2836992cb984SSergei Barannikov if (auto CXXRD = dyn_cast<CXXRecordDecl>(RT->getDecl())) { 2837992cb984SSergei Barannikov if (CXXRD->isDynamicClass()) { 2838992cb984SSergei Barannikov NeededInt = NeededSSE = 0; 2839992cb984SSergei Barannikov return getIndirectReturnResult(Ty); 2840992cb984SSergei Barannikov } 2841992cb984SSergei Barannikov 2842992cb984SSergei Barannikov for (const auto &I : CXXRD->bases()) 2843992cb984SSergei Barannikov if (classifyRegCallStructTypeImpl(I.getType(), NeededInt, NeededSSE, 2844992cb984SSergei Barannikov MaxVectorWidth) 2845992cb984SSergei Barannikov .isIndirect()) { 2846992cb984SSergei Barannikov NeededInt = NeededSSE = 0; 2847992cb984SSergei Barannikov return getIndirectReturnResult(Ty); 2848992cb984SSergei Barannikov } 2849992cb984SSergei Barannikov } 2850992cb984SSergei Barannikov 2851992cb984SSergei Barannikov // Sum up members 2852992cb984SSergei Barannikov for (const auto *FD : RT->getDecl()->fields()) { 2853992cb984SSergei Barannikov QualType MTy = FD->getType(); 2854992cb984SSergei Barannikov if (MTy->isRecordType() && !MTy->isUnionType()) { 2855992cb984SSergei Barannikov if (classifyRegCallStructTypeImpl(MTy, NeededInt, NeededSSE, 2856992cb984SSergei Barannikov MaxVectorWidth) 2857992cb984SSergei Barannikov .isIndirect()) { 2858992cb984SSergei Barannikov NeededInt = NeededSSE = 0; 2859992cb984SSergei Barannikov return getIndirectReturnResult(Ty); 2860992cb984SSergei Barannikov } 2861992cb984SSergei Barannikov } else { 2862992cb984SSergei Barannikov unsigned LocalNeededInt, LocalNeededSSE; 2863992cb984SSergei Barannikov if (classifyArgumentType(MTy, UINT_MAX, LocalNeededInt, LocalNeededSSE, 2864992cb984SSergei Barannikov true, true) 2865992cb984SSergei Barannikov .isIndirect()) { 2866992cb984SSergei Barannikov NeededInt = NeededSSE = 0; 2867992cb984SSergei Barannikov return getIndirectReturnResult(Ty); 2868992cb984SSergei Barannikov } 2869992cb984SSergei Barannikov if (const auto *AT = getContext().getAsConstantArrayType(MTy)) 2870992cb984SSergei Barannikov MTy = AT->getElementType(); 2871992cb984SSergei Barannikov if (const auto *VT = MTy->getAs<VectorType>()) 2872992cb984SSergei Barannikov if (getContext().getTypeSize(VT) > MaxVectorWidth) 2873992cb984SSergei Barannikov MaxVectorWidth = getContext().getTypeSize(VT); 2874992cb984SSergei Barannikov NeededInt += LocalNeededInt; 2875992cb984SSergei Barannikov NeededSSE += LocalNeededSSE; 2876992cb984SSergei Barannikov } 2877992cb984SSergei Barannikov } 2878992cb984SSergei Barannikov 2879992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 2880992cb984SSergei Barannikov } 2881992cb984SSergei Barannikov 2882992cb984SSergei Barannikov ABIArgInfo 2883992cb984SSergei Barannikov X86_64ABIInfo::classifyRegCallStructType(QualType Ty, unsigned &NeededInt, 2884992cb984SSergei Barannikov unsigned &NeededSSE, 2885992cb984SSergei Barannikov unsigned &MaxVectorWidth) const { 2886992cb984SSergei Barannikov 2887992cb984SSergei Barannikov NeededInt = 0; 2888992cb984SSergei Barannikov NeededSSE = 0; 2889992cb984SSergei Barannikov MaxVectorWidth = 0; 2890992cb984SSergei Barannikov 2891992cb984SSergei Barannikov return classifyRegCallStructTypeImpl(Ty, NeededInt, NeededSSE, 2892992cb984SSergei Barannikov MaxVectorWidth); 2893992cb984SSergei Barannikov } 2894992cb984SSergei Barannikov 2895992cb984SSergei Barannikov void X86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { 2896992cb984SSergei Barannikov 2897992cb984SSergei Barannikov const unsigned CallingConv = FI.getCallingConvention(); 2898992cb984SSergei Barannikov // It is possible to force Win64 calling convention on any x86_64 target by 2899992cb984SSergei Barannikov // using __attribute__((ms_abi)). In such case to correctly emit Win64 2900992cb984SSergei Barannikov // compatible code delegate this call to WinX86_64ABIInfo::computeInfo. 2901992cb984SSergei Barannikov if (CallingConv == llvm::CallingConv::Win64) { 2902992cb984SSergei Barannikov WinX86_64ABIInfo Win64ABIInfo(CGT, AVXLevel); 2903992cb984SSergei Barannikov Win64ABIInfo.computeInfo(FI); 2904992cb984SSergei Barannikov return; 2905992cb984SSergei Barannikov } 2906992cb984SSergei Barannikov 2907992cb984SSergei Barannikov bool IsRegCall = CallingConv == llvm::CallingConv::X86_RegCall; 2908992cb984SSergei Barannikov 2909992cb984SSergei Barannikov // Keep track of the number of assigned registers. 2910992cb984SSergei Barannikov unsigned FreeIntRegs = IsRegCall ? 11 : 6; 2911992cb984SSergei Barannikov unsigned FreeSSERegs = IsRegCall ? 16 : 8; 2912992cb984SSergei Barannikov unsigned NeededInt = 0, NeededSSE = 0, MaxVectorWidth = 0; 2913992cb984SSergei Barannikov 2914992cb984SSergei Barannikov if (!::classifyReturnType(getCXXABI(), FI, *this)) { 2915992cb984SSergei Barannikov if (IsRegCall && FI.getReturnType()->getTypePtr()->isRecordType() && 2916992cb984SSergei Barannikov !FI.getReturnType()->getTypePtr()->isUnionType()) { 2917992cb984SSergei Barannikov FI.getReturnInfo() = classifyRegCallStructType( 2918992cb984SSergei Barannikov FI.getReturnType(), NeededInt, NeededSSE, MaxVectorWidth); 2919992cb984SSergei Barannikov if (FreeIntRegs >= NeededInt && FreeSSERegs >= NeededSSE) { 2920992cb984SSergei Barannikov FreeIntRegs -= NeededInt; 2921992cb984SSergei Barannikov FreeSSERegs -= NeededSSE; 2922992cb984SSergei Barannikov } else { 2923992cb984SSergei Barannikov FI.getReturnInfo() = getIndirectReturnResult(FI.getReturnType()); 2924992cb984SSergei Barannikov } 2925992cb984SSergei Barannikov } else if (IsRegCall && FI.getReturnType()->getAs<ComplexType>() && 2926992cb984SSergei Barannikov getContext().getCanonicalType(FI.getReturnType() 2927992cb984SSergei Barannikov ->getAs<ComplexType>() 2928992cb984SSergei Barannikov ->getElementType()) == 2929992cb984SSergei Barannikov getContext().LongDoubleTy) 2930992cb984SSergei Barannikov // Complex Long Double Type is passed in Memory when Regcall 2931992cb984SSergei Barannikov // calling convention is used. 2932992cb984SSergei Barannikov FI.getReturnInfo() = getIndirectReturnResult(FI.getReturnType()); 2933992cb984SSergei Barannikov else 2934992cb984SSergei Barannikov FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); 2935992cb984SSergei Barannikov } 2936992cb984SSergei Barannikov 2937992cb984SSergei Barannikov // If the return value is indirect, then the hidden argument is consuming one 2938992cb984SSergei Barannikov // integer register. 2939992cb984SSergei Barannikov if (FI.getReturnInfo().isIndirect()) 2940992cb984SSergei Barannikov --FreeIntRegs; 2941992cb984SSergei Barannikov else if (NeededSSE && MaxVectorWidth > 0) 2942992cb984SSergei Barannikov FI.setMaxVectorWidth(MaxVectorWidth); 2943992cb984SSergei Barannikov 2944992cb984SSergei Barannikov // The chain argument effectively gives us another free register. 2945992cb984SSergei Barannikov if (FI.isChainCall()) 2946992cb984SSergei Barannikov ++FreeIntRegs; 2947992cb984SSergei Barannikov 2948992cb984SSergei Barannikov unsigned NumRequiredArgs = FI.getNumRequiredArgs(); 2949992cb984SSergei Barannikov // AMD64-ABI 3.2.3p3: Once arguments are classified, the registers 2950992cb984SSergei Barannikov // get assigned (in left-to-right order) for passing as follows... 2951992cb984SSergei Barannikov unsigned ArgNo = 0; 2952992cb984SSergei Barannikov for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); 2953992cb984SSergei Barannikov it != ie; ++it, ++ArgNo) { 2954992cb984SSergei Barannikov bool IsNamedArg = ArgNo < NumRequiredArgs; 2955992cb984SSergei Barannikov 2956992cb984SSergei Barannikov if (IsRegCall && it->type->isStructureOrClassType()) 2957992cb984SSergei Barannikov it->info = classifyRegCallStructType(it->type, NeededInt, NeededSSE, 2958992cb984SSergei Barannikov MaxVectorWidth); 2959992cb984SSergei Barannikov else 2960992cb984SSergei Barannikov it->info = classifyArgumentType(it->type, FreeIntRegs, NeededInt, 2961992cb984SSergei Barannikov NeededSSE, IsNamedArg); 2962992cb984SSergei Barannikov 2963992cb984SSergei Barannikov // AMD64-ABI 3.2.3p3: If there are no registers available for any 2964992cb984SSergei Barannikov // eightbyte of an argument, the whole argument is passed on the 2965992cb984SSergei Barannikov // stack. If registers have already been assigned for some 2966992cb984SSergei Barannikov // eightbytes of such an argument, the assignments get reverted. 2967992cb984SSergei Barannikov if (FreeIntRegs >= NeededInt && FreeSSERegs >= NeededSSE) { 2968992cb984SSergei Barannikov FreeIntRegs -= NeededInt; 2969992cb984SSergei Barannikov FreeSSERegs -= NeededSSE; 2970992cb984SSergei Barannikov if (MaxVectorWidth > FI.getMaxVectorWidth()) 2971992cb984SSergei Barannikov FI.setMaxVectorWidth(MaxVectorWidth); 2972992cb984SSergei Barannikov } else { 2973992cb984SSergei Barannikov it->info = getIndirectResult(it->type, FreeIntRegs); 2974992cb984SSergei Barannikov } 2975992cb984SSergei Barannikov } 2976992cb984SSergei Barannikov } 2977992cb984SSergei Barannikov 2978992cb984SSergei Barannikov static Address EmitX86_64VAArgFromMemory(CodeGenFunction &CGF, 2979992cb984SSergei Barannikov Address VAListAddr, QualType Ty) { 2980992cb984SSergei Barannikov Address overflow_arg_area_p = 2981992cb984SSergei Barannikov CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_p"); 2982992cb984SSergei Barannikov llvm::Value *overflow_arg_area = 2983992cb984SSergei Barannikov CGF.Builder.CreateLoad(overflow_arg_area_p, "overflow_arg_area"); 2984992cb984SSergei Barannikov 2985992cb984SSergei Barannikov // AMD64-ABI 3.5.7p5: Step 7. Align l->overflow_arg_area upwards to a 16 2986992cb984SSergei Barannikov // byte boundary if alignment needed by type exceeds 8 byte boundary. 2987992cb984SSergei Barannikov // It isn't stated explicitly in the standard, but in practice we use 2988992cb984SSergei Barannikov // alignment greater than 16 where necessary. 2989992cb984SSergei Barannikov CharUnits Align = CGF.getContext().getTypeAlignInChars(Ty); 2990992cb984SSergei Barannikov if (Align > CharUnits::fromQuantity(8)) { 2991992cb984SSergei Barannikov overflow_arg_area = emitRoundPointerUpToAlignment(CGF, overflow_arg_area, 2992992cb984SSergei Barannikov Align); 2993992cb984SSergei Barannikov } 2994992cb984SSergei Barannikov 2995992cb984SSergei Barannikov // AMD64-ABI 3.5.7p5: Step 8. Fetch type from l->overflow_arg_area. 2996992cb984SSergei Barannikov llvm::Type *LTy = CGF.ConvertTypeForMem(Ty); 2997b4858c63SBjörn Pettersson llvm::Value *Res = overflow_arg_area; 2998992cb984SSergei Barannikov 2999992cb984SSergei Barannikov // AMD64-ABI 3.5.7p5: Step 9. Set l->overflow_arg_area to: 3000992cb984SSergei Barannikov // l->overflow_arg_area + sizeof(type). 3001992cb984SSergei Barannikov // AMD64-ABI 3.5.7p5: Step 10. Align l->overflow_arg_area upwards to 3002992cb984SSergei Barannikov // an 8 byte boundary. 3003992cb984SSergei Barannikov 3004992cb984SSergei Barannikov uint64_t SizeInBytes = (CGF.getContext().getTypeSize(Ty) + 7) / 8; 3005992cb984SSergei Barannikov llvm::Value *Offset = 3006992cb984SSergei Barannikov llvm::ConstantInt::get(CGF.Int32Ty, (SizeInBytes + 7) & ~7); 3007992cb984SSergei Barannikov overflow_arg_area = CGF.Builder.CreateGEP(CGF.Int8Ty, overflow_arg_area, 3008992cb984SSergei Barannikov Offset, "overflow_arg_area.next"); 3009992cb984SSergei Barannikov CGF.Builder.CreateStore(overflow_arg_area, overflow_arg_area_p); 3010992cb984SSergei Barannikov 3011992cb984SSergei Barannikov // AMD64-ABI 3.5.7p5: Step 11. Return the fetched type. 3012992cb984SSergei Barannikov return Address(Res, LTy, Align); 3013992cb984SSergei Barannikov } 3014992cb984SSergei Barannikov 30156d973b45SMariya Podchishchaeva RValue X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 30166d973b45SMariya Podchishchaeva QualType Ty, AggValueSlot Slot) const { 3017992cb984SSergei Barannikov // Assume that va_list type is correct; should be pointer to LLVM type: 3018992cb984SSergei Barannikov // struct { 3019992cb984SSergei Barannikov // i32 gp_offset; 3020992cb984SSergei Barannikov // i32 fp_offset; 3021992cb984SSergei Barannikov // i8* overflow_arg_area; 3022992cb984SSergei Barannikov // i8* reg_save_area; 3023992cb984SSergei Barannikov // }; 3024992cb984SSergei Barannikov unsigned neededInt, neededSSE; 3025992cb984SSergei Barannikov 3026992cb984SSergei Barannikov Ty = getContext().getCanonicalType(Ty); 3027992cb984SSergei Barannikov ABIArgInfo AI = classifyArgumentType(Ty, 0, neededInt, neededSSE, 3028992cb984SSergei Barannikov /*isNamedArg*/false); 3029992cb984SSergei Barannikov 3030631248dcShstk30-hw // Empty records are ignored for parameter passing purposes. 3031631248dcShstk30-hw if (AI.isIgnore()) 30326d973b45SMariya Podchishchaeva return Slot.asRValue(); 3033631248dcShstk30-hw 3034992cb984SSergei Barannikov // AMD64-ABI 3.5.7p5: Step 1. Determine whether type may be passed 3035992cb984SSergei Barannikov // in the registers. If not go to step 7. 3036992cb984SSergei Barannikov if (!neededInt && !neededSSE) 30376d973b45SMariya Podchishchaeva return CGF.EmitLoadOfAnyValue( 30386d973b45SMariya Podchishchaeva CGF.MakeAddrLValue(EmitX86_64VAArgFromMemory(CGF, VAListAddr, Ty), Ty), 30396d973b45SMariya Podchishchaeva Slot); 3040992cb984SSergei Barannikov 3041992cb984SSergei Barannikov // AMD64-ABI 3.5.7p5: Step 2. Compute num_gp to hold the number of 3042992cb984SSergei Barannikov // general purpose registers needed to pass type and num_fp to hold 3043992cb984SSergei Barannikov // the number of floating point registers needed. 3044992cb984SSergei Barannikov 3045992cb984SSergei Barannikov // AMD64-ABI 3.5.7p5: Step 3. Verify whether arguments fit into 3046992cb984SSergei Barannikov // registers. In the case: l->gp_offset > 48 - num_gp * 8 or 3047992cb984SSergei Barannikov // l->fp_offset > 304 - num_fp * 16 go to step 7. 3048992cb984SSergei Barannikov // 3049992cb984SSergei Barannikov // NOTE: 304 is a typo, there are (6 * 8 + 8 * 16) = 176 bytes of 3050992cb984SSergei Barannikov // register save space). 3051992cb984SSergei Barannikov 3052992cb984SSergei Barannikov llvm::Value *InRegs = nullptr; 3053992cb984SSergei Barannikov Address gp_offset_p = Address::invalid(), fp_offset_p = Address::invalid(); 3054992cb984SSergei Barannikov llvm::Value *gp_offset = nullptr, *fp_offset = nullptr; 3055992cb984SSergei Barannikov if (neededInt) { 3056992cb984SSergei Barannikov gp_offset_p = CGF.Builder.CreateStructGEP(VAListAddr, 0, "gp_offset_p"); 3057992cb984SSergei Barannikov gp_offset = CGF.Builder.CreateLoad(gp_offset_p, "gp_offset"); 3058992cb984SSergei Barannikov InRegs = llvm::ConstantInt::get(CGF.Int32Ty, 48 - neededInt * 8); 3059992cb984SSergei Barannikov InRegs = CGF.Builder.CreateICmpULE(gp_offset, InRegs, "fits_in_gp"); 3060992cb984SSergei Barannikov } 3061992cb984SSergei Barannikov 3062992cb984SSergei Barannikov if (neededSSE) { 3063992cb984SSergei Barannikov fp_offset_p = CGF.Builder.CreateStructGEP(VAListAddr, 1, "fp_offset_p"); 3064992cb984SSergei Barannikov fp_offset = CGF.Builder.CreateLoad(fp_offset_p, "fp_offset"); 3065992cb984SSergei Barannikov llvm::Value *FitsInFP = 3066992cb984SSergei Barannikov llvm::ConstantInt::get(CGF.Int32Ty, 176 - neededSSE * 16); 3067992cb984SSergei Barannikov FitsInFP = CGF.Builder.CreateICmpULE(fp_offset, FitsInFP, "fits_in_fp"); 3068992cb984SSergei Barannikov InRegs = InRegs ? CGF.Builder.CreateAnd(InRegs, FitsInFP) : FitsInFP; 3069992cb984SSergei Barannikov } 3070992cb984SSergei Barannikov 3071992cb984SSergei Barannikov llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg"); 3072992cb984SSergei Barannikov llvm::BasicBlock *InMemBlock = CGF.createBasicBlock("vaarg.in_mem"); 3073992cb984SSergei Barannikov llvm::BasicBlock *ContBlock = CGF.createBasicBlock("vaarg.end"); 3074992cb984SSergei Barannikov CGF.Builder.CreateCondBr(InRegs, InRegBlock, InMemBlock); 3075992cb984SSergei Barannikov 3076992cb984SSergei Barannikov // Emit code to load the value if it was passed in registers. 3077992cb984SSergei Barannikov 3078992cb984SSergei Barannikov CGF.EmitBlock(InRegBlock); 3079992cb984SSergei Barannikov 3080992cb984SSergei Barannikov // AMD64-ABI 3.5.7p5: Step 4. Fetch type from l->reg_save_area with 3081992cb984SSergei Barannikov // an offset of l->gp_offset and/or l->fp_offset. This may require 3082992cb984SSergei Barannikov // copying to a temporary location in case the parameter is passed 3083992cb984SSergei Barannikov // in different register classes or requires an alignment greater 3084992cb984SSergei Barannikov // than 8 for general purpose registers and 16 for XMM registers. 3085992cb984SSergei Barannikov // 3086992cb984SSergei Barannikov // FIXME: This really results in shameful code when we end up needing to 3087992cb984SSergei Barannikov // collect arguments from different places; often what should result in a 3088992cb984SSergei Barannikov // simple assembling of a structure from scattered addresses has many more 3089992cb984SSergei Barannikov // loads than necessary. Can we clean this up? 3090992cb984SSergei Barannikov llvm::Type *LTy = CGF.ConvertTypeForMem(Ty); 3091992cb984SSergei Barannikov llvm::Value *RegSaveArea = CGF.Builder.CreateLoad( 3092992cb984SSergei Barannikov CGF.Builder.CreateStructGEP(VAListAddr, 3), "reg_save_area"); 3093992cb984SSergei Barannikov 3094992cb984SSergei Barannikov Address RegAddr = Address::invalid(); 3095992cb984SSergei Barannikov if (neededInt && neededSSE) { 3096992cb984SSergei Barannikov // FIXME: Cleanup. 3097992cb984SSergei Barannikov assert(AI.isDirect() && "Unexpected ABI info for mixed regs"); 3098992cb984SSergei Barannikov llvm::StructType *ST = cast<llvm::StructType>(AI.getCoerceToType()); 3099992cb984SSergei Barannikov Address Tmp = CGF.CreateMemTemp(Ty); 3100474ec694SYoungsuk Kim Tmp = Tmp.withElementType(ST); 3101992cb984SSergei Barannikov assert(ST->getNumElements() == 2 && "Unexpected ABI info for mixed regs"); 3102992cb984SSergei Barannikov llvm::Type *TyLo = ST->getElementType(0); 3103992cb984SSergei Barannikov llvm::Type *TyHi = ST->getElementType(1); 3104992cb984SSergei Barannikov assert((TyLo->isFPOrFPVectorTy() ^ TyHi->isFPOrFPVectorTy()) && 3105992cb984SSergei Barannikov "Unexpected ABI info for mixed regs"); 3106992cb984SSergei Barannikov llvm::Value *GPAddr = 3107992cb984SSergei Barannikov CGF.Builder.CreateGEP(CGF.Int8Ty, RegSaveArea, gp_offset); 3108992cb984SSergei Barannikov llvm::Value *FPAddr = 3109992cb984SSergei Barannikov CGF.Builder.CreateGEP(CGF.Int8Ty, RegSaveArea, fp_offset); 3110992cb984SSergei Barannikov llvm::Value *RegLoAddr = TyLo->isFPOrFPVectorTy() ? FPAddr : GPAddr; 3111992cb984SSergei Barannikov llvm::Value *RegHiAddr = TyLo->isFPOrFPVectorTy() ? GPAddr : FPAddr; 3112992cb984SSergei Barannikov 3113992cb984SSergei Barannikov // Copy the first element. 3114992cb984SSergei Barannikov // FIXME: Our choice of alignment here and below is probably pessimistic. 3115992cb984SSergei Barannikov llvm::Value *V = CGF.Builder.CreateAlignedLoad( 3116b4858c63SBjörn Pettersson TyLo, RegLoAddr, 3117992cb984SSergei Barannikov CharUnits::fromQuantity(getDataLayout().getABITypeAlign(TyLo))); 3118992cb984SSergei Barannikov CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 0)); 3119992cb984SSergei Barannikov 3120992cb984SSergei Barannikov // Copy the second element. 3121992cb984SSergei Barannikov V = CGF.Builder.CreateAlignedLoad( 3122b4858c63SBjörn Pettersson TyHi, RegHiAddr, 3123992cb984SSergei Barannikov CharUnits::fromQuantity(getDataLayout().getABITypeAlign(TyHi))); 3124992cb984SSergei Barannikov CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 1)); 3125992cb984SSergei Barannikov 3126474ec694SYoungsuk Kim RegAddr = Tmp.withElementType(LTy); 3127a27f40e5SLongsheng Mou } else if (neededInt || neededSSE == 1) { 3128992cb984SSergei Barannikov // Copy to a temporary if necessary to ensure the appropriate alignment. 3129992cb984SSergei Barannikov auto TInfo = getContext().getTypeInfoInChars(Ty); 3130992cb984SSergei Barannikov uint64_t TySize = TInfo.Width.getQuantity(); 3131992cb984SSergei Barannikov CharUnits TyAlign = TInfo.Align; 3132a27f40e5SLongsheng Mou llvm::Type *CoTy = nullptr; 3133a27f40e5SLongsheng Mou if (AI.isDirect()) 3134a27f40e5SLongsheng Mou CoTy = AI.getCoerceToType(); 3135a27f40e5SLongsheng Mou 3136a27f40e5SLongsheng Mou llvm::Value *GpOrFpOffset = neededInt ? gp_offset : fp_offset; 3137a27f40e5SLongsheng Mou uint64_t Alignment = neededInt ? 8 : 16; 3138a27f40e5SLongsheng Mou uint64_t RegSize = neededInt ? neededInt * 8 : 16; 3139a27f40e5SLongsheng Mou // There are two cases require special handling: 3140a27f40e5SLongsheng Mou // 1) 3141a27f40e5SLongsheng Mou // ``` 3142a27f40e5SLongsheng Mou // struct { 3143a27f40e5SLongsheng Mou // struct {} a[8]; 3144a27f40e5SLongsheng Mou // int b; 3145a27f40e5SLongsheng Mou // }; 3146a27f40e5SLongsheng Mou // ``` 3147a27f40e5SLongsheng Mou // The lower 8 bytes of the structure are not stored, 3148a27f40e5SLongsheng Mou // so an 8-byte offset is needed when accessing the structure. 3149a27f40e5SLongsheng Mou // 2) 3150a27f40e5SLongsheng Mou // ``` 3151a27f40e5SLongsheng Mou // struct { 3152a27f40e5SLongsheng Mou // long long a; 3153a27f40e5SLongsheng Mou // struct {} b; 3154a27f40e5SLongsheng Mou // }; 3155a27f40e5SLongsheng Mou // ``` 3156a27f40e5SLongsheng Mou // The stored size of this structure is smaller than its actual size, 3157a27f40e5SLongsheng Mou // which may lead to reading past the end of the register save area. 3158a27f40e5SLongsheng Mou if (CoTy && (AI.getDirectOffset() == 8 || RegSize < TySize)) { 3159a27f40e5SLongsheng Mou Address Tmp = CGF.CreateMemTemp(Ty); 3160a27f40e5SLongsheng Mou llvm::Value *Addr = 3161a27f40e5SLongsheng Mou CGF.Builder.CreateGEP(CGF.Int8Ty, RegSaveArea, GpOrFpOffset); 3162a27f40e5SLongsheng Mou llvm::Value *Src = CGF.Builder.CreateAlignedLoad(CoTy, Addr, TyAlign); 3163a27f40e5SLongsheng Mou llvm::Value *PtrOffset = 3164a27f40e5SLongsheng Mou llvm::ConstantInt::get(CGF.Int32Ty, AI.getDirectOffset()); 3165a27f40e5SLongsheng Mou Address Dst = Address( 3166a27f40e5SLongsheng Mou CGF.Builder.CreateGEP(CGF.Int8Ty, Tmp.getBasePointer(), PtrOffset), 3167a27f40e5SLongsheng Mou LTy, TyAlign); 3168a27f40e5SLongsheng Mou CGF.Builder.CreateStore(Src, Dst); 3169a27f40e5SLongsheng Mou RegAddr = Tmp.withElementType(LTy); 3170a27f40e5SLongsheng Mou } else { 3171a27f40e5SLongsheng Mou RegAddr = 3172a27f40e5SLongsheng Mou Address(CGF.Builder.CreateGEP(CGF.Int8Ty, RegSaveArea, GpOrFpOffset), 3173a27f40e5SLongsheng Mou LTy, CharUnits::fromQuantity(Alignment)); 3174992cb984SSergei Barannikov 3175992cb984SSergei Barannikov // Copy into a temporary if the type is more aligned than the 3176992cb984SSergei Barannikov // register save area. 3177a27f40e5SLongsheng Mou if (neededInt && TyAlign.getQuantity() > 8) { 3178992cb984SSergei Barannikov Address Tmp = CGF.CreateMemTemp(Ty); 3179992cb984SSergei Barannikov CGF.Builder.CreateMemCpy(Tmp, RegAddr, TySize, false); 3180992cb984SSergei Barannikov RegAddr = Tmp; 3181992cb984SSergei Barannikov } 3182a27f40e5SLongsheng Mou } 3183992cb984SSergei Barannikov 3184992cb984SSergei Barannikov } else { 3185992cb984SSergei Barannikov assert(neededSSE == 2 && "Invalid number of needed registers!"); 3186992cb984SSergei Barannikov // SSE registers are spaced 16 bytes apart in the register save 3187992cb984SSergei Barannikov // area, we need to collect the two eightbytes together. 3188992cb984SSergei Barannikov // The ABI isn't explicit about this, but it seems reasonable 3189992cb984SSergei Barannikov // to assume that the slots are 16-byte aligned, since the stack is 3190992cb984SSergei Barannikov // naturally 16-byte aligned and the prologue is expected to store 3191992cb984SSergei Barannikov // all the SSE registers to the RSA. 3192992cb984SSergei Barannikov Address RegAddrLo = Address(CGF.Builder.CreateGEP(CGF.Int8Ty, RegSaveArea, 3193992cb984SSergei Barannikov fp_offset), 3194992cb984SSergei Barannikov CGF.Int8Ty, CharUnits::fromQuantity(16)); 3195992cb984SSergei Barannikov Address RegAddrHi = 3196992cb984SSergei Barannikov CGF.Builder.CreateConstInBoundsByteGEP(RegAddrLo, 3197992cb984SSergei Barannikov CharUnits::fromQuantity(16)); 3198992cb984SSergei Barannikov llvm::Type *ST = AI.canHaveCoerceToType() 3199992cb984SSergei Barannikov ? AI.getCoerceToType() 3200992cb984SSergei Barannikov : llvm::StructType::get(CGF.DoubleTy, CGF.DoubleTy); 3201992cb984SSergei Barannikov llvm::Value *V; 3202992cb984SSergei Barannikov Address Tmp = CGF.CreateMemTemp(Ty); 3203474ec694SYoungsuk Kim Tmp = Tmp.withElementType(ST); 3204474ec694SYoungsuk Kim V = CGF.Builder.CreateLoad( 3205474ec694SYoungsuk Kim RegAddrLo.withElementType(ST->getStructElementType(0))); 3206992cb984SSergei Barannikov CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 0)); 3207474ec694SYoungsuk Kim V = CGF.Builder.CreateLoad( 3208474ec694SYoungsuk Kim RegAddrHi.withElementType(ST->getStructElementType(1))); 3209992cb984SSergei Barannikov CGF.Builder.CreateStore(V, CGF.Builder.CreateStructGEP(Tmp, 1)); 3210992cb984SSergei Barannikov 3211474ec694SYoungsuk Kim RegAddr = Tmp.withElementType(LTy); 3212992cb984SSergei Barannikov } 3213992cb984SSergei Barannikov 3214992cb984SSergei Barannikov // AMD64-ABI 3.5.7p5: Step 5. Set: 3215992cb984SSergei Barannikov // l->gp_offset = l->gp_offset + num_gp * 8 3216992cb984SSergei Barannikov // l->fp_offset = l->fp_offset + num_fp * 16. 3217992cb984SSergei Barannikov if (neededInt) { 3218992cb984SSergei Barannikov llvm::Value *Offset = llvm::ConstantInt::get(CGF.Int32Ty, neededInt * 8); 3219992cb984SSergei Barannikov CGF.Builder.CreateStore(CGF.Builder.CreateAdd(gp_offset, Offset), 3220992cb984SSergei Barannikov gp_offset_p); 3221992cb984SSergei Barannikov } 3222992cb984SSergei Barannikov if (neededSSE) { 3223992cb984SSergei Barannikov llvm::Value *Offset = llvm::ConstantInt::get(CGF.Int32Ty, neededSSE * 16); 3224992cb984SSergei Barannikov CGF.Builder.CreateStore(CGF.Builder.CreateAdd(fp_offset, Offset), 3225992cb984SSergei Barannikov fp_offset_p); 3226992cb984SSergei Barannikov } 3227992cb984SSergei Barannikov CGF.EmitBranch(ContBlock); 3228992cb984SSergei Barannikov 3229992cb984SSergei Barannikov // Emit code to load the value if it was passed in memory. 3230992cb984SSergei Barannikov 3231992cb984SSergei Barannikov CGF.EmitBlock(InMemBlock); 3232992cb984SSergei Barannikov Address MemAddr = EmitX86_64VAArgFromMemory(CGF, VAListAddr, Ty); 3233992cb984SSergei Barannikov 3234992cb984SSergei Barannikov // Return the appropriate result. 3235992cb984SSergei Barannikov 3236992cb984SSergei Barannikov CGF.EmitBlock(ContBlock); 3237992cb984SSergei Barannikov Address ResAddr = emitMergePHI(CGF, RegAddr, InRegBlock, MemAddr, InMemBlock, 3238992cb984SSergei Barannikov "vaarg.addr"); 32396d973b45SMariya Podchishchaeva return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(ResAddr, Ty), Slot); 3240992cb984SSergei Barannikov } 3241992cb984SSergei Barannikov 32426d973b45SMariya Podchishchaeva RValue X86_64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr, 32436d973b45SMariya Podchishchaeva QualType Ty, AggValueSlot Slot) const { 3244992cb984SSergei Barannikov // MS x64 ABI requirement: "Any argument that doesn't fit in 8 bytes, or is 3245992cb984SSergei Barannikov // not 1, 2, 4, or 8 bytes, must be passed by reference." 3246992cb984SSergei Barannikov uint64_t Width = getContext().getTypeSize(Ty); 3247992cb984SSergei Barannikov bool IsIndirect = Width > 64 || !llvm::isPowerOf2_64(Width); 3248992cb984SSergei Barannikov 3249992cb984SSergei Barannikov return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, 3250992cb984SSergei Barannikov CGF.getContext().getTypeInfoInChars(Ty), 3251992cb984SSergei Barannikov CharUnits::fromQuantity(8), 32526d973b45SMariya Podchishchaeva /*allowHigherAlign*/ false, Slot); 3253992cb984SSergei Barannikov } 3254992cb984SSergei Barannikov 3255992cb984SSergei Barannikov ABIArgInfo WinX86_64ABIInfo::reclassifyHvaArgForVectorCall( 3256992cb984SSergei Barannikov QualType Ty, unsigned &FreeSSERegs, const ABIArgInfo ¤t) const { 3257992cb984SSergei Barannikov const Type *Base = nullptr; 3258992cb984SSergei Barannikov uint64_t NumElts = 0; 3259992cb984SSergei Barannikov 3260992cb984SSergei Barannikov if (!Ty->isBuiltinType() && !Ty->isVectorType() && 3261992cb984SSergei Barannikov isHomogeneousAggregate(Ty, Base, NumElts) && FreeSSERegs >= NumElts) { 3262992cb984SSergei Barannikov FreeSSERegs -= NumElts; 3263992cb984SSergei Barannikov return getDirectX86Hva(); 3264992cb984SSergei Barannikov } 3265992cb984SSergei Barannikov return current; 3266992cb984SSergei Barannikov } 3267992cb984SSergei Barannikov 3268992cb984SSergei Barannikov ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, unsigned &FreeSSERegs, 3269992cb984SSergei Barannikov bool IsReturnType, bool IsVectorCall, 3270992cb984SSergei Barannikov bool IsRegCall) const { 3271992cb984SSergei Barannikov 3272992cb984SSergei Barannikov if (Ty->isVoidType()) 3273992cb984SSergei Barannikov return ABIArgInfo::getIgnore(); 3274992cb984SSergei Barannikov 3275992cb984SSergei Barannikov if (const EnumType *EnumTy = Ty->getAs<EnumType>()) 3276992cb984SSergei Barannikov Ty = EnumTy->getDecl()->getIntegerType(); 3277992cb984SSergei Barannikov 3278992cb984SSergei Barannikov TypeInfo Info = getContext().getTypeInfo(Ty); 3279992cb984SSergei Barannikov uint64_t Width = Info.Width; 3280992cb984SSergei Barannikov CharUnits Align = getContext().toCharUnitsFromBits(Info.Align); 3281992cb984SSergei Barannikov 3282992cb984SSergei Barannikov const RecordType *RT = Ty->getAs<RecordType>(); 3283992cb984SSergei Barannikov if (RT) { 3284992cb984SSergei Barannikov if (!IsReturnType) { 3285992cb984SSergei Barannikov if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI())) 3286992cb984SSergei Barannikov return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); 3287992cb984SSergei Barannikov } 3288992cb984SSergei Barannikov 3289992cb984SSergei Barannikov if (RT->getDecl()->hasFlexibleArrayMember()) 3290992cb984SSergei Barannikov return getNaturalAlignIndirect(Ty, /*ByVal=*/false); 3291992cb984SSergei Barannikov 3292992cb984SSergei Barannikov } 3293992cb984SSergei Barannikov 3294992cb984SSergei Barannikov const Type *Base = nullptr; 3295992cb984SSergei Barannikov uint64_t NumElts = 0; 3296992cb984SSergei Barannikov // vectorcall adds the concept of a homogenous vector aggregate, similar to 3297992cb984SSergei Barannikov // other targets. 3298992cb984SSergei Barannikov if ((IsVectorCall || IsRegCall) && 3299992cb984SSergei Barannikov isHomogeneousAggregate(Ty, Base, NumElts)) { 3300992cb984SSergei Barannikov if (IsRegCall) { 3301992cb984SSergei Barannikov if (FreeSSERegs >= NumElts) { 3302992cb984SSergei Barannikov FreeSSERegs -= NumElts; 3303992cb984SSergei Barannikov if (IsReturnType || Ty->isBuiltinType() || Ty->isVectorType()) 3304992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 3305992cb984SSergei Barannikov return ABIArgInfo::getExpand(); 3306992cb984SSergei Barannikov } 3307992cb984SSergei Barannikov return ABIArgInfo::getIndirect(Align, /*ByVal=*/false); 3308992cb984SSergei Barannikov } else if (IsVectorCall) { 3309992cb984SSergei Barannikov if (FreeSSERegs >= NumElts && 3310992cb984SSergei Barannikov (IsReturnType || Ty->isBuiltinType() || Ty->isVectorType())) { 3311992cb984SSergei Barannikov FreeSSERegs -= NumElts; 3312992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 3313992cb984SSergei Barannikov } else if (IsReturnType) { 3314992cb984SSergei Barannikov return ABIArgInfo::getExpand(); 3315992cb984SSergei Barannikov } else if (!Ty->isBuiltinType() && !Ty->isVectorType()) { 3316992cb984SSergei Barannikov // HVAs are delayed and reclassified in the 2nd step. 3317992cb984SSergei Barannikov return ABIArgInfo::getIndirect(Align, /*ByVal=*/false); 3318992cb984SSergei Barannikov } 3319992cb984SSergei Barannikov } 3320992cb984SSergei Barannikov } 3321992cb984SSergei Barannikov 3322992cb984SSergei Barannikov if (Ty->isMemberPointerType()) { 3323992cb984SSergei Barannikov // If the member pointer is represented by an LLVM int or ptr, pass it 3324992cb984SSergei Barannikov // directly. 3325992cb984SSergei Barannikov llvm::Type *LLTy = CGT.ConvertType(Ty); 3326992cb984SSergei Barannikov if (LLTy->isPointerTy() || LLTy->isIntegerTy()) 3327992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 3328992cb984SSergei Barannikov } 3329992cb984SSergei Barannikov 3330992cb984SSergei Barannikov if (RT || Ty->isAnyComplexType() || Ty->isMemberPointerType()) { 3331992cb984SSergei Barannikov // MS x64 ABI requirement: "Any argument that doesn't fit in 8 bytes, or is 3332992cb984SSergei Barannikov // not 1, 2, 4, or 8 bytes, must be passed by reference." 3333992cb984SSergei Barannikov if (Width > 64 || !llvm::isPowerOf2_64(Width)) 3334992cb984SSergei Barannikov return getNaturalAlignIndirect(Ty, /*ByVal=*/false); 3335992cb984SSergei Barannikov 3336992cb984SSergei Barannikov // Otherwise, coerce it to a small integer. 3337992cb984SSergei Barannikov return ABIArgInfo::getDirect(llvm::IntegerType::get(getVMContext(), Width)); 3338992cb984SSergei Barannikov } 3339992cb984SSergei Barannikov 3340992cb984SSergei Barannikov if (const BuiltinType *BT = Ty->getAs<BuiltinType>()) { 3341992cb984SSergei Barannikov switch (BT->getKind()) { 3342992cb984SSergei Barannikov case BuiltinType::Bool: 3343992cb984SSergei Barannikov // Bool type is always extended to the ABI, other builtin types are not 3344992cb984SSergei Barannikov // extended. 3345992cb984SSergei Barannikov return ABIArgInfo::getExtend(Ty); 3346992cb984SSergei Barannikov 3347992cb984SSergei Barannikov case BuiltinType::LongDouble: 3348992cb984SSergei Barannikov // Mingw64 GCC uses the old 80 bit extended precision floating point 3349992cb984SSergei Barannikov // unit. It passes them indirectly through memory. 3350992cb984SSergei Barannikov if (IsMingw64) { 3351992cb984SSergei Barannikov const llvm::fltSemantics *LDF = &getTarget().getLongDoubleFormat(); 3352992cb984SSergei Barannikov if (LDF == &llvm::APFloat::x87DoubleExtended()) 3353992cb984SSergei Barannikov return ABIArgInfo::getIndirect(Align, /*ByVal=*/false); 3354992cb984SSergei Barannikov } 3355992cb984SSergei Barannikov break; 3356992cb984SSergei Barannikov 3357992cb984SSergei Barannikov case BuiltinType::Int128: 3358992cb984SSergei Barannikov case BuiltinType::UInt128: 3359992cb984SSergei Barannikov // If it's a parameter type, the normal ABI rule is that arguments larger 3360992cb984SSergei Barannikov // than 8 bytes are passed indirectly. GCC follows it. We follow it too, 3361992cb984SSergei Barannikov // even though it isn't particularly efficient. 3362992cb984SSergei Barannikov if (!IsReturnType) 3363992cb984SSergei Barannikov return ABIArgInfo::getIndirect(Align, /*ByVal=*/false); 3364992cb984SSergei Barannikov 3365992cb984SSergei Barannikov // Mingw64 GCC returns i128 in XMM0. Coerce to v2i64 to handle that. 3366992cb984SSergei Barannikov // Clang matches them for compatibility. 3367992cb984SSergei Barannikov return ABIArgInfo::getDirect(llvm::FixedVectorType::get( 3368992cb984SSergei Barannikov llvm::Type::getInt64Ty(getVMContext()), 2)); 3369992cb984SSergei Barannikov 3370992cb984SSergei Barannikov default: 3371992cb984SSergei Barannikov break; 3372992cb984SSergei Barannikov } 3373992cb984SSergei Barannikov } 3374992cb984SSergei Barannikov 3375992cb984SSergei Barannikov if (Ty->isBitIntType()) { 3376992cb984SSergei Barannikov // MS x64 ABI requirement: "Any argument that doesn't fit in 8 bytes, or is 3377992cb984SSergei Barannikov // not 1, 2, 4, or 8 bytes, must be passed by reference." 3378992cb984SSergei Barannikov // However, non-power-of-two bit-precise integers will be passed as 1, 2, 4, 3379992cb984SSergei Barannikov // or 8 bytes anyway as long is it fits in them, so we don't have to check 3380992cb984SSergei Barannikov // the power of 2. 3381992cb984SSergei Barannikov if (Width <= 64) 3382992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 3383992cb984SSergei Barannikov return ABIArgInfo::getIndirect(Align, /*ByVal=*/false); 3384992cb984SSergei Barannikov } 3385992cb984SSergei Barannikov 3386992cb984SSergei Barannikov return ABIArgInfo::getDirect(); 3387992cb984SSergei Barannikov } 3388992cb984SSergei Barannikov 3389992cb984SSergei Barannikov void WinX86_64ABIInfo::computeInfo(CGFunctionInfo &FI) const { 3390992cb984SSergei Barannikov const unsigned CC = FI.getCallingConvention(); 3391992cb984SSergei Barannikov bool IsVectorCall = CC == llvm::CallingConv::X86_VectorCall; 3392992cb984SSergei Barannikov bool IsRegCall = CC == llvm::CallingConv::X86_RegCall; 3393992cb984SSergei Barannikov 3394992cb984SSergei Barannikov // If __attribute__((sysv_abi)) is in use, use the SysV argument 3395992cb984SSergei Barannikov // classification rules. 3396992cb984SSergei Barannikov if (CC == llvm::CallingConv::X86_64_SysV) { 3397992cb984SSergei Barannikov X86_64ABIInfo SysVABIInfo(CGT, AVXLevel); 3398992cb984SSergei Barannikov SysVABIInfo.computeInfo(FI); 3399992cb984SSergei Barannikov return; 3400992cb984SSergei Barannikov } 3401992cb984SSergei Barannikov 3402992cb984SSergei Barannikov unsigned FreeSSERegs = 0; 3403992cb984SSergei Barannikov if (IsVectorCall) { 3404992cb984SSergei Barannikov // We can use up to 4 SSE return registers with vectorcall. 3405992cb984SSergei Barannikov FreeSSERegs = 4; 3406992cb984SSergei Barannikov } else if (IsRegCall) { 3407992cb984SSergei Barannikov // RegCall gives us 16 SSE registers. 3408992cb984SSergei Barannikov FreeSSERegs = 16; 3409992cb984SSergei Barannikov } 3410992cb984SSergei Barannikov 3411992cb984SSergei Barannikov if (!getCXXABI().classifyReturnType(FI)) 3412992cb984SSergei Barannikov FI.getReturnInfo() = classify(FI.getReturnType(), FreeSSERegs, true, 3413992cb984SSergei Barannikov IsVectorCall, IsRegCall); 3414992cb984SSergei Barannikov 3415992cb984SSergei Barannikov if (IsVectorCall) { 3416992cb984SSergei Barannikov // We can use up to 6 SSE register parameters with vectorcall. 3417992cb984SSergei Barannikov FreeSSERegs = 6; 3418992cb984SSergei Barannikov } else if (IsRegCall) { 3419992cb984SSergei Barannikov // RegCall gives us 16 SSE registers, we can reuse the return registers. 3420992cb984SSergei Barannikov FreeSSERegs = 16; 3421992cb984SSergei Barannikov } 3422992cb984SSergei Barannikov 3423992cb984SSergei Barannikov unsigned ArgNum = 0; 3424992cb984SSergei Barannikov unsigned ZeroSSERegs = 0; 3425992cb984SSergei Barannikov for (auto &I : FI.arguments()) { 3426992cb984SSergei Barannikov // Vectorcall in x64 only permits the first 6 arguments to be passed as 3427992cb984SSergei Barannikov // XMM/YMM registers. After the sixth argument, pretend no vector 3428992cb984SSergei Barannikov // registers are left. 3429992cb984SSergei Barannikov unsigned *MaybeFreeSSERegs = 3430992cb984SSergei Barannikov (IsVectorCall && ArgNum >= 6) ? &ZeroSSERegs : &FreeSSERegs; 3431992cb984SSergei Barannikov I.info = 3432992cb984SSergei Barannikov classify(I.type, *MaybeFreeSSERegs, false, IsVectorCall, IsRegCall); 3433992cb984SSergei Barannikov ++ArgNum; 3434992cb984SSergei Barannikov } 3435992cb984SSergei Barannikov 3436992cb984SSergei Barannikov if (IsVectorCall) { 3437992cb984SSergei Barannikov // For vectorcall, assign aggregate HVAs to any free vector registers in a 3438992cb984SSergei Barannikov // second pass. 3439992cb984SSergei Barannikov for (auto &I : FI.arguments()) 3440992cb984SSergei Barannikov I.info = reclassifyHvaArgForVectorCall(I.type, FreeSSERegs, I.info); 3441992cb984SSergei Barannikov } 3442992cb984SSergei Barannikov } 3443992cb984SSergei Barannikov 34446d973b45SMariya Podchishchaeva RValue WinX86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 34456d973b45SMariya Podchishchaeva QualType Ty, AggValueSlot Slot) const { 3446992cb984SSergei Barannikov // MS x64 ABI requirement: "Any argument that doesn't fit in 8 bytes, or is 3447992cb984SSergei Barannikov // not 1, 2, 4, or 8 bytes, must be passed by reference." 3448992cb984SSergei Barannikov uint64_t Width = getContext().getTypeSize(Ty); 3449992cb984SSergei Barannikov bool IsIndirect = Width > 64 || !llvm::isPowerOf2_64(Width); 3450992cb984SSergei Barannikov 3451992cb984SSergei Barannikov return emitVoidPtrVAArg(CGF, VAListAddr, Ty, IsIndirect, 3452992cb984SSergei Barannikov CGF.getContext().getTypeInfoInChars(Ty), 3453992cb984SSergei Barannikov CharUnits::fromQuantity(8), 34546d973b45SMariya Podchishchaeva /*allowHigherAlign*/ false, Slot); 3455992cb984SSergei Barannikov } 3456992cb984SSergei Barannikov 3457992cb984SSergei Barannikov std::unique_ptr<TargetCodeGenInfo> CodeGen::createX86_32TargetCodeGenInfo( 3458992cb984SSergei Barannikov CodeGenModule &CGM, bool DarwinVectorABI, bool Win32StructABI, 3459992cb984SSergei Barannikov unsigned NumRegisterParameters, bool SoftFloatABI) { 3460992cb984SSergei Barannikov bool RetSmallStructInRegABI = X86_32TargetCodeGenInfo::isStructReturnInRegABI( 3461992cb984SSergei Barannikov CGM.getTriple(), CGM.getCodeGenOpts()); 3462992cb984SSergei Barannikov return std::make_unique<X86_32TargetCodeGenInfo>( 3463992cb984SSergei Barannikov CGM.getTypes(), DarwinVectorABI, RetSmallStructInRegABI, Win32StructABI, 3464992cb984SSergei Barannikov NumRegisterParameters, SoftFloatABI); 3465992cb984SSergei Barannikov } 3466992cb984SSergei Barannikov 3467992cb984SSergei Barannikov std::unique_ptr<TargetCodeGenInfo> CodeGen::createWinX86_32TargetCodeGenInfo( 3468992cb984SSergei Barannikov CodeGenModule &CGM, bool DarwinVectorABI, bool Win32StructABI, 3469992cb984SSergei Barannikov unsigned NumRegisterParameters) { 3470992cb984SSergei Barannikov bool RetSmallStructInRegABI = X86_32TargetCodeGenInfo::isStructReturnInRegABI( 3471992cb984SSergei Barannikov CGM.getTriple(), CGM.getCodeGenOpts()); 3472992cb984SSergei Barannikov return std::make_unique<WinX86_32TargetCodeGenInfo>( 3473992cb984SSergei Barannikov CGM.getTypes(), DarwinVectorABI, RetSmallStructInRegABI, Win32StructABI, 3474992cb984SSergei Barannikov NumRegisterParameters); 3475992cb984SSergei Barannikov } 3476992cb984SSergei Barannikov 3477992cb984SSergei Barannikov std::unique_ptr<TargetCodeGenInfo> 3478992cb984SSergei Barannikov CodeGen::createX86_64TargetCodeGenInfo(CodeGenModule &CGM, 3479992cb984SSergei Barannikov X86AVXABILevel AVXLevel) { 3480992cb984SSergei Barannikov return std::make_unique<X86_64TargetCodeGenInfo>(CGM.getTypes(), AVXLevel); 3481992cb984SSergei Barannikov } 3482992cb984SSergei Barannikov 3483992cb984SSergei Barannikov std::unique_ptr<TargetCodeGenInfo> 3484992cb984SSergei Barannikov CodeGen::createWinX86_64TargetCodeGenInfo(CodeGenModule &CGM, 3485992cb984SSergei Barannikov X86AVXABILevel AVXLevel) { 3486992cb984SSergei Barannikov return std::make_unique<WinX86_64TargetCodeGenInfo>(CGM.getTypes(), AVXLevel); 3487992cb984SSergei Barannikov } 3488