1 //===- PNaCl.cpp ----------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "ABIInfoImpl.h" 10 #include "TargetInfo.h" 11 12 using namespace clang; 13 using namespace clang::CodeGen; 14 15 //===----------------------------------------------------------------------===// 16 // le32/PNaCl bitcode ABI Implementation 17 // 18 // This is a simplified version of the x86_32 ABI. Arguments and return values 19 // are always passed on the stack. 20 //===----------------------------------------------------------------------===// 21 22 class PNaClABIInfo : public ABIInfo { 23 public: 24 PNaClABIInfo(CodeGen::CodeGenTypes &CGT) : ABIInfo(CGT) {} 25 26 ABIArgInfo classifyReturnType(QualType RetTy) const; 27 ABIArgInfo classifyArgumentType(QualType RetTy) const; 28 29 void computeInfo(CGFunctionInfo &FI) const override; 30 Address EmitVAArg(CodeGenFunction &CGF, 31 Address VAListAddr, QualType Ty) const override; 32 }; 33 34 class PNaClTargetCodeGenInfo : public TargetCodeGenInfo { 35 public: 36 PNaClTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT) 37 : TargetCodeGenInfo(std::make_unique<PNaClABIInfo>(CGT)) {} 38 }; 39 40 void PNaClABIInfo::computeInfo(CGFunctionInfo &FI) const { 41 if (!getCXXABI().classifyReturnType(FI)) 42 FI.getReturnInfo() = classifyReturnType(FI.getReturnType()); 43 44 for (auto &I : FI.arguments()) 45 I.info = classifyArgumentType(I.type); 46 } 47 48 Address PNaClABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 49 QualType Ty) const { 50 // The PNaCL ABI is a bit odd, in that varargs don't use normal 51 // function classification. Structs get passed directly for varargs 52 // functions, through a rewriting transform in 53 // pnacl-llvm/lib/Transforms/NaCl/ExpandVarArgs.cpp, which allows 54 // this target to actually support a va_arg instructions with an 55 // aggregate type, unlike other targets. 56 return EmitVAArgInstr(CGF, VAListAddr, Ty, ABIArgInfo::getDirect()); 57 } 58 59 /// Classify argument of given type \p Ty. 60 ABIArgInfo PNaClABIInfo::classifyArgumentType(QualType Ty) const { 61 if (isAggregateTypeForABI(Ty)) { 62 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) 63 return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); 64 return getNaturalAlignIndirect(Ty); 65 } else if (const EnumType *EnumTy = Ty->getAs<EnumType>()) { 66 // Treat an enum type as its underlying type. 67 Ty = EnumTy->getDecl()->getIntegerType(); 68 } else if (Ty->isFloatingType()) { 69 // Floating-point types don't go inreg. 70 return ABIArgInfo::getDirect(); 71 } else if (const auto *EIT = Ty->getAs<BitIntType>()) { 72 // Treat bit-precise integers as integers if <= 64, otherwise pass 73 // indirectly. 74 if (EIT->getNumBits() > 64) 75 return getNaturalAlignIndirect(Ty); 76 return ABIArgInfo::getDirect(); 77 } 78 79 return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) 80 : ABIArgInfo::getDirect()); 81 } 82 83 ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const { 84 if (RetTy->isVoidType()) 85 return ABIArgInfo::getIgnore(); 86 87 // In the PNaCl ABI we always return records/structures on the stack. 88 if (isAggregateTypeForABI(RetTy)) 89 return getNaturalAlignIndirect(RetTy); 90 91 // Treat bit-precise integers as integers if <= 64, otherwise pass indirectly. 92 if (const auto *EIT = RetTy->getAs<BitIntType>()) { 93 if (EIT->getNumBits() > 64) 94 return getNaturalAlignIndirect(RetTy); 95 return ABIArgInfo::getDirect(); 96 } 97 98 // Treat an enum type as its underlying type. 99 if (const EnumType *EnumTy = RetTy->getAs<EnumType>()) 100 RetTy = EnumTy->getDecl()->getIntegerType(); 101 102 return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy) 103 : ABIArgInfo::getDirect()); 104 } 105 106 std::unique_ptr<TargetCodeGenInfo> 107 CodeGen::createPNaClTargetCodeGenInfo(CodeGenModule &CGM) { 108 return std::make_unique<PNaClTargetCodeGenInfo>(CGM.getTypes()); 109 } 110