10#include "TargetInfo.h"
11#include "llvm/IR/IntrinsicsRISCV.h"
12#include "llvm/TargetParser/RISCVTargetParser.h"
33 bool detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
34 llvm::Type *&Field1Ty,
36 llvm::Type *&Field2Ty,
37 CharUnits &Field2Off)
const;
39 bool detectVLSCCEligibleStruct(QualType Ty,
unsigned ABIVLen,
40 llvm::Type *&VLSType)
const;
43 RISCVABIInfo(CodeGen::CodeGenTypes &CGT,
unsigned XLen,
unsigned FLen,
45 : DefaultABIInfo(CGT), XLen(XLen), FLen(FLen), NumArgGPRs(EABI ? 6 : 8),
46 NumArgFPRs(FLen != 0 ? 8 : 0), EABI(EABI) {}
50 void computeInfo(CGFunctionInfo &FI)
const override;
53 int &ArgFPRsLeft,
unsigned ABIVLen)
const;
56 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
57 AggValueSlot Slot)
const override;
59 ABIArgInfo extendType(QualType Ty, llvm::Type *CoerceTy =
nullptr)
const;
61 bool detectFPCCEligibleStruct(QualType Ty, llvm::Type *&Field1Ty,
62 CharUnits &Field1Off, llvm::Type *&Field2Ty,
63 CharUnits &Field2Off,
int &NeededArgGPRs,
64 int &NeededArgFPRs)
const;
65 ABIArgInfo coerceAndExpandFPCCEligibleStruct(llvm::Type *Field1Ty,
68 CharUnits Field2Off)
const;
70 ABIArgInfo coerceVLSVector(QualType Ty,
unsigned ABIVLen = 0)
const;
73 void appendAttributeMangling(TargetClonesAttr *Attr,
unsigned Index,
74 raw_ostream &Out)
const override;
75 void appendAttributeMangling(StringRef AttrStr,
76 raw_ostream &Out)
const override;
77 llvm::Value *createCoercedLoad(Address SrcAddr,
const ABIArgInfo &AI,
78 CodeGenFunction &CGF)
const override;
79 void createCoercedStore(llvm::Value *Val, Address DstAddr,
80 const ABIArgInfo &AI,
bool DestIsVolatile,
81 CodeGenFunction &CGF)
const override;
85void RISCVABIInfo::appendAttributeMangling(TargetClonesAttr *
Attr,
87 raw_ostream &Out)
const {
88 appendAttributeMangling(Attr->getFeatureStr(Index), Out);
91void RISCVABIInfo::appendAttributeMangling(StringRef AttrStr,
92 raw_ostream &Out)
const {
93 if (AttrStr ==
"default") {
100 SmallVector<StringRef, 8> Attrs;
101 AttrStr.split(Attrs,
';');
105 for (
auto &Attr : Attrs) {
106 if (Attr.starts_with(
"arch="))
111 SmallVector<StringRef, 8> Features;
112 ArchStr.consume_front(
"arch=");
113 ArchStr.split(Features,
',');
115 llvm::stable_sort(Features);
117 for (
auto Feat : Features) {
118 Feat.consume_front(
"+");
123void RISCVABIInfo::computeInfo(CGFunctionInfo &FI)
const {
129#define CC_VLS_CASE(ABI_VLEN) \
130 case CallingConv::CC_RISCVVLSCall_##ABI_VLEN: \
131 ABIVLen = ABI_VLEN; \
158 getContext().getTypeSize(RetTy) > (2 * XLen)) {
160 QualType EltTy = RetTy->
castAs<ComplexType>()->getElementType();
161 IsRetIndirect = getContext().getTypeSize(EltTy) > FLen;
164 IsRetIndirect =
true;
168 int ArgGPRsLeft = IsRetIndirect ? NumArgGPRs - 1 : NumArgGPRs;
169 int ArgFPRsLeft = NumArgFPRs;
174 bool IsFixed = ArgNum < NumFixedArgs;
176 ArgFPRsLeft, ABIVLen);
185bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
186 llvm::Type *&Field1Ty,
187 CharUnits &Field1Off,
188 llvm::Type *&Field2Ty,
189 CharUnits &Field2Off)
const {
193 if (IsInt || IsFloat) {
195 if (IsInt && Size > XLen)
199 if (IsFloat && Size > FLen)
203 if (IsInt && Field1Ty && Field1Ty->isIntegerTy())
206 Field1Ty = CGT.ConvertType(Ty);
211 Field2Ty = CGT.ConvertType(Ty);
218 if (
auto CTy = Ty->
getAs<ComplexType>()) {
221 QualType EltTy = CTy->getElementType();
222 if (getContext().getTypeSize(EltTy) > FLen)
224 Field1Ty = CGT.ConvertType(EltTy);
227 Field2Off = Field1Off + getContext().getTypeSizeInChars(EltTy);
231 if (
const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) {
232 uint64_t ArraySize = ATy->getZExtSize();
233 QualType EltTy = ATy->getElementType();
241 CharUnits EltSize = getContext().getTypeSizeInChars(EltTy);
242 for (uint64_t i = 0; i < ArraySize; ++i) {
243 bool Ret = detectFPCCEligibleStructHelper(EltTy, CurOff, Field1Ty,
244 Field1Off, Field2Ty, Field2Off);
259 const RecordDecl *RD = RTy->getDecl()->getDefinitionOrSelf();
263 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
265 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
266 for (
const CXXBaseSpecifier &B : CXXRD->bases()) {
267 const auto *BDecl = B.getType()->castAsCXXRecordDecl();
269 bool Ret = detectFPCCEligibleStructHelper(B.getType(), CurOff + BaseOff,
270 Field1Ty, Field1Off, Field2Ty,
276 int ZeroWidthBitFieldCount = 0;
277 for (
const FieldDecl *FD : RD->
fields()) {
279 QualType QTy = FD->getType();
280 if (FD->isBitField()) {
281 unsigned BitWidth = FD->getBitWidthValue();
284 if (getContext().getTypeSize(QTy) > XLen && BitWidth <= XLen)
285 QTy = getContext().getIntTypeForBitwidth(XLen,
false);
287 else if (getContext().getTypeSize(QTy) > BitWidth) {
289 FD->getType().getTypePtr()->hasSignedIntegerRepresentation();
290 unsigned Bits = std::max(8U, (
unsigned)llvm::PowerOf2Ceil(BitWidth));
291 QTy = getContext().getIntTypeForBitwidth(Bits, IsSigned);
294 ZeroWidthBitFieldCount++;
299 bool Ret = detectFPCCEligibleStructHelper(
300 QTy, CurOff + getContext().toCharUnitsFromBits(FieldOffInBits),
301 Field1Ty, Field1Off, Field2Ty, Field2Off);
308 if (Field2Ty && ZeroWidthBitFieldCount > 0)
311 return Field1Ty !=
nullptr;
321bool RISCVABIInfo::detectFPCCEligibleStruct(QualType Ty, llvm::Type *&Field1Ty,
322 CharUnits &Field1Off,
323 llvm::Type *&Field2Ty,
324 CharUnits &Field2Off,
326 int &NeededArgFPRs)
const {
331 bool IsCandidate = detectFPCCEligibleStructHelper(
336 if (Field1Ty && !Field2Ty && !Field1Ty->isFloatingPointTy())
340 if (Field1Ty && Field1Ty->isFloatingPointTy())
344 if (Field2Ty && Field2Ty->isFloatingPointTy())
354ABIArgInfo RISCVABIInfo::coerceAndExpandFPCCEligibleStruct(
355 llvm::Type *Field1Ty, CharUnits Field1Off, llvm::Type *Field2Ty,
356 CharUnits Field2Off)
const {
357 SmallVector<llvm::Type *, 3> CoerceElts;
358 SmallVector<llvm::Type *, 2> UnpaddedCoerceElts;
360 CoerceElts.push_back(llvm::ArrayType::get(
361 llvm::Type::getInt8Ty(getVMContext()), Field1Off.
getQuantity()));
363 CoerceElts.push_back(Field1Ty);
364 UnpaddedCoerceElts.push_back(Field1Ty);
368 llvm::StructType::get(getVMContext(), CoerceElts, !Field1Off.
isZero()),
369 UnpaddedCoerceElts[0]);
372 CharUnits Field2Align =
374 CharUnits Field1End = Field1Off +
376 CharUnits Field2OffNoPadNoPack = Field1End.
alignTo(Field2Align);
379 if (Field2Off > Field2OffNoPadNoPack)
380 Padding = Field2Off - Field2OffNoPadNoPack;
381 else if (Field2Off != Field2Align && Field2Off > Field1End)
382 Padding = Field2Off - Field1End;
387 CoerceElts.push_back(llvm::ArrayType::get(
388 llvm::Type::getInt8Ty(getVMContext()), Padding.
getQuantity()));
390 CoerceElts.push_back(Field2Ty);
391 UnpaddedCoerceElts.push_back(Field2Ty);
394 llvm::StructType::get(getVMContext(), CoerceElts, IsPacked);
395 auto UnpaddedCoerceToType =
396 llvm::StructType::get(getVMContext(), UnpaddedCoerceElts, IsPacked);
401bool RISCVABIInfo::detectVLSCCEligibleStruct(QualType Ty,
unsigned ABIVLen,
402 llvm::Type *&VLSType)
const {
464 llvm::StructType *STy = dyn_cast<llvm::StructType>(CGT.ConvertType(Ty));
468 unsigned NumElts = STy->getStructNumElements();
472 auto *FirstEltTy = STy->getElementType(0);
473 if (!STy->containsHomogeneousTypes())
476 if (
auto *ArrayTy = dyn_cast<llvm::ArrayType>(FirstEltTy)) {
480 FirstEltTy = ArrayTy->getArrayElementType();
481 NumElts = ArrayTy->getNumElements();
484 auto *FixedVecTy = dyn_cast<llvm::FixedVectorType>(FirstEltTy);
489 if (NumElts * llvm::divideCeil(
490 FixedVecTy->getNumElements() *
491 FixedVecTy->getElementType()->getScalarSizeInBits(),
499 VLSType = llvm::ScalableVectorType::get(
500 FixedVecTy->getElementType(),
501 llvm::divideCeil(FixedVecTy->getNumElements() *
502 llvm::RISCV::RVVBitsPerBlock,
513 unsigned I8EltCount =
514 llvm::divideCeil(FixedVecTy->getNumElements() *
515 FixedVecTy->getElementType()->getScalarSizeInBits() *
516 llvm::RISCV::RVVBitsPerBlock,
518 VLSType = llvm::TargetExtType::get(
519 getVMContext(),
"riscv.vector.tuple",
520 llvm::ScalableVectorType::get(llvm::Type::getInt8Ty(getVMContext()),
528ABIArgInfo RISCVABIInfo::coerceVLSVector(QualType Ty,
unsigned ABIVLen)
const {
531 const auto *VT = Ty->
castAs<VectorType>();
532 assert(VT->getElementType()->isBuiltinType() &&
"expected builtin type!");
534 auto VScale = getContext().getTargetInfo().getVScaleRange(
535 getContext().getLangOpts(), TargetInfo::ArmStreamingKind::NotStreaming);
537 unsigned NumElts = VT->getNumElements();
538 llvm::Type *EltType = llvm::Type::getInt1Ty(getVMContext());
539 switch (VT->getVectorKind()) {
540 case VectorKind::RVVFixedLengthMask_1:
542 case VectorKind::RVVFixedLengthMask_2:
545 case VectorKind::RVVFixedLengthMask_4:
548 case VectorKind::RVVFixedLengthMask:
552 assert((VT->getVectorKind() == VectorKind::Generic ||
553 VT->getVectorKind() == VectorKind::RVVFixedLengthData) &&
554 "Unexpected vector kind");
555 EltType = CGT.ConvertType(VT->getElementType());
558 llvm::ScalableVectorType *ResType;
565 ResType = llvm::ScalableVectorType::get(EltType, NumElts / VScale->first);
568 if ((EltType->getScalarSizeInBits() * NumElts / ABIVLen) > 8)
569 return getNaturalAlignIndirect(
570 Ty, getDataLayout().getAllocaAddrSpace(),
575 ResType = llvm::ScalableVectorType::get(
577 llvm::divideCeil(NumElts * llvm::RISCV::RVVBitsPerBlock, ABIVLen));
581 const TargetInfo &TI = getContext().getTargetInfo();
582 if ((EltType->isHalfTy() && !TI.
hasFeature(
"zvfhmin")) ||
583 (EltType->isBFloatTy() && !TI.
hasFeature(
"zvfbfmin")) ||
584 (EltType->isFloatTy() && !TI.
hasFeature(
"zve32f")) ||
585 (EltType->isDoubleTy() && !TI.
hasFeature(
"zve64d")) ||
586 (EltType->isIntegerTy(64) && !TI.
hasFeature(
"zve64x")) ||
587 EltType->isIntegerTy(128)) {
589 ResType = llvm::ScalableVectorType::get(
590 llvm::Type::getInt8Ty(getVMContext()),
591 llvm::divideCeil(EltType->getScalarSizeInBits() * NumElts *
592 llvm::RISCV::RVVBitsPerBlock,
600ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty,
bool IsFixed,
603 unsigned ABIVLen)
const {
604 assert(ArgGPRsLeft <= NumArgGPRs &&
"Arg GPR tracking underflow");
612 return getNaturalAlignIndirect(
613 Ty, getDataLayout().getAllocaAddrSpace(),
626 FLen >= Size && ArgFPRsLeft) {
633 if (IsFixed && Ty->
isComplexType() && FLen && ArgFPRsLeft >= 2) {
634 QualType EltTy = Ty->
castAs<ComplexType>()->getElementType();
635 if (getContext().getTypeSize(EltTy) <= FLen) {
642 llvm::Type *Field1Ty =
nullptr;
643 llvm::Type *Field2Ty =
nullptr;
646 int NeededArgGPRs = 0;
647 int NeededArgFPRs = 0;
649 detectFPCCEligibleStruct(Ty, Field1Ty, Field1Off, Field2Ty, Field2Off,
650 NeededArgGPRs, NeededArgFPRs);
651 if (IsCandidate && NeededArgGPRs <= ArgGPRsLeft &&
652 NeededArgFPRs <= ArgFPRsLeft) {
653 ArgGPRsLeft -= NeededArgGPRs;
654 ArgFPRsLeft -= NeededArgFPRs;
655 return coerceAndExpandFPCCEligibleStruct(Field1Ty, Field1Off, Field2Ty,
661 llvm::Type *VLSType =
nullptr;
662 if (detectVLSCCEligibleStruct(Ty, ABIVLen, VLSType))
666 uint64_t NeededAlign = getContext().getTypeAlign(Ty);
673 int NeededArgGPRs = 1;
674 if (!IsFixed && NeededAlign == 2 * XLen)
675 NeededArgGPRs = 2 + (EABI && XLen == 32 ? 0 : (ArgGPRsLeft % 2));
676 else if (Size > XLen && Size <= 2 * XLen)
679 if (NeededArgGPRs > ArgGPRsLeft) {
680 NeededArgGPRs = ArgGPRsLeft;
683 ArgGPRsLeft -= NeededArgGPRs;
688 Ty = ED->getIntegerType();
690 if (
const auto *EIT = Ty->
getAs<BitIntType>()) {
692 if (XLen == 64 && EIT->getNumBits() == 32)
693 return extendType(Ty, CGT.ConvertType(Ty));
695 if (EIT->getNumBits() <= 2 * XLen)
697 return getNaturalAlignIndirect(
698 Ty, getDataLayout().getAllocaAddrSpace(),
703 if (Size < XLen && Ty->isIntegralOrEnumerationType())
704 return extendType(Ty, CGT.ConvertType(Ty));
712 if (
const VectorType *VT = Ty->
getAs<VectorType>();
713 VT && !VT->getElementType()->isBitIntType()) {
714 if (VT->getVectorKind() == VectorKind::RVVFixedLengthData ||
715 VT->getVectorKind() == VectorKind::RVVFixedLengthMask ||
716 VT->getVectorKind() == VectorKind::RVVFixedLengthMask_1 ||
717 VT->getVectorKind() == VectorKind::RVVFixedLengthMask_2 ||
718 VT->getVectorKind() == VectorKind::RVVFixedLengthMask_4)
719 return coerceVLSVector(Ty);
720 if (VT->getVectorKind() == VectorKind::Generic && ABIVLen != 0)
723 return coerceVLSVector(Ty, ABIVLen);
728 if (Size <= 2 * XLen) {
729 unsigned Alignment = getContext().getTypeAlign(Ty);
734 llvm::IntegerType::get(getVMContext(), Size));
737 if (Alignment == 2 * XLen)
739 llvm::IntegerType::get(getVMContext(), 2 * XLen));
742 llvm::ArrayType::get(llvm::IntegerType::get(getVMContext(), XLen), 2));
744 return getNaturalAlignIndirect(
745 Ty, getDataLayout().getAllocaAddrSpace(),
749ABIArgInfo RISCVABIInfo::classifyReturnType(QualType RetTy,
750 unsigned ABIVLen)
const {
755 int ArgFPRsLeft = FLen ? 2 : 0;
763RValue RISCVABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
764 QualType Ty, AggValueSlot Slot)
const {
771 auto TInfo = getContext().getTypeInfoInChars(Ty);
777 if (EABI && XLen == 32)
781 bool IsIndirect = TInfo.Width > 2 * SlotSize;
787ABIArgInfo RISCVABIInfo::extendType(QualType Ty, llvm::Type *CoerceTy)
const {
788 int TySize = getContext().getTypeSize(Ty);
795llvm::Value *RISCVABIInfo::createCoercedLoad(Address Src,
const ABIArgInfo &AI,
796 CodeGenFunction &CGF)
const {
800 assert((Ty->isScalableTy() || Ty->isTargetExtTy()) &&
801 "Only scalable vector type and vector tuple type are allowed for load "
803 if (llvm::TargetExtType *TupTy = dyn_cast<llvm::TargetExtType>(Ty)) {
819 assert(TupTy->getName() ==
"riscv.vector.tuple");
820 llvm::Type *EltTy = TupTy->getTypeParameter(0);
821 unsigned NumElts = TupTy->getIntParameter(0);
823 if (
auto *ArrayTy = dyn_cast<llvm::ArrayType>(SrcSTy->getElementType(0)))
827 llvm::Value *TupleVal = llvm::PoisonValue::get(Ty);
829 for (
unsigned i = 0; i < NumElts; ++i) {
831 llvm::Value *ExtractFromLoad = CGF.
Builder.CreateExtractValue(Load, i);
837 llvm::Value *VectorVal = llvm::PoisonValue::get(EltTy);
839 VectorVal = CGF.
Builder.CreateInsertVector(
840 EltTy, VectorVal, ExtractFromLoad,
uint64_t(0),
"cast.scalable");
842 llvm::Value *Idx = CGF.
Builder.getInt32(i);
844 CGF.
Builder.CreateIntrinsic(llvm::Intrinsic::riscv_tuple_insert,
845 {Ty, EltTy}, {TupleVal, VectorVal, Idx});
865 SrcTy = SrcSTy->getElementType(0);
866 if (
auto *ArrayTy = dyn_cast<llvm::ArrayType>(SrcTy))
867 SrcTy = ArrayTy->getElementType();
870 assert(ScalableDstTy->getElementType() == FixedSrcTy->getElementType());
872 auto *VectorVal = llvm::PoisonValue::get(ScalableDstTy);
874 ScalableDstTy, VectorVal, Load,
uint64_t(0),
"cast.scalable");
878void RISCVABIInfo::createCoercedStore(llvm::Value *Val, Address Dst,
879 const ABIArgInfo &AI,
bool DestIsVolatile,
880 CodeGenFunction &CGF)
const {
881 llvm::Type *SrcTy = Val->getType();
883 assert((SrcTy->isScalableTy() || SrcTy->isTargetExtTy()) &&
884 "Only scalable vector type and vector tuple type are allowed for "
886 if (llvm::TargetExtType *TupTy = dyn_cast<llvm::TargetExtType>(SrcTy)) {
902 assert(TupTy->getName() ==
"riscv.vector.tuple");
903 llvm::Type *EltTy = TupTy->getTypeParameter(0);
904 unsigned NumElts = TupTy->getIntParameter(0);
906 llvm::Type *FixedVecTy = DstSTy->getElementType(0);
907 if (
auto *ArrayTy = dyn_cast<llvm::ArrayType>(DstSTy->getElementType(0))) {
909 FixedVecTy = ArrayTy->getArrayElementType();
913 for (
unsigned i = 0; i < NumElts; ++i) {
920 llvm::Value *Idx = CGF.
Builder.getInt32(i);
921 auto *TupleElement = CGF.
Builder.CreateIntrinsic(
922 llvm::Intrinsic::riscv_tuple_extract, {EltTy, TupTy}, {Val, Idx});
925 auto *ExtractVec = CGF.
Builder.CreateExtractVector(
926 FixedVecTy, TupleElement,
uint64_t(0));
953 llvm::Type *EltTy = DstSTy->getElementType(0);
954 if (
auto *ArrayTy = dyn_cast<llvm::ArrayType>(EltTy)) {
955 assert(ArrayTy->getNumElements() == 1);
956 EltTy = ArrayTy->getElementType();
958 auto *Coerced = CGF.
Builder.CreateExtractVector(
965class RISCVTargetCodeGenInfo :
public TargetCodeGenInfo {
967 RISCVTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT,
unsigned XLen,
968 unsigned FLen,
bool EABI)
970 std::make_unique<RISCVABIInfo>(CGT, XLen, FLen, EABI)) {
972 std::make_unique<SwiftABIInfo>(CGT,
false);
975 void setTargetAttributes(
const Decl *D, llvm::GlobalValue *GV,
976 CodeGen::CodeGenModule &CGM)
const override {
977 const auto *FD = dyn_cast_or_null<FunctionDecl>(D);
983 Fn->addFnAttr(
"hw-shadow-stack");
985 const auto *Attr = FD->getAttr<RISCVInterruptAttr>();
989 StringRef
Kind =
"machine";
990 bool HasSiFiveCLICPreemptible =
false;
991 bool HasSiFiveCLICStackSwap =
false;
992 for (RISCVInterruptAttr::InterruptType
type : Attr->interrupt()) {
994 case RISCVInterruptAttr::machine:
998 case RISCVInterruptAttr::supervisor:
1001 case RISCVInterruptAttr::rnmi:
1004 case RISCVInterruptAttr::qcinest:
1007 case RISCVInterruptAttr::qcinonest:
1008 Kind =
"qci-nonest";
1012 case RISCVInterruptAttr::SiFiveCLICPreemptible: {
1013 HasSiFiveCLICPreemptible =
true;
1014 Kind = HasSiFiveCLICStackSwap ?
"SiFive-CLIC-preemptible-stack-swap"
1015 :
"SiFive-CLIC-preemptible";
1018 case RISCVInterruptAttr::SiFiveCLICStackSwap: {
1019 HasSiFiveCLICStackSwap =
true;
1020 Kind = HasSiFiveCLICPreemptible ?
"SiFive-CLIC-preemptible-stack-swap"
1021 :
"SiFive-CLIC-stack-swap";
1027 Fn->addFnAttr(
"interrupt", Kind);
1032std::unique_ptr<TargetCodeGenInfo>
1034 unsigned FLen,
bool EABI) {
1035 return std::make_unique<RISCVTargetCodeGenInfo>(CGM.
getTypes(), XLen, FLen,
#define CC_VLS_CASE(ABI_VLEN)
static CharUnits getTypeStoreSize(CodeGenModule &CGM, llvm::Type *type)
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Attr - This represents one attribute.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isMultipleOf(CharUnits N) const
Test whether this is a multiple of the other value.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
static ABIArgInfo getIgnore()
static ABIArgInfo getTargetSpecific(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr)
static ABIArgInfo getCoerceAndExpand(llvm::StructType *coerceToType, llvm::Type *unpaddedCoerceToType)
llvm::Type * getCoerceToType() const
static ABIArgInfo getSignExtend(QualType Ty, llvm::Type *T=nullptr)
virtual void appendAttributeMangling(TargetAttr *Attr, raw_ostream &Out) const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreateConstArrayGEP(Address Addr, uint64_t Index, const llvm::Twine &Name="")
Given addr = [n x T]* ... produce name = getelementptr inbounds addr, i64 0, i64 index where i64 is a...
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
RecordArgABI
Specify how one should pass an argument of a record type.
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
FunctionType::ExtInfo getExtInfo() const
ABIArgInfo & getReturnInfo()
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
unsigned getNumRequiredArgs() const
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
See CGDebugInfo::addInstToCurrentSourceAtom.
This class organizes the cross-function state that is used while generating LLVM code.
CodeGenTypes & getTypes()
const CodeGenOptions & getCodeGenOpts() const
DefaultABIInfo - The default implementation for ABI specific details.
CallingConv getCC() const
field_range fields() const
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
bool isComplexType() const
isComplexType() does not include complex integers (a GCC extension).
bool isUnsignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is unsigned or an enumeration types whose underlying ...
const T * castAs() const
Member-template castAs<specific type>.
bool isScalarType() const
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isStructureOrClassType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
RValue emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign, AggValueSlot Slot, bool ForceRightAdjust=false)
Emit va_arg for a platform using the common void* representation, where arguments are simply emitted ...
bool isAggregateTypeForABI(QualType T)
QualType useFirstFieldIfTransparentUnion(QualType Ty)
Pass transparent unions as if they were the type of the first element.
std::unique_ptr< TargetCodeGenInfo > createRISCVTargetCodeGenInfo(CodeGenModule &CGM, unsigned XLen, unsigned FLen, bool EABI)
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
bool Load(InterpState &S, CodePtr OpPC)
PRESERVE_NONE bool Ret(InterpState &S, CodePtr &PC)
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Result
The result type of a method or function.
U cast(CodeGen::Address addr)