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