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"
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
26namespace clang {
27namespace targets {
28
29M68kTargetInfo::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
63bool 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
123bool M68kTargetInfo::hasFeature(StringRef Feature) const {
124 // FIXME elaborate moar
125 return Feature == "M68000";
126}
127
128const char *const M68kTargetInfo::GCCRegNames[] = {
129 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
130 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
131 "pc"};
132
134 return llvm::ArrayRef(GCCRegNames);
135}
136
138 // No aliases.
139 return std::nullopt;
140}
141
143 const char *&Name, TargetInfo::ConstraintInfo &info) const {
144 switch (*Name) {
145 case 'a': // address register
146 case 'd': // data register
147 info.setAllowsRegister();
148 return true;
149 case 'I': // constant integer in the range [1,8]
150 info.setRequiresImmediate(1, 8);
151 return true;
152 case 'J': // constant signed 16-bit integer
153 info.setRequiresImmediate(std::numeric_limits<int16_t>::min(),
154 std::numeric_limits<int16_t>::max());
155 return true;
156 case 'K': // constant that is NOT in the range of [-0x80, 0x80)
158 return true;
159 case 'L': // constant integer in the range [-8,-1]
160 info.setRequiresImmediate(-8, -1);
161 return true;
162 case 'M': // constant that is NOT in the range of [-0x100, 0x100]
164 return true;
165 case 'N': // constant integer in the range [24,31]
166 info.setRequiresImmediate(24, 31);
167 return true;
168 case 'O': // constant integer 16
169 info.setRequiresImmediate(16);
170 return true;
171 case 'P': // constant integer in the range [8,15]
172 info.setRequiresImmediate(8, 15);
173 return true;
174 case 'C':
175 ++Name;
176 switch (*Name) {
177 case '0': // constant integer 0
178 info.setRequiresImmediate(0);
179 return true;
180 case 'i': // constant integer
181 case 'j': // integer constant that doesn't fit in 16 bits
183 return true;
184 default:
185 break;
186 }
187 break;
188 case 'Q': // address register indirect addressing
189 case 'U': // address register indirect w/ constant offset addressing
190 // TODO: Handle 'S' (basically 'm' when pc-rel is enforced) when
191 // '-mpcrel' flag is properly handled by the driver.
192 info.setAllowsMemory();
193 return true;
194 default:
195 break;
196 }
197 return false;
198}
199
200std::optional<std::string>
202 char C;
203 switch (EscChar) {
204 case '.':
205 case '#':
206 C = EscChar;
207 break;
208 case '/':
209 C = '%';
210 break;
211 case '$':
212 C = 's';
213 break;
214 case '&':
215 C = 'd';
216 break;
217 default:
218 return std::nullopt;
219 }
220
221 return std::string(1, C);
222}
223
224std::string M68kTargetInfo::convertConstraint(const char *&Constraint) const {
225 if (*Constraint == 'C')
226 // Two-character constraint; add "^" hint for later parsing
227 return std::string("^") + std::string(Constraint++, 2);
228
229 return std::string(1, *Constraint);
230}
231
232std::string_view M68kTargetInfo::getClobbers() const {
233 // FIXME: Is this really right?
234 return "";
235}
236
239}
240
243 switch (CC) {
244 case CC_C:
245 case CC_M68kRTD:
246 return CCCR_OK;
247 default:
249 }
250}
251} // namespace targets
252} // 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.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:418
Exposes information about the current target.
Definition: TargetInfo.h:212
void resetDataLayout(StringRef DL, const char *UserLabelPrefix="")
Definition: TargetInfo.cpp:189
BuiltinVaListKind
The different kinds of __builtin_va_list types defined by the target implementation.
Definition: TargetInfo.h:310
@ VoidPtrBuiltinVaList
typedef void* __builtin_va_list;
Definition: TargetInfo.h:315
virtual CallingConvCheckResult checkCallingConvention(CallingConv CC) const
Determines whether a given calling convention is valid for the target.
Definition: TargetInfo.h:1637
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:224
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:201
BuiltinVaListKind getBuiltinVaListKind() const override
Returns the kind of __builtin_va_list type that should be used with this target.
Definition: M68k.cpp:237
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:242
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:232
ArrayRef< TargetInfo::GCCRegAlias > getGCCRegAliases() const override
Definition: M68k.cpp:137
ArrayRef< const char * > getGCCRegNames() const override
Definition: M68k.cpp:133
bool validateAsmConstraint(const char *&Name, TargetInfo::ConstraintInfo &info) const override
Definition: M68k.cpp:142
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:1116