forked from OSchip/llvm-project
[mips][ias] Move createCpRestoreMemOp to MipsTargetStreamer. NFC.
Summary: This removes the temporary call to isIntegratedAssemblerRequired() which was added recently. It's effect is now acheived directly in the MipsTargetStreamer hierarchy. Reviewers: sdardis Subscribers: dsanders, sdardis, llvm-commits Differential Revision: http://reviews.llvm.org/D19715 llvm-svn: 268058
This commit is contained in:
parent
173fc57b54
commit
7225cd52e7
|
@ -1891,8 +1891,7 @@ bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
|
|||
STI);
|
||||
|
||||
// Load the $gp from the stack.
|
||||
createCpRestoreMemOp(true /*IsLoad*/, CpRestoreOffset /*StackOffset*/,
|
||||
IDLoc, Out, STI);
|
||||
TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
|
||||
} else
|
||||
Warning(IDLoc, "no .cprestore used in PIC mode");
|
||||
}
|
||||
|
@ -3593,19 +3592,18 @@ void MipsAsmParser::createCpRestoreMemOp(bool IsLoad, int StackOffset,
|
|||
const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer &TOut = getTargetStreamer();
|
||||
|
||||
// If the offset can not fit into 16 bits, we need to expand.
|
||||
if (!isInt<16>(StackOffset)) {
|
||||
MCInst MemInst;
|
||||
MemInst.setOpcode(IsLoad ? Mips::LW : Mips::SW);
|
||||
MemInst.addOperand(MCOperand::createReg(Mips::GP));
|
||||
MemInst.addOperand(MCOperand::createReg(Mips::SP));
|
||||
MemInst.addOperand(MCOperand::createImm(StackOffset));
|
||||
expandMemInst(MemInst, IDLoc, Out, STI, IsLoad, true /*HasImmOpnd*/);
|
||||
if (IsLoad) {
|
||||
TOut.emitLoadWithImmOffset(Mips::LW, Mips::GP, Mips::SP, StackOffset,
|
||||
Mips::GP, IDLoc, STI);
|
||||
return;
|
||||
}
|
||||
|
||||
TOut.emitRRI(IsLoad ? Mips::LW : Mips::SW, Mips::GP, Mips::SP, StackOffset,
|
||||
IDLoc, STI);
|
||||
unsigned ATReg = getATReg(IDLoc);
|
||||
if (!ATReg)
|
||||
return;
|
||||
|
||||
TOut.emitStoreWithImmOffset(Mips::SW, Mips::GP, Mips::SP, StackOffset, ATReg,
|
||||
IDLoc, STI);
|
||||
}
|
||||
|
||||
unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
|
||||
|
@ -5472,14 +5470,11 @@ bool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
|
|||
return false;
|
||||
}
|
||||
|
||||
// Store the $gp on the stack.
|
||||
if (getStreamer().isIntegratedAssemblerRequired()) {
|
||||
const MCSubtargetInfo &STI = getSTI();
|
||||
createCpRestoreMemOp(false /*IsLoad*/, CpRestoreOffset /*StackOffset*/, Loc,
|
||||
getStreamer(), &STI);
|
||||
}
|
||||
unsigned ATReg = getATReg(Loc);
|
||||
if (!ATReg)
|
||||
return true;
|
||||
|
||||
getTargetStreamer().emitDirectiveCpRestore(CpRestoreOffset);
|
||||
getTargetStreamer().emitDirectiveCpRestore(CpRestoreOffset, ATReg, Loc, STI);
|
||||
Parser.Lex(); // Consume the EndOfStatement.
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -88,7 +88,9 @@ void MipsTargetStreamer::emitDirectiveSetHardFloat() {
|
|||
void MipsTargetStreamer::emitDirectiveSetDsp() { forbidModuleDirective(); }
|
||||
void MipsTargetStreamer::emitDirectiveSetNoDsp() { forbidModuleDirective(); }
|
||||
void MipsTargetStreamer::emitDirectiveCpLoad(unsigned RegNo) {}
|
||||
void MipsTargetStreamer::emitDirectiveCpRestore(int Offset) {
|
||||
void MipsTargetStreamer::emitDirectiveCpRestore(int Offset, unsigned ATReg,
|
||||
SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI) {
|
||||
forbidModuleDirective();
|
||||
}
|
||||
void MipsTargetStreamer::emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
|
||||
|
@ -207,12 +209,22 @@ void MipsTargetStreamer::emitNop(SMLoc IDLoc, const MCSubtargetInfo *STI) {
|
|||
emitRRI(Mips::SLL, Mips::ZERO, Mips::ZERO, 0, IDLoc, STI);
|
||||
}
|
||||
|
||||
/// Emit a store instruction with an immediate offset. The immediate is
|
||||
/// expected to be out-of-range for a simm16 and will be expanded to
|
||||
/// appropriate instructions.
|
||||
/// Emit the $gp restore operation for .cprestore.
|
||||
void MipsTargetStreamer::emitGPRestore(int Offset, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI) {
|
||||
emitLoadWithImmOffset(Mips::LW, Mips::GP, Mips::SP, Offset, Mips::GP, IDLoc,
|
||||
STI);
|
||||
}
|
||||
|
||||
/// 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) {
|
||||
if (isInt<16>(Offset)) {
|
||||
emitRRI(Opcode, SrcReg, BaseReg, Offset, IDLoc, STI);
|
||||
return;
|
||||
}
|
||||
|
||||
// sw $8, offset($8) => lui $at, %hi(offset)
|
||||
// add $at, $at, $8
|
||||
// sw $8, %lo(offset)($at)
|
||||
|
@ -250,16 +262,19 @@ void MipsTargetStreamer::emitStoreWithSymOffset(
|
|||
emitRRX(Opcode, SrcReg, ATReg, LoOperand, IDLoc, STI);
|
||||
}
|
||||
|
||||
/// Emit a load instruction with an immediate offset. The immediate is expected
|
||||
/// to be out-of-range for a simm16 and will be expanded to appropriate
|
||||
/// instructions. DstReg and TmpReg are permitted to be the same register iff
|
||||
/// DstReg is distinct from BaseReg and DstReg is a GPR. It is the callers
|
||||
/// responsibility to identify such cases and pass the appropriate register in
|
||||
/// TmpReg.
|
||||
/// Emit a load instruction with an immediate offset. DstReg and TmpReg are
|
||||
/// permitted to be the same register iff DstReg is distinct from BaseReg and
|
||||
/// DstReg is a GPR. It is the callers responsibility to identify such cases
|
||||
/// and pass the appropriate register in TmpReg.
|
||||
void MipsTargetStreamer::emitLoadWithImmOffset(unsigned Opcode, unsigned DstReg,
|
||||
unsigned BaseReg, int64_t Offset,
|
||||
unsigned TmpReg, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI) {
|
||||
if (isInt<16>(Offset)) {
|
||||
emitRRI(Opcode, DstReg, BaseReg, Offset, IDLoc, STI);
|
||||
return;
|
||||
}
|
||||
|
||||
// 1) lw $8, offset($9) => lui $8, %hi(offset)
|
||||
// add $8, $8, $9
|
||||
// lw $8, %lo(offset)($9)
|
||||
|
@ -555,8 +570,10 @@ void MipsTargetAsmStreamer::emitDirectiveCpLoad(unsigned RegNo) {
|
|||
forbidModuleDirective();
|
||||
}
|
||||
|
||||
void MipsTargetAsmStreamer::emitDirectiveCpRestore(int Offset) {
|
||||
MipsTargetStreamer::emitDirectiveCpRestore(Offset);
|
||||
void MipsTargetAsmStreamer::emitDirectiveCpRestore(int Offset, unsigned ATReg,
|
||||
SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer::emitDirectiveCpRestore(Offset, ATReg, IDLoc, STI);
|
||||
OS << "\t.cprestore\t" << Offset << "\n";
|
||||
}
|
||||
|
||||
|
@ -990,8 +1007,10 @@ void MipsTargetELFStreamer::emitDirectiveCpLoad(unsigned RegNo) {
|
|||
forbidModuleDirective();
|
||||
}
|
||||
|
||||
void MipsTargetELFStreamer::emitDirectiveCpRestore(int Offset) {
|
||||
MipsTargetStreamer::emitDirectiveCpRestore(Offset);
|
||||
void MipsTargetELFStreamer::emitDirectiveCpRestore(int Offset, unsigned ATReg,
|
||||
SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI) {
|
||||
MipsTargetStreamer::emitDirectiveCpRestore(Offset, ATReg, IDLoc, STI);
|
||||
// .cprestore offset
|
||||
// When PIC mode is enabled and the O32 ABI is used, this directive expands
|
||||
// to:
|
||||
|
@ -1003,8 +1022,9 @@ void MipsTargetELFStreamer::emitDirectiveCpRestore(int Offset) {
|
|||
if (!Pic || (getABI().IsN32() || getABI().IsN64()))
|
||||
return;
|
||||
|
||||
// FIXME: MipsAsmParser currently emits the instructions that should be
|
||||
// emitted here.
|
||||
// Store the $gp on the stack.
|
||||
emitStoreWithImmOffset(Mips::SW, Mips::GP, Mips::SP, Offset, ATReg, IDLoc,
|
||||
STI);
|
||||
}
|
||||
|
||||
void MipsTargetELFStreamer::emitDirectiveCpsetup(unsigned RegNo,
|
||||
|
|
|
@ -78,7 +78,8 @@ public:
|
|||
|
||||
// PIC support
|
||||
virtual void emitDirectiveCpLoad(unsigned RegNo);
|
||||
virtual void emitDirectiveCpRestore(int Offset);
|
||||
virtual void emitDirectiveCpRestore(int Offset, unsigned ATReg, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI);
|
||||
virtual void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
|
||||
const MCSymbol &Sym, bool IsReg);
|
||||
virtual void emitDirectiveCpreturn(unsigned SaveLocation,
|
||||
|
@ -130,6 +131,7 @@ public:
|
|||
MCOperand &HiOperand, MCOperand &LoOperand,
|
||||
unsigned ATReg, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI);
|
||||
void emitGPRestore(int Offset, SMLoc IDLoc, const MCSubtargetInfo *STI);
|
||||
|
||||
void forbidModuleDirective() { ModuleDirectiveAllowed = false; }
|
||||
void reallowModuleDirective() { ModuleDirectiveAllowed = true; }
|
||||
|
@ -230,7 +232,8 @@ public:
|
|||
|
||||
// PIC support
|
||||
void emitDirectiveCpLoad(unsigned RegNo) override;
|
||||
void emitDirectiveCpRestore(int Offset) override;
|
||||
void emitDirectiveCpRestore(int Offset, unsigned ATReg, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI) override;
|
||||
void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
|
||||
const MCSymbol &Sym, bool IsReg) override;
|
||||
void emitDirectiveCpreturn(unsigned SaveLocation,
|
||||
|
@ -282,7 +285,8 @@ public:
|
|||
|
||||
// PIC support
|
||||
void emitDirectiveCpLoad(unsigned RegNo) override;
|
||||
void emitDirectiveCpRestore(int Offset) override;
|
||||
void emitDirectiveCpRestore(int Offset, unsigned ATReg, SMLoc IDLoc,
|
||||
const MCSubtargetInfo *STI) override;
|
||||
void emitDirectiveCpsetup(unsigned RegNo, int RegOrOffset,
|
||||
const MCSymbol &Sym, bool IsReg) override;
|
||||
void emitDirectiveCpreturn(unsigned SaveLocation,
|
||||
|
|
|
@ -2,9 +2,25 @@
|
|||
# RUN: llvm-mc -triple=mipsel-unknown-linux < %s | \
|
||||
# RUN: llvm-mc -triple=mipsel-unknown-linux | FileCheck %s
|
||||
|
||||
# CHECK: bnez $2, foo
|
||||
# CHECK: nop
|
||||
# CHECK-NOT: nop
|
||||
|
||||
.text
|
||||
branch:
|
||||
bnez $2, foo
|
||||
|
||||
# CHECK-LABEL: branch:
|
||||
# CHECK: bnez $2, foo
|
||||
# CHECK: nop
|
||||
# CHECK-NOT: nop
|
||||
|
||||
cprestore:
|
||||
.option pic2
|
||||
.cprestore 16
|
||||
jal foo
|
||||
|
||||
# CHECK-LABEL: cprestore:
|
||||
# CHECK: .cprestore 16
|
||||
# CHECK: lw $25, %call16(foo)($gp)
|
||||
# CHECK: jalr $25
|
||||
# CHECK: nop
|
||||
# CHECK: lw $gp, 16($sp)
|
||||
# CHECK-NOT: nop
|
||||
# CHECK-NOT: lw
|
||||
|
|
Loading…
Reference in New Issue