llvm.org GIT mirror llvm / dba40dd
[Linker] Add directives to support mixing ARM/Thumb module-level inline asm. Summary: By prepending `.text .thumb .balign 2` to the module-level inline assembly from a Thumb module, the assembler will generate the assembly from that module as Thumb, even if the destination module uses an ARM triple. Similar directives are used for module-level inline assembly in ARM modules. The alignment and instruction set are reset based on the target triple before emitting the first function label. Reviewers: olista01, tejohnson, echristo, t.p.northover, rafael Reviewed By: echristo Subscribers: aemerson, javed.absar, eraman, kristof.beyls, llvm-commits Differential Revision: https://reviews.llvm.org/D34622 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@307772 91177308-0d34-0410-b5e6-96231b3b80d8 Florian Hahn 2 years ago
3 changed file(s) with 39 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
12551255 return Error::success();
12561256 }
12571257
1258 /// Return InlineAsm adjusted with target-specific directives if required.
1259 /// For ARM and Thumb, we have to add directives to select the appropriate ISA
1260 /// to support mixing module-level inline assembly from ARM and Thumb modules.
1261 static std::string adjustInlineAsm(const std::string &InlineAsm,
1262 const Triple &Triple) {
1263 if (Triple.getArch() == Triple::thumb || Triple.getArch() == Triple::thumbeb)
1264 return ".text\n.balign 2\n.thumb\n" + InlineAsm;
1265 if (Triple.getArch() == Triple::arm || Triple.getArch() == Triple::armeb)
1266 return ".text\n.balign 4\n.arm\n" + InlineAsm;
1267 return InlineAsm;
1268 }
1269
12581270 Error IRLinker::run() {
12591271 // Ensure metadata materialized before value mapping.
12601272 if (SrcM->getMaterializer())
12921304
12931305 // Append the module inline asm string.
12941306 if (!IsPerformingImport && !SrcM->getModuleInlineAsm().empty()) {
1307 std::string SrcModuleInlineAsm = adjustInlineAsm(SrcM->getModuleInlineAsm(),
1308 SrcTriple);
12951309 if (DstM.getModuleInlineAsm().empty())
1296 DstM.setModuleInlineAsm(SrcM->getModuleInlineAsm());
1310 DstM.setModuleInlineAsm(SrcModuleInlineAsm);
12971311 else
12981312 DstM.setModuleInlineAsm(DstM.getModuleInlineAsm() + "\n" +
1299 SrcM->getModuleInlineAsm());
1313 SrcModuleInlineAsm);
13001314 }
13011315
13021316 // Loop over all of the linked values to compute type mappings.
0 target triple = "thumbv7-linux-gnueabihf"
1
2 module asm "orn r1, r2, r2"
0 ; This test checks that proper directives to switch between ARM and Thumb mode
1 ; are added when linking ARM and Thumb modules.
2
3 ; RUN: llvm-as %s -o %t1.bc
4 ; RUN: llvm-as %p/Inputs/thumb-module-inline-asm.ll -o %t2.bc
5 ; RUN: llvm-link %t1.bc %t2.bc -S 2> %t3.out | FileCheck %s
6
7 target triple = "armv7-linux-gnueabihf"
8
9 module asm "add r1, r2, r2"
10
11 ; CHECK: .text
12 ; CHECK-NEXT: .balign 4
13 ; CHECK-NEXT: .arm
14 ; CHECK-NEXT: add r1, r2, r2
15 ; CHECK-NEXT: module asm
16 ; CHECK-NEXT: .text
17 ; CHECK-NEXT: .balign 2
18 ; CHECK-NEXT: .thumb
19 ; CHECK-NEXT: orn r1, r2, r2