diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp | 19 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp | 13 | ||||
| -rw-r--r-- | llvm/lib/Target/Mips/MipsTargetStreamer.h | 21 |
3 files changed, 34 insertions, 19 deletions
diff --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp index f7fd72fd27f..128cef7bc8d 100644 --- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp +++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp @@ -2633,16 +2633,17 @@ void MipsAsmParser::expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out, 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(bool IsLoad, int StackOffset, 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) { diff --git a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp index c9e240c7fb3..c6bb84d3b02 100644 --- a/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp +++ b/llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp @@ -228,7 +228,8 @@ void MipsTargetStreamer::emitGPRestore(int Offset, SMLoc IDLoc, /// 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::emitStoreWithImmOffset( // 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::emitDirectiveCpRestore( 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; } diff --git a/llvm/lib/Target/Mips/MipsTargetStreamer.h b/llvm/lib/Target/Mips/MipsTargetStreamer.h index c0b3c443f97..d418f80916b 100644 --- a/llvm/lib/Target/Mips/MipsTargetStreamer.h +++ b/llvm/lib/Target/Mips/MipsTargetStreamer.h @@ -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, |

