Path: blob/main/contrib/llvm-project/clang/lib/Basic/Targets/Sparc.h
35266 views
//===--- Sparc.h - declare sparc target feature support ---------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file declares Sparc TargetInfo objects.9//10//===----------------------------------------------------------------------===//1112#ifndef LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H13#define LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H14#include "clang/Basic/TargetInfo.h"15#include "clang/Basic/TargetOptions.h"16#include "llvm/Support/Compiler.h"17#include "llvm/TargetParser/Triple.h"18namespace clang {19namespace targets {20// Shared base class for SPARC v8 (32-bit) and SPARC v9 (64-bit).21class LLVM_LIBRARY_VISIBILITY SparcTargetInfo : public TargetInfo {22static const TargetInfo::GCCRegAlias GCCRegAliases[];23static const char *const GCCRegNames[];24bool SoftFloat;2526public:27SparcTargetInfo(const llvm::Triple &Triple, const TargetOptions &)28: TargetInfo(Triple), SoftFloat(false) {}2930int getEHDataRegisterNumber(unsigned RegNo) const override {31if (RegNo == 0)32return 24;33if (RegNo == 1)34return 25;35return -1;36}3738bool handleTargetFeatures(std::vector<std::string> &Features,39DiagnosticsEngine &Diags) override {40// Check if software floating point is enabled41if (llvm::is_contained(Features, "+soft-float"))42SoftFloat = true;43return true;44}45void getTargetDefines(const LangOptions &Opts,46MacroBuilder &Builder) const override;4748bool hasFeature(StringRef Feature) const override;4950ArrayRef<Builtin::Info> getTargetBuiltins() const override {51// FIXME: Implement!52return std::nullopt;53}54BuiltinVaListKind getBuiltinVaListKind() const override {55return TargetInfo::VoidPtrBuiltinVaList;56}57ArrayRef<const char *> getGCCRegNames() const override;58ArrayRef<TargetInfo::GCCRegAlias> getGCCRegAliases() const override;59bool validateAsmConstraint(const char *&Name,60TargetInfo::ConstraintInfo &info) const override {61// FIXME: Implement!62switch (*Name) {63case 'I': // Signed 13-bit constant64case 'J': // Zero65case 'K': // 32-bit constant with the low 12 bits clear66case 'L': // A constant in the range supported by movcc (11-bit signed imm)67case 'M': // A constant in the range supported by movrcc (19-bit signed imm)68case 'N': // Same as 'K' but zext (required for SIMode)69case 'O': // The constant 409670return true;7172case 'f':73case 'e':74info.setAllowsRegister();75return true;76}77return false;78}79std::string_view getClobbers() const override {80// FIXME: Implement!81return "";82}8384// No Sparc V7 for now, the backend doesn't support it anyway.85enum CPUKind {86CK_GENERIC,87CK_V8,88CK_SUPERSPARC,89CK_SPARCLITE,90CK_F934,91CK_HYPERSPARC,92CK_SPARCLITE86X,93CK_SPARCLET,94CK_TSC701,95CK_V9,96CK_ULTRASPARC,97CK_ULTRASPARC3,98CK_NIAGARA,99CK_NIAGARA2,100CK_NIAGARA3,101CK_NIAGARA4,102CK_MYRIAD2100,103CK_MYRIAD2150,104CK_MYRIAD2155,105CK_MYRIAD2450,106CK_MYRIAD2455,107CK_MYRIAD2x5x,108CK_MYRIAD2080,109CK_MYRIAD2085,110CK_MYRIAD2480,111CK_MYRIAD2485,112CK_MYRIAD2x8x,113CK_LEON2,114CK_LEON2_AT697E,115CK_LEON2_AT697F,116CK_LEON3,117CK_LEON3_UT699,118CK_LEON3_GR712RC,119CK_LEON4,120CK_LEON4_GR740121} CPU = CK_GENERIC;122123enum CPUGeneration {124CG_V8,125CG_V9,126};127128CPUGeneration getCPUGeneration(CPUKind Kind) const;129130CPUKind getCPUKind(StringRef Name) const;131132bool isValidCPUName(StringRef Name) const override {133return getCPUKind(Name) != CK_GENERIC;134}135136void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;137138bool setCPU(const std::string &Name) override {139CPU = getCPUKind(Name);140return CPU != CK_GENERIC;141}142143std::pair<unsigned, unsigned> hardwareInterferenceSizes() const override {144return std::make_pair(32, 32);145}146};147148// SPARC v8 is the 32-bit mode selected by Triple::sparc.149class LLVM_LIBRARY_VISIBILITY SparcV8TargetInfo : public SparcTargetInfo {150public:151SparcV8TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)152: SparcTargetInfo(Triple, Opts) {153resetDataLayout("E-m:e-p:32:32-i64:64-f128:64-n32-S64");154// NetBSD / OpenBSD use long (same as llvm default); everyone else uses int.155switch (getTriple().getOS()) {156default:157SizeType = UnsignedInt;158IntPtrType = SignedInt;159PtrDiffType = SignedInt;160break;161case llvm::Triple::NetBSD:162case llvm::Triple::OpenBSD:163SizeType = UnsignedLong;164IntPtrType = SignedLong;165PtrDiffType = SignedLong;166break;167}168// Up to 32 bits (V8) or 64 bits (V9) are lock-free atomic, but we're169// willing to do atomic ops on up to 64 bits.170MaxAtomicPromoteWidth = 64;171if (getCPUGeneration(CPU) == CG_V9)172MaxAtomicInlineWidth = 64;173else174// FIXME: This isn't correct for plain V8 which lacks CAS,175// only for LEON 3+ and Myriad.176MaxAtomicInlineWidth = 32;177}178179void getTargetDefines(const LangOptions &Opts,180MacroBuilder &Builder) const override;181182bool hasBitIntType() const override { return true; }183};184185// SPARCV8el is the 32-bit little-endian mode selected by Triple::sparcel.186class LLVM_LIBRARY_VISIBILITY SparcV8elTargetInfo : public SparcV8TargetInfo {187public:188SparcV8elTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)189: SparcV8TargetInfo(Triple, Opts) {190resetDataLayout("e-m:e-p:32:32-i64:64-f128:64-n32-S64");191}192};193194// SPARC v9 is the 64-bit mode selected by Triple::sparcv9.195class LLVM_LIBRARY_VISIBILITY SparcV9TargetInfo : public SparcTargetInfo {196public:197SparcV9TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)198: SparcTargetInfo(Triple, Opts) {199// FIXME: Support Sparc quad-precision long double?200resetDataLayout("E-m:e-i64:64-n32:64-S128");201// This is an LP64 platform.202LongWidth = LongAlign = PointerWidth = PointerAlign = 64;203204// OpenBSD uses long long for int64_t and intmax_t.205if (getTriple().isOSOpenBSD())206IntMaxType = SignedLongLong;207else208IntMaxType = SignedLong;209Int64Type = IntMaxType;210211// The SPARCv8 System V ABI has long double 128-bits in size, but 64-bit212// aligned. The SPARCv9 SCD 2.4.1 says 16-byte aligned.213LongDoubleWidth = 128;214LongDoubleAlign = 128;215SuitableAlign = 128;216LongDoubleFormat = &llvm::APFloat::IEEEquad();217MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;218}219220void getTargetDefines(const LangOptions &Opts,221MacroBuilder &Builder) const override;222223bool isValidCPUName(StringRef Name) const override {224return getCPUGeneration(SparcTargetInfo::getCPUKind(Name)) == CG_V9;225}226227void fillValidCPUList(SmallVectorImpl<StringRef> &Values) const override;228229bool setCPU(const std::string &Name) override {230if (!SparcTargetInfo::setCPU(Name))231return false;232return getCPUGeneration(CPU) == CG_V9;233}234235bool hasBitIntType() const override { return true; }236};237} // namespace targets238} // namespace clang239#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPARC_H240241242