[PATCH] Fix inline assembly that switches between ARM and Thumb modes

Greg Fitzgerald garious at gmail.com
Thu Dec 12 15:23:34 PST 2013


  Taking another shot at fixing the integrated assembler instead of disabling mode switching entirely.  This is the same solution that started this review, but in this revision, the compiler checks to ensure the inline assembly restored the ARM mode.

Hi rengolin, grosbach, aemerson,

http://llvm-reviews.chandlerc.com/D2255

CHANGE SINCE LAST DIFF
  http://llvm-reviews.chandlerc.com/D2255?vs=6068&id=6069#toc

Files:
  lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
  test/CodeGen/ARM/inlineasm-switch-mode-badly.ll
  test/CodeGen/ARM/inlineasm-switch-mode.ll

Index: lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
===================================================================
--- lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -33,6 +33,7 @@
 #include "llvm/Support/TargetRegistry.h"
 #include "llvm/Support/raw_ostream.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetSubtargetInfo.h"
 using namespace llvm;
 
 namespace {
@@ -114,14 +115,12 @@
                                                   OutContext, OutStreamer,
                                                   *MAI));
 
-  // FIXME: It would be nice if we can avoid createing a new instance of
-  // MCSubtargetInfo here given TargetSubtargetInfo is available. However,
-  // we have to watch out for asm directives which can change subtarget
-  // state. e.g. .code 16, .code 32.
-  OwningPtr<MCSubtargetInfo>
-    STI(TM.getTarget().createMCSubtargetInfo(TM.getTargetTriple(),
-                                             TM.getTargetCPU(),
-                                             TM.getTargetFeatureString()));
+  // Reuse the existing Subtarget, because the AsmParser will
+  // modify it.  For example, when switching between ARM and
+  // Thumb mode.
+  const MCSubtargetInfo* STC = TM.getSubtargetImpl();
+  MCSubtargetInfo* STI = const_cast<MCSubtargetInfo*>(STC);
+
   OwningPtr<MCTargetAsmParser>
     TAP(TM.getTarget().createMCAsmParser(*STI, *Parser, *MII));
   if (!TAP)
@@ -129,12 +128,16 @@
                        " we don't have an asm parser for this target\n");
   Parser->setAssemblerDialect(Dialect);
   Parser->setTargetParser(*TAP.get());
+  uint64_t OrigFB = STI->getFeatureBits();
 
   // Don't implicitly switch to the text section before the asm.
   int Res = Parser->Run(/*NoInitialTextSection*/ true,
                         /*NoFinalize*/ true);
   if (Res && !HasDiagHandler)
     report_fatal_error("Error parsing inline asm\n");
+
+  if (STI->getFeatureBits() != OrigFB)
+    report_fatal_error("Inline assembly did not restore ARM mode\n");
 }
 
 static void EmitMSInlineAsmStr(const char *AsmStr, const MachineInstr *MI,
Index: test/CodeGen/ARM/inlineasm-switch-mode-badly.ll
===================================================================
--- /dev/null
+++ test/CodeGen/ARM/inlineasm-switch-mode-badly.ll
@@ -0,0 +1,10 @@
+;RUN:  not llc -mtriple=thumbv7-linux-gnueabi -filetype=obj 2>&1 < %s | FileCheck %s
+
+target triple = "thumbv7--linux-gnueabi"
+
+define hidden void @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", "={r0},{r0},{r1},{r2},r,~{r3}"(i32 %1, i32 %1, i32 0, i32 983042) #3
+  ret void
+}
+; CHECK: Inline assembly did not restore ARM mode
Index: test/CodeGen/ARM/inlineasm-switch-mode.ll
===================================================================
--- /dev/null
+++ test/CodeGen/ARM/inlineasm-switch-mode.ll
@@ -0,0 +1,12 @@
+;RUN:  llc -mtriple=thumbv7-linux-gnueabi -filetype=obj < %s | llvm-objdump -arch=thumb -d - | FileCheck %s
+
+target triple = "thumbv7--linux-gnueabi"
+
+define hidden void @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
+  ret void
+}
+; CHECK: $a
+; CHECK-NEXT: 04 70
+; CHECK-NEXT: 2d e5
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2255.6.patch
Type: text/x-patch
Size: 3735 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131212/04468f7f/attachment.bin>


More information about the llvm-commits mailing list