Make function loadImmediate a member of MipsSEInstrInfo and change it to return

the temporary register that was used to load the immediate. Currently, it always
returns register $at, but this will change if, in the future, we decide to use 
another register.

No changes in functionality.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162417 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Akira Hatanaka 2012-08-23 00:21:05 +00:00
parent 91a35f03da
commit fc4eafa0f4
5 changed files with 54 additions and 65 deletions

View File

@ -262,46 +262,3 @@ unsigned MipsInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
}
}
}
unsigned
llvm::Mips::loadImmediate(int64_t Imm, bool IsN64, const TargetInstrInfo &TII,
MachineBasicBlock& MBB,
MachineBasicBlock::iterator II, DebugLoc DL,
bool LastInstrIsADDiu,
MipsAnalyzeImmediate::Inst *LastInst) {
MipsAnalyzeImmediate AnalyzeImm;
unsigned Size = IsN64 ? 64 : 32;
unsigned LUi = IsN64 ? Mips::LUi64 : Mips::LUi;
unsigned ZEROReg = IsN64 ? Mips::ZERO_64 : Mips::ZERO;
unsigned ATReg = IsN64 ? Mips::AT_64 : Mips::AT;
const MipsAnalyzeImmediate::InstSeq &Seq =
AnalyzeImm.Analyze(Imm, Size, LastInstrIsADDiu);
MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();
if (LastInst && (Seq.size() == 1)) {
*LastInst = *Inst;
return 0;
}
// The first instruction can be a LUi, which is different from other
// instructions (ADDiu, ORI and SLL) in that it does not have a register
// operand.
if (Inst->Opc == LUi)
BuildMI(MBB, II, DL, TII.get(LUi), ATReg)
.addImm(SignExtend64<16>(Inst->ImmOpnd));
else
BuildMI(MBB, II, DL, TII.get(Inst->Opc), ATReg).addReg(ZEROReg)
.addImm(SignExtend64<16>(Inst->ImmOpnd));
// Build the remaining instructions in Seq. Skip the last instruction if
// LastInst is not 0.
for (++Inst; Inst != Seq.end() - !!LastInst; ++Inst)
BuildMI(MBB, II, DL, TII.get(Inst->Opc), ATReg).addReg(ATReg)
.addImm(SignExtend64<16>(Inst->ImmOpnd));
if (LastInst)
*LastInst = *Inst;
return Seq.size() - !!LastInst;
}

View File

@ -88,18 +88,6 @@ private:
const SmallVectorImpl<MachineOperand>& Cond) const;
};
namespace Mips {
/// Emit a series of instructions to load an immediate. All instructions
/// except for the last one are emitted. The function returns the number of
/// MachineInstrs generated. The opcode-immediate pair of the last
/// instruction is returned in LastInst, if it is not 0.
unsigned
loadImmediate(int64_t Imm, bool IsN64, const TargetInstrInfo &TII,
MachineBasicBlock& MBB, MachineBasicBlock::iterator II,
DebugLoc DL, bool LastInstrIsADDiu,
MipsAnalyzeImmediate::Inst *LastInst);
}
/// Create MipsInstrInfo objects.
const MipsInstrInfo *createMips16InstrInfo(MipsTargetMachine &TM);
const MipsInstrInfo *createMipsSEInstrInfo(MipsTargetMachine &TM);

View File

