[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