Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/CodeGen/Targets/PNaCl.cpp
Line
Count
Source (jump to first uncovered line)
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
0
  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
0
       : TargetCodeGenInfo(std::make_unique<PNaClABIInfo>(CGT)) {}
38
};
39
40
0
void PNaClABIInfo::computeInfo(CGFunctionInfo &FI) const {
41
0
  if (!getCXXABI().classifyReturnType(FI))
42
0
    FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
43
44
0
  for (auto &I : FI.arguments())
45
0
    I.info = classifyArgumentType(I.type);
46
0
}
47
48
Address PNaClABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
49
0
                                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
0
  return EmitVAArgInstr(CGF, VAListAddr, Ty, ABIArgInfo::getDirect());
57
0
}
58
59
/// Classify argument of given type \p Ty.
60
0
ABIArgInfo PNaClABIInfo::classifyArgumentType(QualType Ty) const {
61
0
  if (isAggregateTypeForABI(Ty)) {
62
0
    if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
63
0
      return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
64
0
    return getNaturalAlignIndirect(Ty);
65
0
  } else if (const EnumType *EnumTy = Ty->getAs<EnumType>()) {
66
    // Treat an enum type as its underlying type.
67
0
    Ty = EnumTy->getDecl()->getIntegerType();
68
0
  } else if (Ty->isFloatingType()) {
69
    // Floating-point types don't go inreg.
70
0
    return ABIArgInfo::getDirect();
71
0
  } else if (const auto *EIT = Ty->getAs<BitIntType>()) {
72
    // Treat bit-precise integers as integers if <= 64, otherwise pass
73
    // indirectly.
74
0
    if (EIT->getNumBits() > 64)
75
0
      return getNaturalAlignIndirect(Ty);
76
0
    return ABIArgInfo::getDirect();
77
0
  }
78
79
0
  return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
80
0
                                            : ABIArgInfo::getDirect());
81
0
}
82
83
0
ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const {
84
0
  if (RetTy->isVoidType())
85
0
    return ABIArgInfo::getIgnore();
86
87
  // In the PNaCl ABI we always return records/structures on the stack.
88
0
  if (isAggregateTypeForABI(RetTy))
89
0
    return getNaturalAlignIndirect(RetTy);
90
91
  // Treat bit-precise integers as integers if <= 64, otherwise pass indirectly.
92
0
  if (const auto *EIT = RetTy->getAs<BitIntType>()) {
93
0
    if (EIT->getNumBits() > 64)
94
0
      return getNaturalAlignIndirect(RetTy);
95
0
    return ABIArgInfo::getDirect();
96
0
  }
97
98
  // Treat an enum type as its underlying type.
99
0
  if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
100
0
    RetTy = EnumTy->getDecl()->getIntegerType();
101
102
0
  return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
103
0
                                               : ABIArgInfo::getDirect());
104
0
}
105
106
std::unique_ptr<TargetCodeGenInfo>
107
0
CodeGen::createPNaClTargetCodeGenInfo(CodeGenModule &CGM) {
108
0
  return std::make_unique<PNaClTargetCodeGenInfo>(CGM.getTypes());
109
0
}