summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp19
-rw-r--r--llvm/lib/Target/Mips/MCTargetDesc/MipsTargetStreamer.cpp13
-rw-r--r--llvm/lib/Target/Mips/MipsTargetStreamer.h21
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,
OpenPOWER on IntegriCloud