1 | //===- unittests/Driver/MultilibTest.cpp --- Multilib tests ---------------===// |
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 | // Unit tests for Multilib and MultilibSet |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "clang/Driver/Multilib.h" |
14 | #include "SimpleDiagnosticConsumer.h" |
15 | #include "clang/Basic/LLVM.h" |
16 | #include "clang/Basic/Version.h" |
17 | #include "clang/Driver/CommonArgs.h" |
18 | #include "llvm/ADT/ArrayRef.h" |
19 | #include "llvm/ADT/StringRef.h" |
20 | #include "llvm/ADT/StringSwitch.h" |
21 | #include "llvm/Support/SourceMgr.h" |
22 | #include "gtest/gtest.h" |
23 | |
24 | using namespace clang::driver; |
25 | using namespace clang; |
26 | |
27 | TEST(MultilibTest, OpEqReflexivity1) { |
28 | Multilib M; |
29 | ASSERT_TRUE(M == M) << "Multilib::operator==() is not reflexive" ; |
30 | } |
31 | |
32 | TEST(MultilibTest, OpEqReflexivity2) { |
33 | ASSERT_TRUE(Multilib() == Multilib()) |
34 | << "Separately constructed default multilibs are not equal" ; |
35 | } |
36 | |
37 | TEST(MultilibTest, OpEqReflexivity3) { |
38 | Multilib M1({}, {}, {}, {"+foo" }); |
39 | Multilib M2({}, {}, {}, {"+foo" }); |
40 | ASSERT_TRUE(M1 == M2) << "Multilibs with the same flag should be the same" ; |
41 | } |
42 | |
43 | TEST(MultilibTest, OpEqInequivalence1) { |
44 | Multilib M1({}, {}, {}, {"+foo" }); |
45 | Multilib M2({}, {}, {}, {"-foo" }); |
46 | ASSERT_FALSE(M1 == M2) << "Multilibs with conflicting flags are not the same" ; |
47 | ASSERT_FALSE(M2 == M1) |
48 | << "Multilibs with conflicting flags are not the same (commuted)" ; |
49 | } |
50 | |
51 | TEST(MultilibTest, OpEqInequivalence2) { |
52 | Multilib M1; |
53 | Multilib M2({}, {}, {}, {"+foo" }); |
54 | ASSERT_FALSE(M1 == M2) << "Flags make Multilibs different" ; |
55 | } |
56 | |
57 | TEST(MultilibTest, OpEqEquivalence2) { |
58 | Multilib M1("/64" ); |
59 | Multilib M2("/64" ); |
60 | ASSERT_TRUE(M1 == M2) |
61 | << "Constructor argument must match Multilib::gccSuffix()" ; |
62 | ASSERT_TRUE(M2 == M1) |
63 | << "Constructor argument must match Multilib::gccSuffix() (commuted)" ; |
64 | } |
65 | |
66 | TEST(MultilibTest, OpEqEquivalence3) { |
67 | Multilib M1("" , "/32" ); |
68 | Multilib M2("" , "/32" ); |
69 | ASSERT_TRUE(M1 == M2) |
70 | << "Constructor argument must match Multilib::osSuffix()" ; |
71 | ASSERT_TRUE(M2 == M1) |
72 | << "Constructor argument must match Multilib::osSuffix() (commuted)" ; |
73 | } |
74 | |
75 | TEST(MultilibTest, OpEqEquivalence4) { |
76 | Multilib M1("" , "" , "/16" ); |
77 | Multilib M2("" , "" , "/16" ); |
78 | ASSERT_TRUE(M1 == M2) |
79 | << "Constructor argument must match Multilib::includeSuffix()" ; |
80 | ASSERT_TRUE(M2 == M1) |
81 | << "Constructor argument must match Multilib::includeSuffix() (commuted)" ; |
82 | } |
83 | |
84 | TEST(MultilibTest, OpEqInequivalence3) { |
85 | Multilib M1("/foo" ); |
86 | Multilib M2("/bar" ); |
87 | ASSERT_FALSE(M1 == M2) << "Differing gccSuffixes should be different" ; |
88 | ASSERT_FALSE(M2 == M1) |
89 | << "Differing gccSuffixes should be different (commuted)" ; |
90 | } |
91 | |
92 | TEST(MultilibTest, OpEqInequivalence4) { |
93 | Multilib M1("" , "/foo" ); |
94 | Multilib M2("" , "/bar" ); |
95 | ASSERT_FALSE(M1 == M2) << "Differing osSuffixes should be different" ; |
96 | ASSERT_FALSE(M2 == M1) |
97 | << "Differing osSuffixes should be different (commuted)" ; |
98 | } |
99 | |
100 | TEST(MultilibTest, OpEqInequivalence5) { |
101 | Multilib M1("" , "" , "/foo" ); |
102 | Multilib M2("" , "" , "/bar" ); |
103 | ASSERT_FALSE(M1 == M2) << "Differing includeSuffixes should be different" ; |
104 | ASSERT_FALSE(M2 == M1) |
105 | << "Differing includeSuffixes should be different (commuted)" ; |
106 | } |
107 | |
108 | TEST(MultilibTest, Construction1) { |
109 | Multilib M("/gcc64" , "/os64" , "/inc64" ); |
110 | ASSERT_TRUE(M.gccSuffix() == "/gcc64" ); |
111 | ASSERT_TRUE(M.osSuffix() == "/os64" ); |
112 | ASSERT_TRUE(M.includeSuffix() == "/inc64" ); |
113 | } |
114 | |
115 | TEST(MultilibTest, Construction2) { |
116 | Multilib M1; |
117 | Multilib M2("" ); |
118 | Multilib M3("" , "" ); |
119 | Multilib M4("" , "" , "" ); |
120 | ASSERT_TRUE(M1 == M2) |
121 | << "Default arguments to Multilib constructor broken (first argument)" ; |
122 | ASSERT_TRUE(M1 == M3) |
123 | << "Default arguments to Multilib constructor broken (second argument)" ; |
124 | ASSERT_TRUE(M1 == M4) |
125 | << "Default arguments to Multilib constructor broken (third argument)" ; |
126 | } |
127 | |
128 | TEST(MultilibTest, Construction3) { |
129 | Multilib M({}, {}, {}, {"+f1" , "+f2" , "-f3" }); |
130 | for (Multilib::flags_list::const_iterator I = M.flags().begin(), |
131 | E = M.flags().end(); |
132 | I != E; ++I) { |
133 | ASSERT_TRUE(llvm::StringSwitch<bool>(*I) |
134 | .Cases("+f1" , "+f2" , "-f3" , true) |
135 | .Default(false)); |
136 | } |
137 | } |
138 | |
139 | TEST(MultilibTest, SetPushback) { |
140 | MultilibSet MS({ |
141 | Multilib("/one" ), |
142 | Multilib("/two" ), |
143 | }); |
144 | ASSERT_TRUE(MS.size() == 2); |
145 | for (MultilibSet::const_iterator I = MS.begin(), E = MS.end(); I != E; ++I) { |
146 | ASSERT_TRUE(llvm::StringSwitch<bool>(I->gccSuffix()) |
147 | .Cases("/one" , "/two" , true) |
148 | .Default(false)); |
149 | } |
150 | } |
151 | |
152 | TEST(MultilibTest, SetPriority) { |
153 | MultilibSet MS({ |
154 | Multilib("/foo" , {}, {}, {"+foo" }), |
155 | Multilib("/bar" , {}, {}, {"+bar" }), |
156 | }); |
157 | Driver TheDriver = diagnostic_test_driver(); |
158 | Multilib::flags_list Flags1 = {"+foo" , "-bar" }; |
159 | llvm::SmallVector<Multilib> Selection1; |
160 | ASSERT_TRUE(MS.select(TheDriver, Flags1, Selection1)) |
161 | << "Flag set was {\"+foo\"}, but selection not found" ; |
162 | ASSERT_TRUE(Selection1.back().gccSuffix() == "/foo" ) |
163 | << "Selection picked " << Selection1.back() << " which was not expected" ; |
164 | |
165 | Multilib::flags_list Flags2 = {"+foo" , "+bar" }; |
166 | llvm::SmallVector<Multilib> Selection2; |
167 | ASSERT_TRUE(MS.select(TheDriver, Flags2, Selection2)) |
168 | << "Flag set was {\"+bar\"}, but selection not found" ; |
169 | ASSERT_TRUE(Selection2.back().gccSuffix() == "/bar" ) |
170 | << "Selection picked " << Selection2.back() << " which was not expected" ; |
171 | } |
172 | |
173 | TEST(MultilibTest, SelectMultiple) { |
174 | MultilibSet MS({ |
175 | Multilib("/a" , {}, {}, {"x" }), |
176 | Multilib("/b" , {}, {}, {"y" }), |
177 | }); |
178 | llvm::SmallVector<Multilib> Selection; |
179 | Driver TheDriver = diagnostic_test_driver(); |
180 | |
181 | ASSERT_TRUE(MS.select(TheDriver, {"x" }, Selection)); |
182 | ASSERT_EQ(1u, Selection.size()); |
183 | EXPECT_EQ("/a" , Selection[0].gccSuffix()); |
184 | |
185 | ASSERT_TRUE(MS.select(TheDriver, {"y" }, Selection)); |
186 | ASSERT_EQ(1u, Selection.size()); |
187 | EXPECT_EQ("/b" , Selection[0].gccSuffix()); |
188 | |
189 | ASSERT_TRUE(MS.select(TheDriver, {"y" , "x" }, Selection)); |
190 | ASSERT_EQ(2u, Selection.size()); |
191 | EXPECT_EQ("/a" , Selection[0].gccSuffix()); |
192 | EXPECT_EQ("/b" , Selection[1].gccSuffix()); |
193 | } |
194 | |
195 | static void diagnosticCallback(const llvm::SMDiagnostic &D, void *Out) { |
196 | *reinterpret_cast<std::string *>(Out) = D.getMessage(); |
197 | } |
198 | |
199 | static bool parseYaml(MultilibSet &MS, std::string &Diagnostic, |
200 | const char *Data) { |
201 | auto ErrorOrMS = MultilibSet::parseYaml(llvm::MemoryBufferRef(Data, "TEST" ), |
202 | diagnosticCallback, DiagHandlerCtxt: &Diagnostic); |
203 | if (ErrorOrMS.getError()) |
204 | return false; |
205 | MS = std::move(ErrorOrMS.get()); |
206 | return true; |
207 | } |
208 | |
209 | static bool parseYaml(MultilibSet &MS, const char *Data) { |
210 | auto ErrorOrMS = MultilibSet::parseYaml(llvm::MemoryBufferRef(Data, "TEST" )); |
211 | if (ErrorOrMS.getError()) |
212 | return false; |
213 | MS = std::move(ErrorOrMS.get()); |
214 | return true; |
215 | } |
216 | |
217 | // When updating this version also update MultilibVersionCurrent in Multilib.cpp |
218 | #define YAML_PREAMBLE "MultilibVersion: 1.0\n" |
219 | |
220 | TEST(MultilibTest, ParseInvalid) { |
221 | std::string Diagnostic; |
222 | |
223 | MultilibSet MS; |
224 | |
225 | EXPECT_FALSE(parseYaml(MS, Diagnostic, R"( |
226 | Variants: [] |
227 | )" )); |
228 | EXPECT_TRUE( |
229 | StringRef(Diagnostic).contains("missing required key 'MultilibVersion'" )) |
230 | << Diagnostic; |
231 | |
232 | // Reject files with a different major version |
233 | EXPECT_FALSE(parseYaml(MS, Diagnostic, |
234 | R"( |
235 | MultilibVersion: 2.0 |
236 | Variants: [] |
237 | )" )); |
238 | EXPECT_TRUE( |
239 | StringRef(Diagnostic).contains("multilib version 2.0 is unsupported" )) |
240 | << Diagnostic; |
241 | EXPECT_FALSE(parseYaml(MS, Diagnostic, |
242 | R"( |
243 | MultilibVersion: 0.1 |
244 | Variants: [] |
245 | )" )); |
246 | EXPECT_TRUE( |
247 | StringRef(Diagnostic).contains("multilib version 0.1 is unsupported" )) |
248 | << Diagnostic; |
249 | |
250 | // Reject files with a later minor version |
251 | EXPECT_FALSE(parseYaml(MS, Diagnostic, |
252 | R"( |
253 | MultilibVersion: 1.9 |
254 | Variants: [] |
255 | )" )); |
256 | EXPECT_TRUE( |
257 | StringRef(Diagnostic).contains("multilib version 1.9 is unsupported" )) |
258 | << Diagnostic; |
259 | |
260 | // Accept files with the same major version and the same or earlier minor |
261 | // version |
262 | EXPECT_TRUE(parseYaml(MS, Diagnostic, R"( |
263 | MultilibVersion: 1.0 |
264 | Variants: [] |
265 | )" )) << Diagnostic; |
266 | |
267 | EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE)); |
268 | EXPECT_TRUE(StringRef(Diagnostic).contains("missing required key 'Variants'" )) |
269 | << Diagnostic; |
270 | |
271 | EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"( |
272 | Variants: |
273 | - Dir: /abc |
274 | Flags: [] |
275 | )" )); |
276 | EXPECT_TRUE(StringRef(Diagnostic).contains("paths must be relative" )) |
277 | << Diagnostic; |
278 | |
279 | EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"( |
280 | Variants: |
281 | - Flags: [] |
282 | )" )); |
283 | EXPECT_TRUE( |
284 | StringRef(Diagnostic) |
285 | .contains("one of the 'Dir' and 'Error' keys must be specified" )) |
286 | << Diagnostic; |
287 | |
288 | EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"( |
289 | Variants: |
290 | - Dir: . |
291 | )" )); |
292 | EXPECT_TRUE(StringRef(Diagnostic).contains("missing required key 'Flags'" )) |
293 | << Diagnostic; |
294 | |
295 | EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"( |
296 | Variants: [] |
297 | Mappings: |
298 | - Match: abc |
299 | )" )); |
300 | EXPECT_TRUE(StringRef(Diagnostic).contains("value required for 'Flags'" )) |
301 | << Diagnostic; |
302 | |
303 | EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"( |
304 | Variants: [] |
305 | Mappings: |
306 | - Dir: . |
307 | Match: '(' |
308 | Flags: [] |
309 | )" )); |
310 | EXPECT_TRUE(StringRef(Diagnostic).contains("parentheses not balanced" )) |
311 | << Diagnostic; |
312 | } |
313 | |
314 | TEST(MultilibTest, Parse) { |
315 | MultilibSet MS; |
316 | EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( |
317 | Variants: |
318 | - Dir: . |
319 | Flags: [] |
320 | )" )); |
321 | EXPECT_EQ(1U, MS.size()); |
322 | EXPECT_EQ("" , MS.begin()->gccSuffix()); |
323 | |
324 | EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( |
325 | Variants: |
326 | - Dir: abc |
327 | Flags: [] |
328 | )" )); |
329 | EXPECT_EQ(1U, MS.size()); |
330 | EXPECT_EQ("/abc" , MS.begin()->gccSuffix()); |
331 | |
332 | EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( |
333 | Variants: |
334 | - Dir: pqr |
335 | Flags: [-mfloat-abi=soft] |
336 | )" )); |
337 | EXPECT_EQ(1U, MS.size()); |
338 | EXPECT_EQ("/pqr" , MS.begin()->gccSuffix()); |
339 | EXPECT_EQ(std::vector<std::string>({"-mfloat-abi=soft" }), |
340 | MS.begin()->flags()); |
341 | |
342 | EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( |
343 | Variants: |
344 | - Dir: pqr |
345 | Flags: [-mfloat-abi=soft, -fno-exceptions] |
346 | )" )); |
347 | EXPECT_EQ(1U, MS.size()); |
348 | EXPECT_EQ(std::vector<std::string>({"-mfloat-abi=soft" , "-fno-exceptions" }), |
349 | MS.begin()->flags()); |
350 | |
351 | EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( |
352 | Variants: |
353 | - Dir: a |
354 | Flags: [] |
355 | - Dir: b |
356 | Flags: [] |
357 | )" )); |
358 | EXPECT_EQ(2U, MS.size()); |
359 | } |
360 | |
361 | TEST(MultilibTest, SelectSoft) { |
362 | MultilibSet MS; |
363 | llvm::SmallVector<Multilib> Selected; |
364 | ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( |
365 | Variants: |
366 | - Dir: s |
367 | Flags: [-mfloat-abi=soft] |
368 | Mappings: |
369 | - Match: -mfloat-abi=softfp |
370 | Flags: [-mfloat-abi=soft] |
371 | )" )); |
372 | Driver TheDriver = diagnostic_test_driver(); |
373 | EXPECT_TRUE(MS.select(TheDriver, {"-mfloat-abi=soft" }, Selected)); |
374 | EXPECT_TRUE(MS.select(TheDriver, {"-mfloat-abi=softfp" }, Selected)); |
375 | EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=hard" }, Selected)); |
376 | } |
377 | |
378 | TEST(MultilibTest, SelectSoftFP) { |
379 | MultilibSet MS; |
380 | llvm::SmallVector<Multilib> Selected; |
381 | ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( |
382 | Variants: |
383 | - Dir: f |
384 | Flags: [-mfloat-abi=softfp] |
385 | )" )); |
386 | Driver TheDriver = diagnostic_test_driver(); |
387 | EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=soft" }, Selected)); |
388 | EXPECT_TRUE(MS.select(TheDriver, {"-mfloat-abi=softfp" }, Selected)); |
389 | EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=hard" }, Selected)); |
390 | } |
391 | |
392 | TEST(MultilibTest, SelectHard) { |
393 | // If hard float is all that's available then select that only if compiling |
394 | // with hard float. |
395 | MultilibSet MS; |
396 | llvm::SmallVector<Multilib> Selected; |
397 | ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( |
398 | Variants: |
399 | - Dir: h |
400 | Flags: [-mfloat-abi=hard] |
401 | )" )); |
402 | Driver TheDriver = diagnostic_test_driver(); |
403 | EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=soft" }, Selected)); |
404 | EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=softfp" }, Selected)); |
405 | EXPECT_TRUE(MS.select(TheDriver, {"-mfloat-abi=hard" }, Selected)); |
406 | } |
407 | |
408 | TEST(MultilibTest, SelectFloatABI) { |
409 | MultilibSet MS; |
410 | llvm::SmallVector<Multilib> Selected; |
411 | ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( |
412 | Variants: |
413 | - Dir: s |
414 | Flags: [-mfloat-abi=soft] |
415 | - Dir: f |
416 | Flags: [-mfloat-abi=softfp] |
417 | - Dir: h |
418 | Flags: [-mfloat-abi=hard] |
419 | Mappings: |
420 | - Match: -mfloat-abi=softfp |
421 | Flags: [-mfloat-abi=soft] |
422 | )" )); |
423 | Driver TheDriver = diagnostic_test_driver(); |
424 | MS.select(D: TheDriver, Flags: {"-mfloat-abi=soft" }, Selected); |
425 | EXPECT_EQ("/s" , Selected.back().gccSuffix()); |
426 | MS.select(D: TheDriver, Flags: {"-mfloat-abi=softfp" }, Selected); |
427 | EXPECT_EQ("/f" , Selected.back().gccSuffix()); |
428 | MS.select(D: TheDriver, Flags: {"-mfloat-abi=hard" }, Selected); |
429 | EXPECT_EQ("/h" , Selected.back().gccSuffix()); |
430 | } |
431 | |
432 | TEST(MultilibTest, SelectFloatABIReversed) { |
433 | // If soft is specified after softfp then softfp will never be |
434 | // selected because soft is compatible with softfp and last wins. |
435 | MultilibSet MS; |
436 | llvm::SmallVector<Multilib> Selected; |
437 | ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"( |
438 | Variants: |
439 | - Dir: h |
440 | Flags: [-mfloat-abi=hard] |
441 | - Dir: f |
442 | Flags: [-mfloat-abi=softfp] |
443 | - Dir: s |
444 | Flags: [-mfloat-abi=soft] |
445 | Mappings: |
446 | - Match: -mfloat-abi=softfp |
447 | Flags: [-mfloat-abi=soft] |
448 | )" )); |
449 | Driver TheDriver = diagnostic_test_driver(); |
450 | MS.select(D: TheDriver, Flags: {"-mfloat-abi=soft" }, Selected); |
451 | EXPECT_EQ("/s" , Selected.back().gccSuffix()); |
452 | MS.select(D: TheDriver, Flags: {"-mfloat-abi=softfp" }, Selected); |
453 | EXPECT_EQ("/s" , Selected.back().gccSuffix()); |
454 | MS.select(D: TheDriver, Flags: {"-mfloat-abi=hard" }, Selected); |
455 | EXPECT_EQ("/h" , Selected.back().gccSuffix()); |
456 | } |
457 | |
458 | TEST(MultilibTest, SelectMClass) { |
459 | Driver TheDriver = diagnostic_test_driver(); |
460 | |
461 | const char *MultilibSpec = YAML_PREAMBLE R"( |
462 | Variants: |
463 | - Dir: thumb/v6-m/nofp |
464 | Flags: [--target=thumbv6m-none-unknown-eabi, -mfpu=none] |
465 | |
466 | - Dir: thumb/v7-m/nofp |
467 | Flags: [--target=thumbv7m-none-unknown-eabi, -mfpu=none] |
468 | |
469 | - Dir: thumb/v7e-m/nofp |
470 | Flags: [--target=thumbv7em-none-unknown-eabi, -mfpu=none] |
471 | |
472 | - Dir: thumb/v8-m.main/nofp |
473 | Flags: [--target=thumbv8m.main-none-unknown-eabi, -mfpu=none] |
474 | |
475 | - Dir: thumb/v8.1-m.main/nofp/nomve |
476 | Flags: [--target=thumbv8.1m.main-none-unknown-eabi, -mfpu=none] |
477 | |
478 | - Dir: thumb/v7e-m/fpv4_sp_d16 |
479 | Flags: [--target=thumbv7em-none-unknown-eabihf, -mfpu=fpv4-sp-d16] |
480 | |
481 | - Dir: thumb/v7e-m/fpv5_d16 |
482 | Flags: [--target=thumbv7em-none-unknown-eabihf, -mfpu=fpv5-d16] |
483 | |
484 | - Dir: thumb/v8-m.main/fp |
485 | Flags: [--target=thumbv8m.main-none-unknown-eabihf] |
486 | |
487 | - Dir: thumb/v8.1-m.main/fp |
488 | Flags: [--target=thumbv8.1m.main-none-unknown-eabihf] |
489 | |
490 | - Dir: thumb/v8.1-m.main/nofp/mve |
491 | Flags: [--target=thumbv8.1m.main-none-unknown-eabihf, -march=thumbv8.1m.main+mve] |
492 | |
493 | Mappings: |
494 | - Match: --target=thumbv8(\.[0-9]+)?m\.base-none-unknown-eabi |
495 | Flags: [--target=thumbv6m-none-unknown-eabi] |
496 | - Match: -target=thumbv8\.[1-9]m\.main-none-unknown-eabi |
497 | Flags: [--target=thumbv8.1m.main-none-unknown-eabi] |
498 | - Match: -target=thumbv8\.[1-9]m\.main-none-unknown-eabihf |
499 | Flags: [--target=thumbv8.1m.main-none-unknown-eabihf] |
500 | - Match: -march=thumbv8\.[1-9]m\.main.*\+mve($|\+).* |
501 | Flags: [-march=thumbv8.1m.main+mve] |
502 | )" ; |
503 | |
504 | MultilibSet MS; |
505 | llvm::SmallVector<Multilib> Selected; |
506 | ASSERT_TRUE(parseYaml(MS, MultilibSpec)); |
507 | |
508 | ASSERT_TRUE(MS.select(TheDriver, |
509 | {"--target=thumbv6m-none-unknown-eabi" , "-mfpu=none" }, |
510 | Selected)); |
511 | EXPECT_EQ("/thumb/v6-m/nofp" , Selected.back().gccSuffix()); |
512 | |
513 | ASSERT_TRUE(MS.select(TheDriver, |
514 | {"--target=thumbv7m-none-unknown-eabi" , "-mfpu=none" }, |
515 | Selected)); |
516 | EXPECT_EQ("/thumb/v7-m/nofp" , Selected.back().gccSuffix()); |
517 | |
518 | ASSERT_TRUE(MS.select(TheDriver, |
519 | {"--target=thumbv7em-none-unknown-eabi" , "-mfpu=none" }, |
520 | Selected)); |
521 | EXPECT_EQ("/thumb/v7e-m/nofp" , Selected.back().gccSuffix()); |
522 | |
523 | ASSERT_TRUE(MS.select( |
524 | TheDriver, {"--target=thumbv8m.main-none-unknown-eabi" , "-mfpu=none" }, |
525 | Selected)); |
526 | EXPECT_EQ("/thumb/v8-m.main/nofp" , Selected.back().gccSuffix()); |
527 | |
528 | ASSERT_TRUE(MS.select( |
529 | TheDriver, {"--target=thumbv8.1m.main-none-unknown-eabi" , "-mfpu=none" }, |
530 | Selected)); |
531 | EXPECT_EQ("/thumb/v8.1-m.main/nofp/nomve" , Selected.back().gccSuffix()); |
532 | |
533 | ASSERT_TRUE( |
534 | MS.select(TheDriver, |
535 | {"--target=thumbv7em-none-unknown-eabihf" , "-mfpu=fpv4-sp-d16" }, |
536 | Selected)); |
537 | EXPECT_EQ("/thumb/v7e-m/fpv4_sp_d16" , Selected.back().gccSuffix()); |
538 | |
539 | ASSERT_TRUE(MS.select( |
540 | TheDriver, {"--target=thumbv7em-none-unknown-eabihf" , "-mfpu=fpv5-d16" }, |
541 | Selected)); |
542 | EXPECT_EQ("/thumb/v7e-m/fpv5_d16" , Selected.back().gccSuffix()); |
543 | |
544 | ASSERT_TRUE(MS.select( |
545 | TheDriver, {"--target=thumbv8m.main-none-unknown-eabihf" }, Selected)); |
546 | EXPECT_EQ("/thumb/v8-m.main/fp" , Selected.back().gccSuffix()); |
547 | |
548 | ASSERT_TRUE(MS.select( |
549 | TheDriver, {"--target=thumbv8.1m.main-none-unknown-eabihf" }, Selected)); |
550 | EXPECT_EQ("/thumb/v8.1-m.main/fp" , Selected.back().gccSuffix()); |
551 | |
552 | ASSERT_TRUE(MS.select(TheDriver, |
553 | {"--target=thumbv8.1m.main-none-unknown-eabihf" , |
554 | "-mfpu=none" , "-march=thumbv8.1m.main+dsp+mve" }, |
555 | Selected)); |
556 | EXPECT_EQ("/thumb/v8.1-m.main/nofp/mve" , Selected.back().gccSuffix()); |
557 | } |
558 | |