brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.5 KiB · acc2719 Raw
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