xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/Targets/Mips.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===- Mips.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 // MIPS ABI Implementation.  This works for both little-endian and
17 // big-endian variants.
18 //===----------------------------------------------------------------------===//
19 
20 namespace {
21 class MipsABIInfo : public ABIInfo {
22   bool IsO32;
23   const unsigned MinABIStackAlignInBytes, StackAlignInBytes;
24   void CoerceToIntArgs(uint64_t TySize,
25                        SmallVectorImpl<llvm::Type *> &ArgList) const;
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;
29 public:
MipsABIInfo(CodeGenTypes & CGT,bool _IsO32)30   MipsABIInfo(CodeGenTypes &CGT, bool _IsO32) :
31     ABIInfo(CGT), IsO32(_IsO32), MinABIStackAlignInBytes(IsO32 ? 4 : 8),
32     StackAlignInBytes(IsO32 ? 8 : 16) {}
33 
34   ABIArgInfo classifyReturnType(QualType RetTy) const;
35   ABIArgInfo classifyArgumentType(QualType RetTy, uint64_t &Offset) const;
36   void computeInfo(CGFunctionInfo &FI) const override;
37   RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
38                    AggValueSlot Slot) const override;
39   ABIArgInfo extendType(QualType Ty) const;
40 };
41 
42 class MIPSTargetCodeGenInfo : public TargetCodeGenInfo {
43   unsigned SizeOfUnwindException;
44 public:
MIPSTargetCodeGenInfo(CodeGenTypes & CGT,bool IsO32)45   MIPSTargetCodeGenInfo(CodeGenTypes &CGT, bool IsO32)
46       : TargetCodeGenInfo(std::make_unique<MipsABIInfo>(CGT, IsO32)),
47         SizeOfUnwindException(IsO32 ? 24 : 32) {}
48 
getDwarfEHStackPointer(CodeGen::CodeGenModule & CGM) const49   int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override {
50     return 29;
51   }
52 
setTargetAttributes(const Decl * D,llvm::GlobalValue * GV,CodeGen::CodeGenModule & CGM) const53   void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
54                            CodeGen::CodeGenModule &CGM) const override {
55     const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
56     if (!FD) return;
57     llvm::Function *Fn = cast<llvm::Function>(GV);
58 
59     if (FD->hasAttr<MipsLongCallAttr>())
60       Fn->addFnAttr("long-call");
61     else if (FD->hasAttr<MipsShortCallAttr>())
62       Fn->addFnAttr("short-call");
63 
64     // Other attributes do not have a meaning for declarations.
65     if (GV->isDeclaration())
66       return;
67 
68     if (FD->hasAttr<Mips16Attr>()) {
69       Fn->addFnAttr("mips16");
70     }
71     else if (FD->hasAttr<NoMips16Attr>()) {
72       Fn->addFnAttr("nomips16");
73     }
74 
75     if (FD->hasAttr<MicroMipsAttr>())
76       Fn->addFnAttr("micromips");
77     else if (FD->hasAttr<NoMicroMipsAttr>())
78       Fn->addFnAttr("nomicromips");
79 
80     const MipsInterruptAttr *Attr = FD->getAttr<MipsInterruptAttr>();
81     if (!Attr)
82       return;
83 
84     const char *Kind;
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;
95     }
96 
97     Fn->addFnAttr("interrupt", Kind);
98 
99   }
100 
101   bool initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
102                                llvm::Value *Address) const override;
103 
getSizeOfUnwindException() const104   unsigned getSizeOfUnwindException() const override {
105     return SizeOfUnwindException;
106   }
107 };
108 
109 class WindowsMIPSTargetCodeGenInfo : public MIPSTargetCodeGenInfo {
110 public:
WindowsMIPSTargetCodeGenInfo(CodeGenTypes & CGT,bool IsO32)111   WindowsMIPSTargetCodeGenInfo(CodeGenTypes &CGT, bool IsO32)
112       : MIPSTargetCodeGenInfo(CGT, IsO32) {}
113 
getDependentLibraryOption(llvm::StringRef Lib,llvm::SmallString<24> & Opt) const114   void getDependentLibraryOption(llvm::StringRef Lib,
115                                  llvm::SmallString<24> &Opt) const override {
116     Opt = "/DEFAULTLIB:";
117     Opt += qualifyWindowsLibrary(Lib);
118   }
119 
getDetectMismatchOption(llvm::StringRef Name,llvm::StringRef Value,llvm::SmallString<32> & Opt) const120   void getDetectMismatchOption(llvm::StringRef Name, llvm::StringRef Value,
121                                llvm::SmallString<32> &Opt) const override {
122     Opt = "/FAILIFMISMATCH:\"" + Name.str() + "=" + Value.str() + "\"";
123   }
124 };
125 }
126 
CoerceToIntArgs(uint64_t TySize,SmallVectorImpl<llvm::Type * > & ArgList) const127 void MipsABIInfo::CoerceToIntArgs(
128     uint64_t TySize, SmallVectorImpl<llvm::Type *> &ArgList) const {
129   llvm::IntegerType *IntTy =
130     llvm::IntegerType::get(getVMContext(), MinABIStackAlignInBytes * 8);
131 
132   // Add (TySize / MinABIStackAlignInBytes) args of IntTy.
133   for (unsigned N = TySize / (MinABIStackAlignInBytes * 8); N; --N)
134     ArgList.push_back(IntTy);
135 
136   // If necessary, add one more integer type to ArgList.
137   unsigned R = TySize % (MinABIStackAlignInBytes * 8);
138 
139   if (R)
140     ArgList.push_back(llvm::IntegerType::get(getVMContext(), R));
141 }
142 
143 // In N32/64, an aligned double precision floating point field is passed in
144 // a register.
HandleAggregates(QualType Ty,uint64_t TySize) const145 llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty, uint64_t TySize) const {
146   SmallVector<llvm::Type*, 8> ArgList, IntArgList;
147 
148   if (IsO32) {
149     CoerceToIntArgs(TySize, ArgList);
150     return llvm::StructType::get(getVMContext(), ArgList);
151   }
152 
153   if (Ty->isComplexType())
154     return CGT.ConvertType(Ty);
155 
156   const RecordType *RT = Ty->getAs<RecordType>();
157 
158   // Unions/vectors are passed in integer registers.
159   if (!RT || !RT->isStructureOrClassType()) {
160     CoerceToIntArgs(TySize, ArgList);
161     return llvm::StructType::get(getVMContext(), ArgList);
162   }
163 
164   const RecordDecl *RD = RT->getDecl();
165   const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
166   assert(!(TySize % 8) && "Size of structure must be multiple of 8.");
167 
168   uint64_t LastOffset = 0;
169   unsigned idx = 0;
170   llvm::IntegerType *I64 = llvm::IntegerType::get(getVMContext(), 64);
171 
172   // Iterate over fields in the struct/class and check if there are any aligned
173   // double fields.
174   for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
175        i != e; ++i, ++idx) {
176     const QualType Ty = i->getType();
177     const BuiltinType *BT = Ty->getAs<BuiltinType>();
178 
179     if (!BT || BT->getKind() != BuiltinType::Double)
180       continue;
181 
182     uint64_t Offset = Layout.getFieldOffset(idx);
183     if (Offset % 64) // Ignore doubles that are not aligned.
184       continue;
185 
186     // Add ((Offset - LastOffset) / 64) args of type i64.
187     for (unsigned j = (Offset - LastOffset) / 64; j > 0; --j)
188       ArgList.push_back(I64);
189 
190     // Add double type.
191     ArgList.push_back(llvm::Type::getDoubleTy(getVMContext()));
192     LastOffset = Offset + 64;
193   }
194 
195   CoerceToIntArgs(TySize - LastOffset, IntArgList);
196   ArgList.append(IntArgList.begin(), IntArgList.end());
197 
198   return llvm::StructType::get(getVMContext(), ArgList);
199 }
200 
getPaddingType(uint64_t OrigOffset,uint64_t Offset) const201 llvm::Type *MipsABIInfo::getPaddingType(uint64_t OrigOffset,
202                                         uint64_t Offset) const {
203   if (OrigOffset + MinABIStackAlignInBytes > Offset)
204     return nullptr;
205 
206   return llvm::IntegerType::get(getVMContext(), (Offset - OrigOffset) * 8);
207 }
208 
209 ABIArgInfo
classifyArgumentType(QualType Ty,uint64_t & Offset) const210 MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const {
211   Ty = useFirstFieldIfTransparentUnion(Ty);
212 
213   uint64_t OrigOffset = Offset;
214   uint64_t TySize = getContext().getTypeSize(Ty);
215   uint64_t Align = getContext().getTypeAlign(Ty) / 8;
216 
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;
221 
222   if (isAggregateTypeForABI(Ty) || Ty->isVectorType()) {
223     // Ignore empty aggregates.
224     if (TySize == 0)
225       return ABIArgInfo::getIgnore();
226 
227     if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
228       Offset = OrigOffset + MinABIStackAlignInBytes;
229       return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
230                                      RAA == CGCXXABI::RAA_DirectInMemory);
231     }
232 
233     // If we have reached here, aggregates are passed directly by coercing to
234     // another structure type. Padding is inserted if the offset of the
235     // aggregate is unaligned.
236     ABIArgInfo ArgInfo =
237         ABIArgInfo::getDirect(HandleAggregates(Ty, TySize), 0,
238                               getPaddingType(OrigOffset, CurrOffset));
239     ArgInfo.setInReg(true);
240     return ArgInfo;
241   }
242 
243   // Treat an enum type as its underlying type.
244   if (const EnumType *EnumTy = Ty->getAs<EnumType>())
245     Ty = EnumTy->getDecl()->getIntegerType();
246 
247   // Make sure we pass indirectly things that are too large.
248   if (const auto *EIT = Ty->getAs<BitIntType>())
249     if (EIT->getNumBits() > 128 ||
250         (EIT->getNumBits() > 64 &&
251          !getContext().getTargetInfo().hasInt128Type()))
252       return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
253 
254   // All integral types are promoted to the GPR width.
255   if (Ty->isIntegralOrEnumerationType())
256     return extendType(Ty);
257 
258   return ABIArgInfo::getDirect(
259       nullptr, 0, IsO32 ? nullptr : getPaddingType(OrigOffset, CurrOffset));
260 }
261 
262 llvm::Type*
returnAggregateInRegs(QualType RetTy,uint64_t Size) const263 MipsABIInfo::returnAggregateInRegs(QualType RetTy, uint64_t Size) const {
264   const RecordType *RT = RetTy->getAs<RecordType>();
265   SmallVector<llvm::Type*, 8> RTList;
266 
267   if (RT && RT->isStructureOrClassType()) {
268     const RecordDecl *RD = RT->getDecl();
269     const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
270     unsigned FieldCnt = Layout.getFieldCount();
271 
272     // N32/64 returns struct/classes in floating point registers if the
273     // following conditions are met:
274     // 1. The size of the struct/class is no larger than 128-bit.
275     // 2. The struct/class has one or two fields all of which are floating
276     //    point types.
277     // 3. The offset of the first field is zero (this follows what gcc does).
278     //
279     // Any other composite results are returned in integer registers.
280     //
281     if (FieldCnt && (FieldCnt <= 2) && !Layout.getFieldOffset(0)) {
282       RecordDecl::field_iterator b = RD->field_begin(), e = RD->field_end();
283       for (; b != e; ++b) {
284         const BuiltinType *BT = b->getType()->getAs<BuiltinType>();
285 
286         if (!BT || !BT->isFloatingPoint())
287           break;
288 
289         RTList.push_back(CGT.ConvertType(b->getType()));
290       }
291 
292       if (b == e)
293         return llvm::StructType::get(getVMContext(), RTList,
294                                      RD->hasAttr<PackedAttr>());
295 
296       RTList.clear();
297     }
298   }
299 
300   CoerceToIntArgs(Size, RTList);
301   return llvm::StructType::get(getVMContext(), RTList);
302 }
303 
classifyReturnType(QualType RetTy) const304 ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const {
305   uint64_t Size = getContext().getTypeSize(RetTy);
306 
307   if (RetTy->isVoidType())
308     return ABIArgInfo::getIgnore();
309 
310   // O32 doesn't treat zero-sized structs differently from other structs.
311   // However, N32/N64 ignores zero sized return values.
312   if (!IsO32 && Size == 0)
313     return ABIArgInfo::getIgnore();
314 
315   if (isAggregateTypeForABI(RetTy) || RetTy->isVectorType()) {
316     if (Size <= 128) {
317       if (RetTy->isAnyComplexType())
318         return ABIArgInfo::getDirect();
319 
320       // O32 returns integer vectors in registers and N32/N64 returns all small
321       // aggregates in registers.
322       if (!IsO32 ||
323           (RetTy->isVectorType() && !RetTy->hasFloatingRepresentation())) {
324         ABIArgInfo ArgInfo =
325             ABIArgInfo::getDirect(returnAggregateInRegs(RetTy, Size));
326         ArgInfo.setInReg(true);
327         return ArgInfo;
328       }
329     }
330 
331     return getNaturalAlignIndirect(RetTy, getDataLayout().getAllocaAddrSpace());
332   }
333 
334   // Treat an enum type as its underlying type.
335   if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
336     RetTy = EnumTy->getDecl()->getIntegerType();
337 
338   // Make sure we pass indirectly things that are too large.
339   if (const auto *EIT = RetTy->getAs<BitIntType>())
340     if (EIT->getNumBits() > 128 ||
341         (EIT->getNumBits() > 64 &&
342          !getContext().getTargetInfo().hasInt128Type()))
343       return getNaturalAlignIndirect(RetTy,
344                                      getDataLayout().getAllocaAddrSpace());
345 
346   if (isPromotableIntegerTypeForABI(RetTy))
347     return ABIArgInfo::getExtend(RetTy);
348 
349   if ((RetTy->isUnsignedIntegerOrEnumerationType() ||
350       RetTy->isSignedIntegerOrEnumerationType()) && Size == 32 && !IsO32)
351     return ABIArgInfo::getSignExtend(RetTy);
352 
353   return ABIArgInfo::getDirect();
354 }
355 
computeInfo(CGFunctionInfo & FI) const356 void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const {
357   ABIArgInfo &RetInfo = FI.getReturnInfo();
358   if (!getCXXABI().classifyReturnType(FI))
359     RetInfo = classifyReturnType(FI.getReturnType());
360 
361   // Check if a pointer to an aggregate is passed as a hidden argument.
362   uint64_t Offset = RetInfo.isIndirect() ? MinABIStackAlignInBytes : 0;
363 
364   for (auto &I : FI.arguments())
365     I.info = classifyArgumentType(I.type, Offset);
366 }
367 
EmitVAArg(CodeGenFunction & CGF,Address VAListAddr,QualType OrigTy,AggValueSlot Slot) const368 RValue MipsABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
369                               QualType OrigTy, AggValueSlot Slot) const {
370   QualType Ty = OrigTy;
371 
372   // Integer arguments are promoted to 32-bit on O32 and 64-bit on N32/N64.
373   // Pointers are also promoted in the same way but this only matters for N32.
374   unsigned SlotSizeInBits = IsO32 ? 32 : 64;
375   unsigned PtrWidth = getTarget().getPointerWidth(LangAS::Default);
376   bool DidPromote = false;
377   if ((Ty->isIntegerType() &&
378           getContext().getIntWidth(Ty) < SlotSizeInBits) ||
379       (Ty->isPointerType() && PtrWidth < SlotSizeInBits)) {
380     DidPromote = true;
381     Ty = getContext().getIntTypeForBitwidth(SlotSizeInBits,
382                                             Ty->isSignedIntegerType());
383   }
384 
385   auto TyInfo = getContext().getTypeInfoInChars(Ty);
386 
387   // The alignment of things in the argument area is never larger than
388   // StackAlignInBytes.
389   TyInfo.Align =
390     std::min(TyInfo.Align, CharUnits::fromQuantity(StackAlignInBytes));
391 
392   // MinABIStackAlignInBytes is the size of argument slots on the stack.
393   CharUnits ArgSlotSize = CharUnits::fromQuantity(MinABIStackAlignInBytes);
394 
395   RValue Res = emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false, TyInfo,
396                                 ArgSlotSize, /*AllowHigherAlign*/ true, Slot);
397 
398   // If there was a promotion, "unpromote".
399   // TODO: can we just use a pointer into a subset of the original slot?
400   if (DidPromote) {
401     llvm::Type *ValTy = CGF.ConvertType(OrigTy);
402     llvm::Value *Promoted = Res.getScalarVal();
403 
404     // Truncate down to the right width.
405     llvm::Type *IntTy = (OrigTy->isIntegerType() ? ValTy : CGF.IntPtrTy);
406     llvm::Value *V = CGF.Builder.CreateTrunc(Promoted, IntTy);
407     if (OrigTy->isPointerType())
408       V = CGF.Builder.CreateIntToPtr(V, ValTy);
409 
410     return RValue::get(V);
411   }
412 
413   return Res;
414 }
415 
extendType(QualType Ty) const416 ABIArgInfo MipsABIInfo::extendType(QualType Ty) const {
417   int TySize = getContext().getTypeSize(Ty);
418 
419   // MIPS64 ABI requires unsigned 32 bit integers to be sign extended.
420   if (Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32)
421     return ABIArgInfo::getSignExtend(Ty);
422 
423   return ABIArgInfo::getExtend(Ty);
424 }
425 
426 bool
initDwarfEHRegSizeTable(CodeGen::CodeGenFunction & CGF,llvm::Value * Address) const427 MIPSTargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
428                                                llvm::Value *Address) const {
429   // This information comes from gcc's implementation, which seems to
430   // as canonical as it gets.
431 
432   // Everything on MIPS is 4 bytes.  Double-precision FP registers
433   // are aliased to pairs of single-precision FP registers.
434   llvm::Value *Four8 = llvm::ConstantInt::get(CGF.Int8Ty, 4);
435 
436   // 0-31 are the general purpose registers, $0 - $31.
437   // 32-63 are the floating-point registers, $f0 - $f31.
438   // 64 and 65 are the multiply/divide registers, $hi and $lo.
439   // 66 is the (notional, I think) register for signal-handler return.
440   AssignToArrayRange(CGF.Builder, Address, Four8, 0, 65);
441 
442   // 67-74 are the floating-point status registers, $fcc0 - $fcc7.
443   // They are one bit wide and ignored here.
444 
445   // 80-111 are the coprocessor 0 registers, $c0r0 - $c0r31.
446   // (coprocessor 1 is the FP unit)
447   // 112-143 are the coprocessor 2 registers, $c2r0 - $c2r31.
448   // 144-175 are the coprocessor 3 registers, $c3r0 - $c3r31.
449   // 176-181 are the DSP accumulator registers.
450   AssignToArrayRange(CGF.Builder, Address, Four8, 80, 181);
451   return false;
452 }
453 
454 std::unique_ptr<TargetCodeGenInfo>
createMIPSTargetCodeGenInfo(CodeGenModule & CGM,bool IsOS32)455 CodeGen::createMIPSTargetCodeGenInfo(CodeGenModule &CGM, bool IsOS32) {
456   return std::make_unique<MIPSTargetCodeGenInfo>(CGM.getTypes(), IsOS32);
457 }
458 
459 std::unique_ptr<TargetCodeGenInfo>
createWindowsMIPSTargetCodeGenInfo(CodeGenModule & CGM,bool IsOS32)460 CodeGen::createWindowsMIPSTargetCodeGenInfo(CodeGenModule &CGM, bool IsOS32) {
461   return std::make_unique<WindowsMIPSTargetCodeGenInfo>(CGM.getTypes(), IsOS32);
462 }
463