1 //===--- Sparc.h - declare sparc target feature support ---------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file declares Sparc TargetInfo objects. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H 15 #define LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H 16 #include "clang/Basic/TargetInfo.h" 17 #include "clang/Basic/TargetOptions.h" 18 #include "llvm/ADT/Triple.h" 19 #include "llvm/Support/Compiler.h" 20 namespace clang { 21 namespace targets { 22 // Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit). 23 class LLVM_LIBRARY_VISIBILITY SparcTargetInfo : public TargetInfo { 24 static const TargetInfo::GCCRegAlias GCCRegAliases[]; 25 static const char *const GCCRegNames[]; 26 bool SoftFloat; 27 28 public: SparcTargetInfo(const llvm::Triple & Triple,const TargetOptions &)29 SparcTargetInfo(const llvm::Triple &Triple, const TargetOptions &) 30 : TargetInfo(Triple), SoftFloat(false) {} 31 getEHDataRegisterNumber(unsigned RegNo)32 int getEHDataRegisterNumber(unsigned RegNo) const override { 33 if (RegNo == 0) 34 return 24; 35 if (RegNo == 1) 36 return 25; 37 return -1; 38 } 39 handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)40 bool handleTargetFeatures(std::vector<std::string> &Features, 41 DiagnosticsEngine &Diags) override { 42 // Check if software floating point is enabled 43 auto Feature = std::find(Features.begin(), Features.end(), "+soft-float"); 44 if (Feature != Features.end()) { 45 SoftFloat = true; 46 } 47 return true; 48 } 49 void getTargetDefines(const LangOptions &Opts, 50 MacroBuilder &Builder) const override; 51 52 bool hasFeature(StringRef Feature) const override; 53 hasSjLjLowering()54 bool hasSjLjLowering() const override { return true; } 55 getTargetBuiltins()56 ArrayRef<Builtin::Info> getTargetBuiltins() const override { 57 // FIXME: Implement! 58 return None; 59 } getBuiltinVaListKind()60 BuiltinVaListKind getBuiltinVaListKind() const override { 61 return TargetInfo::VoidPtrBuiltinVaList; 62 } 63 ArrayRef<const char *> getGCCRegNames() const override; 64 ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override; validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & info)65 bool validateAsmConstraint(const char *&Name, 66 TargetInfo::ConstraintInfo &info) const override { 67 // FIXME: Implement! 68 switch (*Name) { 69 case 'I': // Signed 13-bit constant 70 case 'J': // Zero 71 case 'K': // 32-bit constant with the low 12 bits clear 72 case 'L': // A constant in the range supported by movcc (11-bit signed imm) 73 case 'M': // A constant in the range supported by movrcc (19-bit signed imm) 74 case 'N': // Same as 'K' but zext (required for SIMode) 75 case 'O': // The constant 4096 76 return true; 77 78 case 'f': 79 case 'e': 80 info.setAllowsRegister(); 81 return true; 82 } 83 return false; 84 } getClobbers()85 const char *getClobbers() const override { 86 // FIXME: Implement! 87 return ""; 88 } 89 90 // No Sparc V7 for now, the backend doesn't support it anyway. 91 enum CPUKind { 92 CK_GENERIC, 93 CK_V8, 94 CK_SUPERSPARC, 95 CK_SPARCLITE, 96 CK_F934, 97 CK_HYPERSPARC, 98 CK_SPARCLITE86X, 99 CK_SPARCLET, 100 CK_TSC701, 101 CK_V9, 102 CK_ULTRASPARC, 103 CK_ULTRASPARC3, 104 CK_NIAGARA, 105 CK_NIAGARA2, 106 CK_NIAGARA3, 107 CK_NIAGARA4, 108 CK_MYRIAD2100, 109 CK_MYRIAD2150, 110 CK_MYRIAD2155, 111 CK_MYRIAD2450, 112 CK_MYRIAD2455, 113 CK_MYRIAD2x5x, 114 CK_MYRIAD2080, 115 CK_MYRIAD2085, 116 CK_MYRIAD2480, 117 CK_MYRIAD2485, 118 CK_MYRIAD2x8x, 119 CK_LEON2, 120 CK_LEON2_AT697E, 121 CK_LEON2_AT697F, 122 CK_LEON3, 123 CK_LEON3_UT699, 124 CK_LEON3_GR712RC, 125 CK_LEON4, 126 CK_LEON4_GR740 127 } CPU = CK_GENERIC; 128 129 enum CPUGeneration { 130 CG_V8, 131 CG_V9, 132 }; 133 134 CPUGeneration getCPUGeneration(CPUKind Kind) const; 135 136 CPUKind getCPUKind(StringRef Name) const; 137 isValidCPUName(StringRef Name)138 bool isValidCPUName(StringRef Name) const override { 139 return getCPUKind(Name) != CK_GENERIC; 140 } 141 142 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 143 setCPU(const std::string & Name)144 bool setCPU(const std::string &Name) override { 145 CPU = getCPUKind(Name); 146 return CPU != CK_GENERIC; 147 } 148 }; 149 150 // SPARC v8 is the 32-bit mode selected by Triple::sparc. 151 class LLVM_LIBRARY_VISIBILITY SparcV8TargetInfo : public SparcTargetInfo { 152 public: SparcV8TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)153 SparcV8TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 154 : SparcTargetInfo(Triple, Opts) { 155 resetDataLayout("E-m:e-p:32:32-i64:64-f128:64-n32-S64"); 156 // NetBSD / OpenBSD use long (same as llvm default); everyone else uses int. 157 switch (getTriple().getOS()) { 158 default: 159 SizeType = UnsignedInt; 160 IntPtrType = SignedInt; 161 PtrDiffType = SignedInt; 162 break; 163 case llvm::Triple::NetBSD: 164 case llvm::Triple::OpenBSD: 165 SizeType = UnsignedLong; 166 IntPtrType = SignedLong; 167 PtrDiffType = SignedLong; 168 break; 169 } 170 // Up to 32 bits are lock-free atomic, but we're willing to do atomic ops 171 // on up to 64 bits. 172 MaxAtomicPromoteWidth = 64; 173 MaxAtomicInlineWidth = 32; 174 } 175 176 void getTargetDefines(const LangOptions &Opts, 177 MacroBuilder &Builder) const override; 178 hasSjLjLowering()179 bool hasSjLjLowering() const override { return true; } 180 }; 181 182 // SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel. 183 class LLVM_LIBRARY_VISIBILITY SparcV8elTargetInfo : public SparcV8TargetInfo { 184 public: SparcV8elTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)185 SparcV8elTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 186 : SparcV8TargetInfo(Triple, Opts) { 187 resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64"); 188 } 189 }; 190 191 // SPARC v9 is the 64-bit mode selected by Triple::sparcv9. 192 class LLVM_LIBRARY_VISIBILITY SparcV9TargetInfo : public SparcTargetInfo { 193 public: SparcV9TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)194 SparcV9TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts) 195 : SparcTargetInfo(Triple, Opts) { 196 // FIXME: Support Sparc quad-precision long double? 197 resetDataLayout("E-m:e-i64:64-n32:64-S128"); 198 // This is an LP64 platform. 199 LongWidth = LongAlign = PointerWidth = PointerAlign = 64; 200 201 // OpenBSD uses long long for int64_t and intmax_t. 202 if (getTriple().isOSOpenBSD()) 203 IntMaxType = SignedLongLong; 204 else 205 IntMaxType = SignedLong; 206 Int64Type = IntMaxType; 207 208 // The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit 209 // aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned. 210 LongDoubleWidth = 128; 211 LongDoubleAlign = 128; 212 LongDoubleFormat = &llvm::APFloat::IEEEquad(); 213 MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64; 214 } 215 216 void getTargetDefines(const LangOptions &Opts, 217 MacroBuilder &Builder) const override; 218 isValidCPUName(StringRef Name)219 bool isValidCPUName(StringRef Name) const override { 220 return getCPUGeneration(SparcTargetInfo::getCPUKind(Name)) == CG_V9; 221 } 222 223 void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override; 224 setCPU(const std::string & Name)225 bool setCPU(const std::string &Name) override { 226 if (!SparcTargetInfo::setCPU(Name)) 227 return false; 228 return getCPUGeneration(CPU) == CG_V9; 229 } 230 }; 231 } // namespace targets 232 } // namespace clang 233 #endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H 234