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
CoerceToIntArgs(uint64_t TySize,SmallVectorImpl<llvm::Type * > & ArgList) const110 void MipsABIInfo::CoerceToIntArgs(
111 uint64_t TySize, SmallVectorImpl<llvm::Type *> &ArgList) const {
112 llvm::IntegerType *IntTy =
113 llvm::IntegerType::get(getVMContext(), MinABIStackAlignInBytes * 8);
114
115 // Add (TySize / MinABIStackAlignInBytes) args of IntTy.
116 for (unsigned N = TySize / (MinABIStackAlignInBytes * 8); N; --N)
117 ArgList.push_back(IntTy);
118
119 // If necessary, add one more integer type to ArgList.
120 unsigned R = TySize % (MinABIStackAlignInBytes * 8);
121
122 if (R)
123 ArgList.push_back(llvm::IntegerType::get(getVMContext(), R));
124 }
125
126 // In N32/64, an aligned double precision floating point field is passed in
127 // a register.
HandleAggregates(QualType Ty,uint64_t TySize) const128 llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty, uint64_t TySize) const {
129 SmallVector<llvm::Type*, 8> ArgList, IntArgList;
130
131 if (IsO32) {
132 CoerceToIntArgs(TySize, ArgList);
133 return llvm::StructType::get(getVMContext(), ArgList);
134 }
135
136 if (Ty->isComplexType())
137 return CGT.ConvertType(Ty);
138
139 const RecordType *RT = Ty->getAs<RecordType>();
140
141 // Unions/vectors are passed in integer registers.
142 if (!RT || !RT->isStructureOrClassType()) {
143 CoerceToIntArgs(TySize, ArgList);
144 return llvm::StructType::get(getVMContext(), ArgList);
145 }
146
147 const RecordDecl *RD = RT->getDecl();
148 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
149 assert(!(TySize % 8) && "Size of structure must be multiple of 8.");
150
151 uint64_t LastOffset = 0;
152 unsigned idx = 0;
153 llvm::IntegerType *I64 = llvm::IntegerType::get(getVMContext(), 64);
154
155 // Iterate over fields in the struct/class and check if there are any aligned
156 // double fields.
157 for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end();
158 i != e; ++i, ++idx) {
159 const QualType Ty = i->getType();
160 const BuiltinType *BT = Ty->getAs<BuiltinType>();
161
162 if (!BT || BT->getKind() != BuiltinType::Double)
163 continue;
164
165 uint64_t Offset = Layout.getFieldOffset(idx);
166 if (Offset % 64) // Ignore doubles that are not aligned.
167 continue;
168
169 // Add ((Offset - LastOffset) / 64) args of type i64.
170 for (unsigned j = (Offset - LastOffset) / 64; j > 0; --j)
171 ArgList.push_back(I64);
172
173 // Add double type.
174 ArgList.push_back(llvm::Type::getDoubleTy(getVMContext()));
175 LastOffset = Offset + 64;
176 }
177
178 CoerceToIntArgs(TySize - LastOffset, IntArgList);
179 ArgList.append(IntArgList.begin(), IntArgList.end());
180
181 return llvm::StructType::get(getVMContext(), ArgList);
182 }
183
getPaddingType(uint64_t OrigOffset,uint64_t Offset) const184 llvm::Type *MipsABIInfo::getPaddingType(uint64_t OrigOffset,
185 uint64_t Offset) const {
186 if (OrigOffset + MinABIStackAlignInBytes > Offset)
187 return nullptr;
188
189 return llvm::IntegerType::get(getVMContext(), (Offset - OrigOffset) * 8);
190 }
191
192 ABIArgInfo
classifyArgumentType(QualType Ty,uint64_t & Offset) const193 MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const {
194 Ty = useFirstFieldIfTransparentUnion(Ty);
195
196 uint64_t OrigOffset = Offset;
197 uint64_t TySize = getContext().getTypeSize(Ty);
198 uint64_t Align = getContext().getTypeAlign(Ty) / 8;
199
200 Align = std::clamp(Align, (uint64_t)MinABIStackAlignInBytes,
201 (uint64_t)StackAlignInBytes);
202 unsigned CurrOffset = llvm::alignTo(Offset, Align);
203 Offset = CurrOffset + llvm::alignTo(TySize, Align * 8) / 8;
204
205 if (isAggregateTypeForABI(Ty) || Ty->isVectorType()) {
206 // Ignore empty aggregates.
207 if (TySize == 0)
208 return ABIArgInfo::getIgnore();
209
210 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI())) {
211 Offset = OrigOffset + MinABIStackAlignInBytes;
212 return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
213 }
214
215 // If we have reached here, aggregates are passed directly by coercing to
216 // another structure type. Padding is inserted if the offset of the
217 // aggregate is unaligned.
218 ABIArgInfo ArgInfo =
219 ABIArgInfo::getDirect(HandleAggregates(Ty, TySize), 0,
220 getPaddingType(OrigOffset, CurrOffset));
221 ArgInfo.setInReg(true);
222 return ArgInfo;
223 }
224
225 // Treat an enum type as its underlying type.
226 if (const EnumType *EnumTy = Ty->getAs<EnumType>())
227 Ty = EnumTy->getDecl()->getIntegerType();
228
229 // Make sure we pass indirectly things that are too large.
230 if (const auto *EIT = Ty->getAs<BitIntType>())
231 if (EIT->getNumBits() > 128 ||
232 (EIT->getNumBits() > 64 &&
233 !getContext().getTargetInfo().hasInt128Type()))
234 return getNaturalAlignIndirect(Ty);
235
236 // All integral types are promoted to the GPR width.
237 if (Ty->isIntegralOrEnumerationType())
238 return extendType(Ty);
239
240 return ABIArgInfo::getDirect(
241 nullptr, 0, IsO32 ? nullptr : getPaddingType(OrigOffset, CurrOffset));
242 }
243
244 llvm::Type*
returnAggregateInRegs(QualType RetTy,uint64_t Size) const245 MipsABIInfo::returnAggregateInRegs(QualType RetTy, uint64_t Size) const {
246 const RecordType *RT = RetTy->getAs<RecordType>();
247 SmallVector<llvm::Type*, 8> RTList;
248
249 if (RT && RT->isStructureOrClassType()) {
250 const RecordDecl *RD = RT->getDecl();
251 const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
252 unsigned FieldCnt = Layout.getFieldCount();
253
254 // N32/64 returns struct/classes in floating point registers if the
255 // following conditions are met:
256 // 1. The size of the struct/class is no larger than 128-bit.
257 // 2. The struct/class has one or two fields all of which are floating
258 // point types.
259 // 3. The offset of the first field is zero (this follows what gcc does).
260 //
261 // Any other composite results are returned in integer registers.
262 //
263 if (FieldCnt && (FieldCnt <= 2) && !Layout.getFieldOffset(0)) {
264 RecordDecl::field_iterator b = RD->field_begin(), e = RD->field_end();
265 for (; b != e; ++b) {
266 const BuiltinType *BT = b->getType()->getAs<BuiltinType>();
267
268 if (!BT || !BT->isFloatingPoint())
269 break;
270
271 RTList.push_back(CGT.ConvertType(b->getType()));
272 }
273
274 if (b == e)
275 return llvm::StructType::get(getVMContext(), RTList,
276 RD->hasAttr<PackedAttr>());
277
278 RTList.clear();
279 }
280 }
281
282 CoerceToIntArgs(Size, RTList);
283 return llvm::StructType::get(getVMContext(), RTList);
284 }
285
classifyReturnType(QualType RetTy) const286 ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const {
287 uint64_t Size = getContext().getTypeSize(RetTy);
288
289 if (RetTy->isVoidType())
290 return ABIArgInfo::getIgnore();
291
292 // O32 doesn't treat zero-sized structs differently from other structs.
293 // However, N32/N64 ignores zero sized return values.
294 if (!IsO32 && Size == 0)
295 return ABIArgInfo::getIgnore();
296
297 if (isAggregateTypeForABI(RetTy) || RetTy->isVectorType()) {
298 if (Size <= 128) {
299 if (RetTy->isAnyComplexType())
300 return ABIArgInfo::getDirect();
301
302 // O32 returns integer vectors in registers and N32/N64 returns all small
303 // aggregates in registers.
304 if (!IsO32 ||
305 (RetTy->isVectorType() && !RetTy->hasFloatingRepresentation())) {
306 ABIArgInfo ArgInfo =
307 ABIArgInfo::getDirect(returnAggregateInRegs(RetTy, Size));
308 ArgInfo.setInReg(true);
309 return ArgInfo;
310 }
311 }
312
313 return getNaturalAlignIndirect(RetTy);
314 }
315
316 // Treat an enum type as its underlying type.
317 if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
318 RetTy = EnumTy->getDecl()->getIntegerType();
319
320 // Make sure we pass indirectly things that are too large.
321 if (const auto *EIT = RetTy->getAs<BitIntType>())
322 if (EIT->getNumBits() > 128 ||
323 (EIT->getNumBits() > 64 &&
324 !getContext().getTargetInfo().hasInt128Type()))
325 return getNaturalAlignIndirect(RetTy);
326
327 if (isPromotableIntegerTypeForABI(RetTy))
328 return ABIArgInfo::getExtend(RetTy);
329
330 if ((RetTy->isUnsignedIntegerOrEnumerationType() ||
331 RetTy->isSignedIntegerOrEnumerationType()) && Size == 32 && !IsO32)
332 return ABIArgInfo::getSignExtend(RetTy);
333
334 return ABIArgInfo::getDirect();
335 }
336
computeInfo(CGFunctionInfo & FI) const337 void MipsABIInfo::computeInfo(CGFunctionInfo &FI) const {
338 ABIArgInfo &RetInfo = FI.getReturnInfo();
339 if (!getCXXABI().classifyReturnType(FI))
340 RetInfo = classifyReturnType(FI.getReturnType());
341
342 // Check if a pointer to an aggregate is passed as a hidden argument.
343 uint64_t Offset = RetInfo.isIndirect() ? MinABIStackAlignInBytes : 0;
344
345 for (auto &I : FI.arguments())
346 I.info = classifyArgumentType(I.type, Offset);
347 }
348
EmitVAArg(CodeGenFunction & CGF,Address VAListAddr,QualType OrigTy,AggValueSlot Slot) const349 RValue MipsABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
350 QualType OrigTy, AggValueSlot Slot) const {
351 QualType Ty = OrigTy;
352
353 // Integer arguments are promoted to 32-bit on O32 and 64-bit on N32/N64.
354 // Pointers are also promoted in the same way but this only matters for N32.
355 unsigned SlotSizeInBits = IsO32 ? 32 : 64;
356 unsigned PtrWidth = getTarget().getPointerWidth(LangAS::Default);
357 bool DidPromote = false;
358 if ((Ty->isIntegerType() &&
359 getContext().getIntWidth(Ty) < SlotSizeInBits) ||
360 (Ty->isPointerType() && PtrWidth < SlotSizeInBits)) {
361 DidPromote = true;
362 Ty = getContext().getIntTypeForBitwidth(SlotSizeInBits,
363 Ty->isSignedIntegerType());
364 }
365
366 auto TyInfo = getContext().getTypeInfoInChars(Ty);
367
368 // The alignment of things in the argument area is never larger than
369 // StackAlignInBytes.
370 TyInfo.Align =
371 std::min(TyInfo.Align, CharUnits::fromQuantity(StackAlignInBytes));
372
373 // MinABIStackAlignInBytes is the size of argument slots on the stack.
374 CharUnits ArgSlotSize = CharUnits::fromQuantity(MinABIStackAlignInBytes);
375
376 RValue Res = emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false, TyInfo,
377 ArgSlotSize, /*AllowHigherAlign*/ true, Slot);
378
379 // If there was a promotion, "unpromote".
380 // TODO: can we just use a pointer into a subset of the original slot?
381 if (DidPromote) {
382 llvm::Type *ValTy = CGF.ConvertType(OrigTy);
383 llvm::Value *Promoted = Res.getScalarVal();
384
385 // Truncate down to the right width.
386 llvm::Type *IntTy = (OrigTy->isIntegerType() ? ValTy : CGF.IntPtrTy);
387 llvm::Value *V = CGF.Builder.CreateTrunc(Promoted, IntTy);
388 if (OrigTy->isPointerType())
389 V = CGF.Builder.CreateIntToPtr(V, ValTy);
390
391 return RValue::get(V);
392 }
393
394 return Res;
395 }
396
extendType(QualType Ty) const397 ABIArgInfo MipsABIInfo::extendType(QualType Ty) const {
398 int TySize = getContext().getTypeSize(Ty);
399
400 // MIPS64 ABI requires unsigned 32 bit integers to be sign extended.
401 if (Ty->isUnsignedIntegerOrEnumerationType() && TySize == 32)
402 return ABIArgInfo::getSignExtend(Ty);
403
404 return ABIArgInfo::getExtend(Ty);
405 }
406
407 bool
initDwarfEHRegSizeTable(CodeGen::CodeGenFunction & CGF,llvm::Value * Address) const408 MIPSTargetCodeGenInfo::initDwarfEHRegSizeTable(CodeGen::CodeGenFunction &CGF,
409 llvm::Value *Address) const {
410 // This information comes from gcc's implementation, which seems to
411 // as canonical as it gets.
412
413 // Everything on MIPS is 4 bytes. Double-precision FP registers
414 // are aliased to pairs of single-precision FP registers.
415 llvm::Value *Four8 = llvm::ConstantInt::get(CGF.Int8Ty, 4);
416
417 // 0-31 are the general purpose registers, $0 - $31.
418 // 32-63 are the floating-point registers, $f0 - $f31.
419 // 64 and 65 are the multiply/divide registers, $hi and $lo.
420 // 66 is the (notional, I think) register for signal-handler return.
421 AssignToArrayRange(CGF.Builder, Address, Four8, 0, 65);
422
423 // 67-74 are the floating-point status registers, $fcc0 - $fcc7.
424 // They are one bit wide and ignored here.
425
426 // 80-111 are the coprocessor 0 registers, $c0r0 - $c0r31.
427 // (coprocessor 1 is the FP unit)
428 // 112-143 are the coprocessor 2 registers, $c2r0 - $c2r31.
429 // 144-175 are the coprocessor 3 registers, $c3r0 - $c3r31.
430 // 176-181 are the DSP accumulator registers.
431 AssignToArrayRange(CGF.Builder, Address, Four8, 80, 181);
432 return false;
433 }
434
435 std::unique_ptr<TargetCodeGenInfo>
createMIPSTargetCodeGenInfo(CodeGenModule & CGM,bool IsOS32)436 CodeGen::createMIPSTargetCodeGenInfo(CodeGenModule &CGM, bool IsOS32) {
437 return std::make_unique<MIPSTargetCodeGenInfo>(CGM.getTypes(), IsOS32);
438 }
439