[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