xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/Targets/SystemZ.cpp (revision 02e9120893770924227138ba49df1edb3896112a)
1 //===- SystemZ.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 #include "clang/Basic/Builtins.h"
12 #include "llvm/IR/IntrinsicsS390.h"
13 
14 using namespace clang;
15 using namespace clang::CodeGen;
16 
17 //===----------------------------------------------------------------------===//
18 // SystemZ ABI Implementation
19 //===----------------------------------------------------------------------===//
20 
21 namespace {
22 
23 class SystemZABIInfo : public ABIInfo {
24   bool HasVector;
25   bool IsSoftFloatABI;
26 
27 public:
28   SystemZABIInfo(CodeGenTypes &CGT, bool HV, bool SF)
29       : ABIInfo(CGT), HasVector(HV), IsSoftFloatABI(SF) {}
30 
31   bool isPromotableIntegerTypeForABI(QualType Ty) const;
32   bool isCompoundType(QualType Ty) const;
33   bool isVectorArgumentType(QualType Ty) const;
34   bool isFPArgumentType(QualType Ty) const;
35   QualType GetSingleElementType(QualType Ty) const;
36 
37   ABIArgInfo classifyReturnType(QualType RetTy) const;
38   ABIArgInfo classifyArgumentType(QualType ArgTy) const;
39 
40   void computeInfo(CGFunctionInfo &FI) const override;
41   Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
42                     QualType Ty) const override;
43 };
44 
45 class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
46   ASTContext &Ctx;
47 
48   // These are used for speeding up the search for a visible vector ABI.
49   mutable bool HasVisibleVecABIFlag = false;
50   mutable std::set<const Type *> SeenTypes;
51 
52   // Returns true (the first time) if Ty is, or is found to include, a vector
53   // type that exposes the vector ABI. This is any vector >=16 bytes which
54   // with vector support are aligned to only 8 bytes. When IsParam is true,
55   // the type belongs to a value as passed between functions. If it is a
56   // vector <=16 bytes it will be passed in a vector register (if supported).
57   bool isVectorTypeBased(const Type *Ty, bool IsParam) const;
58 
59 public:
60   SystemZTargetCodeGenInfo(CodeGenTypes &CGT, bool HasVector, bool SoftFloatABI)
61       : TargetCodeGenInfo(
62             std::make_unique<SystemZABIInfo>(CGT, HasVector, SoftFloatABI)),
63             Ctx(CGT.getContext()) {
64     SwiftInfo =
65         std::make_unique<SwiftABIInfo>(CGT, /*SwiftErrorInRegister=*/false);
66   }
67 
68   // The vector ABI is different when the vector facility is present and when
69   // a module e.g. defines an externally visible vector variable, a flag
70   // indicating a visible vector ABI is added. Eventually this will result in
71   // a GNU attribute indicating the vector ABI of the module.  Ty is the type
72   // of a variable or function parameter that is globally visible.
73   void handleExternallyVisibleObjABI(const Type *Ty, CodeGen::CodeGenModule &M,
74                                      bool IsParam) const {
75     if (!HasVisibleVecABIFlag && isVectorTypeBased(Ty, IsParam)) {
76       M.getModule().addModuleFlag(llvm::Module::Warning,
77                                   "s390x-visible-vector-ABI", 1);
78       HasVisibleVecABIFlag = true;
79     }
80   }
81 
82   void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
83                            CodeGen::CodeGenModule &M) const override {
84     if (!D)
85       return;
86 
87     // Check if the vector ABI becomes visible by an externally visible
88     // variable or function.
89     if (const auto *VD = dyn_cast<VarDecl>(D)) {
90       if (VD->isExternallyVisible())
91         handleExternallyVisibleObjABI(VD->getType().getTypePtr(), M,
92                                       /*IsParam*/false);
93     }
94     else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
95       if (FD->isExternallyVisible())
96         handleExternallyVisibleObjABI(FD->getType().getTypePtr(), M,
97                                       /*IsParam*/false);
98     }
99   }
100 
101   llvm::Value *testFPKind(llvm::Value *V, unsigned BuiltinID,
102                           CGBuilderTy &Builder,
103                           CodeGenModule &CGM) const override {
104     assert(V->getType()->isFloatingPointTy() && "V should have an FP type.");
105     // Only use TDC in constrained FP mode.
106     if (!Builder.getIsFPConstrained())
107       return nullptr;
108 
109     llvm::Type *Ty = V->getType();
110     if (Ty->isFloatTy() || Ty->isDoubleTy() || Ty->isFP128Ty()) {
111       llvm::Module &M = CGM.getModule();
112       auto &Ctx = M.getContext();
113       llvm::Function *TDCFunc =
114           llvm::Intrinsic::getDeclaration(&M, llvm::Intrinsic::s390_tdc, Ty);
115       unsigned TDCBits = 0;
116       switch (BuiltinID) {
117       case Builtin::BI__builtin_isnan:
118         TDCBits = 0xf;
119         break;
120       case Builtin::BIfinite:
121       case Builtin::BI__finite:
122       case Builtin::BIfinitef:
123       case Builtin::BI__finitef:
124       case Builtin::BIfinitel:
125       case Builtin::BI__finitel:
126       case Builtin::BI__builtin_isfinite:
127         TDCBits = 0xfc0;
128         break;
129       case Builtin::BI__builtin_isinf:
130         TDCBits = 0x30;
131         break;
132       default:
133         break;
134       }
135       if (TDCBits)
136         return Builder.CreateCall(
137             TDCFunc,
138             {V, llvm::ConstantInt::get(llvm::Type::getInt64Ty(Ctx), TDCBits)});
139     }
140     return nullptr;
141   }
142 };
143 }
144 
145 bool SystemZABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {
146   // Treat an enum type as its underlying type.
147   if (const EnumType *EnumTy = Ty->getAs<EnumType>())
148     Ty = EnumTy->getDecl()->getIntegerType();
149 
150   // Promotable integer types are required to be promoted by the ABI.
151   if (ABIInfo::isPromotableIntegerTypeForABI(Ty))
152     return true;
153 
154   if (const auto *EIT = Ty->getAs<BitIntType>())
155     if (EIT->getNumBits() < 64)
156       return true;
157 
158   // 32-bit values must also be promoted.
159   if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
160     switch (BT->getKind()) {
161     case BuiltinType::Int:
162     case BuiltinType::UInt:
163       return true;
164     default:
165       return false;
166     }
167   return false;
168 }
169 
170 bool SystemZABIInfo::isCompoundType(QualType Ty) const {
171   return (Ty->isAnyComplexType() ||
172           Ty->isVectorType() ||
173           isAggregateTypeForABI(Ty));
174 }
175 
176 bool SystemZABIInfo::isVectorArgumentType(QualType Ty) const {
177   return (HasVector &&
178           Ty->isVectorType() &&
179           getContext().getTypeSize(Ty) <= 128);
180 }
181 
182 bool SystemZABIInfo::isFPArgumentType(QualType Ty) const {
183   if (IsSoftFloatABI)
184     return false;
185 
186   if (const BuiltinType *BT = Ty->getAs<BuiltinType>())
187     switch (BT->getKind()) {
188     case BuiltinType::Float:
189     case BuiltinType::Double:
190       return true;
191     default:
192       return false;
193     }
194 
195   return false;
196 }
197 
198 QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const {
199   const RecordType *RT = Ty->getAs<RecordType>();
200 
201   if (RT && RT->isStructureOrClassType()) {
202     const RecordDecl *RD = RT->getDecl();
203     QualType Found;
204 
205     // If this is a C++ record, check the bases first.
206     if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
207       if (CXXRD->hasDefinition())
208         for (const auto &I : CXXRD->bases()) {
209           QualType Base = I.getType();
210 
211           // Empty bases don't affect things either way.
212           if (isEmptyRecord(getContext(), Base, true))
213             continue;
214 
215           if (!Found.isNull())
216             return Ty;
217           Found = GetSingleElementType(Base);
218         }
219 
220     // Check the fields.
221     for (const auto *FD : RD->fields()) {
222       // Unlike isSingleElementStruct(), empty structure and array fields
223       // do count.  So do anonymous bitfields that aren't zero-sized.
224 
225       // Like isSingleElementStruct(), ignore C++20 empty data members.
226       if (FD->hasAttr<NoUniqueAddressAttr>() &&
227           isEmptyRecord(getContext(), FD->getType(), true))
228         continue;
229 
230       // Unlike isSingleElementStruct(), arrays do not count.
231       // Nested structures still do though.
232       if (!Found.isNull())
233         return Ty;
234       Found = GetSingleElementType(FD->getType());
235     }
236 
237     // Unlike isSingleElementStruct(), trailing padding is allowed.
238     // An 8-byte aligned struct s { float f; } is passed as a double.
239     if (!Found.isNull())
240       return Found;
241   }
242 
243   return Ty;
244 }
245 
246 Address SystemZABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
247                                   QualType Ty) const {
248   // Assume that va_list type is correct; should be pointer to LLVM type:
249   // struct {
250   //   i64 __gpr;
251   //   i64 __fpr;
252   //   i8 *__overflow_arg_area;
253   //   i8 *__reg_save_area;
254   // };
255 
256   // Every non-vector argument occupies 8 bytes and is passed by preference
257   // in either GPRs or FPRs.  Vector arguments occupy 8 or 16 bytes and are
258   // always passed on the stack.
259   const SystemZTargetCodeGenInfo &SZCGI =
260       static_cast<const SystemZTargetCodeGenInfo &>(
261           CGT.getCGM().getTargetCodeGenInfo());
262   Ty = getContext().getCanonicalType(Ty);
263   auto TyInfo = getContext().getTypeInfoInChars(Ty);
264   llvm::Type *ArgTy = CGF.ConvertTypeForMem(Ty);
265   llvm::Type *DirectTy = ArgTy;
266   ABIArgInfo AI = classifyArgumentType(Ty);
267   bool IsIndirect = AI.isIndirect();
268   bool InFPRs = false;
269   bool IsVector = false;
270   CharUnits UnpaddedSize;
271   CharUnits DirectAlign;
272   SZCGI.handleExternallyVisibleObjABI(Ty.getTypePtr(), CGT.getCGM(),
273                                       /*IsParam*/true);
274   if (IsIndirect) {
275     DirectTy = llvm::PointerType::getUnqual(DirectTy);
276     UnpaddedSize = DirectAlign = CharUnits::fromQuantity(8);
277   } else {
278     if (AI.getCoerceToType())
279       ArgTy = AI.getCoerceToType();
280     InFPRs = (!IsSoftFloatABI && (ArgTy->isFloatTy() || ArgTy->isDoubleTy()));
281     IsVector = ArgTy->isVectorTy();
282     UnpaddedSize = TyInfo.Width;
283     DirectAlign = TyInfo.Align;
284   }
285   CharUnits PaddedSize = CharUnits::fromQuantity(8);
286   if (IsVector && UnpaddedSize > PaddedSize)
287     PaddedSize = CharUnits::fromQuantity(16);
288   assert((UnpaddedSize <= PaddedSize) && "Invalid argument size.");
289 
290   CharUnits Padding = (PaddedSize - UnpaddedSize);
291 
292   llvm::Type *IndexTy = CGF.Int64Ty;
293   llvm::Value *PaddedSizeV =
294     llvm::ConstantInt::get(IndexTy, PaddedSize.getQuantity());
295 
296   if (IsVector) {
297     // Work out the address of a vector argument on the stack.
298     // Vector arguments are always passed in the high bits of a
299     // single (8 byte) or double (16 byte) stack slot.
300     Address OverflowArgAreaPtr =
301         CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_ptr");
302     Address OverflowArgArea =
303         Address(CGF.Builder.CreateLoad(OverflowArgAreaPtr, "overflow_arg_area"),
304                 CGF.Int8Ty, TyInfo.Align);
305     Address MemAddr = OverflowArgArea.withElementType(DirectTy);
306 
307     // Update overflow_arg_area_ptr pointer
308     llvm::Value *NewOverflowArgArea = CGF.Builder.CreateGEP(
309         OverflowArgArea.getElementType(), OverflowArgArea.getPointer(),
310         PaddedSizeV, "overflow_arg_area");
311     CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr);
312 
313     return MemAddr;
314   }
315 
316   assert(PaddedSize.getQuantity() == 8);
317 
318   unsigned MaxRegs, RegCountField, RegSaveIndex;
319   CharUnits RegPadding;
320   if (InFPRs) {
321     MaxRegs = 4; // Maximum of 4 FPR arguments
322     RegCountField = 1; // __fpr
323     RegSaveIndex = 16; // save offset for f0
324     RegPadding = CharUnits(); // floats are passed in the high bits of an FPR
325   } else {
326     MaxRegs = 5; // Maximum of 5 GPR arguments
327     RegCountField = 0; // __gpr
328     RegSaveIndex = 2; // save offset for r2
329     RegPadding = Padding; // values are passed in the low bits of a GPR
330   }
331 
332   Address RegCountPtr =
333       CGF.Builder.CreateStructGEP(VAListAddr, RegCountField, "reg_count_ptr");
334   llvm::Value *RegCount = CGF.Builder.CreateLoad(RegCountPtr, "reg_count");
335   llvm::Value *MaxRegsV = llvm::ConstantInt::get(IndexTy, MaxRegs);
336   llvm::Value *InRegs = CGF.Builder.CreateICmpULT(RegCount, MaxRegsV,
337                                                  "fits_in_regs");
338 
339   llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg");
340   llvm::BasicBlock *InMemBlock = CGF.createBasicBlock("vaarg.in_mem");
341   llvm::BasicBlock *ContBlock = CGF.createBasicBlock("vaarg.end");
342   CGF.Builder.CreateCondBr(InRegs, InRegBlock, InMemBlock);
343 
344   // Emit code to load the value if it was passed in registers.
345   CGF.EmitBlock(InRegBlock);
346 
347   // Work out the address of an argument register.
348   llvm::Value *ScaledRegCount =
349     CGF.Builder.CreateMul(RegCount, PaddedSizeV, "scaled_reg_count");
350   llvm::Value *RegBase =
351     llvm::ConstantInt::get(IndexTy, RegSaveIndex * PaddedSize.getQuantity()
352                                       + RegPadding.getQuantity());
353   llvm::Value *RegOffset =
354     CGF.Builder.CreateAdd(ScaledRegCount, RegBase, "reg_offset");
355   Address RegSaveAreaPtr =
356       CGF.Builder.CreateStructGEP(VAListAddr, 3, "reg_save_area_ptr");
357   llvm::Value *RegSaveArea =
358       CGF.Builder.CreateLoad(RegSaveAreaPtr, "reg_save_area");
359   Address RawRegAddr(
360       CGF.Builder.CreateGEP(CGF.Int8Ty, RegSaveArea, RegOffset, "raw_reg_addr"),
361       CGF.Int8Ty, PaddedSize);
362   Address RegAddr = RawRegAddr.withElementType(DirectTy);
363 
364   // Update the register count
365   llvm::Value *One = llvm::ConstantInt::get(IndexTy, 1);
366   llvm::Value *NewRegCount =
367     CGF.Builder.CreateAdd(RegCount, One, "reg_count");
368   CGF.Builder.CreateStore(NewRegCount, RegCountPtr);
369   CGF.EmitBranch(ContBlock);
370 
371   // Emit code to load the value if it was passed in memory.
372   CGF.EmitBlock(InMemBlock);
373 
374   // Work out the address of a stack argument.
375   Address OverflowArgAreaPtr =
376       CGF.Builder.CreateStructGEP(VAListAddr, 2, "overflow_arg_area_ptr");
377   Address OverflowArgArea =
378       Address(CGF.Builder.CreateLoad(OverflowArgAreaPtr, "overflow_arg_area"),
379               CGF.Int8Ty, PaddedSize);
380   Address RawMemAddr =
381       CGF.Builder.CreateConstByteGEP(OverflowArgArea, Padding, "raw_mem_addr");
382   Address MemAddr = RawMemAddr.withElementType(DirectTy);
383 
384   // Update overflow_arg_area_ptr pointer
385   llvm::Value *NewOverflowArgArea =
386     CGF.Builder.CreateGEP(OverflowArgArea.getElementType(),
387                           OverflowArgArea.getPointer(), PaddedSizeV,
388                           "overflow_arg_area");
389   CGF.Builder.CreateStore(NewOverflowArgArea, OverflowArgAreaPtr);
390   CGF.EmitBranch(ContBlock);
391 
392   // Return the appropriate result.
393   CGF.EmitBlock(ContBlock);
394   Address ResAddr = emitMergePHI(CGF, RegAddr, InRegBlock, MemAddr, InMemBlock,
395                                  "va_arg.addr");
396 
397   if (IsIndirect)
398     ResAddr = Address(CGF.Builder.CreateLoad(ResAddr, "indirect_arg"), ArgTy,
399                       TyInfo.Align);
400 
401   return ResAddr;
402 }
403 
404 ABIArgInfo SystemZABIInfo::classifyReturnType(QualType RetTy) const {
405   if (RetTy->isVoidType())
406     return ABIArgInfo::getIgnore();
407   if (isVectorArgumentType(RetTy))
408     return ABIArgInfo::getDirect();
409   if (isCompoundType(RetTy) || getContext().getTypeSize(RetTy) > 64)
410     return getNaturalAlignIndirect(RetTy);
411   return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
412                                                : ABIArgInfo::getDirect());
413 }
414 
415 ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {
416   // Handle the generic C++ ABI.
417   if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
418     return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
419 
420   // Integers and enums are extended to full register width.
421   if (isPromotableIntegerTypeForABI(Ty))
422     return ABIArgInfo::getExtend(Ty);
423 
424   // Handle vector types and vector-like structure types.  Note that
425   // as opposed to float-like structure types, we do not allow any
426   // padding for vector-like structures, so verify the sizes match.
427   uint64_t Size = getContext().getTypeSize(Ty);
428   QualType SingleElementTy = GetSingleElementType(Ty);
429   if (isVectorArgumentType(SingleElementTy) &&
430       getContext().getTypeSize(SingleElementTy) == Size)
431     return ABIArgInfo::getDirect(CGT.ConvertType(SingleElementTy));
432 
433   // Values that are not 1, 2, 4 or 8 bytes in size are passed indirectly.
434   if (Size != 8 && Size != 16 && Size != 32 && Size != 64)
435     return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
436 
437   // Handle small structures.
438   if (const RecordType *RT = Ty->getAs<RecordType>()) {
439     // Structures with flexible arrays have variable length, so really
440     // fail the size test above.
441     const RecordDecl *RD = RT->getDecl();
442     if (RD->hasFlexibleArrayMember())
443       return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
444 
445     // The structure is passed as an unextended integer, a float, or a double.
446     llvm::Type *PassTy;
447     if (isFPArgumentType(SingleElementTy)) {
448       assert(Size == 32 || Size == 64);
449       if (Size == 32)
450         PassTy = llvm::Type::getFloatTy(getVMContext());
451       else
452         PassTy = llvm::Type::getDoubleTy(getVMContext());
453     } else
454       PassTy = llvm::IntegerType::get(getVMContext(), Size);
455     return ABIArgInfo::getDirect(PassTy);
456   }
457 
458   // Non-structure compounds are passed indirectly.
459   if (isCompoundType(Ty))
460     return getNaturalAlignIndirect(Ty, /*ByVal=*/false);
461 
462   return ABIArgInfo::getDirect(nullptr);
463 }
464 
465 void SystemZABIInfo::computeInfo(CGFunctionInfo &FI) const {
466   const SystemZTargetCodeGenInfo &SZCGI =
467       static_cast<const SystemZTargetCodeGenInfo &>(
468           CGT.getCGM().getTargetCodeGenInfo());
469   if (!getCXXABI().classifyReturnType(FI))
470     FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
471   unsigned Idx = 0;
472   for (auto &I : FI.arguments()) {
473     I.info = classifyArgumentType(I.type);
474     if (FI.isVariadic() && Idx++ >= FI.getNumRequiredArgs())
475       // Check if a vararg vector argument is passed, in which case the
476       // vector ABI becomes visible as the va_list could be passed on to
477       // other functions.
478       SZCGI.handleExternallyVisibleObjABI(I.type.getTypePtr(), CGT.getCGM(),
479                                           /*IsParam*/true);
480   }
481 }
482 
483 bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty,
484                                                  bool IsParam) const {
485   if (!SeenTypes.insert(Ty).second)
486     return false;
487 
488   if (IsParam) {
489     // A narrow (<16 bytes) vector will as a parameter also expose the ABI as
490     // it will be passed in a vector register. A wide (>16 bytes) vector will
491     // be passed via "hidden" pointer where any extra alignment is not
492     // required (per GCC).
493     const Type *SingleEltTy = getABIInfo<SystemZABIInfo>()
494                                   .GetSingleElementType(QualType(Ty, 0))
495                                   .getTypePtr();
496     bool SingleVecEltStruct = SingleEltTy != Ty && SingleEltTy->isVectorType() &&
497       Ctx.getTypeSize(SingleEltTy) == Ctx.getTypeSize(Ty);
498     if (Ty->isVectorType() || SingleVecEltStruct)
499       return Ctx.getTypeSize(Ty) / 8 <= 16;
500   }
501 
502   // Assume pointers are dereferenced.
503   while (Ty->isPointerType() || Ty->isArrayType())
504     Ty = Ty->getPointeeOrArrayElementType();
505 
506   // Vectors >= 16 bytes expose the ABI through alignment requirements.
507   if (Ty->isVectorType() && Ctx.getTypeSize(Ty) / 8 >= 16)
508       return true;
509 
510   if (const auto *RecordTy = Ty->getAs<RecordType>()) {
511     const RecordDecl *RD = RecordTy->getDecl();
512     if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
513       if (CXXRD->hasDefinition())
514         for (const auto &I : CXXRD->bases())
515           if (isVectorTypeBased(I.getType().getTypePtr(), /*IsParam*/false))
516             return true;
517     for (const auto *FD : RD->fields())
518       if (isVectorTypeBased(FD->getType().getTypePtr(), /*IsParam*/false))
519         return true;
520   }
521 
522   if (const auto *FT = Ty->getAs<FunctionType>())
523     if (isVectorTypeBased(FT->getReturnType().getTypePtr(), /*IsParam*/true))
524       return true;
525   if (const FunctionProtoType *Proto = Ty->getAs<FunctionProtoType>())
526     for (const auto &ParamType : Proto->getParamTypes())
527       if (isVectorTypeBased(ParamType.getTypePtr(), /*IsParam*/true))
528         return true;
529 
530   return false;
531 }
532 
533 std::unique_ptr<TargetCodeGenInfo>
534 CodeGen::createSystemZTargetCodeGenInfo(CodeGenModule &CGM, bool HasVector,
535                                         bool SoftFloatABI) {
536   return std::make_unique<SystemZTargetCodeGenInfo>(CGM.getTypes(), HasVector,
537                                                     SoftFloatABI);
538 }
539