Fix inline assembly that switches between ARM and Thumb modes
authorGreg Fitzgerald <gregf@codeaurora.org>
Wed, 22 Jan 2014 18:32:35 +0000 (18:32 +0000)
committerGreg Fitzgerald <gregf@codeaurora.org>
Wed, 22 Jan 2014 18:32:35 +0000 (18:32 +0000)
commit148c7f286c0929962e33019ac4c15c103dd79b76
treed8686b46011fad27e607c50987c7754eae44dc8b
parentfa4a8f4f5a6de6e205f4685196d3d535a395c152
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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@199818 91177308-0d34-0410-b5e6-96231b3b80d8
include/llvm/MC/MCStreamer.h
lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
lib/MC/MCStreamer.cpp
lib/Target/ARM/MCTargetDesc/ARMELFStreamer.cpp
test/CodeGen/ARM/inlineasm-switch-mode-oneway-from-arm.ll [new file with mode: 0644]
test/CodeGen/ARM/inlineasm-switch-mode-oneway-from-thumb.ll [new file with mode: 0644]
test/CodeGen/ARM/inlineasm-switch-mode.ll [new file with mode: 0644]