[PATCH] disabled switching ARM modes in inline asm

Greg Fitzgerald garious at gmail.com
Mon Dec 2 12:43:07 PST 2013


  The previous patch attempted to fix mode-switching in inline assembly, but the patch was incomplete.  While it would generate correct machine code if compiled for Thumb, compiling for armv7 would leave the compiler in a broken state.  If we want to support mode-switching, the streamer needs to restore the original mode after the inline assembly (and preferably not circumvent the type system with const_cast).

Hi grosbach, aemerson,

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

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

Files:
  include/llvm/MC/MCParser/MCAsmParser.h
  include/llvm/MC/MCTargetAsmParser.h
  lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
  lib/MC/MCParser/AsmParser.cpp
  lib/MC/MCParser/MCTargetAsmParser.cpp
  lib/Target/ARM/AsmParser/ARMAsmParser.cpp
  test/CodeGen/ARM/2013-12-02-inline-asm-switch-mode.ll
  test/CodeGen/ARM/2013-12-02-inline-asm-switch-to-arm.ll
  test/CodeGen/ARM/2013-12-02-inline-asm-switch-to-thumb.ll

Index: include/llvm/MC/MCParser/MCAsmParser.h
===================================================================
--- include/llvm/MC/MCParser/MCAsmParser.h
+++ include/llvm/MC/MCParser/MCAsmParser.h
@@ -192,6 +192,9 @@
   /// checkForValidSection - Ensure that we have a valid section set in the
   /// streamer. Otherwise, report an error and switch to .text.
   virtual void checkForValidSection() = 0;
+
+  virtual void setParsingInlineGnuAsm(bool V) = 0;
+  virtual bool isParsingInlineGnuAsm() = 0;
 };
 
 /// \brief Create an MCAsmParser instance.
Index: include/llvm/MC/MCTargetAsmParser.h
===================================================================
--- include/llvm/MC/MCTargetAsmParser.h
+++ include/llvm/MC/MCTargetAsmParser.h
@@ -97,6 +97,9 @@
   /// ms-style inline assembly.
   MCAsmParserSemaCallback *SemaCallback;
 
+  /// ParsingInlineGnuAsm - Are we parsing GAS-syntax inline assembly?
+  bool ParsingInlineGnuAsm;
+
 public:
   virtual ~MCTargetAsmParser();
 
@@ -183,6 +186,9 @@
   }
 
   virtual void onLabelParsed(MCSymbol *Symbol) { };
+
+  bool isParsingInlineGnuAsm () { return ParsingInlineGnuAsm; }
+  void setParsingInlineGnuAsm (bool Value) { ParsingInlineGnuAsm = Value; }
 };
 
 } // End llvm namespace
Index: lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
===================================================================
--- lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
+++ lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -129,6 +129,7 @@
                        " we don't have an asm parser for this target\n");
   Parser->setAssemblerDialect(Dialect);
   Parser->setTargetParser(*TAP.get());
