/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Basic/Targets/M68k.cpp
Line | Count | Source (jump to first uncovered line) |
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" |
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> |
24 | | |
25 | | namespace clang { |
26 | | namespace targets { |
27 | | |
28 | | M68kTargetInfo::M68kTargetInfo(const llvm::Triple &Triple, |
29 | | const TargetOptions &) |
30 | 6 | : TargetInfo(Triple) { |
31 | | |
32 | 6 | std::string Layout; |
33 | | |
34 | | // M68k is Big Endian |
35 | 6 | Layout += "E"; |
36 | | |
37 | | // FIXME how to wire it with the used object format? |
38 | 6 | Layout += "-m:e"; |
39 | | |
40 | | // M68k pointers are always 32 bit wide even for 16-bit CPUs |
41 | 6 | Layout += "-p:32:16:32"; |
42 | | |
43 | | // M68k integer data types |
44 | 6 | Layout += "-i8:8:8-i16:16:16-i32:16:32"; |
45 | | |
46 | | // FIXME no floats at the moment |
47 | | |
48 | | // The registers can hold 8, 16, 32 bits |
49 | 6 | Layout += "-n8:16:32"; |
50 | | |
51 | | // 16 bit alignment for both stack and aggregate |
52 | | // in order to conform to ABI used by GCC |
53 | 6 | Layout += "-a:0:16-S16"; |
54 | | |
55 | 6 | resetDataLayout(Layout); |
56 | | |
57 | 6 | SizeType = UnsignedInt; |
58 | 6 | PtrDiffType = SignedInt; |
59 | 6 | IntPtrType = SignedInt; |
60 | 6 | } clang::targets::M68kTargetInfo::M68kTargetInfo(llvm::Triple const&, clang::TargetOptions const&) Line | Count | Source | 30 | 6 | : TargetInfo(Triple) { | 31 | | | 32 | 6 | std::string Layout; | 33 | | | 34 | | // M68k is Big Endian | 35 | 6 | Layout += "E"; | 36 | | | 37 | | // FIXME how to wire it with the used object format? | 38 | 6 | Layout += "-m:e"; | 39 | | | 40 | | // M68k pointers are always 32 bit wide even for 16-bit CPUs | 41 | 6 | Layout += "-p:32:16:32"; | 42 | | | 43 | | // M68k integer data types | 44 | 6 | Layout += "-i8:8:8-i16:16:16-i32:16:32"; | 45 | | | 46 | | // FIXME no floats at the moment | 47 | | | 48 | | // The registers can hold 8, 16, 32 bits | 49 | 6 | Layout += "-n8:16:32"; | 50 | | | 51 | | // 16 bit alignment for both stack and aggregate | 52 | | // in order to conform to ABI used by GCC | 53 | 6 | Layout += "-a:0:16-S16"; | 54 | | | 55 | 6 | resetDataLayout(Layout); | 56 | | | 57 | 6 | SizeType = UnsignedInt; | 58 | 6 | PtrDiffType = SignedInt; | 59 | 6 | IntPtrType = SignedInt; | 60 | 6 | } |
Unexecuted instantiation: clang::targets::M68kTargetInfo::M68kTargetInfo(llvm::Triple const&, clang::TargetOptions const&) |
61 | | |
62 | 6 | bool M68kTargetInfo::setCPU(const std::string &Name) { |
63 | 6 | StringRef N = Name; |
64 | 6 | CPU = llvm::StringSwitch<CPUKind>(N) |
65 | 6 | .Case("generic", CK_68000) |
66 | 6 | .Case("M68000", CK_68000) |
67 | 6 | .Case("M68010", CK_68010) |
68 | 6 | .Case("M68020", CK_68020) |
69 | 6 | .Case("M68030", CK_68030) |
70 | 6 | .Case("M68040", CK_68040) |
71 | 6 | .Case("M68060", CK_68060) |
72 | 6 | .Default(CK_Unknown); |
73 | 6 | return CPU != CK_Unknown; |
74 | 6 | } |
75 | | |
76 | | void M68kTargetInfo::getTargetDefines(const LangOptions &Opts, |
77 | 6 | MacroBuilder &Builder) const { |
78 | 6 | using llvm::Twine; |
79 | | |
80 | 6 | Builder.defineMacro("__m68k__"); |
81 | | |
82 | 6 | Builder.defineMacro("mc68000"); |
83 | 6 | Builder.defineMacro("__mc68000"); |
84 | 6 | Builder.defineMacro("__mc68000__"); |
85 | | |
86 | | // For sub-architecture |
87 | 6 | switch (CPU) { |
88 | 1 | case CK_68010: |
89 | 1 | Builder.defineMacro("mc68010"); |
90 | 1 | Builder.defineMacro("__mc68010"); |
91 | 1 | Builder.defineMacro("__mc68010__"); |
92 | 1 | break; |
93 | 1 | case CK_68020: |
94 | 1 | Builder.defineMacro("mc68020"); |
95 | 1 | Builder.defineMacro("__mc68020"); |
96 | 1 | Builder.defineMacro("__mc68020__"); |
97 | 1 | break; |
98 | 1 | case CK_68030: |
99 | 1 | Builder.defineMacro("mc68030"); |
100 | 1 | Builder.defineMacro("__mc68030"); |
101 | 1 | Builder.defineMacro("__mc68030__"); |
102 | 1 | break; |
103 | 1 | case CK_68040: |
104 | 1 | Builder.defineMacro("mc68040"); |
105 | 1 | Builder.defineMacro("__mc68040"); |
106 | 1 | Builder.defineMacro("__mc68040__"); |
107 | 1 | break; |
108 | 1 | case CK_68060: |
109 | 1 | Builder.defineMacro("mc68060"); |
110 | 1 | Builder.defineMacro("__mc68060"); |
111 | 1 | Builder.defineMacro("__mc68060__"); |
112 | 1 | break; |
113 | 1 | default: |
114 | 1 | break; |
115 | 6 | } |
116 | 6 | } |
117 | | |
118 | 6 | ArrayRef<Builtin::Info> M68kTargetInfo::getTargetBuiltins() const { |
119 | | // FIXME: Implement. |
120 | 6 | return None; |
121 | 6 | } |
122 | | |
123 | 0 | bool M68kTargetInfo::hasFeature(StringRef Feature) const { |
124 | | // FIXME elaborate moar |
125 | 0 | return Feature == "M68000"; |
126 | 0 | } |
127 | | |
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"}; |
132 | | |
133 | 0 | ArrayRef<const char *> M68kTargetInfo::getGCCRegNames() const { |
134 | 0 | return llvm::makeArrayRef(GCCRegNames); |
135 | 0 | } |
136 | | |
137 | 0 | ArrayRef<TargetInfo::GCCRegAlias> M68kTargetInfo::getGCCRegAliases() const { |
138 | | // No aliases. |
139 | 0 | return None; |
140 | 0 | } |
141 | | |
142 | | bool M68kTargetInfo::validateAsmConstraint( |
143 | 0 | const char *&Name, TargetInfo::ConstraintInfo &info) const { |
144 | 0 | switch (*Name) { |
145 | 0 | case 'a': // address register |
146 | 0 | case 'd': // data register |
147 | 0 | info.setAllowsRegister(); |
148 | 0 | return true; |
149 | 0 | case 'I': // constant integer in the range [1,8] |
150 | 0 | info.setRequiresImmediate(1, 8); |
151 | 0 | return true; |
152 | 0 | case 'J': // constant signed 16-bit integer |
153 | 0 | info.setRequiresImmediate(std::numeric_limits<int16_t>::min(), |
154 | 0 | std::numeric_limits<int16_t>::max()); |
155 | 0 | return true; |
156 | 0 | case 'K': // constant that is NOT in the range of [-0x80, 0x80) |
157 | 0 | info.setRequiresImmediate(); |
158 | 0 | return true; |
159 | 0 | case 'L': // constant integer in the range [-8,-1] |
160 | 0 | info.setRequiresImmediate(-8, -1); |
161 | 0 | return true; |
162 | 0 | case 'M': // constant that is NOT in the range of [-0x100, 0x100] |
163 | 0 | info.setRequiresImmediate(); |
164 | 0 | return true; |
165 | 0 | case 'N': // constant integer in the range [24,31] |
166 | 0 | info.setRequiresImmediate(24, 31); |
167 | 0 | return true; |
168 | 0 | case 'O': // constant integer 16 |
169 | 0 | info.setRequiresImmediate(16); |
170 | 0 | return true; |
171 | 0 | case 'P': // constant integer in the range [8,15] |
172 | 0 | info.setRequiresImmediate(8, 15); |
173 | 0 | return true; |
174 | 0 | case 'C': |
175 | 0 | ++Name; |
176 | 0 | switch (*Name) { |
177 | 0 | case '0': // constant integer 0 |
178 | 0 | info.setRequiresImmediate(0); |
179 | 0 | return true; |
180 | 0 | case 'i': // constant integer |
181 | 0 | case 'j': // integer constant that doesn't fit in 16 bits |
182 | 0 | info.setRequiresImmediate(); |
183 | 0 | return true; |
184 | 0 | default: |
185 | 0 | break; |
186 | 0 | } |
187 | 0 | break; |
188 | 0 | default: |
189 | 0 | break; |
190 | 0 | } |
191 | 0 | return false; |
192 | 0 | } |
193 | | |
194 | | llvm::Optional<std::string> |
195 | 0 | M68kTargetInfo::handleAsmEscapedChar(char EscChar) const { |
196 | 0 | char C; |
197 | 0 | switch (EscChar) { |
198 | 0 | case '.': |
199 | 0 | case '#': |
200 | 0 | C = EscChar; |
201 | 0 | break; |
202 | 0 | case '/': |
203 | 0 | C = '%'; |
204 | 0 | break; |
205 | 0 | case '$': |
206 | 0 | C = 's'; |
207 | 0 | break; |
208 | 0 | case '&': |
209 | 0 | C = 'd'; |
210 | 0 | break; |
211 | 0 | default: |
212 | 0 | return llvm::None; |
213 | 0 | } |
214 | | |
215 | 0 | return std::string(1, C); |
216 | 0 | } |
217 | | |
218 | 0 | std::string M68kTargetInfo::convertConstraint(const char *&Constraint) const { |
219 | 0 | if (*Constraint == 'C') |
220 | | // Two-character constraint; add "^" hint for later parsing |
221 | 0 | return std::string("^") + std::string(Constraint++, 2); |
222 | | |
223 | 0 | return std::string(1, *Constraint); |
224 | 0 | } |
225 | | |
226 | 0 | const char *M68kTargetInfo::getClobbers() const { |
227 | | // FIXME: Is this really right? |
228 | 0 | return ""; |
229 | 0 | } |
230 | | |
231 | 0 | TargetInfo::BuiltinVaListKind M68kTargetInfo::getBuiltinVaListKind() const { |
232 | 0 | return TargetInfo::VoidPtrBuiltinVaList; |
233 | 0 | } |
234 | | |
235 | | } // namespace targets |
236 | | } // namespace clang |