mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[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 llvm-svn: 307772
This commit is contained in:
parent
f5b245992e
commit
f4278d3016
@ -1256,6 +1256,18 @@ Error IRLinker::linkModuleFlagsMetadata() {
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
/// Return InlineAsm adjusted with target-specific directives if required.
|
||||
/// For ARM and Thumb, we have to add directives to select the appropriate ISA
|
||||
/// to support mixing module-level inline assembly from ARM and Thumb modules.
|
||||
static std::string adjustInlineAsm(const std::string &InlineAsm,
|
||||
const Triple &Triple) {
|
||||
if (Triple.getArch() == Triple::thumb || Triple.getArch() == Triple::thumbeb)
|
||||
return ".text\n.balign 2\n.thumb\n" + InlineAsm;
|
||||
if (Triple.getArch() == Triple::arm || Triple.getArch() == Triple::armeb)
|
||||
return ".text\n.balign 4\n.arm\n" + InlineAsm;
|
||||
return InlineAsm;
|
||||
}
|
||||
|
||||
Error IRLinker::run() {
|
||||
// Ensure metadata materialized before value mapping.
|
||||
if (SrcM->getMaterializer())
|
||||
@ -1293,11 +1305,13 @@ Error IRLinker::run() {
|
||||
|
||||
// Append the module inline asm string.
|
||||
if (!IsPerformingImport && !SrcM->getModuleInlineAsm().empty()) {
|
||||
std::string SrcModuleInlineAsm = adjustInlineAsm(SrcM->getModuleInlineAsm(),
|
||||
SrcTriple);
|
||||
if (DstM.getModuleInlineAsm().empty())
|
||||
DstM.setModuleInlineAsm(SrcM->getModuleInlineAsm());
|
||||
DstM.setModuleInlineAsm(SrcModuleInlineAsm);
|
||||
else
|
||||
DstM.setModuleInlineAsm(DstM.getModuleInlineAsm() + "\n" +
|
||||
SrcM->getModuleInlineAsm());
|
||||
SrcModuleInlineAsm);
|
||||
}
|
||||
|
||||
// Loop over all of the linked values to compute type mappings.
|
||||
|
3
test/Linker/Inputs/thumb-module-inline-asm.ll
Normal file
3
test/Linker/Inputs/thumb-module-inline-asm.ll
Normal file
@ -0,0 +1,3 @@
|
||||
target triple = "thumbv7-linux-gnueabihf"
|
||||
|
||||
module asm "orn r1, r2, r2"
|
20
test/Linker/link-arm-and-thumb-module-inline-asm.ll
Normal file
20
test/Linker/link-arm-and-thumb-module-inline-asm.ll
Normal file
@ -0,0 +1,20 @@
|
||||
; This test checks that proper directives to switch between ARM and Thumb mode
|
||||
; are added when linking ARM and Thumb modules.
|
||||
|
||||
; RUN: llvm-as %s -o %t1.bc
|
||||
; RUN: llvm-as %p/Inputs/thumb-module-inline-asm.ll -o %t2.bc
|
||||
; RUN: llvm-link %t1.bc %t2.bc -S 2> %t3.out | FileCheck %s
|
||||
|
||||
target triple = "armv7-linux-gnueabihf"
|
||||
|
||||
module asm "add r1, r2, r2"
|
||||
|
||||
; CHECK: .text
|
||||
; CHECK-NEXT: .balign 4
|
||||
; CHECK-NEXT: .arm
|
||||
; CHECK-NEXT: add r1, r2, r2
|
||||
; CHECK-NEXT: module asm
|
||||
; CHECK-NEXT: .text
|
||||
; CHECK-NEXT: .balign 2
|
||||
; CHECK-NEXT: .thumb
|
||||
; CHECK-NEXT: orn r1, r2, r2
|
Loading…
Reference in New Issue
Block a user