538 lines
16 KiB
C++
538 lines
16 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 "../../lib/Driver/ToolChains/CommonArgs.h"
|
||
|
#include "clang/Basic/LLVM.h"
|
||
|
#include "clang/Basic/Version.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"}),
|
||
|
});
|
||
|
Multilib::flags_list Flags1 = {"+foo", "-bar"};
|
||
|
llvm::SmallVector<Multilib> Selection1;
|
||
|
ASSERT_TRUE(MS.select(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(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;
|
||
|
|
||
|
ASSERT_TRUE(MS.select({"x"}, Selection));
|
||
|
ASSERT_EQ(1u, Selection.size());
|
||
|
EXPECT_EQ("/a", Selection[0].gccSuffix());
|
||
|
|
||
|
ASSERT_TRUE(MS.select({"y"}, Selection));
|
||
|
ASSERT_EQ(1u, Selection.size());
|
||
|
EXPECT_EQ("/b", Selection[0].gccSuffix());
|
||
|
|
||
|
ASSERT_TRUE(MS.select({"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("missing required key 'Dir'"))
|
||
|
<< 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]
|
||
|
)"));
|
||
|
EXPECT_TRUE(MS.select({"-mfloat-abi=soft"}, Selected));
|
||
|
EXPECT_TRUE(MS.select({"-mfloat-abi=softfp"}, Selected));
|
||
|
EXPECT_FALSE(MS.select({"-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]
|
||
|
)"));
|
||
|
EXPECT_FALSE(MS.select({"-mfloat-abi=soft"}, Selected));
|
||
|
EXPECT_TRUE(MS.select({"-mfloat-abi=softfp"}, Selected));
|
||
|
EXPECT_FALSE(MS.select({"-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]
|
||
|
)"));
|
||
|
EXPECT_FALSE(MS.select({"-mfloat-abi=soft"}, Selected));
|
||
|
EXPECT_FALSE(MS.select({"-mfloat-abi=softfp"}, Selected));
|
||
|
EXPECT_TRUE(MS.select({"-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]
|
||
|
)"));
|
||
|
MS.select({"-mfloat-abi=soft"}, Selected);
|
||
|
EXPECT_EQ("/s", Selected.back().gccSuffix());
|
||
|
MS.select({"-mfloat-abi=softfp"}, Selected);
|
||
|
EXPECT_EQ("/f", Selected.back().gccSuffix());
|
||
|
MS.select({"-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]
|
||
|
)"));
|
||
|
MS.select({"-mfloat-abi=soft"}, Selected);
|
||
|
EXPECT_EQ("/s", Selected.back().gccSuffix());
|
||
|
MS.select({"-mfloat-abi=softfp"}, Selected);
|
||
|
EXPECT_EQ("/s", Selected.back().gccSuffix());
|
||
|
MS.select({"-mfloat-abi=hard"}, Selected);
|
||
|
EXPECT_EQ("/h", Selected.back().gccSuffix());
|
||
|
}
|
||
|
|
||
|
TEST(MultilibTest, SelectMClass) {
|
||
|
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({"--target=thumbv6m-none-unknown-eabi", "-mfpu=none"},
|
||
|
Selected));
|
||
|
EXPECT_EQ("/thumb/v6-m/nofp", Selected.back().gccSuffix());
|
||
|
|
||
|
ASSERT_TRUE(MS.select({"--target=thumbv7m-none-unknown-eabi", "-mfpu=none"},
|
||
|
Selected));
|
||
|
EXPECT_EQ("/thumb/v7-m/nofp", Selected.back().gccSuffix());
|
||
|
|
||
|
ASSERT_TRUE(MS.select({"--target=thumbv7em-none-unknown-eabi", "-mfpu=none"},
|
||
|
Selected));
|
||
|
EXPECT_EQ("/thumb/v7e-m/nofp", Selected.back().gccSuffix());
|
||
|
|
||
|
ASSERT_TRUE(MS.select(
|
||
|
{"--target=thumbv8m.main-none-unknown-eabi", "-mfpu=none"}, Selected));
|
||
|
EXPECT_EQ("/thumb/v8-m.main/nofp", Selected.back().gccSuffix());
|
||
|
|
||
|
ASSERT_TRUE(MS.select(
|
||
|
{"--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({"--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(
|
||
|
{"--target=thumbv7em-none-unknown-eabihf", "-mfpu=fpv5-d16"}, Selected));
|
||
|
EXPECT_EQ("/thumb/v7e-m/fpv5_d16", Selected.back().gccSuffix());
|
||
|
|
||
|
ASSERT_TRUE(
|
||
|
MS.select({"--target=thumbv8m.main-none-unknown-eabihf"}, Selected));
|
||
|
EXPECT_EQ("/thumb/v8-m.main/fp", Selected.back().gccSuffix());
|
||
|
|
||
|
ASSERT_TRUE(
|
||
|
MS.select({"--target=thumbv8.1m.main-none-unknown-eabihf"}, Selected));
|
||
|
EXPECT_EQ("/thumb/v8.1-m.main/fp", Selected.back().gccSuffix());
|
||
|
|
||
|
ASSERT_TRUE(MS.select({"--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());
|
||
|
}
|