From 3b97b8630ac53c7f0d825cce9bf600da6857e1c5 Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Wed, 11 May 2016 12:48:19 +0000 Subject: [PATCH] [mips][ias] Fix N32 and N64 .cprestore directive when inside .set noat region. Summary: r268058 unintentionally made the retrieval of the current assembler temporary unconditional. This was fine for the existing tests but it broke the cases where the assembler temporary is not needed (N32/N64 or not PIC) and is unavailable due to a '.set noat' directive. This fixes FreeBSD's libc. Reviewers: emaste, sdardis, seanbruno Subscribers: dsanders, emaste, sdardis, llvm-commits Differential Revision: http://reviews.llvm.org/D20093 llvm-svn: 269179 --- lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 6 ++-- .../Mips/MCTargetDesc/MipsTargetStreamer.cpp | 31 +++++++++------- lib/Target/Mips/MipsTargetStreamer.h | 13 +++---- test/MC/Mips/cprestore-noreorder-noat.s | 36 +++++++++++++++++++ 4 files changed, 64 insertions(+), 22 deletions(-) create mode 100644 test/MC/Mips/cprestore-noreorder-noat.s diff --git a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index 2fa590190c4..f7fd72fd27f 100644 --- a/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -5448,11 +5448,9 @@ bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) { return false; } - unsigned ATReg = getATReg(Loc); - if (!ATReg) + if (!getTargetStreamer().emitDirectiveCpRestore( + CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI)) return true; - - getTargetStreamer().emitDirectiveCpRestore(CpRestoreOffset, ATReg, Loc, STI); Parser.Lex(); // Consume the EndOfStatement. return false; } diff --git a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index 23c46351b82..05c1026c25c 100644 --- a/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -96,10 +96,11 @@ void MipsTargetStreamer::emitDirectiveSetHardFloat() { void MipsTargetStreamer::emitDirectiveSetDsp() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); } void MipsTargetStreamer::emitDirectiveCpLoad(unsigned RegNo) {} -void MipsTargetStreamer::emitDirectiveCpRestore(int Offset, unsigned ATReg, - SMLoc IDLoc, - const MCSubtargetInfo *STI) { +bool MipsTargetStreamer::emitDirectiveCpRestore( + int Offset, std::function GetATReg, SMLoc IDLoc, + const MCSubtargetInfo *STI) { forbidModuleDirective(); + return true; } void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, const MCSymbol &Sym, bool IsReg) { @@ -578,11 +579,12 @@ void MipsTargetAsmStreamer::emitDirectiveCpLoad(unsigned RegNo) { forbidModuleDirective(); } -void MipsTargetAsmStreamer::emitDirectiveCpRestore(int Offset, unsigned ATReg, - SMLoc IDLoc, - const MCSubtargetInfo *STI) { - MipsTargetStreamer::emitDirectiveCpRestore(Offset, ATReg, IDLoc, STI); +bool MipsTargetAsmStreamer::emitDirectiveCpRestore( + int Offset, std::function GetATReg, SMLoc IDLoc, + const MCSubtargetInfo *STI) { + MipsTargetStreamer::emitDirectiveCpRestore(Offset, GetATReg, IDLoc, STI); OS << "\t.cprestore\t" << Offset << "\n"; + return true; } void MipsTargetAsmStreamer::emitDirectiveCpsetup(unsigned RegNo, @@ -1034,10 +1036,10 @@ void MipsTargetELFStreamer::emitDirectiveCpLoad(unsigned RegNo) { forbidModuleDirective(); } -void MipsTargetELFStreamer::emitDirectiveCpRestore(int Offset, unsigned ATReg, - SMLoc IDLoc, - const MCSubtargetInfo *STI) { - MipsTargetStreamer::emitDirectiveCpRestore(Offset, ATReg, IDLoc, STI); +bool MipsTargetELFStreamer::emitDirectiveCpRestore( + int Offset, std::function GetATReg, SMLoc IDLoc, + const MCSubtargetInfo *STI) { + MipsTargetStreamer::emitDirectiveCpRestore(Offset, GetATReg, IDLoc, STI); // .cprestore offset // When PIC mode is enabled and the O32 ABI is used, this directive expands // to: @@ -1047,11 +1049,16 @@ void MipsTargetELFStreamer::emitDirectiveCpRestore(int Offset, unsigned ATReg, // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it // is used in non-PIC mode. if (!Pic || (getABI().IsN32() || getABI().IsN64())) - return; + return true; + + unsigned ATReg = GetATReg(); + if (!ATReg) + return false; // Store the $gp on the stack. emitStoreWithImmOffset(Mips::SW, Mips::GP, Mips::SP, Offset, ATReg, IDLoc, STI); + return true; } void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo, diff --git a/lib/Target/Mips/MipsTargetStreamer.h b/lib/Target/Mips/MipsTargetStreamer.h index 2b39da6ade5..26f38829413 100644 --- a/lib/Target/Mips/MipsTargetStreamer.h +++ b/lib/Target/Mips/MipsTargetStreamer.h @@ -81,8 +81,9 @@ public: // PIC support virtual void emitDirectiveCpLoad(unsigned RegNo); - virtual void emitDirectiveCpRestore(int Offset, unsigned ATReg, SMLoc IDLoc, - const MCSubtargetInfo *STI); + virtual bool emitDirectiveCpRestore(int Offset, + std::function GetATReg, + SMLoc IDLoc, const MCSubtargetInfo *STI); virtual void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, const MCSymbol &Sym, bool IsReg); virtual void emitDirectiveCpreturn(unsigned SaveLocation, @@ -235,8 +236,8 @@ public: // PIC support void emitDirectiveCpLoad(unsigned RegNo) override; - void emitDirectiveCpRestore(int Offset, unsigned ATReg, SMLoc IDLoc, - const MCSubtargetInfo *STI) override; + bool emitDirectiveCpRestore(int Offset, std::function GetATReg, + SMLoc IDLoc, const MCSubtargetInfo *STI) override; void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, const MCSymbol &Sym, bool IsReg) override; void emitDirectiveCpreturn(unsigned SaveLocation, @@ -290,8 +291,8 @@ public: // PIC support void emitDirectiveCpLoad(unsigned RegNo) override; - void emitDirectiveCpRestore(int Offset, unsigned ATReg, SMLoc IDLoc, - const MCSubtargetInfo *STI) override; + bool emitDirectiveCpRestore(int Offset, std::function GetATReg, + SMLoc IDLoc, const MCSubtargetInfo *STI) override; void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset, const MCSymbol &Sym, bool IsReg) override; void emitDirectiveCpreturn(unsigned SaveLocation, diff --git a/test/MC/Mips/cprestore-noreorder-noat.s b/test/MC/Mips/cprestore-noreorder-noat.s new file mode 100644 index 00000000000..d71d8fb91ed --- /dev/null +++ b/test/MC/Mips/cprestore-noreorder-noat.s @@ -0,0 +1,36 @@ +# RUN: not llvm-mc %s -arch=mips -mcpu=mips32 -relocation-model=pic -filetype=obj \ +# RUN: -o /dev/null 2>&1 | FileCheck %s -check-prefix=O32 + +# RUN: llvm-mc %s -arch=mips64 -mcpu=mips64 -relocation-model=pic \ +# RUN: -filetype=obj -o /dev/null 2>&1 | FileCheck %s -allow-empty -check-prefix=N32 + +# RUN: llvm-mc %s -arch=mips64 -mcpu=mips64 -relocation-model=pic -target-abi=n32 \ +# RUN: -filetype=obj -o /dev/null 2>&1 | FileCheck %s -allow-empty -check-prefix=N64 + +# RUN: llvm-mc %s -arch=mips64 -mcpu=mips64 -relocation-model=pic -target-abi=n32 \ +# RUN: -filetype=obj -o - | llvm-objdump -d -r - | \ +# RUN: FileCheck %s -check-prefix=NO-STORE + +# RUN: llvm-mc %s -arch=mips64 -mcpu=mips64 -relocation-model=pic -filetype=obj -o - | \ +# RUN: llvm-objdump -d -r - | \ +# RUN: FileCheck %s -check-prefix=NO-STORE + + .text + .ent foo +foo: + .frame $sp, 0, $ra + .set noreorder + .set noat + + .cpload $25 + .cprestore 8 +# O32: :[[@LINE-1]]:3: error: pseudo-instruction requires $at, which is not available +# N32-NOT: error: pseudo-instruction requires $at, which is not available +# N64-NOT: error: pseudo-instruction requires $at, which is not available +# NO-STORE-NOT: sw $gp, 8($sp) + + jal $25 + jal $4, $25 + jal foo + + .end foo