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