diff options
| author | Owen Anderson <resistor@mac.com> | 2008-01-07 01:35:02 +0000 |
|---|---|---|
| committer | Owen Anderson <resistor@mac.com> | 2008-01-07 01:35:02 +0000 |
| commit | 43dbe05279b753aabda571d9c83eaeb36987001a (patch) | |
| tree | b767b17e91b91d3bb7f897f507175fd60ebadb6b /lib/Target/PowerPC/PPCInstrInfo.cpp | |
| parent | 93f96d00bf10299246ea726956ce84dcb4b9a59e (diff) | |
Move even more functionality from MRegisterInfo into TargetInstrInfo.
Some day I'll get it all moved over...
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@45672 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target/PowerPC/PPCInstrInfo.cpp')
| -rw-r--r-- | lib/Target/PowerPC/PPCInstrInfo.cpp | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index 2ad5e65bc2..4d404a547f 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -534,6 +534,85 @@ void PPCInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, return; } +/// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into +/// copy instructions, turning them into load/store instructions. +MachineInstr *PPCInstrInfo::foldMemoryOperand(MachineInstr *MI, + SmallVectorImpl<unsigned> &Ops, + int FrameIndex) const { + if (Ops.size() != 1) return NULL; + + // Make sure this is a reg-reg copy. Note that we can't handle MCRF, because + // it takes more than one instruction to store it. + unsigned Opc = MI->getOpcode(); + unsigned OpNum = Ops[0]; + + MachineInstr *NewMI = NULL; + if ((Opc == PPC::OR && + MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) { + if (OpNum == 0) { // move -> store + unsigned InReg = MI->getOperand(1).getReg(); + NewMI = addFrameReference(BuildMI(get(PPC::STW)).addReg(InReg), + FrameIndex); + } else { // move -> load + unsigned OutReg = MI->getOperand(0).getReg(); + NewMI = addFrameReference(BuildMI(get(PPC::LWZ), OutReg), + FrameIndex); + } + } else if ((Opc == PPC::OR8 && + MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) { + if (OpNum == 0) { // move -> store + unsigned InReg = MI->getOperand(1).getReg(); + NewMI = addFrameReference(BuildMI(get(PPC::STD)).addReg(InReg), + FrameIndex); + } else { // move -> load + unsigned OutReg = MI->getOperand(0).getReg(); + NewMI = addFrameReference(BuildMI(get(PPC::LD), OutReg), FrameIndex); + } + } else if (Opc == PPC::FMRD) { + if (OpNum == 0) { // move -> store + unsigned InReg = MI->getOperand(1).getReg(); + NewMI = addFrameReference(BuildMI(get(PPC::STFD)).addReg(InReg), + FrameIndex); + } else { // move -> load + unsigned OutReg = MI->getOperand(0).getReg(); + NewMI = addFrameReference(BuildMI(get(PPC::LFD), OutReg), FrameIndex); + } + } else if (Opc == PPC::FMRS) { + if (OpNum == 0) { // move -> store + unsigned InReg = MI->getOperand(1).getReg(); + NewMI = addFrameReference(BuildMI(get(PPC::STFS)).addReg(InReg), + FrameIndex); + } else { // move -> load + unsigned OutReg = MI->getOperand(0).getReg(); + NewMI = addFrameReference(BuildMI(get(PPC::LFS), OutReg), FrameIndex); + } + } + + if (NewMI) + NewMI->copyKillDeadInfo(MI); + return NewMI; +} + +bool PPCInstrInfo::canFoldMemoryOperand(MachineInstr *MI, + SmallVectorImpl<unsigned> &Ops) const { + if (Ops.size() != 1) return false; + + // Make sure this is a reg-reg copy. Note that we can't handle MCRF, because + // it takes more than one instruction to store it. + unsigned Opc = MI->getOpcode(); + + if ((Opc == PPC::OR && + MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) + return true; + else if ((Opc == PPC::OR8 && + MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) + return true; + else if (Opc == PPC::FMRD || Opc == PPC::FMRS) + return true; + + return false; +} + bool PPCInstrInfo::BlockHasNoFallThrough(MachineBasicBlock &MBB) const { if (MBB.empty()) return false; |