+  Parser->setParsingInlineGnuAsm(true);
 
   // Don't implicitly switch to the text section before the asm.
   int Res = Parser->Run(/*NoInitialTextSection*/ true,
Index: lib/MC/MCParser/AsmParser.cpp
===================================================================
--- lib/MC/MCParser/AsmParser.cpp
+++ lib/MC/MCParser/AsmParser.cpp
@@ -241,6 +241,13 @@
   virtual void eatToEndOfStatement();
 
   virtual void checkForValidSection();
+
+  void setParsingInlineGnuAsm(bool V) {
+    getTargetParser().setParsingInlineGnuAsm(V);
+  }
+  bool isParsingInlineGnuAsm() {
+    return getTargetParser().isParsingInlineGnuAsm();
+  }
   /// }
 
 private:
Index: lib/MC/MCParser/MCTargetAsmParser.cpp
===================================================================
--- lib/MC/MCParser/MCTargetAsmParser.cpp
+++ lib/MC/MCParser/MCTargetAsmParser.cpp
@@ -11,7 +11,7 @@
 using namespace llvm;
 
 MCTargetAsmParser::MCTargetAsmParser()
-  : AvailableFeatures(0), ParsingInlineAsm(false)
+  : AvailableFeatures(0), ParsingInlineAsm(false), ParsingInlineGnuAsm(false)
 {
 }
 
Index: lib/Target/ARM/AsmParser/ARMAsmParser.cpp
===================================================================
--- lib/Target/ARM/AsmParser/ARMAsmParser.cpp
+++ lib/Target/ARM/AsmParser/ARMAsmParser.cpp
@@ -7839,6 +7839,9 @@
 /// parseDirectiveThumb
 ///  ::= .thumb
 bool ARMAsmParser::parseDirectiveThumb(SMLoc L) {
+  if (isParsingInlineGnuAsm())
+    return Error(L, ".thumb directive is not permitted in inline assembly");
+
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return Error(L, "unexpected token in directive");
   Parser.Lex();
@@ -7855,6 +7858,9 @@
 /// parseDirectiveARM
 ///  ::= .arm
 bool ARMAsmParser::parseDirectiveARM(SMLoc L) {
+  if (isParsingInlineGnuAsm())
+    return Error(L, ".arm directive is not permitted in inline assembly");
+
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return Error(L, "unexpected token in directive");
   Parser.Lex();
@@ -7941,6 +7947,9 @@
   else
     return Error(L, "invalid operand to .code directive");
 
+  if (isParsingInlineGnuAsm())
+    return Error(L, ".code directive is not permitted in inline assembly");
+
   if (getLexer().isNot(AsmToken::EndOfStatement))
     return Error(Parser.getTok().getLoc(), "unexpected token in directive");
   Parser.Lex();
Index: test/CodeGen/ARM/2013-12-02-inline-asm-switch-mode.ll
===================================================================
--- /dev/null
+++ test/CodeGen/ARM/2013-12-02-inline-asm-switch-mode.ll
@@ -0,0 +1,11 @@
+;RUN:  not llc -mtriple=thumbv7-linux-gnueabi -filetype=obj 2>&1 < %s | FileCheck %s
+;RUN:  not llc -mtriple=armv7-linux-gnueabi -filetype=obj 2>&1 < %s | FileCheck %s
+
+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: .code directive is not permitted in inline assembly
+; CHECK: .code directive is not permitted in inline assembly
+
Index: test/CodeGen/ARM/2013-12-02-inline-asm-switch-to-arm.ll
===================================================================
--- /dev/null
+++ test/CodeGen/ARM/2013-12-02-inline-asm-switch-to-arm.ll
@@ -0,0 +1,11 @@
+;RUN:  not llc -mtriple=thumbv7-linux-gnueabi -filetype=obj 2>&1 < %s | FileCheck %s
+;RUN:  not llc -mtriple=armv7-linux-gnueabi -filetype=obj 2>&1 < %s | FileCheck %s
+
+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.arm \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.thumb \0A2: \0A\09", "={r0},{r0},{r1},{r2},r,~{r3}"(i32 %1, i32 %1, i32 0, i32 983042) #3
+  ret void
+}
+; CHECK: .arm directive is not permitted in inline assembly
+; CHECK: .thumb directive is not permitted in inline assembly
+
Index: test/CodeGen/ARM/2013-12-02-inline-asm-switch-to-thumb.ll
===================================================================
--- /dev/null
+++ test/CodeGen/ARM/2013-12-02-inline-asm-switch-to-thumb.ll
@@ -0,0 +1,10 @@
+;RUN:  not llc -mtriple=thumbv7-linux-gnueabi -filetype=obj 2>&1 < %s | FileCheck %s
+;RUN:  not llc -mtriple=armv7-linux-gnueabi -filetype=obj 2>&1 < %s | FileCheck %s
+
+define hidden void @bah(i8* %start) #0 align 2 {
+  %1 = ptrtoint i8* %start to i32
+  %2 = tail call i32 asm sideeffect "@ Enter THUMB Mode\0A\09adr r3, 1f+1 \0A\09bx  r3 \0A\09.thumb \0A1: \0A\09@ Enter ARM Mode  \0A\09adr r3, 2f \0A\09bx  r3 \0A\09.align 2 \0A\09.arm \0A2:  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: .thumb directive is not permitted in inline assembly
+; CHECK: .arm directive is not permitted in inline assembly
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D2255.2.patch
Type: text/x-patch
Size: 6812 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131202/a296ec71/attachment.bin>


More information about the llvm-commits mailing list