[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / lib / Basic / Targets / M68k.cpp
blobcbc7c79837792ba375bbb48dfd3f7e55a9f09bf6
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.
11 //===----------------------------------------------------------------------===//
13 #include "M68k.h"
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"
21 #include <cstdint>
22 #include <cstring>
23 #include <limits>
24 #include <optional>
26 namespace clang {
27 namespace targets {
29 M68kTargetInfo::M68kTargetInfo(const llvm::Triple &Triple,
30 const TargetOptions &)
31 : TargetInfo(Triple) {
33 std::string Layout;
35 // M68k is Big Endian
36 Layout += "E";
38 // FIXME how to wire it with the used object format?
39 Layout += "-m:e";
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) {
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;
77 void M68kTargetInfo::getTargetDefines(const LangOptions &Opts,
78 MacroBuilder &Builder) const {
79 using llvm::Twine;
81 Builder.defineMacro("__m68k__");
83 Builder.defineMacro("mc68000");
84 Builder.defineMacro("__mc68000");
85 Builder.defineMacro("__mc68000__");
87 // For sub-architecture
88 switch (CPU) {
89 case CK_68010:
90 Builder.defineMacro("mc68010");
91 Builder.defineMacro("__mc68010");
92 Builder.defineMacro("__mc68010__");
93 break;
94 case CK_68020:
95 Builder.defineMacro("mc68020");
96 Builder.defineMacro("__mc68020");
97 Builder.defineMacro("__mc68020__");
98 break;
99 case CK_68030:
100 Builder.defineMacro("mc68030");
101 Builder.defineMacro("__mc68030");
102 Builder.defineMacro("__mc68030__");
103 break;
104 case CK_68040:
105 Builder.defineMacro("mc68040");
106 Builder.defineMacro("__mc68040");
107 Builder.defineMacro("__mc68040__");
108 break;
109 case CK_68060:
110 Builder.defineMacro("mc68060");
111 Builder.defineMacro("__mc68060");
112 Builder.defineMacro("__mc68060__");
113 break;
114 default:
115 break;
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 ArrayRef<Builtin::Info> M68kTargetInfo::getTargetBuiltins() const {
126 // FIXME: Implement.
127 return std::nullopt;
130 bool M68kTargetInfo::hasFeature(StringRef Feature) const {
131 // FIXME elaborate moar
132 return Feature == "M68000";
135 const char *const M68kTargetInfo::GCCRegNames[] = {
136 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
137 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
138 "pc"};
140 ArrayRef<const char *> M68kTargetInfo::getGCCRegNames() const {
141 return llvm::ArrayRef(GCCRegNames);
144 ArrayRef<TargetInfo::GCCRegAlias> M68kTargetInfo::getGCCRegAliases() const {
145 // No aliases.
146 return std::nullopt;
149 bool M68kTargetInfo::validateAsmConstraint(
150 const char *&Name, TargetInfo::ConstraintInfo &info) const {
151 switch (*Name) {
152 case 'a': // address register
153 case 'd': // data register
154 info.setAllowsRegister();
155 return true;
156 case 'I': // constant integer in the range [1,8]
157 info.setRequiresImmediate(1, 8);
158 return true;
159 case 'J': // constant signed 16-bit integer
160 info.setRequiresImmediate(std::numeric_limits<int16_t>::min(),
161 std::numeric_limits<int16_t>::max());
162 return true;
163 case 'K': // constant that is NOT in the range of [-0x80, 0x80)
164 info.setRequiresImmediate();
165 return true;
166 case 'L': // constant integer in the range [-8,-1]
167 info.setRequiresImmediate(-8, -1);
168 return true;
169 case 'M': // constant that is NOT in the range of [-0x100, 0x100]
170 info.setRequiresImmediate();
171 return true;
172 case 'N': // constant integer in the range [24,31]
173 info.setRequiresImmediate(24, 31);
174 return true;
175 case 'O': // constant integer 16
176 info.setRequiresImmediate(16);
177 return true;
178 case 'P': // constant integer in the range [8,15]
179 info.setRequiresImmediate(8, 15);
180 return true;
181 case 'C':
182 ++Name;
183 switch (*Name) {
184 case '0': // constant integer 0
185 info.setRequiresImmediate(0);
186 return true;
187 case 'i': // constant integer
188 case 'j': // integer constant that doesn't fit in 16 bits
189 info.setRequiresImmediate();
190 return true;
191 default:
192 break;
194 break;
195 default:
196 break;
198 return false;
201 std::optional<std::string>
202 M68kTargetInfo::handleAsmEscapedChar(char EscChar) const {
203 char C;
204 switch (EscChar) {
205 case '.':
206 case '#':
207 C = EscChar;
208 break;
209 case '/':
210 C = '%';
211 break;
212 case '$':
213 C = 's';
214 break;
215 case '&':
216 C = 'd';
217 break;
218 default:
219 return std::nullopt;
222 return std::string(1, C);
225 std::string M68kTargetInfo::convertConstraint(const char *&Constraint) const {
226 if (*Constraint == 'C')
227 // Two-character constraint; add "^" hint for later parsing
228 return std::string("^") + std::string(Constraint++, 2);
230 return std::string(1, *Constraint);
233 const char *M68kTargetInfo::getClobbers() const {
234 // FIXME: Is this really right?
235 return "";
238 TargetInfo::BuiltinVaListKind M68kTargetInfo::getBuiltinVaListKind() const {
239 return TargetInfo::VoidPtrBuiltinVaList;
242 } // namespace targets
243 } // namespace clang