xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/Targets/PNaCl.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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:
PNaClABIInfo(CodeGen::CodeGenTypes & CGT)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:
PNaClTargetCodeGenInfo(CodeGen::CodeGenTypes & CGT)36     PNaClTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
37         : TargetCodeGenInfo(std::make_unique<PNaClABIInfo>(CGT)) {}
38  };
39  
computeInfo(CGFunctionInfo & FI) const40  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  
EmitVAArg(CodeGenFunction & CGF,Address VAListAddr,QualType Ty,AggValueSlot Slot) const48  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.
classifyArgumentType(QualType Ty) const63  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  
classifyReturnType(QualType RetTy) const86  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>
createPNaClTargetCodeGenInfo(CodeGenModule & CGM)110  CodeGen::createPNaClTargetCodeGenInfo(CodeGenModule &CGM) {
111    return std::make_unique<PNaClTargetCodeGenInfo>(CGM.getTypes());
112  }
113