Index: include/llvm/CodeGen/AsmPrinter.h =================================================================== --- include/llvm/CodeGen/AsmPrinter.h +++ include/llvm/CodeGen/AsmPrinter.h @@ -469,6 +469,10 @@ unsigned AsmVariant, const char *ExtraCode, raw_ostream &OS); + /// Let the target do anything it needs to do before emitting inlineasm. + /// \p StartInfo - the subtarget info before parsing inline asm + virtual void emitInlineAsmStart(const MCSubtargetInfo &StartInfo) const; + /// Let the target do anything it needs to do after emitting inlineasm. /// This callback can be used restore the original mode in case the /// inlineasm contains directives to switch modes. Index: lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp =================================================================== --- lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp +++ lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp @@ -90,6 +90,7 @@ assert(MCAI && "No MCAsmInfo"); if (!MCAI->useIntegratedAssembler() && !OutStreamer.isIntegratedAssemblerRequired()) { + emitInlineAsmStart(TM.getSubtarget()); OutStreamer.EmitRawText(Str); emitInlineAsmEnd(TM.getSubtarget(), nullptr); return; @@ -152,6 +153,7 @@ TAP->SetFrameRegister(TRI->getFrameRegister(*MF)); } + emitInlineAsmStart(STIOrig); // Don't implicitly switch to the text section before the asm. int Res = Parser->Run(/*NoInitialTextSection*/ true, /*NoFinalize*/ true); @@ -567,5 +569,7 @@ return true; } +void AsmPrinter::emitInlineAsmStart(const MCSubtargetInfo &StartInfo) const {} + void AsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, const MCSubtargetInfo *EndInfo) const {} Index: lib/Target/Mips/Mips16HardFloat.cpp =================================================================== --- lib/Target/Mips/Mips16HardFloat.cpp +++ lib/Target/Mips/Mips16HardFloat.cpp @@ -458,7 +458,6 @@ FStub->setSection(SectionName); BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub); InlineAsmHelper IAH(Context, BB); - IAH.Out(" .set macro"); if (PicMode) { IAH.Out(".set noreorder"); IAH.Out(".cpload $$25"); @@ -467,7 +466,6 @@ IAH.Out("la $$25," + LocalName); } else { - IAH.Out(".set reorder"); IAH.Out("la $$25," + Name); } swapFPIntParams(PV, M, IAH, LE, false); Index: lib/Target/Mips/MipsAsmPrinter.h =================================================================== --- lib/Target/Mips/MipsAsmPrinter.h +++ lib/Target/Mips/MipsAsmPrinter.h @@ -31,7 +31,7 @@ class raw_ostream; class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter { - MipsTargetStreamer &getTargetStreamer(); + MipsTargetStreamer &getTargetStreamer() const; void EmitInstrWithMacroNoAT(const MachineInstr *MI); @@ -60,6 +60,11 @@ std::map StubsNeeded; + void emitInlineAsmStart(const MCSubtargetInfo &StartInfo) const override; + + void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, + const MCSubtargetInfo *EndInfo) const override; + void EmitJal(MCSymbol *Symbol); void EmitInstrReg(unsigned Opcode, unsigned Reg); Index: lib/Target/Mips/MipsAsmPrinter.cpp =================================================================== --- lib/Target/Mips/MipsAsmPrinter.cpp +++ lib/Target/Mips/MipsAsmPrinter.cpp @@ -53,7 +53,7 @@ #define DEBUG_TYPE "mips-asm-printer" -MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() { +MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() const { return static_cast(*OutStreamer.getTargetStreamer()); } @@ -743,6 +743,23 @@ Subtarget->isABI_O32()); } +void MipsAsmPrinter::emitInlineAsmStart( + const MCSubtargetInfo &StartInfo) const { + MipsTargetStreamer &TS = getTargetStreamer(); + + TS.emitDirectiveSetPush(); + TS.emitDirectiveSetAt(); + TS.emitDirectiveSetMacro(); + TS.emitDirectiveSetReorder(); + OutStreamer.AddBlankLine(); +} + +void MipsAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo, + const MCSubtargetInfo *EndInfo) const { + OutStreamer.AddBlankLine(); + getTargetStreamer().emitDirectiveSetPop(); +} + void MipsAsmPrinter::EmitJal(MCSymbol *Symbol) { MCInst I; I.setOpcode(Mips::JAL); Index: test/CodeGen/Mips/fptr2.ll =================================================================== --- test/CodeGen/Mips/fptr2.ll +++ /dev/null @@ -1,20 +0,0 @@ -; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -relocation-model=static < %s | FileCheck %s -check-prefix=static16 - -; Function Attrs: nounwind -define double @my_mul(double %a, double %b) #0 { -entry: - %a.addr = alloca double, align 8 - %b.addr = alloca double, align 8 - store double %a, double* %a.addr, align 8 - store double %b, double* %b.addr, align 8 - %0 = load double* %a.addr, align 8 - %1 = load double* %b.addr, align 8 - %mul = fmul double %0, %1 - ret double %mul -} - -; static16: .ent __fn_stub_my_mul -; static16: .set reorder -; static16-NEXT: #NO_APP -; static16: .end __fn_stub_my_mul -attributes #0 = { nounwind "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="true" } Index: test/CodeGen/Mips/inlineasm-assembler-directives.ll =================================================================== --- /dev/null +++ test/CodeGen/Mips/inlineasm-assembler-directives.ll @@ -0,0 +1,23 @@ +; RUN: llc -march=mips < %s | FileCheck %s + +; Check for the emission of appropriate assembler directives before and +; after the inline assembly code. +define void @f() nounwind { +entry: +; CHECK: #APP +; CHECK-NEXT: .set push +; CHECK-NEXT: .set at +; CHECK-NEXT: .set macro +; CHECK-NEXT: .set reorder +; CHECK: addi $9, ${{[2-9][0-9]?}}, 8 +; CHECK: subi ${{[2-9][0-9]?}}, $9, 6 +; CHECK: .set pop +; CHECK-NEXT: #NO_APP + %a = alloca i32, align 4 + %b = alloca i32, align 4 + store i32 20, i32* %a, align 4 + %0 = load i32* %a, align 4 + %1 = call i32 asm sideeffect "addi $$9, $1, 8\0A\09subi $0, $$9, 6", "=r,r,~{$1}"(i32 %0) + store i32 %1, i32* %b, align 4 + ret void +} Index: test/CodeGen/Mips/inlineasm-cnstrnt-reg.ll =================================================================== --- test/CodeGen/Mips/inlineasm-cnstrnt-reg.ll +++ test/CodeGen/Mips/inlineasm-cnstrnt-reg.ll @@ -32,10 +32,10 @@ ; Now l with 1024: make sure register lo is picked. We do this by checking the instruction ; after the inline expression for a mflo to pull the value out of lo. -; CHECK: #APP -; CHECK-NEXT: mtlo ${{[0-9]+}} +; CHECK: #APP +; CHECK: mtlo ${{[0-9]+}} ; CHECK-NEXT: madd ${{[0-9]+}},${{[0-9]+}} -; CHECK-NEXT: #NO_APP +; CHECK: #NO_APP ; CHECK-NEXT: mflo ${{[0-9]+}} %bosco = alloca i32, align 4 call i32 asm sideeffect "\09mtlo $3 \0A\09\09madd $1,$2 ", "=l,r,r,r"(i32 7, i32 6, i32 44) nounwind Index: test/CodeGen/Mips/inlineasmmemop.ll =================================================================== --- test/CodeGen/Mips/inlineasmmemop.ll +++ test/CodeGen/Mips/inlineasmmemop.ll @@ -5,6 +5,7 @@ define i32 @f1(i32 %x) nounwind { entry: +; CHECK-LABEL: f1: ; CHECK: addiu $[[T0:[0-9]+]], $sp ; CHECK: #APP ; CHECK: sw $4, 0($[[T0]]) @@ -22,17 +23,18 @@ ret i32 %0 } +; CHECK-LABEL: main: ; "D": Second word of double word. This works for any memory element ; double or single. ; CHECK: #APP -; CHECK-NEXT: lw ${{[0-9]+}},4(${{[0-9]+}}); -; CHECK-NEXT: #NO_APP +; CHECK: lw ${{[0-9]+}},4(${{[0-9]+}}); +; CHECK: #NO_APP ; No "D": First word of double word. This works for any memory element ; double or single. ; CHECK: #APP -; CHECK-NEXT: lw ${{[0-9]+}},0(${{[0-9]+}}); -; CHECK-NEXT: #NO_APP +; CHECK: lw ${{[0-9]+}},0(${{[0-9]+}}); +; CHECK: #NO_APP ;int b[8] = {0,1,2,3,4,5,6,7}; ;int main()