clang  19.0.0git
M68k.cpp
Go to the documentation of this file.
1 //===--- M68k.cpp - Implement M68k targets feature support-------------===//
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 implements M68k TargetInfo objects.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "M68k.h"
14 #include "clang/Basic/Builtins.h"
15 #include "clang/Basic/Diagnostic.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/ADT/StringSwitch.h"
20 #include "llvm/TargetParser/TargetParser.h"
21 #include <cstdint>
22 #include <cstring>
23 #include <limits>
24 #include <optional>
25 
26 namespace clang {
27 namespace targets {
28 
29 M68kTargetInfo::M68kTargetInfo(const llvm::Triple &Triple,
30  const TargetOptions &Opts)
31  : TargetInfo(Triple), TargetOpts(Opts) {
32 
33  std::string Layout;
34 
35  // M68k is Big Endian
36  Layout += "E";
37 
38  // FIXME how to wire it with the used object format?
39  Layout += "-m:e";
40 
41  // M68k pointers are always 32 bit wide even for 16-bit CPUs
42  Layout += "-p:32:16:32";
43 
44  // M68k integer data types
45  Layout += "-i8:8:8-i16:16:16-i32:16:32";
46 
47  // FIXME no floats at the moment
48 
49  // The registers can hold 8, 16, 32 bits
50  Layout += "-n8:16:32";
51 
52  // 16 bit alignment for both stack and aggregate
53  // in order to conform to ABI used by GCC
54  Layout += "-a:0:16-S16";
55 
56  resetDataLayout(Layout);
57 
61 }
62 
63 bool M68kTargetInfo::setCPU(const std::string &Name) {
64  StringRef N = Name;
65  CPU = llvm::StringSwitch<CPUKind>(N)
66  .Case("generic", CK_68000)
67  .Case("M68000", CK_68000)
68  .Case("M68010", CK_68010)
69  .Case("M68020", CK_68020)
70  .Case("M68030", CK_68030)
71  .Case("M68040", CK_68040)
72  .Case("M68060", CK_68060)
73  .Default(CK_Unknown);
74  return CPU != CK_Unknown;
75 }
76 
78  MacroBuilder &Builder) const {
79  using llvm::Twine;
80 
81  Builder.defineMacro("__m68k__");
82 
83  DefineStd(Builder, "mc68000", Opts);
84 
85  // For sub-architecture
86  switch (CPU) {
87  case CK_68010:
88  DefineStd(Builder, "mc68010", Opts);
89  break;
90  case CK_68020:
91  DefineStd(Builder, "mc68020", Opts);
92  break;
93  case CK_68030:
94  DefineStd(Builder, "mc68030", Opts);
95  break;
96  case CK_68040:
97  DefineStd(Builder, "mc68040", Opts);
98  break;
99  case CK_68060:
100  DefineStd(Builder, "mc68060", Opts);
101  break;
102  default:
103  break;
104  }
105 
106  if (CPU >= CK_68020) {
107  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
108  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
109  Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
110  }
111 
112  // Floating point
113  if (TargetOpts.FeatureMap.lookup("isa-68881") ||
114  TargetOpts.FeatureMap.lookup("isa-68882"))
115  Builder.defineMacro("__HAVE_68881__");
116 }
117 
119  // FIXME: Implement.
120  return std::nullopt;
121 }
122 
123 bool M68kTargetInfo::hasFeature(StringRef Feature) const {
124  // FIXME elaborate moar
125  return Feature == "M68000";
126 }
127 
128 const char *const M68kTargetInfo::GCCRegNames[] = {
129  "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
130  "a0", "a1", "a2", "a3", "a4", "a5", "a6", "sp",
131  "pc"};
132 
134  return llvm::ArrayRef(GCCRegNames);
135 }
136 
137 const TargetInfo::GCCRegAlias M68kTargetInfo::GCCRegAliases[] = {
138  {{"bp"}, "a5"},
139  {{"fp"}, "a6"},
140  {{"usp", "ssp", "isp", "a7"}, "sp"},
141 };
142 
144  return llvm::ArrayRef(GCCRegAliases);
145 }
146 
148  const char *&Name, TargetInfo::ConstraintInfo &info) const {
149  switch (*Name) {
150  case 'a': // address register
151  case 'd': // data register
152  info.setAllowsRegister();
153  return true;
154  case 'I': // constant integer in the range [1,8]
155  info.setRequiresImmediate(1, 8);
156  return true;
157  case 'J': // constant signed 16-bit integer
160  return true;
161  case 'K': // constant that is NOT in the range of [-0x80, 0x80)
162  info.setRequiresImmediate();
163  return true;
164  case 'L': // constant integer in the range [-8,-1]
165  info.setRequiresImmediate(-8, -1);
166  return true;
167  case 'M': // constant that is NOT in the range of [-0x100, 0x100]
168  info.setRequiresImmediate();
169  return true;
170  case 'N': // constant integer in the range [24,31]
171  info.setRequiresImmediate(24, 31);
172  return true;
173  case 'O': // constant integer 16
174  info.setRequiresImmediate(16);
175  return true;
176  case 'P': // constant integer in the range [8,15]
177  info.setRequiresImmediate(8, 15);
178  return true;
179  case 'C':
180  ++Name;
181  switch (*Name) {
182  case '0': // constant integer 0
183  info.setRequiresImmediate(0);
184  return true;
185  case 'i': // constant integer
186  case 'j': // integer constant that doesn't fit in 16 bits
187  info.setRequiresImmediate();
188  return true;
189  default:
190  break;
191  }
192  break;
193  case 'Q': // address register indirect addressing
194  case 'U': // address register indirect w/ constant offset addressing
195  // TODO: Handle 'S' (basically 'm' when pc-rel is enforced) when
196  // '-mpcrel' flag is properly handled by the driver.
197  info.setAllowsMemory();
198  return true;
199  default:
200  break;
201  }
202  return false;
203 }
204 
205 std::optional<std::string>
207  char C;
208  switch (EscChar) {
209  case '.':
210  case '#':
211  C = EscChar;
212  break;
213  case '/':
214  C = '%';
215  break;
216  case '$':
217  C = 's';
218  break;
219  case '&':
220  C = 'd';
221  break;
222  default:
223  return std::nullopt;
224  }
225 
226  return std::string(1, C);
227 }
228 
229 std::string M68kTargetInfo::convertConstraint(const char *&Constraint) const {
230  if (*Constraint == 'C')
231  // Two-character constraint; add "^" hint for later parsing
232  return std::string("^") + std::string(Constraint++, 2);
233 
234  return std::string(1, *Constraint);
235 }
236 
237 std::string_view M68kTargetInfo::getClobbers() const {
238  // FIXME: Is this really right?
239  return "";
240 }
241 
244 }
245 
248  switch (CC) {
249  case CC_C:
250  case CC_M68kRTD:
251  return CCCR_OK;
252  default:
254  }
255 }
256 } // namespace targets
257 } // namespace clang
Defines the Diagnostic-related interfaces.
Defines enum values for all the target-independent builtin functions.
Enumerates target-specific builtins in their own namespaces within namespace clang.
__DEVICE__ int min(int __a, int __b)
__DEVICE__ int max(int __a, int __b)
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:482
Exposes information about the current target.
Definition: TargetInfo.h:218
void resetDataLayout(StringRef DL, const char *UserLabelPrefix="")
Definition: TargetInfo.cpp:190
BuiltinVaListKind
The different kinds of __builtin_va_list types defined by the target implementation.
Definition: TargetInfo.h:319
@ VoidPtrBuiltinVaList
typedef void* __builtin_va_list;
Definition: TargetInfo.h:324
virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const
Determines whether a given calling convention is valid for the target.
Definition: TargetInfo.h:1679
Options for controlling the target.
Definition: TargetOptions.h:26
llvm::StringMap< bool > FeatureMap
The map of which features have been enabled disabled based on the command line.
Definition: TargetOptions.h:62
std::string convertConstraint(const char *&Constraint) const override
Definition: M68k.cpp:229
bool hasFeature(StringRef Feature) const override
Determine whether the given target has the given feature.
Definition: M68k.cpp:123
ArrayRef< Builtin::Info > getTargetBuiltins() const override
Return information about target-specific builtins for the current primary target, and info about whic...
Definition: M68k.cpp:118
std::optional< std::string > handleAsmEscapedChar(char EscChar) const override
Replace some escaped characters with another string based on target-specific rules.
Definition: M68k.cpp:206
BuiltinVaListKind getBuiltinVaListKind() const override
Returns the kind of __builtin_va_list type that should be used with this target.
Definition: M68k.cpp:242
bool setCPU(const std::string &Name) override
Target the specified CPU.
Definition: M68k.cpp:63
M68kTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
Definition: M68k.cpp:29
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override
Determines whether a given calling convention is valid for the target.
Definition: M68k.cpp:247
void getTargetDefines(const LangOptions &Opts, MacroBuilder &Builder) const override
===-— Other target property query methods -----------------------—===//
Definition: M68k.cpp:77
std::string_view getClobbers() const override
Returns a string of target-specific clobbers, in LLVM format.
Definition: M68k.cpp:237
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
Definition: M68k.cpp:143
ArrayRef< const char * > getGCCRegNames() const override
Definition: M68k.cpp:133
bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override
Definition: M68k.cpp:147
void DefineStd(MacroBuilder &Builder, StringRef MacroName, const LangOptions &Opts)
DefineStd - Define a macro name and standard variants.
Definition: Targets.cpp:60
The JSON file list parser is used to communicate input to InstallAPI.
CallingConv
CallingConv - Specifies the calling convention that a function uses.
Definition: Specifiers.h:275
@ CC_C
Definition: Specifiers.h:276
@ CC_M68kRTD
Definition: Specifiers.h:297
void setRequiresImmediate(int Min, int Max)
Definition: TargetInfo.h:1153