10#include "TargetInfo.h"
21class MipsABIInfo :
public ABIInfo {
23 const unsigned MinABIStackAlignInBytes, StackAlignInBytes;
24 void CoerceToIntArgs(uint64_t TySize,
26 llvm::Type* HandleAggregates(
QualType Ty, uint64_t TySize)
const;
27 llvm::Type* returnAggregateInRegs(
QualType RetTy, uint64_t Size)
const;
28 llvm::Type* getPaddingType(uint64_t Align, uint64_t Offset)
const;
31 ABIInfo(CGT), IsO32(_IsO32), MinABIStackAlignInBytes(IsO32 ? 4 : 8),
32 StackAlignInBytes(IsO32 ? 8 : 16) {}
43 unsigned SizeOfUnwindException;
47 SizeOfUnwindException(IsO32 ? 24 : 32) {}
57 llvm::Function *
Fn = cast<llvm::Function>(GV);
59 if (FD->
hasAttr<MipsLongCallAttr>())
60 Fn->addFnAttr(
"long-call");
61 else if (FD->
hasAttr<MipsShortCallAttr>())
62 Fn->addFnAttr(
"short-call");
65 if (GV->isDeclaration())
68 if (FD->
hasAttr<Mips16Attr>()) {
69 Fn->addFnAttr(
"mips16");
71 else if (FD->
hasAttr<NoMips16Attr>()) {
72 Fn->addFnAttr(
"nomips16");
75 if (FD->
hasAttr<MicroMipsAttr>())
76 Fn->addFnAttr(
"micromips");
77 else if (FD->
hasAttr<NoMicroMipsAttr>())
78 Fn->addFnAttr(
"nomicromips");
80 const MipsInterruptAttr *
Attr = FD->
getAttr<MipsInterruptAttr>();
85 switch (
Attr->getInterrupt()) {
86 case MipsInterruptAttr::eic:
Kind =
"eic";
break;
87 case MipsInterruptAttr::sw0:
Kind =
"sw0";
break;
88 case MipsInterruptAttr::sw1:
Kind =
"sw1";
break;
89 case MipsInterruptAttr::hw0:
Kind =
"hw0";
break;
90 case MipsInterruptAttr::hw1:
Kind =
"hw1";
break;
91 case MipsInterruptAttr::hw2:
Kind =
"hw2";
break;
92 case MipsInterruptAttr::hw3:
Kind =
"hw3";
break;
93 case MipsInterruptAttr::hw4:
Kind =
"hw4";
break;
94 case MipsInterruptAttr::hw5:
Kind =
"hw5";
break;
97 Fn->addFnAttr(
"interrupt", Kind);
102 llvm::Value *
Address)
const override;
105 return SizeOfUnwindException;
109class WindowsMIPSTargetCodeGenInfo :
public MIPSTargetCodeGenInfo {
111 WindowsMIPSTargetCodeGenInfo(
CodeGenTypes &CGT,
bool IsO32)
112 : MIPSTargetCodeGenInfo(CGT, IsO32) {}
114 void getDependentLibraryOption(llvm::StringRef Lib,
116 Opt =
"/DEFAULTLIB:";
117 Opt += qualifyWindowsLibrary(Lib);
120 void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef
Value,
122 Opt =
"/FAILIFMISMATCH:\"" + Name.str() +
"=" +
Value.str() +
"\"";
127void MipsABIInfo::CoerceToIntArgs(
129 llvm::IntegerType *IntTy =
130 llvm::IntegerType::get(getVMContext(), MinABIStackAlignInBytes * 8);
133 for (
unsigned N = TySize / (MinABIStackAlignInBytes * 8); N; --N)
134 ArgList.push_back(IntTy);
137 unsigned R = TySize % (MinABIStackAlignInBytes * 8);
140 ArgList.push_back(llvm::IntegerType::get(getVMContext(), R));
145llvm::Type* MipsABIInfo::HandleAggregates(
QualType Ty, uint64_t TySize)
const {
149 CoerceToIntArgs(TySize, ArgList);
150 return llvm::StructType::get(getVMContext(), ArgList);
154 return CGT.ConvertType(Ty);
160 CoerceToIntArgs(TySize, ArgList);
161 return llvm::StructType::get(getVMContext(), ArgList);
166 assert(!(TySize % 8) &&
"Size of structure must be multiple of 8.");
170 llvm::IntegerType *I64 = llvm::IntegerType::get(getVMContext(), 64);
175 i != e; ++i, ++idx) {
179 if (!BT || BT->
getKind() != BuiltinType::Double)
187 for (
unsigned j = (Offset - LastOffset) / 64; j > 0; --j)
188 ArgList.push_back(I64);
191 ArgList.push_back(llvm::Type::getDoubleTy(getVMContext()));
192 LastOffset = Offset + 64;
195 CoerceToIntArgs(TySize - LastOffset, IntArgList);
196 ArgList.append(IntArgList.begin(), IntArgList.end());
198 return llvm::StructType::get(getVMContext(), ArgList);
201llvm::Type *MipsABIInfo::getPaddingType(uint64_t OrigOffset,
202 uint64_t Offset)
const {
203 if (OrigOffset + MinABIStackAlignInBytes > Offset)
206 return llvm::IntegerType::get(getVMContext(), (Offset - OrigOffset) * 8);
210MipsABIInfo::classifyArgumentType(
QualType Ty, uint64_t &Offset)
const {
214 uint64_t TySize = getContext().getTypeSize(Ty);
215 uint64_t Align = getContext().getTypeAlign(Ty) / 8;
217 Align = std::clamp(Align, (uint64_t)MinABIStackAlignInBytes,
218 (uint64_t)StackAlignInBytes);
219 unsigned CurrOffset = llvm::alignTo(Offset, Align);
220 Offset = CurrOffset + llvm::alignTo(TySize, Align * 8) / 8;
228 Offset = OrigOffset + MinABIStackAlignInBytes;
237 getPaddingType(OrigOffset, CurrOffset));
244 Ty = EnumTy->getDecl()->getIntegerType();
248 if (EIT->getNumBits() > 128 ||
249 (EIT->getNumBits() > 64 &&
250 !getContext().getTargetInfo().hasInt128Type()))
251 return getNaturalAlignIndirect(Ty);
255 return extendType(Ty);
258 nullptr, 0, IsO32 ?
nullptr : getPaddingType(OrigOffset, CurrOffset));
262MipsABIInfo::returnAggregateInRegs(
QualType RetTy, uint64_t Size)
const {
282 for (;
b != e; ++
b) {
288 RTList.push_back(CGT.ConvertType(
b->getType()));
292 return llvm::StructType::get(getVMContext(), RTList,
299 CoerceToIntArgs(Size, RTList);
300 return llvm::StructType::get(getVMContext(), RTList);
311 if (!IsO32 && Size == 0)