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 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty, 31 AggValueSlot Slot) 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 RValue PNaClABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, 49 QualType Ty, AggValueSlot Slot) 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 CGF.EmitLoadOfAnyValue( 57 CGF.MakeAddrLValue( 58 EmitVAArgInstr(CGF, VAListAddr, Ty, ABIArgInfo::getDirect()), Ty), 59 Slot); 60 } 61 62 /// Classify argument of given type \p Ty. 63 ABIArgInfo PNaClABIInfo::classifyArgumentType(QualType Ty) const { 64 if (isAggregateTypeForABI(Ty)) { 65 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) 66 return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory); 67 return getNaturalAlignIndirect(Ty); 68 } else if (const EnumType *EnumTy = Ty->getAs<EnumType>()) { 69 // Treat an enum type as its underlying type. 70 Ty = EnumTy->getDecl()->getIntegerType(); 71 } else if (Ty->isFloatingType()) { 72 // Floating-point types don't go inreg. 73 return ABIArgInfo::getDirect(); 74 } else if (const auto *EIT = Ty->getAs<BitIntType>()) { 75 // Treat bit-precise integers as integers if <= 64, otherwise pass 76 // indirectly. 77 if (EIT->getNumBits() > 64) 78 return getNaturalAlignIndirect(Ty); 79 return ABIArgInfo::getDirect(); 80 } 81 82 return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty) 83 : ABIArgInfo::getDirect()); 84 } 85 86 ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const { 87 if (RetTy->isVoidType()) 88 return ABIArgInfo::getIgnore(); 89 90 // In the PNaCl ABI we always return records/structures on the stack. 91 if (isAggregateTypeForABI(RetTy)) 92 return getNaturalAlignIndirect(RetTy); 93 94 // Treat bit-precise integers as integers if <= 64, otherwise pass indirectly. 95 if (const auto *EIT = RetTy->getAs<BitIntType>()) { 96 if (EIT->getNumBits() > 64) 97 return getNaturalAlignIndirect(RetTy); 98 return ABIArgInfo::getDirect(); 99 } 100 101 // Treat an enum type as its underlying type. 102 if (const EnumType *EnumTy = RetTy->getAs<EnumType>()) 103 RetTy = EnumTy->getDecl()->getIntegerType(); 104 105 return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy) 106 : ABIArgInfo::getDirect()); 107 } 108 109 std::unique_ptr<TargetCodeGenInfo> 110 CodeGen::createPNaClTargetCodeGenInfo(CodeGenModule &CGM) { 111 return std::make_unique<PNaClTargetCodeGenInfo>(CGM.getTypes()); 112 } 113