summaryrefslogtreecommitdiffstats
path: root/llvm/test/CodeGen/ARM/inlineasm-switch-mode.ll
diff options
context:
space:
mode:
authorGreg Fitzgerald <gregf@codeaurora.org>2014-01-22 18:32:35 +0000
committerGreg Fitzgerald <gregf@codeaurora.org>2014-01-22 18:32:35 +0000
commit1f6a6086aedbb08e6cd788de5ee85c7ac99c7175 (patch)
tree74f2a5ec17177e836a73add0f866d7f8d1cd1b1a /llvm/test/CodeGen/ARM/inlineasm-switch-mode.ll
parent6b70ec0d4605be6901c254510698517e42e42cdd (diff)
downloadbcm5719-llvm-1f6a6086aedbb08e6cd788de5ee85c7ac99c7175.tar.gz
bcm5719-llvm-1f6a6086aedbb08e6cd788de5ee85c7ac99c7175.zip
Fix inline assembly that switches between ARM and Thumb modes
This patch restores the ARM mode if the user's inline assembly does not. In the object streamer, it ensures that instructions following the inline assembly are encoded correctly and that correct mapping symbols are emitted. For the asm streamer, it emits a .arm or .thumb directive. This patch does not ensure that the inline assembly contains the ADR instruction to switch modes at runtime. The problem we need to solve is code like this: int foo(int a, int b) { int r = a + b; asm volatile( ".align 2 \n" ".arm \n" "add r0,r0,r0 \n" : : "r"(r)); return r+1; } If we compile this function in thumb mode then the inline assembly will switch to arm mode. We need to make sure that we switch back to thumb mode after emitting the inline assembly or we will incorrectly encode the instructions that follow (i.e. the assembly instructions for return r+1). Based on patch by David Peixotto Change-Id: Ib57f6d2d78a22afad5de8693fba6230ff56ba48b llvm-svn: 199818
Diffstat (limited to 'llvm/test/CodeGen/ARM/inlineasm-switch-mode.ll')
-rw-r--r--llvm/test/CodeGen/ARM/inlineasm-switch-mode.ll22
1 files changed, 22 insertions, 0 deletions
diff --git a/llvm/test/CodeGen/ARM/inlineasm-switch-mode.ll b/llvm/test/CodeGen/ARM/inlineasm-switch-mode.ll
new file mode 100644
index 00000000000..29ac598f527
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/inlineasm-switch-mode.ll
@@ -0,0 +1,22 @@
+;RUN: llc -mtriple=thumbv7-linux-gnueabi -filetype=obj < %s > %t
+; Two pass decoding needed because llvm-objdump does not respect mapping symbols
+;RUN: llvm-objdump -triple=armv7 -d %t | FileCheck %s --check-prefix=ARM
+;RUN: llvm-objdump -triple=thumbv7 -d %t | FileCheck %s --check-prefix=THUMB
+
+define hidden i32 @bah(i8* %start) #0 align 2 {
+ %1 = ptrtoint i8* %start to i32
+ %2 = tail call i32 asm sideeffect "@ Enter ARM Mode \0A\09adr r3, 1f \0A\09bx r3 \0A\09.align 2 \0A\09.code 32 \0A1: push {r7} \0A\09mov r7, $4 \0A\09svc 0x0 \0A\09pop {r7} \0A\09@ Enter THUMB Mode\0A\09adr r3, 2f+1 \0A\09bx r3 \0A\09.code 16 \0A2: \0A\09", "={r0},{r0},{r1},{r2},r,~{r3}"(i32 %1, i32 %1, i32 0, i32 983042) #3
+ %3 = add i32 %1, 1
+ ret i32 %3
+}
+
+; ARM: $a
+; ARM-NEXT: 04 70 2d e5 str r7, [sp, #-4]!
+; ARM: $t
+; ARM-NEXT: 48 1c
+
+; THUMB: $a
+; THUMB-NEXT: 04 70
+; THUMB-NEXT: 2d e5
+; THUMB: $t
+; THUMB-NEXT: 48 1c adds r0, r1, #1
OpenPOWER on IntegriCloud