llvm.org GIT mirror llvm / d3e5e74
Merging r224425: ------------------------------------------------------------------------ r224425 | tomatabacu | 2014-12-17 10:56:16 +0000 (Wed, 17 Dec 2014) | 17 lines [mips] Set GCC-compatible MIPS asssembler options before inline asm blocks. Summary: When generating MIPS assembly, LLVM always overrides the default assembler options by emitting the '.set noreorder', '.set nomacro' and '.set noat' directives, while GCC uses the default options if an assembly-level function contains inline assembly code. This becomes a problem when the code generated by LLVM is interleaved with inline assembly which assumes GCC-like assembler options (from Linux, for example). This patch fixes these conflicts by setting the appropriate assembler options at the beginning of an inline asm block and popping them at the end. Reviewers: dsanders Reviewed By: dsanders Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D6637 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_35@232083 91177308-0d34-0410-b5e6-96231b3b80d8 Daniel Sanders 5 years ago
9 changed file(s) with 64 addition(s) and 31 deletion(s). Raw diff Collapse all Expand all
460460 unsigned AsmVariant, const char *ExtraCode,
461461 raw_ostream &OS);
462462
463 /// Let the target do anything it needs to do before emitting inlineasm.
464 /// \p StartInfo - the subtarget info before parsing inline asm
465 virtual void emitInlineAsmStart(const MCSubtargetInfo &StartInfo) const;
466
463467 /// Let the target do anything it needs to do after emitting inlineasm.
464468 /// This callback can be used restore the original mode in case the
465469 /// inlineasm contains directives to switch modes.
8888 assert(MCAI && "No MCAsmInfo");
8989 if (!MCAI->useIntegratedAssembler() &&
9090 !OutStreamer.isIntegratedAssemblerRequired()) {
91 emitInlineAsmStart(TM.getSubtarget());
9192 OutStreamer.EmitRawText(Str);
9293 emitInlineAsmEnd(TM.getSubtarget(), nullptr);
9394 return;
146147 Parser->setAssemblerDialect(Dialect);
147148 Parser->setTargetParser(*TAP.get());
148149
150 emitInlineAsmStart(STIOrig);
149151 // Don't implicitly switch to the text section before the asm.
150152 int Res = Parser->Run(/*NoInitialTextSection*/ true,
151153 /*NoFinalize*/ true);
560562 return true;
561563 }
562564
565 void AsmPrinter::emitInlineAsmStart(const MCSubtargetInfo &StartInfo) const {}
566
563567 void AsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
564568 const MCSubtargetInfo *EndInfo) const {}
457457 FStub->setSection(SectionName);
458458 BasicBlock *BB = BasicBlock::Create(Context, "entry", FStub);
459459 InlineAsmHelper IAH(Context, BB);
460 IAH.Out(" .set macro");
461460 if (PicMode) {
462461 IAH.Out(".set noreorder");
463462 IAH.Out(".cpload $$25");
466465 IAH.Out("la $$25," + LocalName);
467466 }
468467 else {
469 IAH.Out(".set reorder");
470468 IAH.Out("la $$25," + Name);
471469 }
472470 swapFPIntParams(PV, M, IAH, LE, false);
5252
5353 #define DEBUG_TYPE "mips-asm-printer"
5454
55 MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() {
55 MipsTargetStreamer &MipsAsmPrinter::getTargetStreamer() const {
5656 return static_cast(*OutStreamer.getTargetStreamer());
5757 }
5858
720720 Subtarget->isABI_O32());
721721 }
722722
723 void MipsAsmPrinter::emitInlineAsmStart(
724 const MCSubtargetInfo &StartInfo) const {
725 MipsTargetStreamer &TS = getTargetStreamer();
726
727 TS.emitDirectiveSetPush();
728 TS.emitDirectiveSetAt();
729 TS.emitDirectiveSetMacro();
730 TS.emitDirectiveSetReorder();
731 OutStreamer.AddBlankLine();
732 }
733
734 void MipsAsmPrinter::emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
735 const MCSubtargetInfo *EndInfo) const {
736 OutStreamer.AddBlankLine();
737 getTargetStreamer().emitDirectiveSetPop();
738 }
739
723740 void MipsAsmPrinter::EmitJal(MCSymbol *Symbol) {
724741 MCInst I;
725742 I.setOpcode(Mips::JAL);
3030 class raw_ostream;
3131
3232 class LLVM_LIBRARY_VISIBILITY MipsAsmPrinter : public AsmPrinter {
33 MipsTargetStreamer &getTargetStreamer();
33 MipsTargetStreamer &getTargetStreamer() const;
3434
3535 void EmitInstrWithMacroNoAT(const MachineInstr *MI);
3636
5858
5959 std::map
6060 StubsNeeded;
61
62 void emitInlineAsmStart(const MCSubtargetInfo &StartInfo) const override;
63
64 void emitInlineAsmEnd(const MCSubtargetInfo &StartInfo,
65 const MCSubtargetInfo *EndInfo) const override;
6166
6267 void EmitJal(MCSymbol *Symbol);
6368
+0
-20
test/CodeGen/Mips/fptr2.ll less more
None ; RUN: llc -mtriple=mipsel-linux-gnu -march=mipsel -mcpu=mips16 -relocation-model=static < %s | FileCheck %s -check-prefix=static16
1
2 ; Function Attrs: nounwind
3 define double @my_mul(double %a, double %b) #0 {
4 entry:
5 %a.addr = alloca double, align 8
6 %b.addr = alloca double, align 8
7 store double %a, double* %a.addr, align 8
8 store double %b, double* %b.addr, align 8
9 %0 = load double* %a.addr, align 8
10 %1 = load double* %b.addr, align 8
11 %mul = fmul double %0, %1
12 ret double %mul
13 }
14
15 ; static16: .ent __fn_stub_my_mul
16 ; static16: .set reorder
17 ; static16-NEXT: #NO_APP
18 ; static16: .end __fn_stub_my_mul
19 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" }
0 ; RUN: llc -march=mips < %s | FileCheck %s
1
2 ; Check for the emission of appropriate assembler directives before and
3 ; after the inline assembly code.
4 define void @f() nounwind {
5 entry:
6 ; CHECK: #APP
7 ; CHECK-NEXT: .set push
8 ; CHECK-NEXT: .set at
9 ; CHECK-NEXT: .set macro
10 ; CHECK-NEXT: .set reorder
11 ; CHECK: addi $9, ${{[2-9][0-9]?}}, 8
12 ; CHECK: subi ${{[2-9][0-9]?}}, $9, 6
13 ; CHECK: .set pop
14 ; CHECK-NEXT: #NO_APP
15 %a = alloca i32, align 4
16 %b = alloca i32, align 4
17 store i32 20, i32* %a, align 4
18 %0 = load i32* %a, align 4
19 %1 = call i32 asm sideeffect "addi $$9, $1, 8\0A\09subi $0, $$9, 6", "=r,r,~{$1}"(i32 %0)
20 store i32 %1, i32* %b, align 4
21 ret void
22 }
3131
3232 ; Now l with 1024: make sure register lo is picked. We do this by checking the instruction
3333 ; after the inline expression for a mflo to pull the value out of lo.
34 ; CHECK: #APP
35 ; CHECK-NEXT: mtlo ${{[0-9]+}}
34 ; CHECK: #APP
35 ; CHECK: mtlo ${{[0-9]+}}
3636 ; CHECK-NEXT: madd ${{[0-9]+}},${{[0-9]+}}
37 ; CHECK-NEXT: #NO_APP
37 ; CHECK: #NO_APP
3838 ; CHECK-NEXT: mflo ${{[0-9]+}}
3939 %bosco = alloca i32, align 4
4040 call i32 asm sideeffect "\09mtlo $3 \0A\09\09madd $1,$2 ", "=l,r,r,r"(i32 7, i32 6, i32 44) nounwind
44
55 define i32 @f1(i32 %x) nounwind {
66 entry:
7 ; CHECK-LABEL: f1:
78 ; CHECK: addiu $[[T0:[0-9]+]], $sp
89 ; CHECK: #APP
910 ; CHECK: sw $4, 0($[[T0]])
2122 ret i32 %0
2223 }
2324
25 ; CHECK-LABEL: main:
2426 ; "D": Second word of double word. This works for any memory element
2527 ; double or single.
2628 ; CHECK: #APP
27 ; CHECK-NEXT: lw ${{[0-9]+}},4(${{[0-9]+}});
28 ; CHECK-NEXT: #NO_APP
29 ; CHECK: lw ${{[0-9]+}},4(${{[0-9]+}});
30 ; CHECK: #NO_APP
2931
3032 ; No "D": First word of double word. This works for any memory element
3133 ; double or single.
3234 ; CHECK: #APP
33 ; CHECK-NEXT: lw ${{[0-9]+}},0(${{[0-9]+}});
34 ; CHECK-NEXT: #NO_APP
35 ; CHECK: lw ${{[0-9]+}},0(${{[0-9]+}});
36 ; CHECK: #NO_APP
3537
3638 ;int b[8] = {0,1,2,3,4,5,6,7};
3739 ;int main()