1 //===--- M68k.cpp - Implement M68k targets feature support-------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements M68k TargetInfo objects.
11 //===----------------------------------------------------------------------===//
14 #include "clang/Basic/Builtins.h"
15 #include "clang/Basic/Diagnostic.h"
16 #include "clang/Basic/TargetBuiltins.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"
29 M68kTargetInfo::M68kTargetInfo(const llvm::Triple
&Triple
,
30 const TargetOptions
&Opts
)
31 : TargetInfo(Triple
), TargetOpts(Opts
) {
38 // FIXME how to wire it with the used object format?
41 // M68k pointers are always 32 bit wide even for 16-bit CPUs
42 Layout
+= "-p:32:16:32";
44 // M68k integer data types
45 Layout
+= "-i8:8:8-i16:16:16-i32:16:32";
47 // FIXME no floats at the moment
49 // The registers can hold 8, 16, 32 bits
50 Layout
+= "-n8:16:32";
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";
56 resetDataLayout(Layout
);
58 SizeType
= UnsignedInt
;
59 PtrDiffType
= SignedInt
;
60 IntPtrType
= SignedInt
;
63 bool M68kTargetInfo::setCPU(const std::string
&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
)
74 return CPU
!= CK_Unknown
;
77 void M68kTargetInfo::getTargetDefines(const LangOptions
&Opts
,
78 MacroBuilder
&Builder
) const {
81 Builder
.defineMacro("__m68k__");
83 Builder
.defineMacro("mc68000");
84 Builder
.defineMacro("__mc68000");
85 Builder
.defineMacro("__mc68000__");
87 // For sub-architecture
90 Builder
.defineMacro("mc68010");
91 Builder
.defineMacro("__mc68010");
92 Builder
.defineMacro("__mc68010__");
95 Builder
.defineMacro("mc68020");
96 Builder
.defineMacro("__mc68020");
97 Builder
.defineMacro("__mc68020__");
100 Builder
.defineMacro("mc68030");
101 Builder
.defineMacro("__mc68030");
102 Builder
.defineMacro("__mc68030__");
105 Builder
.defineMacro("mc68040");
106 Builder
.defineMacro("__mc68040");
107 Builder
.defineMacro("__mc68040__");
110 Builder
.defineMacro("mc68060");
111 Builder
.defineMacro("__mc68060");
112 Builder
.defineMacro("__mc68060__");
118 if (CPU
>= CK_68020
) {
119 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
120 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
121 Builder
.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
125 if (TargetOpts
.FeatureMap
.lookup("isa-68881") ||
126 TargetOpts
.FeatureMap
.lookup("isa-68882"))
127 Builder
.defineMacro("__HAVE_68881__");
130 ArrayRef
<Builtin::Info
> M68kTargetInfo::getTargetBuiltins() const {
135 bool M68kTargetInfo::hasFeature(StringRef Feature
) const {
136 // FIXME elaborate moar
137 return Feature
== "M68000";
140 const char *const M68kTargetInfo::GCCRegNames
[] = {
141 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
142 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
145 ArrayRef
<const char *> M68kTargetInfo::getGCCRegNames() const {
146 return llvm::ArrayRef(GCCRegNames
);
149 ArrayRef
<TargetInfo::GCCRegAlias
> M68kTargetInfo::getGCCRegAliases() const {
154 bool M68kTargetInfo::validateAsmConstraint(
155 const char *&Name
, TargetInfo::ConstraintInfo
&info
) const {
157 case 'a': // address register
158 case 'd': // data register
159 info
.setAllowsRegister();
161 case 'I': // constant integer in the range [1,8]
162 info
.setRequiresImmediate(1, 8);
164 case 'J': // constant signed 16-bit integer
165 info
.setRequiresImmediate(std::numeric_limits
<int16_t>::min(),
166 std::numeric_limits
<int16_t>::max());
168 case 'K': // constant that is NOT in the range of [-0x80, 0x80)
169 info
.setRequiresImmediate();
171 case 'L': // constant integer in the range [-8,-1]
172 info
.setRequiresImmediate(-8, -1);
174 case 'M': // constant that is NOT in the range of [-0x100, 0x100]
175 info
.setRequiresImmediate();
177 case 'N': // constant integer in the range [24,31]
178 info
.setRequiresImmediate(24, 31);
180 case 'O': // constant integer 16
181 info
.setRequiresImmediate(16);
183 case 'P': // constant integer in the range [8,15]
184 info
.setRequiresImmediate(8, 15);
189 case '0': // constant integer 0
190 info
.setRequiresImmediate(0);
192 case 'i': // constant integer
193 case 'j': // integer constant that doesn't fit in 16 bits
194 info
.setRequiresImmediate();
200 case 'Q': // address register indirect addressing
201 case 'U': // address register indirect w/ constant offset addressing
202 // TODO: Handle 'S' (basically 'm' when pc-rel is enforced) when
203 // '-mpcrel' flag is properly handled by the driver.
204 info
.setAllowsMemory();
212 std::optional
<std::string
>
213 M68kTargetInfo::handleAsmEscapedChar(char EscChar
) const {
233 return std::string(1, C
);
236 std::string
M68kTargetInfo::convertConstraint(const char *&Constraint
) const {
237 if (*Constraint
== 'C')
238 // Two-character constraint; add "^" hint for later parsing
239 return std::string("^") + std::string(Constraint
++, 2);
241 return std::string(1, *Constraint
);
244 std::string_view
M68kTargetInfo::getClobbers() const {
245 // FIXME: Is this really right?
249 TargetInfo::BuiltinVaListKind
M68kTargetInfo::getBuiltinVaListKind() const {
250 return TargetInfo::VoidPtrBuiltinVaList
;
253 } // namespace targets