[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / lib / Basic / Targets / M68k.cpp
blobada5b97ed66de43e1b627cd5c5cb61b694e611f0
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/Support/TargetParser.h"
21 #include <cstdint>
22 #include <cstring>
23 #include <limits>
25 namespace clang {
26 namespace targets {
28 M68kTargetInfo::M68kTargetInfo(const llvm::Triple &Triple,
29 const TargetOptions &)
30 : TargetInfo(Triple) {
32 std::string Layout;
34 // M68k is Big Endian
35 Layout += "E";
37 // FIXME how to wire it with the used object format?
38 Layout += "-m:e";
40 // M68k pointers are always 32 bit wide even for 16-bit CPUs
41 Layout += "-p:32:16:32";
43 // M68k integer data types
44 Layout += "-i8:8:8-i16:16:16-i32:16:32";
46 // FIXME no floats at the moment
48 // The registers can hold 8, 16, 32 bits
49 Layout += "-n8:16:32";
51 // 16 bit alignment for both stack and aggregate
52 // in order to conform to ABI used by GCC
53 Layout += "-a:0:16-S16";
55 resetDataLayout(Layout);
57 SizeType = UnsignedInt;
58 PtrDiffType = SignedInt;
59 IntPtrType = SignedInt;
62 bool M68kTargetInfo::setCPU(const std::string &Name) {
63 StringRef N = Name;
64 CPU = llvm::StringSwitch<CPUKind>(N)
65 .Case("generic", CK_68000)
66 .Case("M68000", CK_68000)
67 .Case("M68010", CK_68010)
68 .Case("M68020", CK_68020)
69 .Case("M68030", CK_68030)
70 .Case("M68040", CK_68040)
71 .Case("M68060", CK_68060)
72 .Default(CK_Unknown);
73 return CPU != CK_Unknown;
76 void M68kTargetInfo::getTargetDefines(const LangOptions &Opts,
77 MacroBuilder &Builder) const {
78 using llvm::Twine;
80 Builder.defineMacro("__m68k__");
82 Builder.defineMacro("mc68000");
83 Builder.defineMacro("__mc68000");
84 Builder.defineMacro("__mc68000__");
86 // For sub-architecture
87 switch (CPU) {
88 case CK_68010:
89 Builder.defineMacro("mc68010");
90 Builder.defineMacro("__mc68010");
91 Builder.defineMacro("__mc68010__");
92 break;
93 case CK_68020:
94 Builder.defineMacro("mc68020");
95 Builder.defineMacro("__mc68020");
96 Builder.defineMacro("__mc68020__");
97 break;
98 case CK_68030:
99 Builder.defineMacro("mc68030");
100 Builder.defineMacro("__mc68030");
101 Builder.defineMacro("__mc68030__");
102 break;
103 case CK_68040:
104 Builder.defineMacro("mc68040");
105 Builder.defineMacro("__mc68040");
106 Builder.defineMacro("__mc68040__");
107 break;
108 case CK_68060:
109 Builder.defineMacro("mc68060");
110 Builder.defineMacro("__mc68060");
111 Builder.defineMacro("__mc68060__");
112 break;
113 default:
114 break;
118 ArrayRef<Builtin::Info> M68kTargetInfo::getTargetBuiltins() const {
119 // FIXME: Implement.
120 return None;
123 bool M68kTargetInfo::hasFeature(StringRef Feature) const {
124 // FIXME elaborate moar
125 return Feature == "M68000";
128 const char *const M68kTargetInfo::GCCRegNames[] = {
129 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
130 "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
131 "pc"};
133 ArrayRef<const char *> M68kTargetInfo::getGCCRegNames() const {
134 return llvm::makeArrayRef(GCCRegNames);
137 ArrayRef<TargetInfo::GCCRegAlias> M68kTargetInfo::getGCCRegAliases() const {
138 // No aliases.
139 return None;
142 bool M68kTargetInfo::validateAsmConstraint(
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)
157 info.setRequiresImmediate();
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]
163 info.setRequiresImmediate();
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
182 info.setRequiresImmediate();
183 return true;
184 default:
185 break;
187 break;
188 default:
189 break;
191 return false;
194 llvm::Optional<std::string>
195 M68kTargetInfo::handleAsmEscapedChar(char EscChar) const {
196 char C;
197 switch (EscChar) {
198 case '.':
199 case '#':
200 C = EscChar;
201 break;
202 case '/':
203 C = '%';
204 break;
205 case '$':
206 C = 's';
207 break;
208 case '&':
209 C = 'd';
210 break;
211 default:
212 return llvm::None;
215 return std::string(1, C);
218 std::string M68kTargetInfo::convertConstraint(const char *&Constraint) const {
219 if (*Constraint == 'C')
220 // Two-character constraint; add "^" hint for later parsing
221 return std::string("^") + std::string(Constraint++, 2);
223 return std::string(1, *Constraint);
226 const char *M68kTargetInfo::getClobbers() const {
227 // FIXME: Is this really right?
228 return "";
231 TargetInfo::BuiltinVaListKind M68kTargetInfo::getBuiltinVaListKind() const {
232 return TargetInfo::VoidPtrBuiltinVaList;
235 } // namespace targets
236 } // namespace clang