10b57cec5SDimitry Andric //===--- Mips.h - Declare Mips target feature support -----------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file declares Mips TargetInfo objects. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 120b57cec5SDimitry Andric 130b57cec5SDimitry Andric #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_MIPS_H 140b57cec5SDimitry Andric #define LLVM_CLANG_LIB_BASIC_TARGETS_MIPS_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 170b57cec5SDimitry Andric #include "clang/Basic/TargetOptions.h" 180b57cec5SDimitry Andric #include "llvm/Support/Compiler.h" 19*06c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace clang { 220b57cec5SDimitry Andric namespace targets { 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo { 250b57cec5SDimitry Andric void setDataLayout() { 260b57cec5SDimitry Andric StringRef Layout; 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric if (ABI == "o32") 290b57cec5SDimitry Andric Layout = "m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"; 300b57cec5SDimitry Andric else if (ABI == "n32") 310b57cec5SDimitry Andric Layout = "m:e-p:32:32-i8:8:32-i16:16:32-i64:64-n32:64-S128"; 320b57cec5SDimitry Andric else if (ABI == "n64") 330b57cec5SDimitry Andric Layout = "m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128"; 340b57cec5SDimitry Andric else 350b57cec5SDimitry Andric llvm_unreachable("Invalid ABI"); 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric if (BigEndian) 380b57cec5SDimitry Andric resetDataLayout(("E-" + Layout).str()); 390b57cec5SDimitry Andric else 400b57cec5SDimitry Andric resetDataLayout(("e-" + Layout).str()); 410b57cec5SDimitry Andric } 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric std::string CPU; 440b57cec5SDimitry Andric bool IsMips16; 450b57cec5SDimitry Andric bool IsMicromips; 460b57cec5SDimitry Andric bool IsNan2008; 470b57cec5SDimitry Andric bool IsAbs2008; 480b57cec5SDimitry Andric bool IsSingleFloat; 490b57cec5SDimitry Andric bool IsNoABICalls; 500b57cec5SDimitry Andric bool CanUseBSDABICalls; 510b57cec5SDimitry Andric enum MipsFloatABI { HardFloat, SoftFloat } FloatABI; 520b57cec5SDimitry Andric enum DspRevEnum { NoDSP, DSP1, DSP2 } DspRev; 530b57cec5SDimitry Andric bool HasMSA; 540b57cec5SDimitry Andric bool DisableMadd4; 550b57cec5SDimitry Andric bool UseIndirectJumpHazard; 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric protected: 580b57cec5SDimitry Andric enum FPModeEnum { FPXX, FP32, FP64 } FPMode; 590b57cec5SDimitry Andric std::string ABI; 600b57cec5SDimitry Andric 610b57cec5SDimitry Andric public: 620b57cec5SDimitry Andric MipsTargetInfo(const llvm::Triple &Triple, const TargetOptions &) 630b57cec5SDimitry Andric : TargetInfo(Triple), IsMips16(false), IsMicromips(false), 640b57cec5SDimitry Andric IsNan2008(false), IsAbs2008(false), IsSingleFloat(false), 650b57cec5SDimitry Andric IsNoABICalls(false), CanUseBSDABICalls(false), FloatABI(HardFloat), 660b57cec5SDimitry Andric DspRev(NoDSP), HasMSA(false), DisableMadd4(false), 670b57cec5SDimitry Andric UseIndirectJumpHazard(false), FPMode(FPXX) { 680b57cec5SDimitry Andric TheCXXABI.set(TargetCXXABI::GenericMIPS); 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric if (Triple.isMIPS32()) 710b57cec5SDimitry Andric setABI("o32"); 720b57cec5SDimitry Andric else if (Triple.getEnvironment() == llvm::Triple::GNUABIN32) 730b57cec5SDimitry Andric setABI("n32"); 740b57cec5SDimitry Andric else 750b57cec5SDimitry Andric setABI("n64"); 760b57cec5SDimitry Andric 770b57cec5SDimitry Andric CPU = ABI == "o32" ? "mips32r2" : "mips64r2"; 780b57cec5SDimitry Andric 790b57cec5SDimitry Andric CanUseBSDABICalls = Triple.isOSFreeBSD() || 800b57cec5SDimitry Andric Triple.isOSOpenBSD(); 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric bool isIEEE754_2008Default() const { 840b57cec5SDimitry Andric return CPU == "mips32r6" || CPU == "mips64r6"; 850b57cec5SDimitry Andric } 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric bool isFP64Default() const { 880b57cec5SDimitry Andric return CPU == "mips32r6" || ABI == "n32" || ABI == "n64" || ABI == "64"; 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric 910b57cec5SDimitry Andric bool isNan2008() const override { return IsNan2008; } 920b57cec5SDimitry Andric 930b57cec5SDimitry Andric bool processorSupportsGPR64() const; 940b57cec5SDimitry Andric 950b57cec5SDimitry Andric StringRef getABI() const override { return ABI; } 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric bool setABI(const std::string &Name) override { 980b57cec5SDimitry Andric if (Name == "o32") { 990b57cec5SDimitry Andric setO32ABITypes(); 1000b57cec5SDimitry Andric ABI = Name; 1010b57cec5SDimitry Andric return true; 1020b57cec5SDimitry Andric } 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric if (Name == "n32") { 1050b57cec5SDimitry Andric setN32ABITypes(); 1060b57cec5SDimitry Andric ABI = Name; 1070b57cec5SDimitry Andric return true; 1080b57cec5SDimitry Andric } 1090b57cec5SDimitry Andric if (Name == "n64") { 1100b57cec5SDimitry Andric setN64ABITypes(); 1110b57cec5SDimitry Andric ABI = Name; 1120b57cec5SDimitry Andric return true; 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric return false; 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric void setO32ABITypes() { 1180b57cec5SDimitry Andric Int64Type = SignedLongLong; 1190b57cec5SDimitry Andric IntMaxType = Int64Type; 1200b57cec5SDimitry Andric LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 1210b57cec5SDimitry Andric LongDoubleWidth = LongDoubleAlign = 64; 1220b57cec5SDimitry Andric LongWidth = LongAlign = 32; 1230b57cec5SDimitry Andric MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 32; 1240b57cec5SDimitry Andric PointerWidth = PointerAlign = 32; 1250b57cec5SDimitry Andric PtrDiffType = SignedInt; 1260b57cec5SDimitry Andric SizeType = UnsignedInt; 1270b57cec5SDimitry Andric SuitableAlign = 64; 1280b57cec5SDimitry Andric } 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric void setN32N64ABITypes() { 1310b57cec5SDimitry Andric LongDoubleWidth = LongDoubleAlign = 128; 1320b57cec5SDimitry Andric LongDoubleFormat = &llvm::APFloat::IEEEquad(); 1330b57cec5SDimitry Andric if (getTriple().isOSFreeBSD()) { 1340b57cec5SDimitry Andric LongDoubleWidth = LongDoubleAlign = 64; 1350b57cec5SDimitry Andric LongDoubleFormat = &llvm::APFloat::IEEEdouble(); 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; 1380b57cec5SDimitry Andric SuitableAlign = 128; 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric void setN64ABITypes() { 1420b57cec5SDimitry Andric setN32N64ABITypes(); 1430b57cec5SDimitry Andric if (getTriple().isOSOpenBSD()) { 1440b57cec5SDimitry Andric Int64Type = SignedLongLong; 1450b57cec5SDimitry Andric } else { 1460b57cec5SDimitry Andric Int64Type = SignedLong; 1470b57cec5SDimitry Andric } 1480b57cec5SDimitry Andric IntMaxType = Int64Type; 1490b57cec5SDimitry Andric LongWidth = LongAlign = 64; 1500b57cec5SDimitry Andric PointerWidth = PointerAlign = 64; 1510b57cec5SDimitry Andric PtrDiffType = SignedLong; 1520b57cec5SDimitry Andric SizeType = UnsignedLong; 1530b57cec5SDimitry Andric } 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric void setN32ABITypes() { 1560b57cec5SDimitry Andric setN32N64ABITypes(); 1570b57cec5SDimitry Andric Int64Type = SignedLongLong; 1580b57cec5SDimitry Andric IntMaxType = Int64Type; 1590b57cec5SDimitry Andric LongWidth = LongAlign = 32; 1600b57cec5SDimitry Andric PointerWidth = PointerAlign = 32; 1610b57cec5SDimitry Andric PtrDiffType = SignedInt; 1620b57cec5SDimitry Andric SizeType = UnsignedInt; 1630b57cec5SDimitry Andric } 1640b57cec5SDimitry Andric 1650b57cec5SDimitry Andric bool isValidCPUName(StringRef Name) const override; 1660b57cec5SDimitry Andric void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric bool setCPU(const std::string &Name) override { 1690b57cec5SDimitry Andric CPU = Name; 1700b57cec5SDimitry Andric return isValidCPUName(Name); 1710b57cec5SDimitry Andric } 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric const std::string &getCPU() const { return CPU; } 1740b57cec5SDimitry Andric bool 1750b57cec5SDimitry Andric initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, 1760b57cec5SDimitry Andric StringRef CPU, 1770b57cec5SDimitry Andric const std::vector<std::string> &FeaturesVec) const override { 1780b57cec5SDimitry Andric if (CPU.empty()) 1790b57cec5SDimitry Andric CPU = getCPU(); 1800b57cec5SDimitry Andric if (CPU == "octeon") 1810b57cec5SDimitry Andric Features["mips64r2"] = Features["cnmips"] = true; 1820b57cec5SDimitry Andric else if (CPU == "octeon+") 1830b57cec5SDimitry Andric Features["mips64r2"] = Features["cnmips"] = Features["cnmipsp"] = true; 1840b57cec5SDimitry Andric else 1850b57cec5SDimitry Andric Features[CPU] = true; 1860b57cec5SDimitry Andric return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec); 1870b57cec5SDimitry Andric } 1880b57cec5SDimitry Andric 1890b57cec5SDimitry Andric unsigned getISARev() const; 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric void getTargetDefines(const LangOptions &Opts, 1920b57cec5SDimitry Andric MacroBuilder &Builder) const override; 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric ArrayRef<Builtin::Info> getTargetBuiltins() const override; 1950b57cec5SDimitry Andric 1960b57cec5SDimitry Andric bool hasFeature(StringRef Feature) const override; 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric BuiltinVaListKind getBuiltinVaListKind() const override { 1990b57cec5SDimitry Andric return TargetInfo::VoidPtrBuiltinVaList; 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric ArrayRef<const char *> getGCCRegNames() const override { 2030b57cec5SDimitry Andric static const char *const GCCRegNames[] = { 2040b57cec5SDimitry Andric // CPU register names 2050b57cec5SDimitry Andric // Must match second column of GCCRegAliases 2060b57cec5SDimitry Andric "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9", "$10", 2070b57cec5SDimitry Andric "$11", "$12", "$13", "$14", "$15", "$16", "$17", "$18", "$19", "$20", 2080b57cec5SDimitry Andric "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "$29", "$30", 2090b57cec5SDimitry Andric "$31", 2100b57cec5SDimitry Andric // Floating point register names 2110b57cec5SDimitry Andric "$f0", "$f1", "$f2", "$f3", "$f4", "$f5", "$f6", "$f7", "$f8", "$f9", 2120b57cec5SDimitry Andric "$f10", "$f11", "$f12", "$f13", "$f14", "$f15", "$f16", "$f17", "$f18", 2130b57cec5SDimitry Andric "$f19", "$f20", "$f21", "$f22", "$f23", "$f24", "$f25", "$f26", "$f27", 2140b57cec5SDimitry Andric "$f28", "$f29", "$f30", "$f31", 2150b57cec5SDimitry Andric // Hi/lo and condition register names 2160b57cec5SDimitry Andric "hi", "lo", "", "$fcc0", "$fcc1", "$fcc2", "$fcc3", "$fcc4", "$fcc5", 2170b57cec5SDimitry Andric "$fcc6", "$fcc7", "$ac1hi", "$ac1lo", "$ac2hi", "$ac2lo", "$ac3hi", 2180b57cec5SDimitry Andric "$ac3lo", 2190b57cec5SDimitry Andric // MSA register names 2200b57cec5SDimitry Andric "$w0", "$w1", "$w2", "$w3", "$w4", "$w5", "$w6", "$w7", "$w8", "$w9", 2210b57cec5SDimitry Andric "$w10", "$w11", "$w12", "$w13", "$w14", "$w15", "$w16", "$w17", "$w18", 2220b57cec5SDimitry Andric "$w19", "$w20", "$w21", "$w22", "$w23", "$w24", "$w25", "$w26", "$w27", 2230b57cec5SDimitry Andric "$w28", "$w29", "$w30", "$w31", 2240b57cec5SDimitry Andric // MSA control register names 2250b57cec5SDimitry Andric "$msair", "$msacsr", "$msaaccess", "$msasave", "$msamodify", 2260b57cec5SDimitry Andric "$msarequest", "$msamap", "$msaunmap" 2270b57cec5SDimitry Andric }; 228bdd1243dSDimitry Andric return llvm::ArrayRef(GCCRegNames); 2290b57cec5SDimitry Andric } 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric bool validateAsmConstraint(const char *&Name, 2320b57cec5SDimitry Andric TargetInfo::ConstraintInfo &Info) const override { 2330b57cec5SDimitry Andric switch (*Name) { 2340b57cec5SDimitry Andric default: 2350b57cec5SDimitry Andric return false; 2360b57cec5SDimitry Andric case 'r': // CPU registers. 2370b57cec5SDimitry Andric case 'd': // Equivalent to "r" unless generating MIPS16 code. 2380b57cec5SDimitry Andric case 'y': // Equivalent to "r", backward compatibility only. 2390b57cec5SDimitry Andric case 'f': // floating-point registers. 2400b57cec5SDimitry Andric case 'c': // $25 for indirect jumps 2410b57cec5SDimitry Andric case 'l': // lo register 2420b57cec5SDimitry Andric case 'x': // hilo register pair 2430b57cec5SDimitry Andric Info.setAllowsRegister(); 2440b57cec5SDimitry Andric return true; 2450b57cec5SDimitry Andric case 'I': // Signed 16-bit constant 2460b57cec5SDimitry Andric case 'J': // Integer 0 2470b57cec5SDimitry Andric case 'K': // Unsigned 16-bit constant 2480b57cec5SDimitry Andric case 'L': // Signed 32-bit constant, lower 16-bit zeros (for lui) 2490b57cec5SDimitry Andric case 'M': // Constants not loadable via lui, addiu, or ori 2500b57cec5SDimitry Andric case 'N': // Constant -1 to -65535 2510b57cec5SDimitry Andric case 'O': // A signed 15-bit constant 2520b57cec5SDimitry Andric case 'P': // A constant between 1 go 65535 2530b57cec5SDimitry Andric return true; 2540b57cec5SDimitry Andric case 'R': // An address that can be used in a non-macro load or store 2550b57cec5SDimitry Andric Info.setAllowsMemory(); 2560b57cec5SDimitry Andric return true; 2570b57cec5SDimitry Andric case 'Z': 2580b57cec5SDimitry Andric if (Name[1] == 'C') { // An address usable by ll, and sc. 2590b57cec5SDimitry Andric Info.setAllowsMemory(); 2600b57cec5SDimitry Andric Name++; // Skip over 'Z'. 2610b57cec5SDimitry Andric return true; 2620b57cec5SDimitry Andric } 2630b57cec5SDimitry Andric return false; 2640b57cec5SDimitry Andric } 2650b57cec5SDimitry Andric } 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric std::string convertConstraint(const char *&Constraint) const override { 2680b57cec5SDimitry Andric std::string R; 2690b57cec5SDimitry Andric switch (*Constraint) { 2700b57cec5SDimitry Andric case 'Z': // Two-character constraint; add "^" hint for later parsing. 2710b57cec5SDimitry Andric if (Constraint[1] == 'C') { 2720b57cec5SDimitry Andric R = std::string("^") + std::string(Constraint, 2); 2730b57cec5SDimitry Andric Constraint++; 2740b57cec5SDimitry Andric return R; 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric break; 2770b57cec5SDimitry Andric } 2780b57cec5SDimitry Andric return TargetInfo::convertConstraint(Constraint); 2790b57cec5SDimitry Andric } 2800b57cec5SDimitry Andric 281*06c3fb27SDimitry Andric std::string_view getClobbers() const override { 2820b57cec5SDimitry Andric // In GCC, $1 is not widely used in generated code (it's used only in a few 2830b57cec5SDimitry Andric // specific situations), so there is no real need for users to add it to 2840b57cec5SDimitry Andric // the clobbers list if they want to use it in their inline assembly code. 2850b57cec5SDimitry Andric // 2860b57cec5SDimitry Andric // In LLVM, $1 is treated as a normal GPR and is always allocatable during 2870b57cec5SDimitry Andric // code generation, so using it in inline assembly without adding it to the 2880b57cec5SDimitry Andric // clobbers list can cause conflicts between the inline assembly code and 2890b57cec5SDimitry Andric // the surrounding generated code. 2900b57cec5SDimitry Andric // 2910b57cec5SDimitry Andric // Another problem is that LLVM is allowed to choose $1 for inline assembly 2920b57cec5SDimitry Andric // operands, which will conflict with the ".set at" assembler option (which 2930b57cec5SDimitry Andric // we use only for inline assembly, in order to maintain compatibility with 2940b57cec5SDimitry Andric // GCC) and will also conflict with the user's usage of $1. 2950b57cec5SDimitry Andric // 2960b57cec5SDimitry Andric // The easiest way to avoid these conflicts and keep $1 as an allocatable 2970b57cec5SDimitry Andric // register for generated code is to automatically clobber $1 for all inline 2980b57cec5SDimitry Andric // assembly code. 2990b57cec5SDimitry Andric // 3000b57cec5SDimitry Andric // FIXME: We should automatically clobber $1 only for inline assembly code 3010b57cec5SDimitry Andric // which actually uses it. This would allow LLVM to use $1 for inline 3020b57cec5SDimitry Andric // assembly operands if the user's assembly code doesn't use it. 3030b57cec5SDimitry Andric return "~{$1}"; 3040b57cec5SDimitry Andric } 3050b57cec5SDimitry Andric 3060b57cec5SDimitry Andric bool handleTargetFeatures(std::vector<std::string> &Features, 3070b57cec5SDimitry Andric DiagnosticsEngine &Diags) override { 3080b57cec5SDimitry Andric IsMips16 = false; 3090b57cec5SDimitry Andric IsMicromips = false; 3100b57cec5SDimitry Andric IsNan2008 = isIEEE754_2008Default(); 3110b57cec5SDimitry Andric IsAbs2008 = isIEEE754_2008Default(); 3120b57cec5SDimitry Andric IsSingleFloat = false; 3130b57cec5SDimitry Andric FloatABI = HardFloat; 3140b57cec5SDimitry Andric DspRev = NoDSP; 3150b57cec5SDimitry Andric FPMode = isFP64Default() ? FP64 : FPXX; 3160b57cec5SDimitry Andric 3170b57cec5SDimitry Andric for (const auto &Feature : Features) { 3180b57cec5SDimitry Andric if (Feature == "+single-float") 3190b57cec5SDimitry Andric IsSingleFloat = true; 3200b57cec5SDimitry Andric else if (Feature == "+soft-float") 3210b57cec5SDimitry Andric FloatABI = SoftFloat; 3220b57cec5SDimitry Andric else if (Feature == "+mips16") 3230b57cec5SDimitry Andric IsMips16 = true; 3240b57cec5SDimitry Andric else if (Feature == "+micromips") 3250b57cec5SDimitry Andric IsMicromips = true; 3260b57cec5SDimitry Andric else if (Feature == "+dsp") 3270b57cec5SDimitry Andric DspRev = std::max(DspRev, DSP1); 3280b57cec5SDimitry Andric else if (Feature == "+dspr2") 3290b57cec5SDimitry Andric DspRev = std::max(DspRev, DSP2); 3300b57cec5SDimitry Andric else if (Feature == "+msa") 3310b57cec5SDimitry Andric HasMSA = true; 3320b57cec5SDimitry Andric else if (Feature == "+nomadd4") 3330b57cec5SDimitry Andric DisableMadd4 = true; 3340b57cec5SDimitry Andric else if (Feature == "+fp64") 3350b57cec5SDimitry Andric FPMode = FP64; 3360b57cec5SDimitry Andric else if (Feature == "-fp64") 3370b57cec5SDimitry Andric FPMode = FP32; 3380b57cec5SDimitry Andric else if (Feature == "+fpxx") 3390b57cec5SDimitry Andric FPMode = FPXX; 3400b57cec5SDimitry Andric else if (Feature == "+nan2008") 3410b57cec5SDimitry Andric IsNan2008 = true; 3420b57cec5SDimitry Andric else if (Feature == "-nan2008") 3430b57cec5SDimitry Andric IsNan2008 = false; 3440b57cec5SDimitry Andric else if (Feature == "+abs2008") 3450b57cec5SDimitry Andric IsAbs2008 = true; 3460b57cec5SDimitry Andric else if (Feature == "-abs2008") 3470b57cec5SDimitry Andric IsAbs2008 = false; 3480b57cec5SDimitry Andric else if (Feature == "+noabicalls") 3490b57cec5SDimitry Andric IsNoABICalls = true; 3500b57cec5SDimitry Andric else if (Feature == "+use-indirect-jump-hazard") 3510b57cec5SDimitry Andric UseIndirectJumpHazard = true; 3520b57cec5SDimitry Andric } 3530b57cec5SDimitry Andric 3540b57cec5SDimitry Andric setDataLayout(); 3550b57cec5SDimitry Andric 3560b57cec5SDimitry Andric return true; 3570b57cec5SDimitry Andric } 3580b57cec5SDimitry Andric 3590b57cec5SDimitry Andric int getEHDataRegisterNumber(unsigned RegNo) const override { 3600b57cec5SDimitry Andric if (RegNo == 0) 3610b57cec5SDimitry Andric return 4; 3620b57cec5SDimitry Andric if (RegNo == 1) 3630b57cec5SDimitry Andric return 5; 3640b57cec5SDimitry Andric return -1; 3650b57cec5SDimitry Andric } 3660b57cec5SDimitry Andric 3670b57cec5SDimitry Andric bool isCLZForZeroUndef() const override { return false; } 3680b57cec5SDimitry Andric 3690b57cec5SDimitry Andric ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override { 3700b57cec5SDimitry Andric static const TargetInfo::GCCRegAlias O32RegAliases[] = { 3710b57cec5SDimitry Andric {{"at"}, "$1"}, {{"v0"}, "$2"}, {{"v1"}, "$3"}, 3720b57cec5SDimitry Andric {{"a0"}, "$4"}, {{"a1"}, "$5"}, {{"a2"}, "$6"}, 3730b57cec5SDimitry Andric {{"a3"}, "$7"}, {{"t0"}, "$8"}, {{"t1"}, "$9"}, 3740b57cec5SDimitry Andric {{"t2"}, "$10"}, {{"t3"}, "$11"}, {{"t4"}, "$12"}, 3750b57cec5SDimitry Andric {{"t5"}, "$13"}, {{"t6"}, "$14"}, {{"t7"}, "$15"}, 3760b57cec5SDimitry Andric {{"s0"}, "$16"}, {{"s1"}, "$17"}, {{"s2"}, "$18"}, 3770b57cec5SDimitry Andric {{"s3"}, "$19"}, {{"s4"}, "$20"}, {{"s5"}, "$21"}, 3780b57cec5SDimitry Andric {{"s6"}, "$22"}, {{"s7"}, "$23"}, {{"t8"}, "$24"}, 3790b57cec5SDimitry Andric {{"t9"}, "$25"}, {{"k0"}, "$26"}, {{"k1"}, "$27"}, 3800b57cec5SDimitry Andric {{"gp"}, "$28"}, {{"sp", "$sp"}, "$29"}, {{"fp", "$fp"}, "$30"}, 3810b57cec5SDimitry Andric {{"ra"}, "$31"} 3820b57cec5SDimitry Andric }; 3830b57cec5SDimitry Andric static const TargetInfo::GCCRegAlias NewABIRegAliases[] = { 3840b57cec5SDimitry Andric {{"at"}, "$1"}, {{"v0"}, "$2"}, {{"v1"}, "$3"}, 3850b57cec5SDimitry Andric {{"a0"}, "$4"}, {{"a1"}, "$5"}, {{"a2"}, "$6"}, 3860b57cec5SDimitry Andric {{"a3"}, "$7"}, {{"a4"}, "$8"}, {{"a5"}, "$9"}, 3870b57cec5SDimitry Andric {{"a6"}, "$10"}, {{"a7"}, "$11"}, {{"t0"}, "$12"}, 3880b57cec5SDimitry Andric {{"t1"}, "$13"}, {{"t2"}, "$14"}, {{"t3"}, "$15"}, 3890b57cec5SDimitry Andric {{"s0"}, "$16"}, {{"s1"}, "$17"}, {{"s2"}, "$18"}, 3900b57cec5SDimitry Andric {{"s3"}, "$19"}, {{"s4"}, "$20"}, {{"s5"}, "$21"}, 3910b57cec5SDimitry Andric {{"s6"}, "$22"}, {{"s7"}, "$23"}, {{"t8"}, "$24"}, 3920b57cec5SDimitry Andric {{"t9"}, "$25"}, {{"k0"}, "$26"}, {{"k1"}, "$27"}, 3930b57cec5SDimitry Andric {{"gp"}, "$28"}, {{"sp", "$sp"}, "$29"}, {{"fp", "$fp"}, "$30"}, 3940b57cec5SDimitry Andric {{"ra"}, "$31"} 3950b57cec5SDimitry Andric }; 3960b57cec5SDimitry Andric if (ABI == "o32") 397bdd1243dSDimitry Andric return llvm::ArrayRef(O32RegAliases); 398bdd1243dSDimitry Andric return llvm::ArrayRef(NewABIRegAliases); 3990b57cec5SDimitry Andric } 4000b57cec5SDimitry Andric 4010b57cec5SDimitry Andric bool hasInt128Type() const override { 4020b57cec5SDimitry Andric return (ABI == "n32" || ABI == "n64") || getTargetOpts().ForceEnableInt128; 4030b57cec5SDimitry Andric } 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric unsigned getUnwindWordWidth() const override; 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric bool validateTarget(DiagnosticsEngine &Diags) const override; 4080eae32dcSDimitry Andric bool hasBitIntType() const override { return true; } 4090b57cec5SDimitry Andric }; 4100b57cec5SDimitry Andric } // namespace targets 4110b57cec5SDimitry Andric } // namespace clang 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric #endif // LLVM_CLANG_LIB_BASIC_TARGETS_MIPS_H 414