@ -260,14 +260,53 @@ void MipsSEInstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,
if (isInt<16>(Amount))// addi sp, sp, amount
BuildMI(MBB, I, DL, get(ADDiu), SP).addReg(SP).addImm(Amount);
else { // Expand immediate that doesn't fit in 16-bit.
unsigned ATReg = STI.isABI_N64() ? Mips::AT_64 : Mips::AT;
MBB.getParent()->getInfo<MipsFunctionInfo>()->setEmitNOAT();
Mips::loadImmediate(Amount, STI.isABI_N64(), *this, MBB, I, DL, false, 0);
BuildMI(MBB, I, DL, get(ADDu), SP).addReg(SP).addReg(ATReg);
unsigned Reg = loadImmediate(Amount, MBB, I, DL, 0);
BuildMI(MBB, I, DL, get(ADDu), SP).addReg(SP).addReg(Reg);
}
}
/// This function generates the sequence of instructions needed to get the
/// result of adding register REG and immediate IMM.
unsigned
MipsSEInstrInfo::loadImmediate(int64_t Imm, MachineBasicBlock &MBB,
MachineBasicBlock::iterator II, DebugLoc DL,
unsigned *NewImm) const {
MipsAnalyzeImmediate AnalyzeImm;
const MipsSubtarget &STI = TM.getSubtarget<MipsSubtarget>();
unsigned Size = STI.isABI_N64() ? 64 : 32;
unsigned LUi = STI.isABI_N64() ? Mips::LUi64 : Mips::LUi;
unsigned ZEROReg = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
unsigned ATReg = STI.isABI_N64() ? Mips::AT_64 : Mips::AT;
bool LastInstrIsADDiu = NewImm;
const MipsAnalyzeImmediate::InstSeq &Seq =
AnalyzeImm.Analyze(Imm, Size, LastInstrIsADDiu);
MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();
assert(Seq.size() && (!LastInstrIsADDiu || (Seq.size() > 1)));
// The first instruction can be a LUi, which is different from other
// instructions (ADDiu, ORI and SLL) in that it does not have a register
// operand.
if (Inst->Opc == LUi)
BuildMI(MBB, II, DL, get(LUi), ATReg)
.addImm(SignExtend64<16>(Inst->ImmOpnd));
else
BuildMI(MBB, II, DL, get(Inst->Opc), ATReg).addReg(ZEROReg)
.addImm(SignExtend64<16>(Inst->ImmOpnd));
// Build the remaining instructions in Seq.
for (++Inst; Inst != Seq.end() - LastInstrIsADDiu; ++Inst)
BuildMI(MBB, II, DL, get(Inst->Opc), ATReg).addReg(ATReg)
.addImm(SignExtend64<16>(Inst->ImmOpnd));
if (LastInstrIsADDiu)
*NewImm = Inst->ImmOpnd;
return ATReg;
}
unsigned MipsSEInstrInfo::GetAnalyzableBrOpc(unsigned Opc) const {
return (Opc == Mips::BEQ || Opc == Mips::BNE || Opc == Mips::BGTZ ||
Opc == Mips::BGEZ || Opc == Mips::BLTZ || Opc == Mips::BLEZ ||

View File

@ -15,7 +15,6 @@
#define MIPSSEINSTRUCTIONINFO_H
#include "MipsInstrInfo.h"
#include "MipsAnalyzeImmediate.h"
#include "MipsSERegisterInfo.h"
namespace llvm {
@ -70,6 +69,13 @@ public:
void adjustStackPtr(unsigned SP, int64_t Amount, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
/// Emit a series of instructions to load an immediate. If NewImm is a
/// non-NULL parameter, the last instruction is not emitted, but instead
/// its immediate operand is returned in NewImm.
unsigned loadImmediate(int64_t Imm, MachineBasicBlock &MBB,
MachineBasicBlock::iterator II, DebugLoc DL,
unsigned *NewImm) const;
private:
virtual unsigned GetAnalyzableBrOpc(unsigned Opc) const;

View File

@ -122,15 +122,14 @@ void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
DebugLoc DL = II->getDebugLoc();
unsigned ADDu = Subtarget.isABI_N64() ? Mips::DADDu : Mips::ADDu;
unsigned ATReg = Subtarget.isABI_N64() ? Mips::AT_64 : Mips::AT;
MipsAnalyzeImmediate::Inst LastInst(0, 0);
unsigned NewImm;
MipsFI->setEmitNOAT();
Mips::loadImmediate(Offset, Subtarget.isABI_N64(), TII, MBB, II, DL, true,
&LastInst);
BuildMI(MBB, II, DL, TII.get(ADDu), ATReg).addReg(FrameReg).addReg(ATReg);
unsigned Reg = TII.loadImmediate(Offset, MBB, II, DL, &NewImm);
BuildMI(MBB, II, DL, TII.get(ADDu), ATReg).addReg(FrameReg).addReg(Reg);
FrameReg = ATReg;
Offset = SignExtend64<16>(LastInst.ImmOpnd);
Offset = SignExtend64<16>(NewImm);
}
MI.getOperand(OpNo).ChangeToRegister(FrameReg, false);