Sparc.h 7.1 KB

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