xref: /llvm-project/clang/lib/CodeGen/Targets/Mips.cpp (revision 71d6287f5b1e65466de5fe5c093852fa7903cdbe)
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:
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:
45   MIPSTargetCodeGenInfo(CodeGenTypes &CGT, bool IsO32)
46       : TargetCodeGenInfo(std::make_unique<MipsABIInfo>(CGT, IsO32)),
47         SizeOfUnwindException(IsO32 ? 24 : 32) {}
48 
49   int getDwarfEHStackPointer(CodeGen::CodeGenModule &CGM) const override {
50     return 29;
51   }
52 
53   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 
104   unsigned getSizeOfUnwindException() const override {
105     return SizeOfUnwindException;
106   }
107 };
108 
109 class WindowsMIPSTargetCodeGenInfo : public MIPSTargetCodeGenInfo {
110 public:
111   WindowsMIPSTargetCodeGenInfo(CodeGenTypes &CGT, bool IsO32)
112       : MIPSTargetCodeGenInfo(CGT, IsO32) {}
113 
114   void getDependentLibraryOption(llvm::StringRef Lib,
115                                  llvm::SmallString<24> &Opt) const override {
116     Opt = "/DEFAULTLIB:";
117     Opt += qualifyWindowsLibrary(Lib);
118   }
119 
120   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 
127 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.
145 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 
201 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
210 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, RAA == CGCXXABI::RAA_DirectInMemory);
230     }
231 
232     // If we have reached here, aggregates are passed directly by coercing to
233     // another structure type. Padding is inserted if the offset of the
234     // aggregate is unaligned.
235     ABIArgInfo ArgInfo =
236         ABIArgInfo::getDirect(HandleAggregates(Ty, TySize), 0,
237                               getPaddingType(OrigOffset, CurrOffset));
238     ArgInfo.setInReg(true);
239     return ArgInfo;
240   }
241 
242   // Treat an enum type as its underlying type.
243   if (const EnumType *EnumTy = Ty->getAs<EnumType>())
244     Ty = EnumTy->getDecl()->getIntegerType();
245 
246   // Make sure we pass indirectly things that are too large.
247   if (const auto *EIT = Ty->getAs<BitIntType>())
248     if (EIT->getNumBits() > 128 ||
249         (EIT->getNumBits() > 64 &&
250          !getContext().getTargetInfo().hasInt128Type()))
251       return getNaturalAlignIndirect(Ty);
252 
253   // All integral types are promoted to the GPR width.
254   if (Ty->isIntegralOrEnumerationType())
255     return extendType(Ty);
256 
257   return ABIArgInfo::getDirect(
258       nullptr, 0, IsO32 ? nullptr : getPaddingType(OrigOffset, CurrOffset));
259 }
260 
261 llvm::Type*
262 MipsABIInfo::returnAggregateInRegs(QualType RetTy, uint64_t Size) const {
263   const RecordType *RT = RetTy->getAs<RecordType>();
264   SmallVector<llvm::Type*, 8> RTList;
265 
266   if (RT && RT->isStructureOrClassType()) {
267     const RecordDecl *RD = RT->getDecl();
268     const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
269     unsigned FieldCnt = Layout.getFieldCount();
270 
271     // N32/64 returns struct/classes in floating point registers if the
272     // following conditions are met:
273     // 1. The size of the struct/class is no larger than 128-bit.
274     // 2. The struct/class has one or two fields all of which are floating
275     //    point types.
276     // 3. The offset of the first field is zero (this follows what gcc does).
277     //
278     // Any other composite results are returned in integer registers.
279     //
280     if (FieldCnt && (FieldCnt <= 2) && !Layout.getFieldOffset(0)) {
281       RecordDecl::field_iterator b = RD->field_begin(), e = RD->field_end();
282       for (; b != e; ++b) {
283         const BuiltinType *BT = b->getType()->getAs<BuiltinType>();
284 
285         if (!BT || !BT->isFloatingPoint())
286           break;
287 
288         RTList.push_back(CGT.ConvertType(b->getType()));
289       }
290 
291       if (b == e)
292         return llvm::StructType::get(getVMContext(), RTList,
293                                      RD->hasAttr<PackedAttr>());
294 
295       RTList.clear();
296     }
297   }
298 
299   CoerceToIntArgs(Size, RTList);
300   return llvm::StructType::get(getVMContext(), RTList);
301 }
302 
303 ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const {
304   uint64_t Size = getContext().getTypeSize(RetTy);
305 
306   if (RetTy->isVoidType())
307     return ABIArgInfo::getIgnore();
308 
309   // O32 doesn't treat zero-sized structs differently from other structs.
310   // However, N32/N64 ignores zero sized return values.
311   if (!IsO32 && Size == 0)
312     return ABIArgInfo::getIgnore();
313 
314   if (isAggregateTypeForABI(RetTy) || RetTy->isVectorType()) {
315     if (Size <= 128) {
316       if (RetTy->isAnyComplexType())
317         return ABIArgInfo::getDirect();
318 
319       // O32 returns integer vectors in registers and N32/N64 returns all small
320       // aggregates in registers.
321       if (!IsO32 ||
322           (RetTy->isVectorType() && !RetTy->hasFloatingRepresentation())) {
323         ABIArgInfo ArgInfo =
324             ABIArgInfo::getDirect(returnAggregateInRegs(RetTy, Size));
325         ArgInfo.setInReg(true);
326         return ArgInfo;
327       }
328     }
329 
330     return getNaturalAlignIndirect(RetTy);
331   }
332 
333   // Treat an enum type as its underlying type.
334   if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
335     RetTy = EnumTy->getDecl()->getIntegerType();
336 
337   // Make sure we pass indirectly things that are too large.
338   if (const auto *EIT = RetTy->getAs<BitIntType>())
339     if (EIT->getNumBits() > 128 ||
340         (EIT->getNumBits() > 64 &&
341          !getContext().getTargetInfo().hasInt128Type()))
342       return getNaturalAlignIndirect(RetTy);
343 
344   if (isPromotableIntegerTypeForABI(RetTy))
345     return ABIArgInfo::getExtend(RetTy);
346 
347   if ((RetTy->isUnsignedIntegerOrEnumerationType() ||
348       RetTy->isSignedIntegerOrEnumerationType()) && Size == 32 && !IsO32)
349     return ABIArgInfo::getSignExtend(RetTy);
350 
351   return ABIArgInfo::getDirect();
352 }
353 
354 void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const {
355   ABIArgInfo &RetInfo = FI.getReturnInfo();
356   if (!getCXXABI().classifyReturnType(FI))
357     RetInfo = classifyReturnType(FI.getReturnType());
358 
359   // Check if a pointer to an aggregate is passed as a hidden argument.
360   uint64_t Offset = RetInfo.isIndirect() ? MinABIStackAlignInBytes : 0;
361 
362   for (auto &I : FI.arguments())
363     I.info = classifyArgumentType(I.type, Offset);
364 }
365 
366 RValue MipsABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
367                               QualType OrigTy, AggValueSlot Slot) const {
368   QualType Ty = OrigTy;
369 
370   // Integer arguments are promoted to 32-bit on O32 and 64-bit on N32/N64.
371   // Pointers are also promoted in the same way but this only matters for N32.
372   unsigned SlotSizeInBits = IsO32 ? 32 : 64;
373   unsigned PtrWidth = getTarget().getPointerWidth(LangAS::Default);
374   bool DidPromote = false;
375   if ((Ty->isIntegerType() &&
376           getContext().getIntWidth(Ty) < SlotSizeInBits) ||
377       (Ty->isPointerType() && PtrWidth < SlotSizeInBits)) {
378     DidPromote = true;
379     Ty = getContext().getIntTypeForBitwidth(SlotSizeInBits,
380                                             Ty->isSignedIntegerType());
381   }
382 
383   auto TyInfo = getContext().getTypeInfoInChars(Ty);
384 
385   // The alignment of things in the argument area is never larger than
386   // StackAlignInBytes.
387   TyInfo.Align =
388     std::min(TyInfo.Align, CharUnits::fromQuantity(StackAlignInBytes));
389 
390   // MinABIStackAlignInBytes is the size of argument slots on the stack.
391   CharUnits ArgSlotSize = CharUnits::fromQuantity(MinABIStackAlignInBytes);
392 
393   RValue Res = emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false, TyInfo,
394                                 ArgSlotSize, /*AllowHigherAlign*/ true, Slot);
395 
396   // If there was a promotion, "unpromote".
397   // TODO: can we just use a pointer into a subset of the original slot?
398   if (DidPromote) {
399     llvm::Type *ValTy = CGF.ConvertType(OrigTy);
400     llvm::Value *Promoted = Res.getScalarVal();
401 
402     // Truncate down to the right width.
403     llvm::Type *IntTy = (OrigTy->isIntegerType() ? ValTy : CGF.IntPtrTy);
404     llvm::Value *V = CGF.Builder.CreateTrunc(Promoted, IntTy);
405     if (OrigTy->isPointerType())
406       V = CGF.Builder.CreateIntToPtr(V, ValTy);
407 
408     return RValue::get(V);
409   }
410 
411   return Res;
412 }
413 
414 ABIArgInfo MipsABIInfo::extendType(QualType Ty) const {
415   int TySize = getContext().getTypeSize(Ty);
416 
417   // MIPS64 ABI requires unsigned 32 bit integers to be sign extended.
418   if (Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32)
419     return ABIArgInfo::getSignExtend(Ty);
420 
421   return ABIArgInfo::getExtend(Ty);
422 }
423 
424 bool
425 MIPSTargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
426                                                llvm::Value *Address) const {
427   // This information comes from gcc's implementation, which seems to
428   // as canonical as it gets.
429 
430   // Everything on MIPS is 4 bytes.  Double-precision FP registers
431   // are aliased to pairs of single-precision FP registers.
432   llvm::Value *Four8 = llvm::ConstantInt::get(CGF.Int8Ty, 4);
433 
434   // 0-31 are the general purpose registers, $0 - $31.
435   // 32-63 are the floating-point registers, $f0 - $f31.
436   // 64 and 65 are the multiply/divide registers, $hi and $lo.
437   // 66 is the (notional, I think) register for signal-handler return.
438   AssignToArrayRange(CGF.Builder, Address, Four8, 0, 65);
439 
440   // 67-74 are the floating-point status registers, $fcc0 - $fcc7.
441   // They are one bit wide and ignored here.
442 
443   // 80-111 are the coprocessor 0 registers, $c0r0 - $c0r31.
444   // (coprocessor 1 is the FP unit)
445   // 112-143 are the coprocessor 2 registers, $c2r0 - $c2r31.
446   // 144-175 are the coprocessor 3 registers, $c3r0 - $c3r31.
447   // 176-181 are the DSP accumulator registers.
448   AssignToArrayRange(CGF.Builder, Address, Four8, 80, 181);
449   return false;
450 }
451 
452 std::unique_ptr<TargetCodeGenInfo>
453 CodeGen::createMIPSTargetCodeGenInfo(CodeGenModule &CGM, bool IsOS32) {
454   return std::make_unique<MIPSTargetCodeGenInfo>(CGM.getTypes(), IsOS32);
455 }
456 
457 std::unique_ptr<TargetCodeGenInfo>
458 CodeGen::createWindowsMIPSTargetCodeGenInfo(CodeGenModule &CGM, bool IsOS32) {
459   return std::make_unique<WindowsMIPSTargetCodeGenInfo>(CGM.getTypes(), IsOS32);
460 }
461