}
public:
- /// Return true if the instruction is a register to register move
- /// and leave the source and dest operands in the passed parameters.
+ /// Return true if the instruction is a register to register move and return
+ /// the source and dest operands and their sub-register indices by reference.
virtual bool isMoveInstr(const MachineInstr& MI,
- unsigned& sourceReg,
- unsigned& destReg) const {
+ unsigned& SrcReg, unsigned& DstReg,
+ unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
return false;
}
if (index == end) break;
MachineInstr *MI = getInstructionFromIndex(index);
- unsigned SrcReg, DstReg;
- if (tii_->isMoveInstr(*MI, SrcReg, DstReg))
+ unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
+ if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
if (SrcReg == li.reg || DstReg == li.reg)
continue;
for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
defIndex = getUseIndex(MIIdx);
VNInfo *ValNo;
MachineInstr *CopyMI = NULL;
- unsigned SrcReg, DstReg;
+ unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (mi->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG ||
mi->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
- tii_->isMoveInstr(*mi, SrcReg, DstReg))
+ tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg))
CopyMI = mi;
// Earlyclobbers move back one.
ValNo = interval.getNextValue(defIndex, CopyMI, VNInfoAllocator);
VNInfo *ValNo;
MachineInstr *CopyMI = NULL;
- unsigned SrcReg, DstReg;
+ unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (mi->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG ||
mi->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
- tii_->isMoveInstr(*mi, SrcReg, DstReg))
+ tii_->isMoveInstr(*mi, SrcReg, DstReg, SrcSubReg, DstSubReg))
CopyMI = mi;
ValNo = interval.getNextValue(defIndex, CopyMI, VNInfoAllocator);
getOrCreateInterval(MO.getReg()));
else if (allocatableRegs_[MO.getReg()]) {
MachineInstr *CopyMI = NULL;
- unsigned SrcReg, DstReg;
+ unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG ||
MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG ||
- tii_->isMoveInstr(*MI, SrcReg, DstReg))
+ tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg))
CopyMI = MI;
handlePhysicalRegisterDef(MBB, MI, MIIdx, MO,
getOrCreateInterval(MO.getReg()), CopyMI);
} else if (VNI->copy->getOpcode() == TargetInstrInfo::INSERT_SUBREG)
return VNI->copy->getOperand(2).getReg();
- unsigned SrcReg, DstReg;
- if (tii_->isMoveInstr(*VNI->copy, SrcReg, DstReg))
+ unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
+ if (tii_->isMoveInstr(*VNI->copy, SrcReg, DstReg, SrcSubReg, DstSubReg))
return SrcReg;
assert(0 && "Unrecognized copy instruction!");
return 0;
VNInfo* NewVN = LI->getNextValue(DefIdx, 0, Alloc);
// If the def is a move, set the copy field.
- unsigned source, dest;
- if (TII->isMoveInstr(*DI, source, dest))
- if (dest == LI->reg)
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+ if (TII->isMoveInstr(*DI, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
+ if (DstReg == LI->reg)
NewVN->copy = &*DI;
NewVNs[&*DI] = NewVN;
}
// Finally, if this is a noop copy instruction, zap it.
- unsigned SrcReg, DstReg;
- if (TII.isMoveInstr(*MI, SrcReg, DstReg) && SrcReg == DstReg)
+ unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
+ if (TII.isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
+ SrcReg == DstReg)
MBB.erase(MI);
}
if (!vni->def || vni->def == ~1U || vni->def == ~0U)
return Reg;
MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def);
- unsigned SrcReg, DstReg;
- if (!CopyMI || !tii_->isMoveInstr(*CopyMI, SrcReg, DstReg))
+ unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
+ if (!CopyMI ||
+ !tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubReg, DstSubReg))
return Reg;
if (TargetRegisterInfo::isVirtualRegister(SrcReg)) {
if (!vrm_->isAssignedReg(SrcReg))
VNInfo *vni = cur->begin()->valno;
if (vni->def && vni->def != ~1U && vni->def != ~0U) {
MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def);
- unsigned SrcReg, DstReg;
- if (CopyMI && tii_->isMoveInstr(*CopyMI, SrcReg, DstReg)) {
+ unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
+ if (CopyMI &&
+ tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubReg, DstSubReg)) {
unsigned Reg = 0;
if (TargetRegisterInfo::isPhysicalRegister(SrcReg))
Reg = SrcReg;
}
// Finally, if this is a noop copy instruction, zap it.
- unsigned SrcReg, DstReg;
- if (TII->isMoveInstr(*MI, SrcReg, DstReg) && SrcReg == DstReg)
+ unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
+ if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
+ SrcReg == DstReg)
MBB.erase(MI);
}
iItr != iEnd; ++iItr) {
const MachineInstr *instr = &*iItr;
- unsigned srcReg, dstReg;
+ unsigned srcReg, dstReg, srcSubReg, dstSubReg;
// If this isn't a copy then continue to the next instruction.
- if (!tii->isMoveInstr(*instr, srcReg, dstReg))
+ if (!tii->isMoveInstr(*instr, srcReg, dstReg, srcSubReg, dstSubReg))
continue;
// If the registers are already the same our job is nice and easy.
// don't coalesce. Also, only coalesce away a virtual register to virtual
// register copy.
bool Coalesced = false;
- unsigned SrcReg, DstReg;
+ unsigned SrcReg, DstReg, SrcSubReg, DstSubReg;
if (NumUses == 1 &&
- TII.isMoveInstr(*UseMI, SrcReg, DstReg) &&
+ TII.isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubReg, DstSubReg) &&
TargetRegisterInfo::isVirtualRegister(DstReg)) {
VirtReg = DstReg;
Coalesced = true;
else
BKills.push_back(li_->getUseIndex(UseIdx)+1);
}
- unsigned SrcReg, DstReg;
- if (!tii_->isMoveInstr(*UseMI, SrcReg, DstReg))
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+ if (!tii_->isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
continue;
if (DstReg == IntB.reg) {
// This copy will become a noop. If it's defining a new val#,
if (OldSubIdx)
UseDstReg = tri_->getSubReg(DstReg, OldSubIdx);
- unsigned CopySrcReg, CopyDstReg;
- if (tii_->isMoveInstr(*UseMI, CopySrcReg, CopyDstReg) &&
+ unsigned CopySrcReg, CopyDstReg, CopySrcSubIdx, CopyDstSubIdx;
+ if (tii_->isMoveInstr(*UseMI, CopySrcReg, CopyDstReg,
+ CopySrcSubIdx, CopyDstSubIdx) &&
CopySrcReg != CopyDstReg &&
CopySrcReg == SrcReg && CopyDstReg != UseDstReg) {
// If the use is a copy and it won't be coalesced away, and its source
// After updating the operand, check if the machine instruction has
// become a copy. If so, update its val# information.
const TargetInstrDesc &TID = UseMI->getDesc();
- unsigned CopySrcReg, CopyDstReg;
+ unsigned CopySrcReg, CopyDstReg, CopySrcSubIdx, CopyDstSubIdx;
if (TID.getNumDefs() == 1 && TID.getNumOperands() > 2 &&
- tii_->isMoveInstr(*UseMI, CopySrcReg, CopyDstReg) &&
+ tii_->isMoveInstr(*UseMI, CopySrcReg, CopyDstReg,
+ CopySrcSubIdx, CopyDstSubIdx) &&
CopySrcReg != CopyDstReg &&
(TargetRegisterInfo::isVirtualRegister(CopyDstReg) ||
allocatableRegs_[CopyDstReg])) {
// of last use.
LastUse->setIsKill();
removeRange(li, li_->getDefIndex(LastUseIdx), LR->end, li_, tri_);
- unsigned SrcReg, DstReg;
- if (tii_->isMoveInstr(*LastUseMI, SrcReg, DstReg) &&
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+ if (tii_->isMoveInstr(*LastUseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
DstReg == li.reg) {
// Last use is itself an identity code.
int DeadIdx = LastUseMI->findRegisterDefOperandIdx(li.reg, false, tri_);
if (ULR == li.end() || ULR->valno != LR->valno)
continue;
// If the use is not a use, then it's not safe to coalesce the move.
- unsigned SrcReg, DstReg;
- if (!tii_->isMoveInstr(*UseMI, SrcReg, DstReg)) {
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+ if (!tii_->isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) {
if (UseMI->getOpcode() == TargetInstrInfo::INSERT_SUBREG &&
UseMI->getOperand(1).getReg() == li.reg)
continue;
if (ULR == li.end() || ULR->valno != VNI)
continue;
// If the use is a copy, turn it into an identity copy.
- unsigned SrcReg, DstReg;
- if (tii_->isMoveInstr(*MI, SrcReg, DstReg) && SrcReg == li.reg) {
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+ if (tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
+ SrcReg == li.reg) {
// Each use MI may have multiple uses of this register. Change them all.
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI->getOperand(i);
DOUT << li_->getInstructionIndex(CopyMI) << '\t' << *CopyMI;
- unsigned SrcReg;
- unsigned DstReg;
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
bool isExtSubReg = CopyMI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG;
bool isInsSubReg = CopyMI->getOpcode() == TargetInstrInfo::INSERT_SUBREG;
unsigned SubIdx = 0;
}
DstReg = CopyMI->getOperand(0).getReg();
SrcReg = CopyMI->getOperand(2).getReg();
- } else if (!tii_->isMoveInstr(*CopyMI, SrcReg, DstReg)) {
+ } else if (!tii_->isMoveInstr(*CopyMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)){
assert(0 && "Unrecognized copy instruction!");
return false;
}
if (!vni->def || vni->def == ~1U || vni->def == ~0U)
continue;
MachineInstr *CopyMI = li_->getInstructionFromIndex(vni->def);
- unsigned NewSrcReg, NewDstReg;
+ unsigned NewSrcReg, NewDstReg, NewSrcSubIdx, NewDstSubIdx;
if (CopyMI &&
JoinedCopies.count(CopyMI) == 0 &&
- tii_->isMoveInstr(*CopyMI, NewSrcReg, NewDstReg)) {
+ tii_->isMoveInstr(*CopyMI, NewSrcReg, NewDstReg,
+ NewSrcSubIdx, NewDstSubIdx)) {
unsigned LoopDepth = loopInfo->getLoopDepth(CopyMBB);
JoinQueue->push(CopyRec(CopyMI, LoopDepth,
isBackEdgeCopy(CopyMI, DstReg)));
// It's a sub-register live interval, we may not have precise information.
// Re-compute it.
MachineInstr *DefMI = li_->getInstructionFromIndex(LR->start);
- unsigned SrcReg, DstReg;
- if (DefMI && tii_->isMoveInstr(*DefMI, SrcReg, DstReg) &&
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+ if (DefMI &&
+ tii_->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
DstReg == li.reg && SrcReg == Reg) {
// Cache computed info.
LR->valno->def = LR->start;
MachineInstr *Inst = MII++;
// If this isn't a copy nor a extract_subreg, we can't join intervals.
- unsigned SrcReg, DstReg;
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (Inst->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG) {
DstReg = Inst->getOperand(0).getReg();
SrcReg = Inst->getOperand(1).getReg();
} else if (Inst->getOpcode() == TargetInstrInfo::INSERT_SUBREG) {
DstReg = Inst->getOperand(0).getReg();
SrcReg = Inst->getOperand(2).getReg();
- } else if (!tii_->isMoveInstr(*Inst, SrcReg, DstReg))
+ } else if (!tii_->isMoveInstr(*Inst, SrcReg, DstReg, SrcSubIdx, DstSubIdx))
continue;
bool SrcIsPhys = TargetRegisterInfo::isPhysicalRegister(SrcReg);
E = mri_->use_end(); I != E; ++I) {
MachineOperand &Use = I.getOperand();
MachineInstr *UseMI = Use.getParent();
- unsigned SrcReg, DstReg;
- if (tii_->isMoveInstr(*UseMI, SrcReg, DstReg) && SrcReg == DstReg)
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+ if (tii_->isMoveInstr(*UseMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
+ SrcReg == DstReg)
// Ignore identity copies.
continue;
unsigned Idx = li_->getInstructionIndex(UseMI);
return NULL;
// Ignore identity copies.
- unsigned SrcReg, DstReg;
- if (!(tii_->isMoveInstr(*MI, SrcReg, DstReg) && SrcReg == DstReg))
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
+ if (!(tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) &&
+ SrcReg == DstReg))
for (unsigned i = 0, NumOps = MI->getNumOperands(); i != NumOps; ++i) {
MachineOperand &Use = MI->getOperand(i);
if (Use.isReg() && Use.isUse() && Use.getReg() &&
for (MachineBasicBlock::iterator mii = mbb->begin(), mie = mbb->end();
mii != mie; ) {
MachineInstr *MI = mii;
- unsigned SrcReg, DstReg;
+ unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx;
if (JoinedCopies.count(MI)) {
// Delete all coalesced copies.
- if (!tii_->isMoveInstr(*MI, SrcReg, DstReg)) {
+ if (!tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx)) {
assert((MI->getOpcode() == TargetInstrInfo::EXTRACT_SUBREG ||
MI->getOpcode() == TargetInstrInfo::INSERT_SUBREG) &&
"Unrecognized copy instruction");
}
// If the move will be an identity move delete it
- bool isMove = tii_->isMoveInstr(*MI, SrcReg, DstReg);
+ bool isMove= tii_->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx);
if (isMove && SrcReg == DstReg) {
if (li_->hasInterval(SrcReg)) {
LiveInterval &RegInt = li_->getInterval(SrcReg);
if (!TargetRegisterInfo::isVirtualRegister(VirtReg)) {
// Check to see if this is a noop copy. If so, eliminate the
// instruction before considering the dest reg to be changed.
- unsigned Src, Dst;
- if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
+ unsigned Src, Dst, SrcSR, DstSR;
+ if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst) {
++NumDCE;
DOUT << "Removing now-noop copy: " << MI;
SmallVector<unsigned, 2> KillRegs;
// Check to see if this is a noop copy. If so, eliminate the
// instruction before considering the dest reg to be changed.
{
- unsigned Src, Dst;
- if (TII->isMoveInstr(MI, Src, Dst) && Src == Dst) {
+ unsigned Src, Dst, SrcSR, DstSR;
+ if (TII->isMoveInstr(MI, Src, Dst, SrcSR, DstSR) && Src == Dst) {
++NumDCE;
DOUT << "Removing now-noop copy: " << MI;
InvalidateKills(MI, RegKills, KillOps);
/// leave the source and dest operands in the passed parameters.
///
bool ARMInstrInfo::isMoveInstr(const MachineInstr &MI,
- unsigned &SrcReg, unsigned &DstReg) const {
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned& SrcSubIdx, unsigned& DstSubIdx) const {
+ SrcSubIdx = DstSubIdx = 0; // No sub-registers.
+
unsigned oc = MI.getOpcode();
switch (oc) {
default:
/// This is used for addressing modes.
virtual const TargetRegisterClass *getPointerRegClass() const;
- /// Return true if the instruction is a register to register move and
- /// leave the source and dest operands in the passed parameters.
- ///
+ /// Return true if the instruction is a register to register move and return
+ /// the source and dest operands and their sub-register indices by reference.
virtual bool isMoveInstr(const MachineInstr &MI,
- unsigned &SrcReg, unsigned &DstReg) const;
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
+
virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
int &FrameIndex) const;
virtual unsigned isStoreToStackSlot(const MachineInstr *MI,
bool AlphaInstrInfo::isMoveInstr(const MachineInstr& MI,
- unsigned& sourceReg,
- unsigned& destReg) const {
+ unsigned& sourceReg, unsigned& destReg,
+ unsigned& SrcSR, unsigned& DstSR) const {
unsigned oc = MI.getOpcode();
if (oc == Alpha::BISr ||
oc == Alpha::CPYSS ||
if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) {
sourceReg = MI.getOperand(1).getReg();
destReg = MI.getOperand(0).getReg();
+ SrcSR = DstSR = 0;
return true;
}
}
///
virtual const AlphaRegisterInfo &getRegisterInfo() const { return RI; }
- /// Return true if the instruction is a register to register move and
- /// leave the source and dest operands in the passed parameters.
- ///
+ /// Return true if the instruction is a register to register move and return
+ /// the source and dest operands and their sub-register indices by reference.
virtual bool isMoveInstr(const MachineInstr &MI,
- unsigned &SrcReg, unsigned &DstReg) const;
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
virtual unsigned isLoadFromStackSlot(const MachineInstr *MI,
int &FrameIndex) const;
bool
SPUInstrInfo::isMoveInstr(const MachineInstr& MI,
unsigned& sourceReg,
- unsigned& destReg) const {
+ unsigned& destReg,
+ unsigned& SrcSR, unsigned& DstSR) const {
+ SrcSR = DstSR = 0; // No sub-registers.
+
// Primarily, ORI and OR are generated by copyRegToReg. But, there are other
// cases where we can safely say that what's being done is really a move
// (see how PowerPC does this -- it's the model for this code too.)
/// This is used for addressing modes.
virtual const TargetRegisterClass *getPointerRegClass() const;
- // Return true if the instruction is a register to register move and
- // leave the source and dest operands in the passed parameters.
- //
- virtual bool isMoveInstr(const MachineInstr& MI,
- unsigned& sourceReg,
- unsigned& destReg) const;
+ /// Return true if the instruction is a register to register move and return
+ /// the source and dest operands and their sub-register indices by reference.
+ virtual bool isMoveInstr(const MachineInstr &MI,
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
unsigned isLoadFromStackSlot(const MachineInstr *MI,
int &FrameIndex) const;
bool IA64InstrInfo::isMoveInstr(const MachineInstr& MI,
- unsigned& sourceReg,
- unsigned& destReg) const {
+ unsigned& sourceReg,
+ unsigned& destReg,
+ unsigned& SrcSR, unsigned& DstSR) const {
+ SrcSR = DstSR = 0; // No sub-registers.
+
unsigned oc = MI.getOpcode();
if (oc == IA64::MOV || oc == IA64::FMOV) {
// TODO: this doesn't detect predicate moves
///
virtual const IA64RegisterInfo &getRegisterInfo() const { return RI; }
- //
- // Return true if the instruction is a register to register move and
- // leave the source and dest operands in the passed parameters.
- //
- virtual bool isMoveInstr(const MachineInstr& MI,
- unsigned& sourceReg,
- unsigned& destReg) const;
+ /// Return true if the instruction is a register to register move and return
+ /// the source and dest operands and their sub-register indices by reference.
+ virtual bool isMoveInstr(const MachineInstr &MI,
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
MachineBasicBlock *FBB,
const SmallVectorImpl<MachineOperand> &Cond) const;
/// Return true if the instruction is a register to register move and
/// leave the source and dest operands in the passed parameters.
bool MipsInstrInfo::
-isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg) const
+isMoveInstr(const MachineInstr &MI, unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const
{
+ SrcSubIdx = DstSubIdx = 0; // No sub-registers.
+
// addu $dst, $src, $zero || addu $dst, $zero, $src
// or $dst, $src, $zero || or $dst, $zero, $src
if ((MI.getOpcode() == Mips::ADDu) || (MI.getOpcode() == Mips::OR)) {
///
virtual const MipsRegisterInfo &getRegisterInfo() const { return RI; }
- /// Return true if the instruction is a register to register move and
- /// leave the source and dest operands in the passed parameters.
- ///
+ /// Return true if the instruction is a register to register move and return
+ /// the source and dest operands and their sub-register indices by reference.
virtual bool isMoveInstr(const MachineInstr &MI,
- unsigned &SrcReg, unsigned &DstReg) const;
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
/// isLoadFromStackSlot - If the specified machine instruction is a direct
/// load from a stack slot, return the virtual or physical register number of
}
bool PIC16InstrInfo::isMoveInstr(const MachineInstr &MI,
- unsigned &SrcReg,
- unsigned &DestReg) const {
+ unsigned &SrcReg, unsigned &DestReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
+ SrcSubIdx = DstSubIdx = 0; // No sub-registers.
if (MI.getOpcode() == PIC16::copy_fsr
|| MI.getOpcode() == PIC16::copy_w) {
const TargetRegisterClass *DestRC,
const TargetRegisterClass *SrcRC) const;
virtual bool isMoveInstr(const MachineInstr &MI,
- unsigned &SrcReg,
- unsigned &DestReg) const;
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
};
bool PPCInstrInfo::isMoveInstr(const MachineInstr& MI,
unsigned& sourceReg,
- unsigned& destReg) const {
+ unsigned& destReg,
+ unsigned& sourceSubIdx,
+ unsigned& destSubIdx) const {
+ sourceSubIdx = destSubIdx = 0; // No sub-registers.
+
unsigned oc = MI.getOpcode();
if (oc == PPC::OR || oc == PPC::OR8 || oc == PPC::VOR ||
oc == PPC::OR4To8 || oc == PPC::OR8To4) { // or r1, r2, r2
/// This is used for addressing modes.
virtual const TargetRegisterClass *getPointerRegClass() const;
- // Return true if the instruction is a register to register move and
- // leave the source and dest operands in the passed parameters.
- //
- virtual bool isMoveInstr(const MachineInstr& MI,
- unsigned& sourceReg,
- unsigned& destReg) const;
+ /// Return true if the instruction is a register to register move and return
+ /// the source and dest operands and their sub-register indices by reference.
+ virtual bool isMoveInstr(const MachineInstr &MI,
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
unsigned isLoadFromStackSlot(const MachineInstr *MI,
int &FrameIndex) const;
/// leave the source and dest operands in the passed parameters.
///
bool SparcInstrInfo::isMoveInstr(const MachineInstr &MI,
- unsigned &SrcReg, unsigned &DstReg) const {
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSR, unsigned &DstSR) const {
+ SrcSR = DstSR = 0; // No sub-registers.
+
// We look for 3 kinds of patterns here:
// or with G0 or 0
// add with G0 or 0
///
virtual const SparcRegisterInfo &getRegisterInfo() const { return RI; }
- /// Return true if the instruction is a register to register move and
- /// leave the source and dest operands in the passed parameters.
- ///
+ /// Return true if the instruction is a register to register move and return
+ /// the source and dest operands and their sub-register indices by reference.
virtual bool isMoveInstr(const MachineInstr &MI,
- unsigned &SrcReg, unsigned &DstReg) const;
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
/// isLoadFromStackSlot - If the specified machine instruction is a direct
/// load from a stack slot, return the virtual or physical register number of
const MachineInstr &MI = *RI;
if (MI.modifiesRegister(Reg)) {
- unsigned Src, Dst;
+ unsigned Src, Dst, SrcSR, DstSR;
- if (getInstrInfo()->isMoveInstr(MI, Src, Dst)) {
+ if (getInstrInfo()->isMoveInstr(MI, Src, Dst, SrcSR, DstSR)) {
Reg = Src;
continue;
}
}
bool X86InstrInfo::isMoveInstr(const MachineInstr& MI,
- unsigned& sourceReg,
- unsigned& destReg) const {
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const {
switch (MI.getOpcode()) {
default:
return false;
MI.getOperand(0).isReg() &&
MI.getOperand(1).isReg() &&
"invalid register-register move instruction");
- sourceReg = MI.getOperand(1).getReg();
- destReg = MI.getOperand(0).getReg();
+ SrcReg = MI.getOperand(1).getReg();
+ DstReg = MI.getOperand(0).getReg();
+ SrcSubIdx = MI.getOperand(1).getSubReg();
+ DstSubIdx = MI.getOperand(0).getSubReg();
return true;
}
}
///
virtual const X86RegisterInfo &getRegisterInfo() const { return RI; }
- // Return true if the instruction is a register to register move and
- // leave the source and dest operands in the passed parameters.
- //
- bool isMoveInstr(const MachineInstr& MI, unsigned& sourceReg,
- unsigned& destReg) const;
+ /// Return true if the instruction is a register to register move and return
+ /// the source and dest operands and their sub-register indices by reference.
+ virtual bool isMoveInstr(const MachineInstr &MI,
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
+
unsigned isLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const;
unsigned isStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const;
++EmittedInsts;
// Check for mov mnemonic
- unsigned src, dst;
- if (TM.getInstrInfo()->isMoveInstr(*MI, src, dst)) {
+ unsigned src, dst, srcSR, dstSR;
+ if (TM.getInstrInfo()->isMoveInstr(*MI, src, dst, srcSR, dstSR)) {
O << "\tmov ";
O << TM.getRegisterInfo()->get(dst).AsmName;
O << ", ";
/// leave the source and dest operands in the passed parameters.
///
bool XCoreInstrInfo::isMoveInstr(const MachineInstr &MI,
- unsigned &SrcReg, unsigned &DstReg) const {
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSR, unsigned &DstSR) const {
+ SrcSR = DstSR = 0; // No sub-registers.
+
// We look for 4 kinds of patterns here:
// add dst, src, 0
// sub dst, src, 0
///
virtual const TargetRegisterInfo &getRegisterInfo() const { return RI; }
- /// Return true if the instruction is a register to register move and
- /// leave the source and dest operands in the passed parameters.
- ///
+ /// Return true if the instruction is a register to register move and return
+ /// the source and dest operands and their sub-register indices by reference.
virtual bool isMoveInstr(const MachineInstr &MI,
- unsigned &SrcReg, unsigned &DstReg) const;
+ unsigned &SrcReg, unsigned &DstReg,
+ unsigned &SrcSubIdx, unsigned &DstSubIdx) const;
/// isLoadFromStackSlot - If the specified machine instruction is a direct
/// load from a stack slot, return the virtual or physical register number of