brintos

brintos / llvm-project-archived public Read only

0
0
Text · 9.2 KiB · 4e15d5a Raw
296 lines · c
1//===--- SystemZ.h - Declare SystemZ 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 SystemZ TargetInfo objects.10//11//===----------------------------------------------------------------------===//12 13#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H14#define LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H15 16#include "clang/Basic/TargetInfo.h"17#include "clang/Basic/TargetOptions.h"18#include "llvm/Support/Compiler.h"19#include "llvm/TargetParser/Triple.h"20 21namespace clang {22namespace targets {23 24static const unsigned ZOSAddressMap[] = {25    0, // Default26    0, // opencl_global27    0, // opencl_local28    0, // opencl_constant29    0, // opencl_private30    0, // opencl_generic31    0, // opencl_global_device32    0, // opencl_global_host33    0, // cuda_device34    0, // cuda_constant35    0, // cuda_shared36    0, // sycl_global37    0, // sycl_global_device38    0, // sycl_global_host39    0, // sycl_local40    0, // sycl_private41    0, // ptr32_sptr42    1, // ptr32_uptr43    0, // ptr6444    0, // hlsl_groupshared45    0, // hlsl_constant46    0, // hlsl_private47    0, // hlsl_device48    0, // hlsl_input49    0  // wasm_funcref50};51 52class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {53 54  static const char *const GCCRegNames[];55  int ISARevision;56  bool HasTransactionalExecution;57  bool HasVector;58  bool SoftFloat;59  bool UnalignedSymbols;60  enum AddrSpace { ptr32 = 1 };61 62public:63  SystemZTargetInfo(const llvm::Triple &Triple, const TargetOptions &)64      : TargetInfo(Triple), ISARevision(getISARevision("z10")),65        HasTransactionalExecution(false), HasVector(false), SoftFloat(false),66        UnalignedSymbols(false) {67    IntMaxType = SignedLong;68    Int64Type = SignedLong;69    IntWidth = IntAlign = 32;70    LongWidth = LongLongWidth = LongAlign = LongLongAlign = 64;71    Int128Align = 64;72    PointerWidth = PointerAlign = 64;73    LongDoubleWidth = 128;74    LongDoubleAlign = 64;75    LongDoubleFormat = &llvm::APFloat::IEEEquad();76    DefaultAlignForAttributeAligned = 64;77    MinGlobalAlign = 16;78    HasUnalignedAccess = true;79    if (Triple.isOSzOS()) {80      if (Triple.isArch64Bit()) {81        AddrSpaceMap = &ZOSAddressMap;82      }83      TLSSupported = false;84      // All vector types are default aligned on an 8-byte boundary, even if the85      // vector facility is not available. That is different from Linux.86      MaxVectorAlign = 64;87      // Compared to Linux/ELF, the data layout differs only in some details:88      // - name mangling is GOFF.89      // - 32 bit pointers, either as default or special address space90      resetDataLayout("E-m:l-p1:32:32-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-"91                      "a:8:16-n32:64");92    } else {93      // Support _Float16.94      HasFloat16 = true;95      TLSSupported = true;96      resetDataLayout("E-m:e-i1:8:16-i8:8:16-i64:64-f128:64"97                      "-v128:64-a:8:16-n32:64");98    }99    MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 128;100 101    // True if the backend supports operations on the half LLVM IR type.102    // By setting this to false, conversions will happen for _Float16 around103    // a statement by default, with operations done in float. However, if104    // -ffloat16-excess-precision=none is given, no conversions will be made105    // and instead the backend will promote each half operation to float106    // individually.107    HasFastHalfType = false;108 109    HasStrictFP = true;110  }111 112  unsigned getMinGlobalAlign(uint64_t Size, bool HasNonWeakDef) const override;113 114  bool useFP16ConversionIntrinsics() const override { return false; }115 116  void getTargetDefines(const LangOptions &Opts,117                        MacroBuilder &Builder) const override;118 119  llvm::SmallVector<Builtin::InfosShard> getTargetBuiltins() const override;120 121  ArrayRef<const char *> getGCCRegNames() const override;122 123  ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override {124    // No aliases.125    return {};126  }127 128  ArrayRef<TargetInfo::AddlRegName> getGCCAddlRegNames() const override;129 130  bool isSPRegName(StringRef RegName) const override {131    return RegName == "r15";132  }133 134  bool validateAsmConstraint(const char *&Name,135                             TargetInfo::ConstraintInfo &info) const override;136 137  std::string convertConstraint(const char *&Constraint) const override {138    switch (Constraint[0]) {139    case '@': // Flag output operand.140      if (llvm::StringRef(Constraint) == "@cc") {141        Constraint += 2;142        return std::string("{@cc}");143      }144      break;145    case 'p': // Keep 'p' constraint.146      return std::string("p");147    case 'Z':148      switch (Constraint[1]) {149      case 'Q': // Address with base and unsigned 12-bit displacement150      case 'R': // Likewise, plus an index151      case 'S': // Address with base and signed 20-bit displacement152      case 'T': // Likewise, plus an index153        // "^" hints llvm that this is a 2 letter constraint.154        // "Constraint++" is used to promote the string iterator155        // to the next constraint.156        return std::string("^") + std::string(Constraint++, 2);157      default:158        break;159      }160      break;161    default:162      break;163    }164    return TargetInfo::convertConstraint(Constraint);165  }166 167  std::string_view getClobbers() const override {168    // FIXME: Is this really right?169    return "";170  }171 172  BuiltinVaListKind getBuiltinVaListKind() const override {173    return TargetInfo::SystemZBuiltinVaList;174  }175 176  int getISARevision(StringRef Name) const;177 178  bool isValidCPUName(StringRef Name) const override {179    return getISARevision(Name) != -1;180  }181 182  void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;183 184  bool isValidTuneCPUName(StringRef Name) const override {185    return isValidCPUName(Name);186  }187 188  void fillValidTuneCPUList(SmallVectorImpl<StringRef> &Values) const override {189    fillValidCPUList(Values);190  }191 192  bool setCPU(const std::string &Name) override {193    ISARevision = getISARevision(Name);194    return ISARevision != -1;195  }196 197  bool198  initFeatureMap(llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags,199                 StringRef CPU,200                 const std::vector<std::string> &FeaturesVec) const override {201    int ISARevision = getISARevision(CPU);202    if (ISARevision >= 10)203      Features["transactional-execution"] = true;204    if (ISARevision >= 11)205      Features["vector"] = true;206    if (ISARevision >= 12)207      Features["vector-enhancements-1"] = true;208    if (ISARevision >= 13)209      Features["vector-enhancements-2"] = true;210    if (ISARevision >= 14)211      Features["nnp-assist"] = true;212    if (ISARevision >= 15) {213      Features["miscellaneous-extensions-4"] = true;214      Features["vector-enhancements-3"] = true;215    }216    return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);217  }218 219  bool handleTargetFeatures(std::vector<std::string> &Features,220                            DiagnosticsEngine &Diags) override {221    HasTransactionalExecution = false;222    HasVector = false;223    SoftFloat = false;224    UnalignedSymbols = false;225    for (const auto &Feature : Features) {226      if (Feature == "+transactional-execution")227        HasTransactionalExecution = true;228      else if (Feature == "+vector")229        HasVector = true;230      else if (Feature == "+soft-float")231        SoftFloat = true;232      else if (Feature == "+unaligned-symbols")233        UnalignedSymbols = true;234    }235    HasVector &= !SoftFloat;236 237    // If we use the vector ABI, vector types are 64-bit aligned. The238    // DataLayout string is always set to this alignment as it is not a239    // requirement that it follows the alignment emitted by the front end. It240    // is assumed generally that the Datalayout should reflect only the241    // target triple and not any specific feature.242    if (HasVector && !getTriple().isOSzOS())243      MaxVectorAlign = 64;244 245    return true;246  }247 248  bool hasFeature(StringRef Feature) const override;249 250  CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {251    switch (CC) {252    case CC_C:253    case CC_Swift:254    case CC_DeviceKernel:255      return CCCR_OK;256    case CC_SwiftAsync:257      return CCCR_Error;258    default:259      return CCCR_Warning;260    }261  }262 263  StringRef getABI() const override {264    if (HasVector)265      return "vector";266    return "";267  }268 269  const char *getLongDoubleMangling() const override { return "g"; }270 271  bool hasBitIntType() const override { return true; }272 273  int getEHDataRegisterNumber(unsigned RegNo) const override {274    return RegNo < 4 ? 6 + RegNo : -1;275  }276 277  bool hasSjLjLowering() const override { return true; }278 279  std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {280    return std::make_pair(256, 256);281  }282  uint64_t getPointerWidthV(LangAS AddrSpace) const override {283    return (getTriple().isOSzOS() && getTriple().isArch64Bit() &&284            getTargetAddressSpace(AddrSpace) == ptr32)285               ? 32286               : PointerWidth;287  }288 289  uint64_t getPointerAlignV(LangAS AddrSpace) const override {290    return getPointerWidthV(AddrSpace);291  }292};293} // namespace targets294} // namespace clang295#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SYSTEMZ_H296