[llvm] r269295 - [mips][ias] Fix O32 .cprestore directive when inside .set noat region and offset is in range.
Daniel Sanders via llvm-commits
llvm-commits at lists.llvm.org
Thu May 12 07:01:50 PDT 2016
Author: dsanders
Date: Thu May 12 09:01:50 2016
New Revision: 269295
URL: http://llvm.org/viewvc/llvm-project?rev=269295&view=rev
Log:
[mips][ias] Fix O32 .cprestore directive when inside .set noat region and offset is in range.
Summary:
This expands on r269179 to fix an additional case that was not covered by our
tests. The assembler temporary is not needed when the .cprestore offset fits
inside a simm16 and it is not an error to use it inside a '.set noat' in this
case.
Reviewers: emaste, seanbruno, sdardis
Subscribers: dsanders, sdardis, llvm-commits
Differential Revision: http://reviews.llvm.org/D20199
Modified:
llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h
llvm/trunk/test/MC/Mips/cprestore-noreorder-noat.s
Modified: llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp?rev=269295&r1=269294&r2=269295&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp (original)
+++ llvm/trunk/lib/Target/Mips/AsmParser/MipsAsmParser.cpp Thu May 12 09:01:50 2016
@@ -2633,16 +2633,17 @@ void MipsAsmParser::expandStoreInst(MCIn
unsigned SrcReg = Inst.getOperand(0).getReg();
unsigned BaseReg = Inst.getOperand(1).getReg();
- unsigned ATReg = getATReg(IDLoc);
- if (!ATReg)
- return;
-
if (IsImmOpnd) {
TOut.emitStoreWithImmOffset(Inst.getOpcode(), SrcReg, BaseReg,
- Inst.getOperand(2).getImm(), ATReg, IDLoc, STI);
+ Inst.getOperand(2).getImm(),
+ [&]() { return getATReg(IDLoc); }, IDLoc, STI);
return;
}
+ unsigned ATReg = getATReg(IDLoc);
+ if (!ATReg)
+ return;
+
const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
MCOperand LoOperand = MCOperand::createExpr(
MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
@@ -3626,12 +3627,8 @@ void MipsAsmParser::createCpRestoreMemOp
return;
}
- unsigned ATReg = getATReg(IDLoc);
- if (!ATReg)
- return;
-
- TOut.emitStoreWithImmOffset(Mips::SW, Mips::GP, Mips::SP, StackOffset, ATReg,
- IDLoc, STI);
+ TOut.emitStoreWithImmOffset(Mips::SW, Mips::GP, Mips::SP, StackOffset,
+ [&]() { return getATReg(IDLoc); }, IDLoc, STI);
}
unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
Modified: llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp?rev=269295&r1=269294&r2=269295&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp (original)
+++ llvm/trunk/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp Thu May 12 09:01:50 2016
@@ -228,7 +228,8 @@ void MipsTargetStreamer::emitGPRestore(i
/// Emit a store instruction with an immediate offset.
void MipsTargetStreamer::emitStoreWithImmOffset(
unsigned Opcode, unsigned SrcReg, unsigned BaseReg, int64_t Offset,
- unsigned ATReg, SMLoc IDLoc, const MCSubtargetInfo *STI) {
+ std::function<unsigned()> GetATReg, SMLoc IDLoc,
+ const MCSubtargetInfo *STI) {
if (isInt<16>(Offset)) {
emitRRI(Opcode, SrcReg, BaseReg, Offset, IDLoc, STI);
return;
@@ -238,6 +239,10 @@ void MipsTargetStreamer::emitStoreWithIm
// add $at, $at, $8
// sw $8, %lo(offset)($at)
+ unsigned ATReg = GetATReg();
+ if (!ATReg)
+ return;
+
unsigned LoOffset = Offset & 0x0000ffff;
unsigned HiOffset = (Offset & 0xffff0000) >> 16;
@@ -1055,12 +1060,8 @@ bool MipsTargetELFStreamer::emitDirectiv
if (!Pic || (getABI().IsN32() || getABI().IsN64()))
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,
+ emitStoreWithImmOffset(Mips::SW, Mips::GP, Mips::SP, Offset, GetATReg, IDLoc,
STI);
return true;
}
Modified: llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h?rev=269295&r1=269294&r2=269295&view=diff
==============================================================================
--- llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h (original)
+++ llvm/trunk/lib/Target/Mips/MipsTargetStreamer.h Thu May 12 09:01:50 2016
@@ -122,9 +122,18 @@ public:
void emitEmptyDelaySlot(bool hasShortDelaySlot, SMLoc IDLoc,
const MCSubtargetInfo *STI);
void emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI);
+
+ /// Emit a store instruction with an offset. If the offset is out of range
+ /// then it will be synthesized using the assembler temporary.
+ ///
+ /// GetATReg() is a callback that can be used to obtain the current assembler
+ /// temporary and is only called when the assembler temporary is required. It
+ /// must handle the case where no assembler temporary is available (typically
+ /// by reporting an error).
void emitStoreWithImmOffset(unsigned Opcode, unsigned SrcReg,
- unsigned BaseReg, int64_t Offset, unsigned ATReg,
- SMLoc IDLoc, const MCSubtargetInfo *STI);
+ unsigned BaseReg, int64_t Offset,
+ std::function<unsigned()> GetATReg, SMLoc IDLoc,
+ const MCSubtargetInfo *STI);
void emitStoreWithSymOffset(unsigned Opcode, unsigned SrcReg,
unsigned BaseReg, MCOperand &HiOperand,
MCOperand &LoOperand, unsigned ATReg, SMLoc IDLoc,
@@ -237,6 +246,14 @@ public:
// PIC support
void emitDirectiveCpLoad(unsigned RegNo) override;
+
+ /// Emit a .cprestore directive. If the offset is out of range then it will
+ /// be synthesized using the assembler temporary.
+ ///
+ /// GetATReg() is a callback that can be used to obtain the current assembler
+ /// temporary and is only called when the assembler temporary is required. It
+ /// must handle the case where no assembler temporary is available (typically
+ /// by reporting an error).
bool emitDirectiveCpRestore(int Offset, std::function<unsigned()> GetATReg,
SMLoc IDLoc, const MCSubtargetInfo *STI) override;
void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
Modified: llvm/trunk/test/MC/Mips/cprestore-noreorder-noat.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Mips/cprestore-noreorder-noat.s?rev=269295&r1=269294&r2=269295&view=diff
==============================================================================
--- llvm/trunk/test/MC/Mips/cprestore-noreorder-noat.s (original)
+++ llvm/trunk/test/MC/Mips/cprestore-noreorder-noat.s Thu May 12 09:01:50 2016
@@ -24,7 +24,7 @@ foo:
.cpload $25
.cprestore 8
-# O32: :[[@LINE-1]]:3: error: pseudo-instruction requires $at, which is not available
+# O32-NOT: 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)
@@ -34,3 +34,22 @@ foo:
jal foo
.end foo
+
+ .ent bar
+bar:
+ .frame $sp, 0, $ra
+ .set noreorder
+ .set noat
+
+ .cpload $25
+ .cprestore 65536
+# 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,
+
+ jal $25
+ jal $4, $25
+ jal bar
+
+ .end bar
More information about the llvm-commits
mailing list