Skip to content

Commit 45f9050

Browse files
parth-07quic-seaswara
authored andcommitted
Add emulation option support for hexagon, arm and aarch64
This commit adds support for emulation option (`-m <emulation>`) for hexagon, arm, and aarch64 targets. It also modifies the LIT to use ld.eld instead of the target symlinks for running tests. Closes qualcomm#54 Signed-off-by: Parth Arora <[email protected]>
1 parent b3197fa commit 45f9050

File tree

13 files changed

+98
-57
lines changed

13 files changed

+98
-57
lines changed

include/eld/Driver/ARMLinkDriver.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,12 @@
1111
#include "eld/Core/Module.h"
1212
#include "eld/Driver/GnuLdDriver.h"
1313
#include "llvm/ADT/StringRef.h"
14+
#include "llvm/TargetParser/Triple.h"
15+
#include <optional>
16+
17+
namespace eld {
18+
class DiagnosticEngine;
19+
}
1420

1521
// Create OptTable class for parsing actual command line arguments
1622
class OPT_ARMLinkOptTable : public llvm::opt::GenericOptTable {
@@ -60,6 +66,9 @@ class ARMLinkDriver : public GnuLdDriver {
6066
template <class T>
6167
bool createInputActions(llvm::opt::InputArgList &Args,
6268
std::vector<eld::InputAction *> &actions);
69+
70+
static std::optional<llvm::Triple>
71+
ParseEmulation(std::string pEmulation, eld::DiagnosticEngine *DiagEngine);
6372
};
6473

6574
#endif

include/eld/Driver/HexagonLinkDriver.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ class HexagonLinkDriver : public GnuLdDriver {
6666
template <class T = OPT_HexagonLinkOptTable>
6767
bool createInputActions(llvm::opt::InputArgList &Args,
6868
std::vector<eld::InputAction *> &actions);
69+
70+
static bool isValidEmulation(llvm::StringRef Emulation);
6971
};
7072

7173
#endif

lib/LinkerWrapper/ARMLinkDriver.cpp

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "llvm/Support/Process.h"
1616
#include "llvm/Support/Signals.h"
1717
#include "llvm/Support/raw_ostream.h"
18+
#include <optional>
1819

1920
using namespace llvm;
2021
using namespace llvm::opt;
@@ -40,21 +41,21 @@ static constexpr llvm::opt::OptTable::Info infoTable[] = {
4041
#undef OPTION
4142
};
4243

43-
static Triple ParseEmulation(std::string pEmulation, Triple &triple,
44-
DiagnosticEngine *DiagEngine) {
44+
std::optional<Triple>
45+
ARMLinkDriver::ParseEmulation(std::string pEmulation,
46+
DiagnosticEngine *DiagEngine) {
4547
// armelf_linux_androideabi -- used for android emulation.
46-
Triple result =
47-
StringSwitch<Triple>(pEmulation)
48+
std::optional<Triple> result =
49+
StringSwitch<std::optional<Triple>>(pEmulation)
4850
.Case("aarch64linux", Triple("aarch64", "", "linux", "gnu"))
4951
.Case("aarch64linux_androideabi",
5052
Triple("aarch64", "", "linux", "androideabi"))
5153
.Case("armelf_linux_eabi", Triple("arm", "", "linux", "gnueabi"))
5254
.Case("armelf_linux_androideabi",
5355
Triple("arm", "", "linux", "androideabi"))
54-
.Default(Triple("unknown", "", "", ""));
55-
// Report invalid emulation error for unknown emulation.
56-
if (result.getArchName() == "unknown")
57-
DiagEngine->raise(Diag::err_invalid_emulation) << pEmulation << "\n";
56+
.Case("armelf", Triple("arm", "", "", ""))
57+
.Case("aarch64elf", Triple("aarch64", "", "", ""))
58+
.Default(std::nullopt);
5859
return result;
5960
}
6061

@@ -244,11 +245,18 @@ bool ARMLinkDriver::processTargetOptions(llvm::opt::InputArgList &Args) {
244245
// If a specific emulation was requested, apply it now.
245246
if (!emulation.empty()) {
246247
llvm::Triple TheTriple = Config.targets().triple();
247-
Triple EmulationTriple =
248-
ParseEmulation(emulation, TheTriple, Config.getDiagEngine());
248+
std::optional<Triple> OptEmulationTriple =
249+
ParseEmulation(emulation, Config.getDiagEngine());
250+
// Report invalid emulation error for unknown emulation.
251+
if (!OptEmulationTriple) {
252+
DiagEngine->raise(Diag::err_invalid_emulation) << emulation << "\n";
253+
return false;
254+
}
255+
Triple EmulationTriple = OptEmulationTriple.value();
249256
if (EmulationTriple.getArch() != Triple::UnknownArch)
250257
TheTriple.setArch(EmulationTriple.getArch());
251-
TheTriple.setOS(EmulationTriple.getOS());
258+
if (EmulationTriple.getOS() != Triple::OSType::UnknownOS)
259+
TheTriple.setOS(EmulationTriple.getOS());
252260
if (EmulationTriple.getEnvironment() != Triple::UnknownEnvironment)
253261
TheTriple.setEnvironment(EmulationTriple.getEnvironment());
254262
Config.targets().setTriple(TheTriple);

lib/LinkerWrapper/Driver.cpp

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ Driver::getFlavorAndTripleFromLinkCommand(llvm::ArrayRef<const char *> Args) {
163163
if (llvm::opt::Arg *Arg = ArgList.getLastArg(OPT_GnuLdOptTable::emulation)) {
164164
std::string Emulation = Arg->getValue();
165165
#if defined(ELD_ENABLE_TARGET_HEXAGON)
166-
// FIXME: Support -m hexagonelf in HexagonLinkDriver
166+
if (HexagonLinkDriver::isValidEmulation(Emulation))
167+
F = Flavor::Hexagon;
167168
#endif
168169
#if defined(ELD_ENABLE_TARGET_RISCV)
169170
// It is okay to consider RISCV64 emulation as RISCV32 flavor
@@ -172,14 +173,20 @@ Driver::getFlavorAndTripleFromLinkCommand(llvm::ArrayRef<const char *> Args) {
172173
F = Flavor::RISCV32;
173174
#endif
174175
#if defined(ELD_ENABLE_TARGET_ARM) || defined(ELD_ENABLE_TARGET_AARCH64)
175-
// FIXME: Support -m aarch64elf and -m armelf in ARMLinkDriver
176+
std::optional<llvm::Triple> optTriple =
177+
ARMLinkDriver::ParseEmulation(Emulation, DiagEngine);
178+
if (optTriple.has_value()) {
179+
llvm::Triple EmulationTriple = optTriple.value();
180+
if (EmulationTriple.getArch() == llvm::Triple::arm)
181+
F = Flavor::ARM;
182+
else if (EmulationTriple.getArch() == llvm::Triple::aarch64)
183+
F = Flavor::AArch64;
184+
}
176185
#endif
177-
// FIXME: Enable the below code once emulations of all the targets
178-
// are covered.
179-
// if (F == Flavor::Invalid)
180-
// return std::make_unique<eld::DiagnosticEntry>(
181-
// eld::Diag::fatal_unsupported_emulation,
182-
// std::vector<std::string>{Emulation});
186+
if (F == Flavor::Invalid)
187+
return std::make_unique<eld::DiagnosticEntry>(
188+
eld::Diag::fatal_unsupported_emulation,
189+
std::vector<std::string>{Emulation});
183190
}
184191
return std::pair<Flavor, std::string>{F, ""};
185192
}

lib/LinkerWrapper/HexagonLinkDriver.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,3 +198,10 @@ template <class T>
198198
bool HexagonLinkDriver::processLLVMOptions(llvm::opt::InputArgList &Args) {
199199
return GnuLdDriver::processLLVMOptions<T>(Args);
200200
}
201+
202+
bool HexagonLinkDriver::isValidEmulation(llvm::StringRef Emulation) {
203+
return llvm::StringSwitch<bool>(Emulation)
204+
.Cases("hexagonelf", "v68", "v69", "v71", "v71t", true)
205+
.Cases("v73", "v75", "v77", "v79", "v81", "v83", "v85", true)
206+
.Default(false);
207+
}

lib/Target/Hexagon/HexagonEmulation.cpp

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "eld/Support/MsgHandling.h"
1111
#include "eld/Support/TargetRegistry.h"
1212
#include "eld/Target/ELFEmulation.h"
13+
#include "llvm/ADT/StringRef.h"
1314
#include "llvm/ADT/StringSwitch.h"
1415

1516
using namespace llvm;
@@ -20,21 +21,21 @@ static bool ELDEmulateHexagonELF(LinkerScript &pScript, LinkerConfig &pConfig) {
2021
// set up bitclass and endian
2122
pConfig.targets().setEndian(TargetOptions::Little);
2223
pConfig.targets().setBitClass(32);
23-
if (!pConfig.options().getEmulation().empty()) {
24-
StringRef flag =
25-
llvm::StringSwitch<StringRef>(pConfig.options().getEmulation())
26-
.Case("v68", "hexagonv68")
27-
.Case("v69", "hexagonv69")
28-
.Case("v71", "hexagonv71")
29-
.Case("v71t", "hexagonv71t")
30-
.Case("v73", "hexagonv73")
31-
.Case("v75", "hexagonv75")
32-
.Case("v77", "hexagonv77")
33-
.Case("v79", "hexagonv79")
34-
.Case("v81", "hexagonv81")
35-
.Case("v83", "hexagonv83")
36-
.Case("v85", "hexagonv85")
37-
.Default("invalid");
24+
llvm::StringRef Emulation = pConfig.options().getEmulation();
25+
if (!Emulation.empty()) {
26+
llvm::StringRef flag = llvm::StringSwitch<StringRef>(Emulation)
27+
.Cases("v68", "hexagonelf", "hexagonv68")
28+
.Case("v69", "hexagonv69")
29+
.Case("v71", "hexagonv71")
30+
.Case("v71t", "hexagonv71t")
31+
.Case("v73", "hexagonv73")
32+
.Case("v75", "hexagonv75")
33+
.Case("v77", "hexagonv77")
34+
.Case("v79", "hexagonv79")
35+
.Case("v81", "hexagonv81")
36+
.Case("v83", "hexagonv83")
37+
.Case("v85", "hexagonv85")
38+
.Default("invalid");
3839
if (flag == "deprecated") {
3940
pConfig.raise(Diag::deprecated_emulation)
4041
<< pConfig.options().getEmulation();
@@ -45,7 +46,13 @@ static bool ELDEmulateHexagonELF(LinkerScript &pScript, LinkerConfig &pConfig) {
4546
<< pConfig.options().getEmulation();
4647
return false;
4748
}
48-
pConfig.targets().setTargetCPU(flag.str());
49+
TargetOptions &TargetOpts = pConfig.targets();
50+
const std::string &CurTargetCPU = TargetOpts.getTargetCPU();
51+
// -m hexagonelf -mcpu hexagonvx should be allowed and
52+
// -mcpu should be given priority over hexagonelf.
53+
if (Emulation != "hexagonelf" ||
54+
(Emulation == "hexagonelf" && CurTargetCPU.empty()))
55+
pConfig.targets().setTargetCPU(flag.str());
4956
}
5057
if (LinkerConfig::DynObj == pConfig.codeGenType())
5158
pConfig.options().setGPSize(0);

test/ARM/standalone/InvalidEmulationTest/InvalidEmulation.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@
77
RUN: %clang %clangopts -target arm -c %p/Inputs/f.c -o %t1.o
88
RUN: %not %link -o %t1.out %linkopts -map=test.map %t1.o 2>&1 | %filecheck %s
99

10-
CHECK: Invalid target emulation: `ap=test.map
10+
CHECK: Invalid Emulation ap=test.map

test/Hexagon/standalone/InvalidEmulation/InvalidEmulation.test

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
UNSUPPORTED: true
2+
# This test is temporarily marked unsupported because currently we do not do
3+
# consistency checks for multiple emulation options.
14
#---InvalidEmulation.test--------------------- Executable --------------------#
25
#BEGIN_COMMENT
36
# This tests that the linker should reject invalid Emulations specified on the

test/RISCV/standalone/32bit/EFlags/Map/FloatABI/FloatABI.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#END_COMMENT
66
RUN: %yaml2obj %p/Inputs/float.yaml -o %t.o
77
RUN: %link %linkopts %t.o -o %t1.out -M 2>&1 | %filecheck --check-prefix=FLOATABI %s
8-
RUN: %not %link -march riscv64 %t.o -o %t1.out -M 2>&1 | %filecheck --check-prefix=ERROR %s
8+
RUN: %not %link -m elf64lriscv -march riscv64 %t.o -o %t1.out -M 2>&1 | %filecheck --check-prefix=ERROR %s
99

1010
#FLOATABI: Single
1111
#ERROR: riscv64

test/RISCV/standalone/ArchCheck/ArchCheck.test

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77
RUN: %yaml2obj %p/Inputs/t32.yaml -o %t.t32.o
88
RUN: %yaml2obj %p/Inputs/t64.yaml -o %t.t64.o
99

10-
RUN: %link -march riscv32 %t.t32.o -o %t1.out
11-
RUN: %link -march riscv32 -mabi=ilp32 %t.t32.o -o %t2.out
12-
RUN: %link %linkopts -march rv32i -mabi=ilp32 %t.t32.o -o %t2.out
13-
RUN: %link %linkopts -march rv32im %t.t32.o -o %t2.out
10+
RUN: %link -m elf32lriscv -march riscv32 %t.t32.o -o %t1.out
11+
RUN: %link -m elf32lriscv -march riscv32 -mabi=ilp32 %t.t32.o -o %t2.out
12+
RUN: %link %linkopts -m elf32lriscv -march rv32i -mabi=ilp32 %t.t32.o -o %t2.out
13+
RUN: %link %linkopts -m elf32lriscv -march rv32im %t.t32.o -o %t2.out
1414
RUN: %link -m elf32lriscv %t.t32.o -o %t3.out
1515
RUN: %readelf -h %t3.out | %filecheck --check-prefix=RISCV32 %s
1616
RUN: %link -m elf64lriscv %t.t64.o -o %t4.out
1717
RUN: %readelf -h %t4.out | %filecheck --check-prefix=RISCV64 %s
18-
RUN: %link -march riscv64 %t.t64.o -o %t5.out
18+
RUN: %link -m elf64lriscv -march riscv64 %t.t64.o -o %t5.out
1919
RUN: %readelf -h %t5.out | %filecheck --check-prefix=RISCV64 %s
2020

2121
RISCV32: Class: ELF32

0 commit comments

Comments
 (0)