Skip to content

Commit

Permalink
[mips][ias] Fix N32 and N64 .cprestore directive when inside .set noa…
Browse files Browse the repository at this point in the history
…t 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
  • Loading branch information
dsandersllvm committed May 11, 2016
1 parent 8b4b8c2 commit df8510d
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 22 deletions.
6 changes: 2 additions & 4 deletions llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
Expand Up @@ -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;
}
Expand Down
31 changes: 19 additions & 12 deletions llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
Expand Up @@ -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<unsigned()> GetATReg, SMLoc IDLoc,
const MCSubtargetInfo *STI) {
forbidModuleDirective();
return true;
}
void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
const MCSymbol &Sym, bool IsReg) {
Expand Down Expand Up @@ -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<unsigned()> 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,
Expand Down Expand Up @@ -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<unsigned()> 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:
Expand All @@ -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,
Expand Down
13 changes: 7 additions & 6 deletions llvm/lib/Target/Mips/MipsTargetStreamer.h
Expand Up @@ -81,8 +81,9 @@ class MipsTargetStreamer : public MCTargetStreamer {

// 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<unsigned()> GetATReg,
SMLoc IDLoc, const MCSubtargetInfo *STI);
virtual void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
const MCSymbol &Sym, bool IsReg);
virtual void emitDirectiveCpreturn(unsigned SaveLocation,
Expand Down Expand Up @@ -235,8 +236,8 @@ class MipsTargetAsmStreamer : public MipsTargetStreamer {

// 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<unsigned()> GetATReg,
SMLoc IDLoc, const MCSubtargetInfo *STI) override;
void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
const MCSymbol &Sym, bool IsReg) override;
void emitDirectiveCpreturn(unsigned SaveLocation,
Expand Down Expand Up @@ -290,8 +291,8 @@ class MipsTargetELFStreamer : public MipsTargetStreamer {

// 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<unsigned()> GetATReg,
SMLoc IDLoc, const MCSubtargetInfo *STI) override;
void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
const MCSymbol &Sym, bool IsReg) override;
void emitDirectiveCpreturn(unsigned SaveLocation,
Expand Down
36 changes: 36 additions & 0 deletions llvm/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

0 comments on commit df8510d

Please sign in to comment.