
This patch moves the CommonArgs utilities into a location visible by the Frontend Drivers, so that the Frontend Drivers may share option parsing code with the Compiler Driver. This is useful when the Frontend Drivers would like to verify that their incoming options are well-formed and also not reinvent the option parsing wheel. We already see code in the Clang/Flang Drivers that is parsing and verifying its incoming options. E.g. OPT_ffp_contract. This option is parsed in the Compiler Driver, Clang Driver, and Flang Driver, all with slightly different parsing code. It would be nice if the Frontend Drivers were not required to duplicate this Compiler Driver code. That way there is no/low maintenance burden on keeping all these parsing functions in sync. Along those lines, the Frontend Drivers will now have a useful mechanism to verify their incoming options are well-formed. Currently, the Frontend Drivers trust that the Compiler Driver is not passing back junk in some cases. The Language Drivers may even accept junk with no error at all. E.g.: `clang -cc1 -mprefer-vector-width=junk test.c' With this patch, we'll now be able to tighten up incomming options to the Frontend drivers in a lightweight way. --------- Co-authored-by: Cameron McInally <cmcinally@nvidia.com> Co-authored-by: Shafik Yaghmour <shafik.yaghmour@intel.com>
558 lines
17 KiB
C++
558 lines
17 KiB
C++
//===- unittests/Driver/MultilibTest.cpp --- Multilib tests ---------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Unit tests for Multilib and MultilibSet
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "clang/Driver/Multilib.h"
|
|
#include "SimpleDiagnosticConsumer.h"
|
|
#include "clang/Basic/LLVM.h"
|
|
#include "clang/Basic/Version.h"
|
|
#include "clang/Driver/CommonArgs.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/ADT/StringRef.h"
|
|
#include "llvm/ADT/StringSwitch.h"
|
|
#include "llvm/Support/SourceMgr.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
using namespace clang::driver;
|
|
using namespace clang;
|
|
|
|
TEST(MultilibTest, OpEqReflexivity1) {
|
|
Multilib M;
|
|
ASSERT_TRUE(M == M) << "Multilib::operator==() is not reflexive";
|
|
}
|
|
|
|
TEST(MultilibTest, OpEqReflexivity2) {
|
|
ASSERT_TRUE(Multilib() == Multilib())
|
|
<< "Separately constructed default multilibs are not equal";
|
|
}
|
|
|
|
TEST(MultilibTest, OpEqReflexivity3) {
|
|
Multilib M1({}, {}, {}, {"+foo"});
|
|
Multilib M2({}, {}, {}, {"+foo"});
|
|
ASSERT_TRUE(M1 == M2) << "Multilibs with the same flag should be the same";
|
|
}
|
|
|
|
TEST(MultilibTest, OpEqInequivalence1) {
|
|
Multilib M1({}, {}, {}, {"+foo"});
|
|
Multilib M2({}, {}, {}, {"-foo"});
|
|
ASSERT_FALSE(M1 == M2) << "Multilibs with conflicting flags are not the same";
|
|
ASSERT_FALSE(M2 == M1)
|
|
<< "Multilibs with conflicting flags are not the same (commuted)";
|
|
}
|
|
|
|
TEST(MultilibTest, OpEqInequivalence2) {
|
|
Multilib M1;
|
|
Multilib M2({}, {}, {}, {"+foo"});
|
|
ASSERT_FALSE(M1 == M2) << "Flags make Multilibs different";
|
|
}
|
|
|
|
TEST(MultilibTest, OpEqEquivalence2) {
|
|
Multilib M1("/64");
|
|
Multilib M2("/64");
|
|
ASSERT_TRUE(M1 == M2)
|
|
<< "Constructor argument must match Multilib::gccSuffix()";
|
|
ASSERT_TRUE(M2 == M1)
|
|
<< "Constructor argument must match Multilib::gccSuffix() (commuted)";
|
|
}
|
|
|
|
TEST(MultilibTest, OpEqEquivalence3) {
|
|
Multilib M1("", "/32");
|
|
Multilib M2("", "/32");
|
|
ASSERT_TRUE(M1 == M2)
|
|
<< "Constructor argument must match Multilib::osSuffix()";
|
|
ASSERT_TRUE(M2 == M1)
|
|
<< "Constructor argument must match Multilib::osSuffix() (commuted)";
|
|
}
|
|
|
|
TEST(MultilibTest, OpEqEquivalence4) {
|
|
Multilib M1("", "", "/16");
|
|
Multilib M2("", "", "/16");
|
|
ASSERT_TRUE(M1 == M2)
|
|
<< "Constructor argument must match Multilib::includeSuffix()";
|
|
ASSERT_TRUE(M2 == M1)
|
|
<< "Constructor argument must match Multilib::includeSuffix() (commuted)";
|
|
}
|
|
|
|
TEST(MultilibTest, OpEqInequivalence3) {
|
|
Multilib M1("/foo");
|
|
Multilib M2("/bar");
|
|
ASSERT_FALSE(M1 == M2) << "Differing gccSuffixes should be different";
|
|
ASSERT_FALSE(M2 == M1)
|
|
<< "Differing gccSuffixes should be different (commuted)";
|
|
}
|
|
|
|
TEST(MultilibTest, OpEqInequivalence4) {
|
|
Multilib M1("", "/foo");
|
|
Multilib M2("", "/bar");
|
|
ASSERT_FALSE(M1 == M2) << "Differing osSuffixes should be different";
|
|
ASSERT_FALSE(M2 == M1)
|
|
<< "Differing osSuffixes should be different (commuted)";
|
|
}
|
|
|
|
TEST(MultilibTest, OpEqInequivalence5) {
|
|
Multilib M1("", "", "/foo");
|
|
Multilib M2("", "", "/bar");
|
|
ASSERT_FALSE(M1 == M2) << "Differing includeSuffixes should be different";
|
|
ASSERT_FALSE(M2 == M1)
|
|
<< "Differing includeSuffixes should be different (commuted)";
|
|
}
|
|
|
|
TEST(MultilibTest, Construction1) {
|
|
Multilib M("/gcc64", "/os64", "/inc64");
|
|
ASSERT_TRUE(M.gccSuffix() == "/gcc64");
|
|
ASSERT_TRUE(M.osSuffix() == "/os64");
|
|
ASSERT_TRUE(M.includeSuffix() == "/inc64");
|
|
}
|
|
|
|
TEST(MultilibTest, Construction2) {
|
|
Multilib M1;
|
|
Multilib M2("");
|
|
Multilib M3("", "");
|
|
Multilib M4("", "", "");
|
|
ASSERT_TRUE(M1 == M2)
|
|
<< "Default arguments to Multilib constructor broken (first argument)";
|
|
ASSERT_TRUE(M1 == M3)
|
|
<< "Default arguments to Multilib constructor broken (second argument)";
|
|
ASSERT_TRUE(M1 == M4)
|
|
<< "Default arguments to Multilib constructor broken (third argument)";
|
|
}
|
|
|
|
TEST(MultilibTest, Construction3) {
|
|
Multilib M({}, {}, {}, {"+f1", "+f2", "-f3"});
|
|
for (Multilib::flags_list::const_iterator I = M.flags().begin(),
|
|
E = M.flags().end();
|
|
I != E; ++I) {
|
|
ASSERT_TRUE(llvm::StringSwitch<bool>(*I)
|
|
.Cases("+f1", "+f2", "-f3", true)
|
|
.Default(false));
|
|
}
|
|
}
|
|
|
|
TEST(MultilibTest, SetPushback) {
|
|
MultilibSet MS({
|
|
Multilib("/one"),
|
|
Multilib("/two"),
|
|
});
|
|
ASSERT_TRUE(MS.size() == 2);
|
|
for (MultilibSet::const_iterator I = MS.begin(), E = MS.end(); I != E; ++I) {
|
|
ASSERT_TRUE(llvm::StringSwitch<bool>(I->gccSuffix())
|
|
.Cases("/one", "/two", true)
|
|
.Default(false));
|
|
}
|
|
}
|
|
|
|
TEST(MultilibTest, SetPriority) {
|
|
MultilibSet MS({
|
|
Multilib("/foo", {}, {}, {"+foo"}),
|
|
Multilib("/bar", {}, {}, {"+bar"}),
|
|
});
|
|
Driver TheDriver = diagnostic_test_driver();
|
|
Multilib::flags_list Flags1 = {"+foo", "-bar"};
|
|
llvm::SmallVector<Multilib> Selection1;
|
|
ASSERT_TRUE(MS.select(TheDriver, Flags1, Selection1))
|
|
<< "Flag set was {\"+foo\"}, but selection not found";
|
|
ASSERT_TRUE(Selection1.back().gccSuffix() == "/foo")
|
|
<< "Selection picked " << Selection1.back() << " which was not expected";
|
|
|
|
Multilib::flags_list Flags2 = {"+foo", "+bar"};
|
|
llvm::SmallVector<Multilib> Selection2;
|
|
ASSERT_TRUE(MS.select(TheDriver, Flags2, Selection2))
|
|
<< "Flag set was {\"+bar\"}, but selection not found";
|
|
ASSERT_TRUE(Selection2.back().gccSuffix() == "/bar")
|
|
<< "Selection picked " << Selection2.back() << " which was not expected";
|
|
}
|
|
|
|
TEST(MultilibTest, SelectMultiple) {
|
|
MultilibSet MS({
|
|
Multilib("/a", {}, {}, {"x"}),
|
|
Multilib("/b", {}, {}, {"y"}),
|
|
});
|
|
llvm::SmallVector<Multilib> Selection;
|
|
Driver TheDriver = diagnostic_test_driver();
|
|
|
|
ASSERT_TRUE(MS.select(TheDriver, {"x"}, Selection));
|
|
ASSERT_EQ(1u, Selection.size());
|
|
EXPECT_EQ("/a", Selection[0].gccSuffix());
|
|
|
|
ASSERT_TRUE(MS.select(TheDriver, {"y"}, Selection));
|
|
ASSERT_EQ(1u, Selection.size());
|
|
EXPECT_EQ("/b", Selection[0].gccSuffix());
|
|
|
|
ASSERT_TRUE(MS.select(TheDriver, {"y", "x"}, Selection));
|
|
ASSERT_EQ(2u, Selection.size());
|
|
EXPECT_EQ("/a", Selection[0].gccSuffix());
|
|
EXPECT_EQ("/b", Selection[1].gccSuffix());
|
|
}
|
|
|
|
static void diagnosticCallback(const llvm::SMDiagnostic &D, void *Out) {
|
|
*reinterpret_cast<std::string *>(Out) = D.getMessage();
|
|
}
|
|
|
|
static bool parseYaml(MultilibSet &MS, std::string &Diagnostic,
|
|
const char *Data) {
|
|
auto ErrorOrMS = MultilibSet::parseYaml(llvm::MemoryBufferRef(Data, "TEST"),
|
|
diagnosticCallback, &Diagnostic);
|
|
if (ErrorOrMS.getError())
|
|
return false;
|
|
MS = std::move(ErrorOrMS.get());
|
|
return true;
|
|
}
|
|
|
|
static bool parseYaml(MultilibSet &MS, const char *Data) {
|
|
auto ErrorOrMS = MultilibSet::parseYaml(llvm::MemoryBufferRef(Data, "TEST"));
|
|
if (ErrorOrMS.getError())
|
|
return false;
|
|
MS = std::move(ErrorOrMS.get());
|
|
return true;
|
|
}
|
|
|
|
// When updating this version also update MultilibVersionCurrent in Multilib.cpp
|
|
#define YAML_PREAMBLE "MultilibVersion: 1.0\n"
|
|
|
|
TEST(MultilibTest, ParseInvalid) {
|
|
std::string Diagnostic;
|
|
|
|
MultilibSet MS;
|
|
|
|
EXPECT_FALSE(parseYaml(MS, Diagnostic, R"(
|
|
Variants: []
|
|
)"));
|
|
EXPECT_TRUE(
|
|
StringRef(Diagnostic).contains("missing required key 'MultilibVersion'"))
|
|
<< Diagnostic;
|
|
|
|
// Reject files with a different major version
|
|
EXPECT_FALSE(parseYaml(MS, Diagnostic,
|
|
R"(
|
|
MultilibVersion: 2.0
|
|
Variants: []
|
|
)"));
|
|
EXPECT_TRUE(
|
|
StringRef(Diagnostic).contains("multilib version 2.0 is unsupported"))
|
|
<< Diagnostic;
|
|
EXPECT_FALSE(parseYaml(MS, Diagnostic,
|
|
R"(
|
|
MultilibVersion: 0.1
|
|
Variants: []
|
|
)"));
|
|
EXPECT_TRUE(
|
|
StringRef(Diagnostic).contains("multilib version 0.1 is unsupported"))
|
|
<< Diagnostic;
|
|
|
|
// Reject files with a later minor version
|
|
EXPECT_FALSE(parseYaml(MS, Diagnostic,
|
|
R"(
|
|
MultilibVersion: 1.9
|
|
Variants: []
|
|
)"));
|
|
EXPECT_TRUE(
|
|
StringRef(Diagnostic).contains("multilib version 1.9 is unsupported"))
|
|
<< Diagnostic;
|
|
|
|
// Accept files with the same major version and the same or earlier minor
|
|
// version
|
|
EXPECT_TRUE(parseYaml(MS, Diagnostic, R"(
|
|
MultilibVersion: 1.0
|
|
Variants: []
|
|
)")) << Diagnostic;
|
|
|
|
EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE));
|
|
EXPECT_TRUE(StringRef(Diagnostic).contains("missing required key 'Variants'"))
|
|
<< Diagnostic;
|
|
|
|
EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"(
|
|
Variants:
|
|
- Dir: /abc
|
|
Flags: []
|
|
)"));
|
|
EXPECT_TRUE(StringRef(Diagnostic).contains("paths must be relative"))
|
|
<< Diagnostic;
|
|
|
|
EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"(
|
|
Variants:
|
|
- Flags: []
|
|
)"));
|
|
EXPECT_TRUE(
|
|
StringRef(Diagnostic)
|
|
.contains("one of the 'Dir' and 'Error' keys must be specified"))
|
|
<< Diagnostic;
|
|
|
|
EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"(
|
|
Variants:
|
|
- Dir: .
|
|
)"));
|
|
EXPECT_TRUE(StringRef(Diagnostic).contains("missing required key 'Flags'"))
|
|
<< Diagnostic;
|
|
|
|
EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"(
|
|
Variants: []
|
|
Mappings:
|
|
- Match: abc
|
|
)"));
|
|
EXPECT_TRUE(StringRef(Diagnostic).contains("value required for 'Flags'"))
|
|
<< Diagnostic;
|
|
|
|
EXPECT_FALSE(parseYaml(MS, Diagnostic, YAML_PREAMBLE R"(
|
|
Variants: []
|
|
Mappings:
|
|
- Dir: .
|
|
Match: '('
|
|
Flags: []
|
|
)"));
|
|
EXPECT_TRUE(StringRef(Diagnostic).contains("parentheses not balanced"))
|
|
<< Diagnostic;
|
|
}
|
|
|
|
TEST(MultilibTest, Parse) {
|
|
MultilibSet MS;
|
|
EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
|
|
Variants:
|
|
- Dir: .
|
|
Flags: []
|
|
)"));
|
|
EXPECT_EQ(1U, MS.size());
|
|
EXPECT_EQ("", MS.begin()->gccSuffix());
|
|
|
|
EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
|
|
Variants:
|
|
- Dir: abc
|
|
Flags: []
|
|
)"));
|
|
EXPECT_EQ(1U, MS.size());
|
|
EXPECT_EQ("/abc", MS.begin()->gccSuffix());
|
|
|
|
EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
|
|
Variants:
|
|
- Dir: pqr
|
|
Flags: [-mfloat-abi=soft]
|
|
)"));
|
|
EXPECT_EQ(1U, MS.size());
|
|
EXPECT_EQ("/pqr", MS.begin()->gccSuffix());
|
|
EXPECT_EQ(std::vector<std::string>({"-mfloat-abi=soft"}),
|
|
MS.begin()->flags());
|
|
|
|
EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
|
|
Variants:
|
|
- Dir: pqr
|
|
Flags: [-mfloat-abi=soft, -fno-exceptions]
|
|
)"));
|
|
EXPECT_EQ(1U, MS.size());
|
|
EXPECT_EQ(std::vector<std::string>({"-mfloat-abi=soft", "-fno-exceptions"}),
|
|
MS.begin()->flags());
|
|
|
|
EXPECT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
|
|
Variants:
|
|
- Dir: a
|
|
Flags: []
|
|
- Dir: b
|
|
Flags: []
|
|
)"));
|
|
EXPECT_EQ(2U, MS.size());
|
|
}
|
|
|
|
TEST(MultilibTest, SelectSoft) {
|
|
MultilibSet MS;
|
|
llvm::SmallVector<Multilib> Selected;
|
|
ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
|
|
Variants:
|
|
- Dir: s
|
|
Flags: [-mfloat-abi=soft]
|
|
Mappings:
|
|
- Match: -mfloat-abi=softfp
|
|
Flags: [-mfloat-abi=soft]
|
|
)"));
|
|
Driver TheDriver = diagnostic_test_driver();
|
|
EXPECT_TRUE(MS.select(TheDriver, {"-mfloat-abi=soft"}, Selected));
|
|
EXPECT_TRUE(MS.select(TheDriver, {"-mfloat-abi=softfp"}, Selected));
|
|
EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=hard"}, Selected));
|
|
}
|
|
|
|
TEST(MultilibTest, SelectSoftFP) {
|
|
MultilibSet MS;
|
|
llvm::SmallVector<Multilib> Selected;
|
|
ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
|
|
Variants:
|
|
- Dir: f
|
|
Flags: [-mfloat-abi=softfp]
|
|
)"));
|
|
Driver TheDriver = diagnostic_test_driver();
|
|
EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=soft"}, Selected));
|
|
EXPECT_TRUE(MS.select(TheDriver, {"-mfloat-abi=softfp"}, Selected));
|
|
EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=hard"}, Selected));
|
|
}
|
|
|
|
TEST(MultilibTest, SelectHard) {
|
|
// If hard float is all that's available then select that only if compiling
|
|
// with hard float.
|
|
MultilibSet MS;
|
|
llvm::SmallVector<Multilib> Selected;
|
|
ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
|
|
Variants:
|
|
- Dir: h
|
|
Flags: [-mfloat-abi=hard]
|
|
)"));
|
|
Driver TheDriver = diagnostic_test_driver();
|
|
EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=soft"}, Selected));
|
|
EXPECT_FALSE(MS.select(TheDriver, {"-mfloat-abi=softfp"}, Selected));
|
|
EXPECT_TRUE(MS.select(TheDriver, {"-mfloat-abi=hard"}, Selected));
|
|
}
|
|
|
|
TEST(MultilibTest, SelectFloatABI) {
|
|
MultilibSet MS;
|
|
llvm::SmallVector<Multilib> Selected;
|
|
ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
|
|
Variants:
|
|
- Dir: s
|
|
Flags: [-mfloat-abi=soft]
|
|
- Dir: f
|
|
Flags: [-mfloat-abi=softfp]
|
|
- Dir: h
|
|
Flags: [-mfloat-abi=hard]
|
|
Mappings:
|
|
- Match: -mfloat-abi=softfp
|
|
Flags: [-mfloat-abi=soft]
|
|
)"));
|
|
Driver TheDriver = diagnostic_test_driver();
|
|
MS.select(TheDriver, {"-mfloat-abi=soft"}, Selected);
|
|
EXPECT_EQ("/s", Selected.back().gccSuffix());
|
|
MS.select(TheDriver, {"-mfloat-abi=softfp"}, Selected);
|
|
EXPECT_EQ("/f", Selected.back().gccSuffix());
|
|
MS.select(TheDriver, {"-mfloat-abi=hard"}, Selected);
|
|
EXPECT_EQ("/h", Selected.back().gccSuffix());
|
|
}
|
|
|
|
TEST(MultilibTest, SelectFloatABIReversed) {
|
|
// If soft is specified after softfp then softfp will never be
|
|
// selected because soft is compatible with softfp and last wins.
|
|
MultilibSet MS;
|
|
llvm::SmallVector<Multilib> Selected;
|
|
ASSERT_TRUE(parseYaml(MS, YAML_PREAMBLE R"(
|
|
Variants:
|
|
- Dir: h
|
|
Flags: [-mfloat-abi=hard]
|
|
- Dir: f
|
|
Flags: [-mfloat-abi=softfp]
|
|
- Dir: s
|
|
Flags: [-mfloat-abi=soft]
|
|
Mappings:
|
|
- Match: -mfloat-abi=softfp
|
|
Flags: [-mfloat-abi=soft]
|
|
)"));
|
|
Driver TheDriver = diagnostic_test_driver();
|
|
MS.select(TheDriver, {"-mfloat-abi=soft"}, Selected);
|
|
EXPECT_EQ("/s", Selected.back().gccSuffix());
|
|
MS.select(TheDriver, {"-mfloat-abi=softfp"}, Selected);
|
|
EXPECT_EQ("/s", Selected.back().gccSuffix());
|
|
MS.select(TheDriver, {"-mfloat-abi=hard"}, Selected);
|
|
EXPECT_EQ("/h", Selected.back().gccSuffix());
|
|
}
|
|
|
|
TEST(MultilibTest, SelectMClass) {
|
|
Driver TheDriver = diagnostic_test_driver();
|
|
|
|
const char *MultilibSpec = YAML_PREAMBLE R"(
|
|
Variants:
|
|
- Dir: thumb/v6-m/nofp
|
|
Flags: [--target=thumbv6m-none-unknown-eabi, -mfpu=none]
|
|
|
|
- Dir: thumb/v7-m/nofp
|
|
Flags: [--target=thumbv7m-none-unknown-eabi, -mfpu=none]
|
|
|
|
- Dir: thumb/v7e-m/nofp
|
|
Flags: [--target=thumbv7em-none-unknown-eabi, -mfpu=none]
|
|
|
|
- Dir: thumb/v8-m.main/nofp
|
|
Flags: [--target=thumbv8m.main-none-unknown-eabi, -mfpu=none]
|
|
|
|
- Dir: thumb/v8.1-m.main/nofp/nomve
|
|
Flags: [--target=thumbv8.1m.main-none-unknown-eabi, -mfpu=none]
|
|
|
|
- Dir: thumb/v7e-m/fpv4_sp_d16
|
|
Flags: [--target=thumbv7em-none-unknown-eabihf, -mfpu=fpv4-sp-d16]
|
|
|
|
- Dir: thumb/v7e-m/fpv5_d16
|
|
Flags: [--target=thumbv7em-none-unknown-eabihf, -mfpu=fpv5-d16]
|
|
|
|
- Dir: thumb/v8-m.main/fp
|
|
Flags: [--target=thumbv8m.main-none-unknown-eabihf]
|
|
|
|
- Dir: thumb/v8.1-m.main/fp
|
|
Flags: [--target=thumbv8.1m.main-none-unknown-eabihf]
|
|
|
|
- Dir: thumb/v8.1-m.main/nofp/mve
|
|
Flags: [--target=thumbv8.1m.main-none-unknown-eabihf, -march=thumbv8.1m.main+mve]
|
|
|
|
Mappings:
|
|
- Match: --target=thumbv8(\.[0-9]+)?m\.base-none-unknown-eabi
|
|
Flags: [--target=thumbv6m-none-unknown-eabi]
|
|
- Match: -target=thumbv8\.[1-9]m\.main-none-unknown-eabi
|
|
Flags: [--target=thumbv8.1m.main-none-unknown-eabi]
|
|
- Match: -target=thumbv8\.[1-9]m\.main-none-unknown-eabihf
|
|
Flags: [--target=thumbv8.1m.main-none-unknown-eabihf]
|
|
- Match: -march=thumbv8\.[1-9]m\.main.*\+mve($|\+).*
|
|
Flags: [-march=thumbv8.1m.main+mve]
|
|
)";
|
|
|
|
MultilibSet MS;
|
|
llvm::SmallVector<Multilib> Selected;
|
|
ASSERT_TRUE(parseYaml(MS, MultilibSpec));
|
|
|
|
ASSERT_TRUE(MS.select(TheDriver,
|
|
{"--target=thumbv6m-none-unknown-eabi", "-mfpu=none"},
|
|
Selected));
|
|
EXPECT_EQ("/thumb/v6-m/nofp", Selected.back().gccSuffix());
|
|
|
|
ASSERT_TRUE(MS.select(TheDriver,
|
|
{"--target=thumbv7m-none-unknown-eabi", "-mfpu=none"},
|
|
Selected));
|
|
EXPECT_EQ("/thumb/v7-m/nofp", Selected.back().gccSuffix());
|
|
|
|
ASSERT_TRUE(MS.select(TheDriver,
|
|
{"--target=thumbv7em-none-unknown-eabi", "-mfpu=none"},
|
|
Selected));
|
|
EXPECT_EQ("/thumb/v7e-m/nofp", Selected.back().gccSuffix());
|
|
|
|
ASSERT_TRUE(MS.select(
|
|
TheDriver, {"--target=thumbv8m.main-none-unknown-eabi", "-mfpu=none"},
|
|
Selected));
|
|
EXPECT_EQ("/thumb/v8-m.main/nofp", Selected.back().gccSuffix());
|
|
|
|
ASSERT_TRUE(MS.select(
|
|
TheDriver, {"--target=thumbv8.1m.main-none-unknown-eabi", "-mfpu=none"},
|
|
Selected));
|
|
EXPECT_EQ("/thumb/v8.1-m.main/nofp/nomve", Selected.back().gccSuffix());
|
|
|
|
ASSERT_TRUE(
|
|
MS.select(TheDriver,
|
|
{"--target=thumbv7em-none-unknown-eabihf", "-mfpu=fpv4-sp-d16"},
|
|
Selected));
|
|
EXPECT_EQ("/thumb/v7e-m/fpv4_sp_d16", Selected.back().gccSuffix());
|
|
|
|
ASSERT_TRUE(MS.select(
|
|
TheDriver, {"--target=thumbv7em-none-unknown-eabihf", "-mfpu=fpv5-d16"},
|
|
Selected));
|
|
EXPECT_EQ("/thumb/v7e-m/fpv5_d16", Selected.back().gccSuffix());
|
|
|
|
ASSERT_TRUE(MS.select(
|
|
TheDriver, {"--target=thumbv8m.main-none-unknown-eabihf"}, Selected));
|
|
EXPECT_EQ("/thumb/v8-m.main/fp", Selected.back().gccSuffix());
|
|
|
|
ASSERT_TRUE(MS.select(
|
|
TheDriver, {"--target=thumbv8.1m.main-none-unknown-eabihf"}, Selected));
|
|
EXPECT_EQ("/thumb/v8.1-m.main/fp", Selected.back().gccSuffix());
|
|
|
|
ASSERT_TRUE(MS.select(TheDriver,
|
|
{"--target=thumbv8.1m.main-none-unknown-eabihf",
|
|
"-mfpu=none", "-march=thumbv8.1m.main+dsp+mve"},
|
|
Selected));
|
|
EXPECT_EQ("/thumb/v8.1-m.main/nofp/mve", Selected.back().gccSuffix());
|
|
}
|