| Nate Begeman | 21e463b | 2005-10-16 05:39:50 +0000 | [diff] [blame] | 1 | //===- PPCInstrInfo.cpp - PowerPC32 Instruction Information -----*- C++ -*-===// | 
| Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame] | 2 | // | 
| Misha Brukman | f2ccb77 | 2004-08-17 04:55:41 +0000 | [diff] [blame] | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
| Chris Lattner | 4ee451d | 2007-12-29 20:36:04 +0000 | [diff] [blame] | 5 | // This file is distributed under the University of Illinois Open Source | 
 | 6 | // License. See LICENSE.TXT for details. | 
| Misha Brukman | b5f662f | 2005-04-21 23:30:14 +0000 | [diff] [blame] | 7 | // | 
| Misha Brukman | f2ccb77 | 2004-08-17 04:55:41 +0000 | [diff] [blame] | 8 | //===----------------------------------------------------------------------===// | 
 | 9 | // | 
 | 10 | // This file contains the PowerPC implementation of the TargetInstrInfo class. | 
 | 11 | // | 
 | 12 | //===----------------------------------------------------------------------===// | 
 | 13 |  | 
| Chris Lattner | 16e71f2 | 2005-10-14 23:59:06 +0000 | [diff] [blame] | 14 | #include "PPCInstrInfo.h" | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 15 | #include "PPCInstrBuilder.h" | 
| Bill Wendling | 7194aaf | 2008-03-03 22:19:16 +0000 | [diff] [blame] | 16 | #include "PPCMachineFunctionInfo.h" | 
| Chris Lattner | df4ed63 | 2006-11-17 22:10:59 +0000 | [diff] [blame] | 17 | #include "PPCPredicates.h" | 
| Chris Lattner | 4c7b43b | 2005-10-14 23:37:35 +0000 | [diff] [blame] | 18 | #include "PPCGenInstrInfo.inc" | 
| Chris Lattner | b1d26f6 | 2006-06-17 00:01:04 +0000 | [diff] [blame] | 19 | #include "PPCTargetMachine.h" | 
| Owen Anderson | 718cb66 | 2007-09-07 04:06:50 +0000 | [diff] [blame] | 20 | #include "llvm/ADT/STLExtras.h" | 
| Misha Brukman | f2ccb77 | 2004-08-17 04:55:41 +0000 | [diff] [blame] | 21 | #include "llvm/CodeGen/MachineInstrBuilder.h" | 
| Bill Wendling | 880d0f6 | 2008-03-04 23:13:51 +0000 | [diff] [blame] | 22 | #include "llvm/Support/CommandLine.h" | 
| Nicolas Geoffray | 52e724a | 2008-04-16 20:10:13 +0000 | [diff] [blame] | 23 | #include "llvm/Target/TargetAsmInfo.h" | 
| Misha Brukman | f2ccb77 | 2004-08-17 04:55:41 +0000 | [diff] [blame] | 24 | using namespace llvm; | 
 | 25 |  | 
| Bill Wendling | 4a66e9a | 2008-03-10 22:49:16 +0000 | [diff] [blame] | 26 | extern cl::opt<bool> EnablePPC32RS;  // FIXME (64-bit): See PPCRegisterInfo.cpp. | 
 | 27 | extern cl::opt<bool> EnablePPC64RS;  // FIXME (64-bit): See PPCRegisterInfo.cpp. | 
| Bill Wendling | 880d0f6 | 2008-03-04 23:13:51 +0000 | [diff] [blame] | 28 |  | 
| Chris Lattner | b1d26f6 | 2006-06-17 00:01:04 +0000 | [diff] [blame] | 29 | PPCInstrInfo::PPCInstrInfo(PPCTargetMachine &tm) | 
| Chris Lattner | 6410552 | 2008-01-01 01:03:04 +0000 | [diff] [blame] | 30 |   : TargetInstrInfoImpl(PPCInsts, array_lengthof(PPCInsts)), TM(tm), | 
| Evan Cheng | 7ce4578 | 2006-11-13 23:36:35 +0000 | [diff] [blame] | 31 |     RI(*TM.getSubtargetImpl(), *this) {} | 
| Chris Lattner | b1d26f6 | 2006-06-17 00:01:04 +0000 | [diff] [blame] | 32 |  | 
| Nate Begeman | 21e463b | 2005-10-16 05:39:50 +0000 | [diff] [blame] | 33 | bool PPCInstrInfo::isMoveInstr(const MachineInstr& MI, | 
 | 34 |                                unsigned& sourceReg, | 
| Evan Cheng | 04ee5a1 | 2009-01-20 19:12:24 +0000 | [diff] [blame] | 35 |                                unsigned& destReg, | 
 | 36 |                                unsigned& sourceSubIdx, | 
 | 37 |                                unsigned& destSubIdx) const { | 
 | 38 |   sourceSubIdx = destSubIdx = 0; // No sub-registers. | 
 | 39 |  | 
| Chris Lattner | cc8cd0c | 2008-01-07 02:48:55 +0000 | [diff] [blame] | 40 |   unsigned oc = MI.getOpcode(); | 
| Chris Lattner | b410dc9 | 2006-06-20 23:18:58 +0000 | [diff] [blame] | 41 |   if (oc == PPC::OR || oc == PPC::OR8 || oc == PPC::VOR || | 
| Chris Lattner | 14c09b8 | 2005-10-19 01:50:36 +0000 | [diff] [blame] | 42 |       oc == PPC::OR4To8 || oc == PPC::OR8To4) {                // or r1, r2, r2 | 
| Evan Cheng | 1e341729 | 2007-04-25 07:12:14 +0000 | [diff] [blame] | 43 |     assert(MI.getNumOperands() >= 3 && | 
| Dan Gohman | d735b80 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 44 |            MI.getOperand(0).isReg() && | 
 | 45 |            MI.getOperand(1).isReg() && | 
 | 46 |            MI.getOperand(2).isReg() && | 
| Misha Brukman | f2ccb77 | 2004-08-17 04:55:41 +0000 | [diff] [blame] | 47 |            "invalid PPC OR instruction!"); | 
 | 48 |     if (MI.getOperand(1).getReg() == MI.getOperand(2).getReg()) { | 
 | 49 |       sourceReg = MI.getOperand(1).getReg(); | 
 | 50 |       destReg = MI.getOperand(0).getReg(); | 
 | 51 |       return true; | 
 | 52 |     } | 
 | 53 |   } else if (oc == PPC::ADDI) {             // addi r1, r2, 0 | 
| Evan Cheng | 1e341729 | 2007-04-25 07:12:14 +0000 | [diff] [blame] | 54 |     assert(MI.getNumOperands() >= 3 && | 
| Dan Gohman | d735b80 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 55 |            MI.getOperand(0).isReg() && | 
 | 56 |            MI.getOperand(2).isImm() && | 
| Misha Brukman | f2ccb77 | 2004-08-17 04:55:41 +0000 | [diff] [blame] | 57 |            "invalid PPC ADDI instruction!"); | 
| Dan Gohman | d735b80 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 58 |     if (MI.getOperand(1).isReg() && MI.getOperand(2).getImm() == 0) { | 
| Misha Brukman | f2ccb77 | 2004-08-17 04:55:41 +0000 | [diff] [blame] | 59 |       sourceReg = MI.getOperand(1).getReg(); | 
 | 60 |       destReg = MI.getOperand(0).getReg(); | 
 | 61 |       return true; | 
 | 62 |     } | 
| Nate Begeman | cb90de3 | 2004-10-07 22:26:12 +0000 | [diff] [blame] | 63 |   } else if (oc == PPC::ORI) {             // ori r1, r2, 0 | 
| Evan Cheng | 1e341729 | 2007-04-25 07:12:14 +0000 | [diff] [blame] | 64 |     assert(MI.getNumOperands() >= 3 && | 
| Dan Gohman | d735b80 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 65 |            MI.getOperand(0).isReg() && | 
 | 66 |            MI.getOperand(1).isReg() && | 
 | 67 |            MI.getOperand(2).isImm() && | 
| Nate Begeman | cb90de3 | 2004-10-07 22:26:12 +0000 | [diff] [blame] | 68 |            "invalid PPC ORI instruction!"); | 
| Chris Lattner | 9a1ceae | 2007-12-30 20:49:49 +0000 | [diff] [blame] | 69 |     if (MI.getOperand(2).getImm() == 0) { | 
| Nate Begeman | cb90de3 | 2004-10-07 22:26:12 +0000 | [diff] [blame] | 70 |       sourceReg = MI.getOperand(1).getReg(); | 
 | 71 |       destReg = MI.getOperand(0).getReg(); | 
 | 72 |       return true; | 
 | 73 |     } | 
| Chris Lattner | eb5d47d | 2005-10-07 05:00:52 +0000 | [diff] [blame] | 74 |   } else if (oc == PPC::FMRS || oc == PPC::FMRD || | 
 | 75 |              oc == PPC::FMRSD) {      // fmr r1, r2 | 
| Evan Cheng | 1e341729 | 2007-04-25 07:12:14 +0000 | [diff] [blame] | 76 |     assert(MI.getNumOperands() >= 2 && | 
| Dan Gohman | d735b80 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 77 |            MI.getOperand(0).isReg() && | 
 | 78 |            MI.getOperand(1).isReg() && | 
| Misha Brukman | f2ccb77 | 2004-08-17 04:55:41 +0000 | [diff] [blame] | 79 |            "invalid PPC FMR instruction"); | 
 | 80 |     sourceReg = MI.getOperand(1).getReg(); | 
 | 81 |     destReg = MI.getOperand(0).getReg(); | 
 | 82 |     return true; | 
| Nate Begeman | 7af0248 | 2005-04-12 07:04:16 +0000 | [diff] [blame] | 83 |   } else if (oc == PPC::MCRF) {             // mcrf cr1, cr2 | 
| Evan Cheng | 1e341729 | 2007-04-25 07:12:14 +0000 | [diff] [blame] | 84 |     assert(MI.getNumOperands() >= 2 && | 
| Dan Gohman | d735b80 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 85 |            MI.getOperand(0).isReg() && | 
 | 86 |            MI.getOperand(1).isReg() && | 
| Nate Begeman | 7af0248 | 2005-04-12 07:04:16 +0000 | [diff] [blame] | 87 |            "invalid PPC MCRF instruction"); | 
 | 88 |     sourceReg = MI.getOperand(1).getReg(); | 
 | 89 |     destReg = MI.getOperand(0).getReg(); | 
 | 90 |     return true; | 
| Misha Brukman | f2ccb77 | 2004-08-17 04:55:41 +0000 | [diff] [blame] | 91 |   } | 
 | 92 |   return false; | 
 | 93 | } | 
| Chris Lattner | 043870d | 2005-09-09 18:17:41 +0000 | [diff] [blame] | 94 |  | 
| Dan Gohman | cbad42c | 2008-11-18 19:49:32 +0000 | [diff] [blame] | 95 | unsigned PPCInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,  | 
| Chris Lattner | 9c09c9e | 2006-03-16 22:24:02 +0000 | [diff] [blame] | 96 |                                            int &FrameIndex) const { | 
| Chris Lattner | 4083960 | 2006-02-02 20:12:32 +0000 | [diff] [blame] | 97 |   switch (MI->getOpcode()) { | 
 | 98 |   default: break; | 
 | 99 |   case PPC::LD: | 
 | 100 |   case PPC::LWZ: | 
 | 101 |   case PPC::LFS: | 
 | 102 |   case PPC::LFD: | 
| Dan Gohman | d735b80 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 103 |     if (MI->getOperand(1).isImm() && !MI->getOperand(1).getImm() && | 
 | 104 |         MI->getOperand(2).isFI()) { | 
| Chris Lattner | 8aa797a | 2007-12-30 23:10:15 +0000 | [diff] [blame] | 105 |       FrameIndex = MI->getOperand(2).getIndex(); | 
| Chris Lattner | 4083960 | 2006-02-02 20:12:32 +0000 | [diff] [blame] | 106 |       return MI->getOperand(0).getReg(); | 
 | 107 |     } | 
 | 108 |     break; | 
 | 109 |   } | 
 | 110 |   return 0; | 
| Chris Lattner | 6524287 | 2006-02-02 20:16:12 +0000 | [diff] [blame] | 111 | } | 
| Chris Lattner | 4083960 | 2006-02-02 20:12:32 +0000 | [diff] [blame] | 112 |  | 
| Dan Gohman | cbad42c | 2008-11-18 19:49:32 +0000 | [diff] [blame] | 113 | unsigned PPCInstrInfo::isStoreToStackSlot(const MachineInstr *MI,  | 
| Chris Lattner | 6524287 | 2006-02-02 20:16:12 +0000 | [diff] [blame] | 114 |                                           int &FrameIndex) const { | 
 | 115 |   switch (MI->getOpcode()) { | 
 | 116 |   default: break; | 
| Nate Begeman | 3b478b3 | 2006-02-02 21:07:50 +0000 | [diff] [blame] | 117 |   case PPC::STD: | 
| Chris Lattner | 6524287 | 2006-02-02 20:16:12 +0000 | [diff] [blame] | 118 |   case PPC::STW: | 
 | 119 |   case PPC::STFS: | 
 | 120 |   case PPC::STFD: | 
| Dan Gohman | d735b80 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 121 |     if (MI->getOperand(1).isImm() && !MI->getOperand(1).getImm() && | 
 | 122 |         MI->getOperand(2).isFI()) { | 
| Chris Lattner | 8aa797a | 2007-12-30 23:10:15 +0000 | [diff] [blame] | 123 |       FrameIndex = MI->getOperand(2).getIndex(); | 
| Chris Lattner | 6524287 | 2006-02-02 20:16:12 +0000 | [diff] [blame] | 124 |       return MI->getOperand(0).getReg(); | 
 | 125 |     } | 
 | 126 |     break; | 
 | 127 |   } | 
 | 128 |   return 0; | 
 | 129 | } | 
| Chris Lattner | 4083960 | 2006-02-02 20:12:32 +0000 | [diff] [blame] | 130 |  | 
| Chris Lattner | 043870d | 2005-09-09 18:17:41 +0000 | [diff] [blame] | 131 | // commuteInstruction - We can commute rlwimi instructions, but only if the | 
 | 132 | // rotate amt is zero.  We also have to munge the immediates a bit. | 
| Evan Cheng | 58dcb0e | 2008-06-16 07:33:11 +0000 | [diff] [blame] | 133 | MachineInstr * | 
 | 134 | PPCInstrInfo::commuteInstruction(MachineInstr *MI, bool NewMI) const { | 
| Dan Gohman | 8e5f2c6 | 2008-07-07 23:14:23 +0000 | [diff] [blame] | 135 |   MachineFunction &MF = *MI->getParent()->getParent(); | 
 | 136 |  | 
| Chris Lattner | 043870d | 2005-09-09 18:17:41 +0000 | [diff] [blame] | 137 |   // Normal instructions can be commuted the obvious way. | 
 | 138 |   if (MI->getOpcode() != PPC::RLWIMI) | 
| Evan Cheng | 58dcb0e | 2008-06-16 07:33:11 +0000 | [diff] [blame] | 139 |     return TargetInstrInfoImpl::commuteInstruction(MI, NewMI); | 
| Chris Lattner | 043870d | 2005-09-09 18:17:41 +0000 | [diff] [blame] | 140 |    | 
 | 141 |   // Cannot commute if it has a non-zero rotate count. | 
| Chris Lattner | 9a1ceae | 2007-12-30 20:49:49 +0000 | [diff] [blame] | 142 |   if (MI->getOperand(3).getImm() != 0) | 
| Chris Lattner | 043870d | 2005-09-09 18:17:41 +0000 | [diff] [blame] | 143 |     return 0; | 
 | 144 |    | 
 | 145 |   // If we have a zero rotate count, we have: | 
 | 146 |   //   M = mask(MB,ME) | 
 | 147 |   //   Op0 = (Op1 & ~M) | (Op2 & M) | 
 | 148 |   // Change this to: | 
 | 149 |   //   M = mask((ME+1)&31, (MB-1)&31) | 
 | 150 |   //   Op0 = (Op2 & ~M) | (Op1 & M) | 
 | 151 |  | 
 | 152 |   // Swap op1/op2 | 
| Evan Cheng | a4d16a1 | 2008-02-13 02:46:49 +0000 | [diff] [blame] | 153 |   unsigned Reg0 = MI->getOperand(0).getReg(); | 
| Chris Lattner | 043870d | 2005-09-09 18:17:41 +0000 | [diff] [blame] | 154 |   unsigned Reg1 = MI->getOperand(1).getReg(); | 
 | 155 |   unsigned Reg2 = MI->getOperand(2).getReg(); | 
| Evan Cheng | 6ce7dc2 | 2006-11-15 20:58:11 +0000 | [diff] [blame] | 156 |   bool Reg1IsKill = MI->getOperand(1).isKill(); | 
 | 157 |   bool Reg2IsKill = MI->getOperand(2).isKill(); | 
| Evan Cheng | 58dcb0e | 2008-06-16 07:33:11 +0000 | [diff] [blame] | 158 |   bool ChangeReg0 = false; | 
| Evan Cheng | a4d16a1 | 2008-02-13 02:46:49 +0000 | [diff] [blame] | 159 |   // If machine instrs are no longer in two-address forms, update | 
 | 160 |   // destination register as well. | 
 | 161 |   if (Reg0 == Reg1) { | 
 | 162 |     // Must be two address instruction! | 
 | 163 |     assert(MI->getDesc().getOperandConstraint(0, TOI::TIED_TO) && | 
 | 164 |            "Expecting a two-address instruction!"); | 
| Evan Cheng | a4d16a1 | 2008-02-13 02:46:49 +0000 | [diff] [blame] | 165 |     Reg2IsKill = false; | 
| Evan Cheng | 58dcb0e | 2008-06-16 07:33:11 +0000 | [diff] [blame] | 166 |     ChangeReg0 = true; | 
| Evan Cheng | a4d16a1 | 2008-02-13 02:46:49 +0000 | [diff] [blame] | 167 |   } | 
| Evan Cheng | 58dcb0e | 2008-06-16 07:33:11 +0000 | [diff] [blame] | 168 |  | 
 | 169 |   // Masks. | 
 | 170 |   unsigned MB = MI->getOperand(4).getImm(); | 
 | 171 |   unsigned ME = MI->getOperand(5).getImm(); | 
 | 172 |  | 
 | 173 |   if (NewMI) { | 
 | 174 |     // Create a new instruction. | 
 | 175 |     unsigned Reg0 = ChangeReg0 ? Reg2 : MI->getOperand(0).getReg(); | 
 | 176 |     bool Reg0IsDead = MI->getOperand(0).isDead(); | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 177 |     return BuildMI(MF, MI->getDebugLoc(), MI->getDesc()) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 178 |       .addReg(Reg0, RegState::Define | getDeadRegState(Reg0IsDead)) | 
 | 179 |       .addReg(Reg2, getKillRegState(Reg2IsKill)) | 
 | 180 |       .addReg(Reg1, getKillRegState(Reg1IsKill)) | 
| Evan Cheng | 58dcb0e | 2008-06-16 07:33:11 +0000 | [diff] [blame] | 181 |       .addImm((ME+1) & 31) | 
 | 182 |       .addImm((MB-1) & 31); | 
 | 183 |   } | 
 | 184 |  | 
 | 185 |   if (ChangeReg0) | 
 | 186 |     MI->getOperand(0).setReg(Reg2); | 
| Chris Lattner | e53f4a0 | 2006-05-04 17:52:23 +0000 | [diff] [blame] | 187 |   MI->getOperand(2).setReg(Reg1); | 
 | 188 |   MI->getOperand(1).setReg(Reg2); | 
| Chris Lattner | f738230 | 2007-12-30 21:56:09 +0000 | [diff] [blame] | 189 |   MI->getOperand(2).setIsKill(Reg1IsKill); | 
 | 190 |   MI->getOperand(1).setIsKill(Reg2IsKill); | 
| Chris Lattner | 043870d | 2005-09-09 18:17:41 +0000 | [diff] [blame] | 191 |    | 
 | 192 |   // Swap the mask around. | 
| Chris Lattner | 9a1ceae | 2007-12-30 20:49:49 +0000 | [diff] [blame] | 193 |   MI->getOperand(4).setImm((ME+1) & 31); | 
 | 194 |   MI->getOperand(5).setImm((MB-1) & 31); | 
| Chris Lattner | 043870d | 2005-09-09 18:17:41 +0000 | [diff] [blame] | 195 |   return MI; | 
 | 196 | } | 
| Chris Lattner | bbf1c72 | 2006-03-05 23:49:55 +0000 | [diff] [blame] | 197 |  | 
 | 198 | void PPCInstrInfo::insertNoop(MachineBasicBlock &MBB,  | 
 | 199 |                               MachineBasicBlock::iterator MI) const { | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 200 |   DebugLoc DL = DebugLoc::getUnknownLoc(); | 
 | 201 |   if (MI != MBB.end()) DL = MI->getDebugLoc(); | 
 | 202 |  | 
 | 203 |   BuildMI(MBB, MI, DL, get(PPC::NOP)); | 
| Chris Lattner | bbf1c72 | 2006-03-05 23:49:55 +0000 | [diff] [blame] | 204 | } | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 205 |  | 
 | 206 |  | 
 | 207 | // Branch analysis. | 
 | 208 | bool PPCInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,MachineBasicBlock *&TBB, | 
 | 209 |                                  MachineBasicBlock *&FBB, | 
| Evan Cheng | dc54d31 | 2009-02-09 07:14:22 +0000 | [diff] [blame] | 210 |                                  SmallVectorImpl<MachineOperand> &Cond, | 
 | 211 |                                  bool AllowModify) const { | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 212 |   // If the block has no terminators, it just falls into the block after it. | 
 | 213 |   MachineBasicBlock::iterator I = MBB.end(); | 
| Evan Cheng | bfd2ec4 | 2007-06-08 21:59:56 +0000 | [diff] [blame] | 214 |   if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 215 |     return false; | 
 | 216 |  | 
 | 217 |   // Get the last instruction in the block. | 
 | 218 |   MachineInstr *LastInst = I; | 
 | 219 |    | 
 | 220 |   // If there is only one terminator instruction, process it. | 
| Evan Cheng | bfd2ec4 | 2007-06-08 21:59:56 +0000 | [diff] [blame] | 221 |   if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 222 |     if (LastInst->getOpcode() == PPC::B) { | 
| Evan Cheng | 82ae933 | 2009-05-08 23:09:25 +0000 | [diff] [blame] | 223 |       if (!LastInst->getOperand(0).isMBB()) | 
 | 224 |         return true; | 
| Chris Lattner | 8aa797a | 2007-12-30 23:10:15 +0000 | [diff] [blame] | 225 |       TBB = LastInst->getOperand(0).getMBB(); | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 226 |       return false; | 
| Chris Lattner | 289c2d5 | 2006-11-17 22:14:47 +0000 | [diff] [blame] | 227 |     } else if (LastInst->getOpcode() == PPC::BCC) { | 
| Evan Cheng | 82ae933 | 2009-05-08 23:09:25 +0000 | [diff] [blame] | 228 |       if (!LastInst->getOperand(2).isMBB()) | 
 | 229 |         return true; | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 230 |       // Block ends with fall-through condbranch. | 
| Chris Lattner | 8aa797a | 2007-12-30 23:10:15 +0000 | [diff] [blame] | 231 |       TBB = LastInst->getOperand(2).getMBB(); | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 232 |       Cond.push_back(LastInst->getOperand(0)); | 
 | 233 |       Cond.push_back(LastInst->getOperand(1)); | 
| Chris Lattner | 7c4fe25 | 2006-10-21 06:03:11 +0000 | [diff] [blame] | 234 |       return false; | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 235 |     } | 
 | 236 |     // Otherwise, don't know what this is. | 
 | 237 |     return true; | 
 | 238 |   } | 
 | 239 |    | 
 | 240 |   // Get the instruction before it if it's a terminator. | 
 | 241 |   MachineInstr *SecondLastInst = I; | 
 | 242 |  | 
 | 243 |   // If there are three terminators, we don't know what sort of block this is. | 
 | 244 |   if (SecondLastInst && I != MBB.begin() && | 
| Evan Cheng | bfd2ec4 | 2007-06-08 21:59:56 +0000 | [diff] [blame] | 245 |       isUnpredicatedTerminator(--I)) | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 246 |     return true; | 
 | 247 |    | 
| Chris Lattner | 289c2d5 | 2006-11-17 22:14:47 +0000 | [diff] [blame] | 248 |   // If the block ends with PPC::B and PPC:BCC, handle it. | 
 | 249 |   if (SecondLastInst->getOpcode() == PPC::BCC &&  | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 250 |       LastInst->getOpcode() == PPC::B) { | 
| Evan Cheng | 82ae933 | 2009-05-08 23:09:25 +0000 | [diff] [blame] | 251 |     if (!SecondLastInst->getOperand(2).isMBB() || | 
 | 252 |         !LastInst->getOperand(0).isMBB()) | 
 | 253 |       return true; | 
| Chris Lattner | 8aa797a | 2007-12-30 23:10:15 +0000 | [diff] [blame] | 254 |     TBB =  SecondLastInst->getOperand(2).getMBB(); | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 255 |     Cond.push_back(SecondLastInst->getOperand(0)); | 
 | 256 |     Cond.push_back(SecondLastInst->getOperand(1)); | 
| Chris Lattner | 8aa797a | 2007-12-30 23:10:15 +0000 | [diff] [blame] | 257 |     FBB = LastInst->getOperand(0).getMBB(); | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 258 |     return false; | 
 | 259 |   } | 
 | 260 |    | 
| Dale Johannesen | 13e8b51 | 2007-06-13 17:59:52 +0000 | [diff] [blame] | 261 |   // If the block ends with two PPC:Bs, handle it.  The second one is not | 
 | 262 |   // executed, so remove it. | 
 | 263 |   if (SecondLastInst->getOpcode() == PPC::B &&  | 
 | 264 |       LastInst->getOpcode() == PPC::B) { | 
| Evan Cheng | 82ae933 | 2009-05-08 23:09:25 +0000 | [diff] [blame] | 265 |     if (!SecondLastInst->getOperand(0).isMBB()) | 
 | 266 |       return true; | 
| Chris Lattner | 8aa797a | 2007-12-30 23:10:15 +0000 | [diff] [blame] | 267 |     TBB = SecondLastInst->getOperand(0).getMBB(); | 
| Dale Johannesen | 13e8b51 | 2007-06-13 17:59:52 +0000 | [diff] [blame] | 268 |     I = LastInst; | 
| Evan Cheng | dc54d31 | 2009-02-09 07:14:22 +0000 | [diff] [blame] | 269 |     if (AllowModify) | 
 | 270 |       I->eraseFromParent(); | 
| Dale Johannesen | 13e8b51 | 2007-06-13 17:59:52 +0000 | [diff] [blame] | 271 |     return false; | 
 | 272 |   } | 
 | 273 |  | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 274 |   // Otherwise, can't handle this. | 
 | 275 |   return true; | 
 | 276 | } | 
 | 277 |  | 
| Evan Cheng | b5cdaa2 | 2007-05-18 00:05:48 +0000 | [diff] [blame] | 278 | unsigned PPCInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 279 |   MachineBasicBlock::iterator I = MBB.end(); | 
| Evan Cheng | b5cdaa2 | 2007-05-18 00:05:48 +0000 | [diff] [blame] | 280 |   if (I == MBB.begin()) return 0; | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 281 |   --I; | 
| Chris Lattner | 289c2d5 | 2006-11-17 22:14:47 +0000 | [diff] [blame] | 282 |   if (I->getOpcode() != PPC::B && I->getOpcode() != PPC::BCC) | 
| Evan Cheng | b5cdaa2 | 2007-05-18 00:05:48 +0000 | [diff] [blame] | 283 |     return 0; | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 284 |    | 
 | 285 |   // Remove the branch. | 
 | 286 |   I->eraseFromParent(); | 
 | 287 |    | 
 | 288 |   I = MBB.end(); | 
 | 289 |  | 
| Evan Cheng | b5cdaa2 | 2007-05-18 00:05:48 +0000 | [diff] [blame] | 290 |   if (I == MBB.begin()) return 1; | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 291 |   --I; | 
| Chris Lattner | 289c2d5 | 2006-11-17 22:14:47 +0000 | [diff] [blame] | 292 |   if (I->getOpcode() != PPC::BCC) | 
| Evan Cheng | b5cdaa2 | 2007-05-18 00:05:48 +0000 | [diff] [blame] | 293 |     return 1; | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 294 |    | 
 | 295 |   // Remove the branch. | 
 | 296 |   I->eraseFromParent(); | 
| Evan Cheng | b5cdaa2 | 2007-05-18 00:05:48 +0000 | [diff] [blame] | 297 |   return 2; | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 298 | } | 
 | 299 |  | 
| Evan Cheng | b5cdaa2 | 2007-05-18 00:05:48 +0000 | [diff] [blame] | 300 | unsigned | 
 | 301 | PPCInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, | 
 | 302 |                            MachineBasicBlock *FBB, | 
| Owen Anderson | 44eb65c | 2008-08-14 22:49:33 +0000 | [diff] [blame] | 303 |                            const SmallVectorImpl<MachineOperand> &Cond) const { | 
| Dale Johannesen | 536a2f1 | 2009-02-13 02:27:39 +0000 | [diff] [blame] | 304 |   // FIXME this should probably have a DebugLoc argument | 
 | 305 |   DebugLoc dl = DebugLoc::getUnknownLoc(); | 
| Chris Lattner | 2dc7723 | 2006-10-17 18:06:55 +0000 | [diff] [blame] | 306 |   // Shouldn't be a fall through. | 
 | 307 |   assert(TBB && "InsertBranch must not be told to insert a fallthrough"); | 
| Chris Lattner | 5410806 | 2006-10-21 05:36:13 +0000 | [diff] [blame] | 308 |   assert((Cond.size() == 2 || Cond.size() == 0) &&  | 
 | 309 |          "PPC branch conditions have two components!"); | 
| Chris Lattner | 2dc7723 | 2006-10-17 18:06:55 +0000 | [diff] [blame] | 310 |    | 
| Chris Lattner | 5410806 | 2006-10-21 05:36:13 +0000 | [diff] [blame] | 311 |   // One-way branch. | 
| Chris Lattner | 2dc7723 | 2006-10-17 18:06:55 +0000 | [diff] [blame] | 312 |   if (FBB == 0) { | 
| Chris Lattner | 5410806 | 2006-10-21 05:36:13 +0000 | [diff] [blame] | 313 |     if (Cond.empty())   // Unconditional branch | 
| Dale Johannesen | 536a2f1 | 2009-02-13 02:27:39 +0000 | [diff] [blame] | 314 |       BuildMI(&MBB, dl, get(PPC::B)).addMBB(TBB); | 
| Chris Lattner | 5410806 | 2006-10-21 05:36:13 +0000 | [diff] [blame] | 315 |     else                // Conditional branch | 
| Dale Johannesen | 536a2f1 | 2009-02-13 02:27:39 +0000 | [diff] [blame] | 316 |       BuildMI(&MBB, dl, get(PPC::BCC)) | 
| Chris Lattner | 18258c6 | 2006-11-17 22:37:34 +0000 | [diff] [blame] | 317 |         .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB); | 
| Evan Cheng | b5cdaa2 | 2007-05-18 00:05:48 +0000 | [diff] [blame] | 318 |     return 1; | 
| Chris Lattner | 2dc7723 | 2006-10-17 18:06:55 +0000 | [diff] [blame] | 319 |   } | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 320 |    | 
| Chris Lattner | 879d09c | 2006-10-21 05:42:09 +0000 | [diff] [blame] | 321 |   // Two-way Conditional Branch. | 
| Dale Johannesen | 536a2f1 | 2009-02-13 02:27:39 +0000 | [diff] [blame] | 322 |   BuildMI(&MBB, dl, get(PPC::BCC)) | 
| Chris Lattner | 18258c6 | 2006-11-17 22:37:34 +0000 | [diff] [blame] | 323 |     .addImm(Cond[0].getImm()).addReg(Cond[1].getReg()).addMBB(TBB); | 
| Dale Johannesen | 536a2f1 | 2009-02-13 02:27:39 +0000 | [diff] [blame] | 324 |   BuildMI(&MBB, dl, get(PPC::B)).addMBB(FBB); | 
| Evan Cheng | b5cdaa2 | 2007-05-18 00:05:48 +0000 | [diff] [blame] | 325 |   return 2; | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 326 | } | 
 | 327 |  | 
| Owen Anderson | 940f83e | 2008-08-26 18:03:31 +0000 | [diff] [blame] | 328 | bool PPCInstrInfo::copyRegToReg(MachineBasicBlock &MBB, | 
| Owen Anderson | d10fd97 | 2007-12-31 06:32:00 +0000 | [diff] [blame] | 329 |                                    MachineBasicBlock::iterator MI, | 
 | 330 |                                    unsigned DestReg, unsigned SrcReg, | 
 | 331 |                                    const TargetRegisterClass *DestRC, | 
 | 332 |                                    const TargetRegisterClass *SrcRC) const { | 
 | 333 |   if (DestRC != SrcRC) { | 
| Owen Anderson | 940f83e | 2008-08-26 18:03:31 +0000 | [diff] [blame] | 334 |     // Not yet supported! | 
 | 335 |     return false; | 
| Owen Anderson | d10fd97 | 2007-12-31 06:32:00 +0000 | [diff] [blame] | 336 |   } | 
 | 337 |  | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 338 |   DebugLoc DL = DebugLoc::getUnknownLoc(); | 
 | 339 |   if (MI != MBB.end()) DL = MI->getDebugLoc(); | 
 | 340 |  | 
| Owen Anderson | d10fd97 | 2007-12-31 06:32:00 +0000 | [diff] [blame] | 341 |   if (DestRC == PPC::GPRCRegisterClass) { | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 342 |     BuildMI(MBB, MI, DL, get(PPC::OR), DestReg).addReg(SrcReg).addReg(SrcReg); | 
| Owen Anderson | d10fd97 | 2007-12-31 06:32:00 +0000 | [diff] [blame] | 343 |   } else if (DestRC == PPC::G8RCRegisterClass) { | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 344 |     BuildMI(MBB, MI, DL, get(PPC::OR8), DestReg).addReg(SrcReg).addReg(SrcReg); | 
| Owen Anderson | d10fd97 | 2007-12-31 06:32:00 +0000 | [diff] [blame] | 345 |   } else if (DestRC == PPC::F4RCRegisterClass) { | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 346 |     BuildMI(MBB, MI, DL, get(PPC::FMRS), DestReg).addReg(SrcReg); | 
| Owen Anderson | d10fd97 | 2007-12-31 06:32:00 +0000 | [diff] [blame] | 347 |   } else if (DestRC == PPC::F8RCRegisterClass) { | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 348 |     BuildMI(MBB, MI, DL, get(PPC::FMRD), DestReg).addReg(SrcReg); | 
| Owen Anderson | d10fd97 | 2007-12-31 06:32:00 +0000 | [diff] [blame] | 349 |   } else if (DestRC == PPC::CRRCRegisterClass) { | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 350 |     BuildMI(MBB, MI, DL, get(PPC::MCRF), DestReg).addReg(SrcReg); | 
| Owen Anderson | d10fd97 | 2007-12-31 06:32:00 +0000 | [diff] [blame] | 351 |   } else if (DestRC == PPC::VRRCRegisterClass) { | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 352 |     BuildMI(MBB, MI, DL, get(PPC::VOR), DestReg).addReg(SrcReg).addReg(SrcReg); | 
| Nicolas Geoffray | 0404cd9 | 2008-03-10 14:12:10 +0000 | [diff] [blame] | 353 |   } else if (DestRC == PPC::CRBITRCRegisterClass) { | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 354 |     BuildMI(MBB, MI, DL, get(PPC::CROR), DestReg).addReg(SrcReg).addReg(SrcReg); | 
| Owen Anderson | d10fd97 | 2007-12-31 06:32:00 +0000 | [diff] [blame] | 355 |   } else { | 
| Owen Anderson | 940f83e | 2008-08-26 18:03:31 +0000 | [diff] [blame] | 356 |     // Attempt to copy register that is not GPR or FPR | 
 | 357 |     return false; | 
| Owen Anderson | d10fd97 | 2007-12-31 06:32:00 +0000 | [diff] [blame] | 358 |   } | 
| Owen Anderson | 940f83e | 2008-08-26 18:03:31 +0000 | [diff] [blame] | 359 |    | 
 | 360 |   return true; | 
| Owen Anderson | d10fd97 | 2007-12-31 06:32:00 +0000 | [diff] [blame] | 361 | } | 
 | 362 |  | 
| Bill Wendling | 4a66e9a | 2008-03-10 22:49:16 +0000 | [diff] [blame] | 363 | bool | 
| Dan Gohman | 8e5f2c6 | 2008-07-07 23:14:23 +0000 | [diff] [blame] | 364 | PPCInstrInfo::StoreRegToStackSlot(MachineFunction &MF, | 
 | 365 |                                   unsigned SrcReg, bool isKill, | 
| Bill Wendling | 4a66e9a | 2008-03-10 22:49:16 +0000 | [diff] [blame] | 366 |                                   int FrameIdx, | 
 | 367 |                                   const TargetRegisterClass *RC, | 
 | 368 |                                   SmallVectorImpl<MachineInstr*> &NewMIs) const{ | 
| Dale Johannesen | 21b5541 | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 369 |   DebugLoc DL = DebugLoc::getUnknownLoc(); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 370 |   if (RC == PPC::GPRCRegisterClass) { | 
 | 371 |     if (SrcReg != PPC::LR) { | 
| Dale Johannesen | 21b5541 | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 372 |       NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STW)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 373 |                                          .addReg(SrcReg, | 
 | 374 |                                                  getKillRegState(isKill)), | 
| Bill Wendling | 4a66e9a | 2008-03-10 22:49:16 +0000 | [diff] [blame] | 375 |                                          FrameIdx)); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 376 |     } else { | 
 | 377 |       // FIXME: this spills LR immediately to memory in one step.  To do this, | 
 | 378 |       // we use R11, which we know cannot be used in the prolog/epilog.  This is | 
 | 379 |       // a hack. | 
| Dale Johannesen | 21b5541 | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 380 |       NewMIs.push_back(BuildMI(MF, DL, get(PPC::MFLR), PPC::R11)); | 
 | 381 |       NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STW)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 382 |                                          .addReg(PPC::R11, | 
 | 383 |                                                  getKillRegState(isKill)), | 
| Bill Wendling | 4a66e9a | 2008-03-10 22:49:16 +0000 | [diff] [blame] | 384 |                                          FrameIdx)); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 385 |     } | 
 | 386 |   } else if (RC == PPC::G8RCRegisterClass) { | 
 | 387 |     if (SrcReg != PPC::LR8) { | 
| Dale Johannesen | 21b5541 | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 388 |       NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STD)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 389 |                                          .addReg(SrcReg, | 
 | 390 |                                                  getKillRegState(isKill)), | 
 | 391 |                                          FrameIdx)); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 392 |     } else { | 
 | 393 |       // FIXME: this spills LR immediately to memory in one step.  To do this, | 
 | 394 |       // we use R11, which we know cannot be used in the prolog/epilog.  This is | 
 | 395 |       // a hack. | 
| Dale Johannesen | 21b5541 | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 396 |       NewMIs.push_back(BuildMI(MF, DL, get(PPC::MFLR8), PPC::X11)); | 
 | 397 |       NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STD)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 398 |                                          .addReg(PPC::X11, | 
 | 399 |                                                  getKillRegState(isKill)), | 
 | 400 |                                          FrameIdx)); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 401 |     } | 
 | 402 |   } else if (RC == PPC::F8RCRegisterClass) { | 
| Dale Johannesen | 21b5541 | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 403 |     NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STFD)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 404 |                                        .addReg(SrcReg, | 
 | 405 |                                                getKillRegState(isKill)), | 
 | 406 |                                        FrameIdx)); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 407 |   } else if (RC == PPC::F4RCRegisterClass) { | 
| Dale Johannesen | 21b5541 | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 408 |     NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STFS)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 409 |                                        .addReg(SrcReg, | 
 | 410 |                                                getKillRegState(isKill)), | 
 | 411 |                                        FrameIdx)); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 412 |   } else if (RC == PPC::CRRCRegisterClass) { | 
| Bill Wendling | 4a66e9a | 2008-03-10 22:49:16 +0000 | [diff] [blame] | 413 |     if ((EnablePPC32RS && !TM.getSubtargetImpl()->isPPC64()) || | 
 | 414 |         (EnablePPC64RS && TM.getSubtargetImpl()->isPPC64())) { | 
 | 415 |       // FIXME (64-bit): Enable | 
| Dale Johannesen | 21b5541 | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 416 |       NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::SPILL_CR)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 417 |                                          .addReg(SrcReg, | 
 | 418 |                                                  getKillRegState(isKill)), | 
| Chris Lattner | 71a2cb2 | 2008-03-20 01:22:40 +0000 | [diff] [blame] | 419 |                                          FrameIdx)); | 
| Bill Wendling | 7194aaf | 2008-03-03 22:19:16 +0000 | [diff] [blame] | 420 |       return true; | 
 | 421 |     } else { | 
 | 422 |       // FIXME: We use R0 here, because it isn't available for RA.  We need to | 
 | 423 |       // store the CR in the low 4-bits of the saved value.  First, issue a MFCR | 
 | 424 |       // to save all of the CRBits. | 
| Dale Johannesen | 21b5541 | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 425 |       NewMIs.push_back(BuildMI(MF, DL, get(PPC::MFCR), PPC::R0)); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 426 |      | 
| Bill Wendling | 7194aaf | 2008-03-03 22:19:16 +0000 | [diff] [blame] | 427 |       // If the saved register wasn't CR0, shift the bits left so that they are | 
 | 428 |       // in CR0's slot. | 
 | 429 |       if (SrcReg != PPC::CR0) { | 
 | 430 |         unsigned ShiftBits = PPCRegisterInfo::getRegisterNumbering(SrcReg)*4; | 
 | 431 |         // rlwinm r0, r0, ShiftBits, 0, 31. | 
| Dale Johannesen | 21b5541 | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 432 |         NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), PPC::R0) | 
| Chris Lattner | cb341de | 2008-03-10 18:55:53 +0000 | [diff] [blame] | 433 |                        .addReg(PPC::R0).addImm(ShiftBits).addImm(0).addImm(31)); | 
| Bill Wendling | 7194aaf | 2008-03-03 22:19:16 +0000 | [diff] [blame] | 434 |       } | 
 | 435 |      | 
| Dale Johannesen | 21b5541 | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 436 |       NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::STW)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 437 |                                          .addReg(PPC::R0, | 
 | 438 |                                                  getKillRegState(isKill)), | 
| Bill Wendling | 7194aaf | 2008-03-03 22:19:16 +0000 | [diff] [blame] | 439 |                                          FrameIdx)); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 440 |     } | 
| Nicolas Geoffray | 0404cd9 | 2008-03-10 14:12:10 +0000 | [diff] [blame] | 441 |   } else if (RC == PPC::CRBITRCRegisterClass) { | 
 | 442 |     // FIXME: We use CRi here because there is no mtcrf on a bit. Since the | 
 | 443 |     // backend currently only uses CR1EQ as an individual bit, this should | 
 | 444 |     // not cause any bug. If we need other uses of CR bits, the following | 
 | 445 |     // code may be invalid. | 
| Nicolas Geoffray | 9348c69 | 2008-03-10 17:46:45 +0000 | [diff] [blame] | 446 |     unsigned Reg = 0; | 
| Nicolas Geoffray | 0404cd9 | 2008-03-10 14:12:10 +0000 | [diff] [blame] | 447 |     if (SrcReg >= PPC::CR0LT || SrcReg <= PPC::CR0UN)  | 
| Nicolas Geoffray | 9348c69 | 2008-03-10 17:46:45 +0000 | [diff] [blame] | 448 |       Reg = PPC::CR0; | 
| Nicolas Geoffray | 0404cd9 | 2008-03-10 14:12:10 +0000 | [diff] [blame] | 449 |     else if (SrcReg >= PPC::CR1LT || SrcReg <= PPC::CR1UN)  | 
| Nicolas Geoffray | 9348c69 | 2008-03-10 17:46:45 +0000 | [diff] [blame] | 450 |       Reg = PPC::CR1; | 
 | 451 |     else if (SrcReg >= PPC::CR2LT || SrcReg <= PPC::CR2UN)  | 
 | 452 |       Reg = PPC::CR2; | 
 | 453 |     else if (SrcReg >= PPC::CR3LT || SrcReg <= PPC::CR3UN)  | 
 | 454 |       Reg = PPC::CR3; | 
 | 455 |     else if (SrcReg >= PPC::CR4LT || SrcReg <= PPC::CR4UN)  | 
 | 456 |       Reg = PPC::CR4; | 
 | 457 |     else if (SrcReg >= PPC::CR5LT || SrcReg <= PPC::CR5UN)  | 
 | 458 |       Reg = PPC::CR5; | 
 | 459 |     else if (SrcReg >= PPC::CR6LT || SrcReg <= PPC::CR6UN)  | 
 | 460 |       Reg = PPC::CR6; | 
 | 461 |     else if (SrcReg >= PPC::CR7LT || SrcReg <= PPC::CR7UN)  | 
 | 462 |       Reg = PPC::CR7; | 
 | 463 |  | 
| Dan Gohman | 8e5f2c6 | 2008-07-07 23:14:23 +0000 | [diff] [blame] | 464 |     return StoreRegToStackSlot(MF, Reg, isKill, FrameIdx,  | 
| Nicolas Geoffray | 9348c69 | 2008-03-10 17:46:45 +0000 | [diff] [blame] | 465 |                                PPC::CRRCRegisterClass, NewMIs); | 
 | 466 |  | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 467 |   } else if (RC == PPC::VRRCRegisterClass) { | 
 | 468 |     // We don't have indexed addressing for vector loads.  Emit: | 
 | 469 |     // R0 = ADDI FI# | 
 | 470 |     // STVX VAL, 0, R0 | 
 | 471 |     //  | 
 | 472 |     // FIXME: We use R0 here, because it isn't available for RA. | 
| Dale Johannesen | 21b5541 | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 473 |     NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::ADDI), PPC::R0), | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 474 |                                        FrameIdx, 0, 0)); | 
| Dale Johannesen | 21b5541 | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 475 |     NewMIs.push_back(BuildMI(MF, DL, get(PPC::STVX)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 476 |                      .addReg(SrcReg, getKillRegState(isKill)) | 
 | 477 |                      .addReg(PPC::R0) | 
 | 478 |                      .addReg(PPC::R0)); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 479 |   } else { | 
 | 480 |     assert(0 && "Unknown regclass!"); | 
 | 481 |     abort(); | 
 | 482 |   } | 
| Bill Wendling | 7194aaf | 2008-03-03 22:19:16 +0000 | [diff] [blame] | 483 |  | 
 | 484 |   return false; | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 485 | } | 
 | 486 |  | 
 | 487 | void | 
 | 488 | PPCInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, | 
| Bill Wendling | 7194aaf | 2008-03-03 22:19:16 +0000 | [diff] [blame] | 489 |                                   MachineBasicBlock::iterator MI, | 
 | 490 |                                   unsigned SrcReg, bool isKill, int FrameIdx, | 
 | 491 |                                   const TargetRegisterClass *RC) const { | 
| Dan Gohman | 8e5f2c6 | 2008-07-07 23:14:23 +0000 | [diff] [blame] | 492 |   MachineFunction &MF = *MBB.getParent(); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 493 |   SmallVector<MachineInstr*, 4> NewMIs; | 
| Bill Wendling | 7194aaf | 2008-03-03 22:19:16 +0000 | [diff] [blame] | 494 |  | 
| Dan Gohman | 8e5f2c6 | 2008-07-07 23:14:23 +0000 | [diff] [blame] | 495 |   if (StoreRegToStackSlot(MF, SrcReg, isKill, FrameIdx, RC, NewMIs)) { | 
 | 496 |     PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); | 
| Bill Wendling | 7194aaf | 2008-03-03 22:19:16 +0000 | [diff] [blame] | 497 |     FuncInfo->setSpillsCR(); | 
 | 498 |   } | 
 | 499 |  | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 500 |   for (unsigned i = 0, e = NewMIs.size(); i != e; ++i) | 
 | 501 |     MBB.insert(MI, NewMIs[i]); | 
 | 502 | } | 
 | 503 |  | 
 | 504 | void PPCInstrInfo::storeRegToAddr(MachineFunction &MF, unsigned SrcReg, | 
| Bill Wendling | 7194aaf | 2008-03-03 22:19:16 +0000 | [diff] [blame] | 505 |                                   bool isKill, | 
 | 506 |                                   SmallVectorImpl<MachineOperand> &Addr, | 
 | 507 |                                   const TargetRegisterClass *RC, | 
 | 508 |                                   SmallVectorImpl<MachineInstr*> &NewMIs) const{ | 
| Dan Gohman | d735b80 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 509 |   if (Addr[0].isFI()) { | 
| Dan Gohman | 8e5f2c6 | 2008-07-07 23:14:23 +0000 | [diff] [blame] | 510 |     if (StoreRegToStackSlot(MF, SrcReg, isKill, | 
 | 511 |                             Addr[0].getIndex(), RC, NewMIs)) { | 
| Bill Wendling | 7194aaf | 2008-03-03 22:19:16 +0000 | [diff] [blame] | 512 |       PPCFunctionInfo *FuncInfo = MF.getInfo<PPCFunctionInfo>(); | 
 | 513 |       FuncInfo->setSpillsCR(); | 
 | 514 |     } | 
 | 515 |  | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 516 |     return; | 
 | 517 |   } | 
 | 518 |  | 
| Dale Johannesen | 21b5541 | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 519 |   DebugLoc DL = DebugLoc::getUnknownLoc(); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 520 |   unsigned Opc = 0; | 
 | 521 |   if (RC == PPC::GPRCRegisterClass) { | 
 | 522 |     Opc = PPC::STW; | 
 | 523 |   } else if (RC == PPC::G8RCRegisterClass) { | 
 | 524 |     Opc = PPC::STD; | 
 | 525 |   } else if (RC == PPC::F8RCRegisterClass) { | 
 | 526 |     Opc = PPC::STFD; | 
 | 527 |   } else if (RC == PPC::F4RCRegisterClass) { | 
 | 528 |     Opc = PPC::STFS; | 
 | 529 |   } else if (RC == PPC::VRRCRegisterClass) { | 
 | 530 |     Opc = PPC::STVX; | 
 | 531 |   } else { | 
 | 532 |     assert(0 && "Unknown regclass!"); | 
 | 533 |     abort(); | 
 | 534 |   } | 
| Dale Johannesen | 21b5541 | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 535 |   MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 536 |     .addReg(SrcReg, getKillRegState(isKill)); | 
| Dan Gohman | 9735761 | 2009-02-18 05:45:50 +0000 | [diff] [blame] | 537 |   for (unsigned i = 0, e = Addr.size(); i != e; ++i) | 
 | 538 |     MIB.addOperand(Addr[i]); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 539 |   NewMIs.push_back(MIB); | 
 | 540 |   return; | 
 | 541 | } | 
 | 542 |  | 
| Bill Wendling | 4a66e9a | 2008-03-10 22:49:16 +0000 | [diff] [blame] | 543 | void | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 544 | PPCInstrInfo::LoadRegFromStackSlot(MachineFunction &MF, DebugLoc DL, | 
| Dan Gohman | 8e5f2c6 | 2008-07-07 23:14:23 +0000 | [diff] [blame] | 545 |                                    unsigned DestReg, int FrameIdx, | 
| Bill Wendling | 4a66e9a | 2008-03-10 22:49:16 +0000 | [diff] [blame] | 546 |                                    const TargetRegisterClass *RC, | 
 | 547 |                                    SmallVectorImpl<MachineInstr*> &NewMIs)const{ | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 548 |   if (RC == PPC::GPRCRegisterClass) { | 
 | 549 |     if (DestReg != PPC::LR) { | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 550 |       NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ), | 
 | 551 |                                                  DestReg), FrameIdx)); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 552 |     } else { | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 553 |       NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ), | 
 | 554 |                                                  PPC::R11), FrameIdx)); | 
 | 555 |       NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTLR)).addReg(PPC::R11)); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 556 |     } | 
 | 557 |   } else if (RC == PPC::G8RCRegisterClass) { | 
 | 558 |     if (DestReg != PPC::LR8) { | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 559 |       NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LD), DestReg), | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 560 |                                          FrameIdx)); | 
 | 561 |     } else { | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 562 |       NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LD), | 
 | 563 |                                                  PPC::R11), FrameIdx)); | 
 | 564 |       NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTLR8)).addReg(PPC::R11)); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 565 |     } | 
 | 566 |   } else if (RC == PPC::F8RCRegisterClass) { | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 567 |     NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFD), DestReg), | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 568 |                                        FrameIdx)); | 
 | 569 |   } else if (RC == PPC::F4RCRegisterClass) { | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 570 |     NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LFS), DestReg), | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 571 |                                        FrameIdx)); | 
 | 572 |   } else if (RC == PPC::CRRCRegisterClass) { | 
 | 573 |     // FIXME: We use R0 here, because it isn't available for RA. | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 574 |     NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::LWZ), PPC::R0), | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 575 |                                        FrameIdx)); | 
 | 576 |      | 
 | 577 |     // If the reloaded register isn't CR0, shift the bits right so that they are | 
 | 578 |     // in the right CR's slot. | 
 | 579 |     if (DestReg != PPC::CR0) { | 
 | 580 |       unsigned ShiftBits = PPCRegisterInfo::getRegisterNumbering(DestReg)*4; | 
 | 581 |       // rlwinm r11, r11, 32-ShiftBits, 0, 31. | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 582 |       NewMIs.push_back(BuildMI(MF, DL, get(PPC::RLWINM), PPC::R0) | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 583 |                     .addReg(PPC::R0).addImm(32-ShiftBits).addImm(0).addImm(31)); | 
 | 584 |     } | 
 | 585 |      | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 586 |     NewMIs.push_back(BuildMI(MF, DL, get(PPC::MTCRF), DestReg).addReg(PPC::R0)); | 
| Nicolas Geoffray | 0404cd9 | 2008-03-10 14:12:10 +0000 | [diff] [blame] | 587 |   } else if (RC == PPC::CRBITRCRegisterClass) { | 
| Nicolas Geoffray | 9348c69 | 2008-03-10 17:46:45 +0000 | [diff] [blame] | 588 |     | 
 | 589 |     unsigned Reg = 0; | 
| Nicolas Geoffray | 0404cd9 | 2008-03-10 14:12:10 +0000 | [diff] [blame] | 590 |     if (DestReg >= PPC::CR0LT || DestReg <= PPC::CR0UN)  | 
| Nicolas Geoffray | 9348c69 | 2008-03-10 17:46:45 +0000 | [diff] [blame] | 591 |       Reg = PPC::CR0; | 
| Nicolas Geoffray | 0404cd9 | 2008-03-10 14:12:10 +0000 | [diff] [blame] | 592 |     else if (DestReg >= PPC::CR1LT || DestReg <= PPC::CR1UN)  | 
| Nicolas Geoffray | 9348c69 | 2008-03-10 17:46:45 +0000 | [diff] [blame] | 593 |       Reg = PPC::CR1; | 
 | 594 |     else if (DestReg >= PPC::CR2LT || DestReg <= PPC::CR2UN)  | 
 | 595 |       Reg = PPC::CR2; | 
 | 596 |     else if (DestReg >= PPC::CR3LT || DestReg <= PPC::CR3UN)  | 
 | 597 |       Reg = PPC::CR3; | 
 | 598 |     else if (DestReg >= PPC::CR4LT || DestReg <= PPC::CR4UN)  | 
 | 599 |       Reg = PPC::CR4; | 
 | 600 |     else if (DestReg >= PPC::CR5LT || DestReg <= PPC::CR5UN)  | 
 | 601 |       Reg = PPC::CR5; | 
 | 602 |     else if (DestReg >= PPC::CR6LT || DestReg <= PPC::CR6UN)  | 
 | 603 |       Reg = PPC::CR6; | 
 | 604 |     else if (DestReg >= PPC::CR7LT || DestReg <= PPC::CR7UN)  | 
 | 605 |       Reg = PPC::CR7; | 
 | 606 |  | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 607 |     return LoadRegFromStackSlot(MF, DL, Reg, FrameIdx,  | 
| Nicolas Geoffray | 9348c69 | 2008-03-10 17:46:45 +0000 | [diff] [blame] | 608 |                                 PPC::CRRCRegisterClass, NewMIs); | 
 | 609 |  | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 610 |   } else if (RC == PPC::VRRCRegisterClass) { | 
 | 611 |     // We don't have indexed addressing for vector loads.  Emit: | 
 | 612 |     // R0 = ADDI FI# | 
 | 613 |     // Dest = LVX 0, R0 | 
 | 614 |     //  | 
 | 615 |     // FIXME: We use R0 here, because it isn't available for RA. | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 616 |     NewMIs.push_back(addFrameReference(BuildMI(MF, DL, get(PPC::ADDI), PPC::R0), | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 617 |                                        FrameIdx, 0, 0)); | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 618 |     NewMIs.push_back(BuildMI(MF, DL, get(PPC::LVX),DestReg).addReg(PPC::R0) | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 619 |                      .addReg(PPC::R0)); | 
 | 620 |   } else { | 
 | 621 |     assert(0 && "Unknown regclass!"); | 
 | 622 |     abort(); | 
 | 623 |   } | 
 | 624 | } | 
 | 625 |  | 
 | 626 | void | 
 | 627 | PPCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, | 
| Bill Wendling | 7194aaf | 2008-03-03 22:19:16 +0000 | [diff] [blame] | 628 |                                    MachineBasicBlock::iterator MI, | 
 | 629 |                                    unsigned DestReg, int FrameIdx, | 
 | 630 |                                    const TargetRegisterClass *RC) const { | 
| Dan Gohman | 8e5f2c6 | 2008-07-07 23:14:23 +0000 | [diff] [blame] | 631 |   MachineFunction &MF = *MBB.getParent(); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 632 |   SmallVector<MachineInstr*, 4> NewMIs; | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 633 |   DebugLoc DL = DebugLoc::getUnknownLoc(); | 
 | 634 |   if (MI != MBB.end()) DL = MI->getDebugLoc(); | 
 | 635 |   LoadRegFromStackSlot(MF, DL, DestReg, FrameIdx, RC, NewMIs); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 636 |   for (unsigned i = 0, e = NewMIs.size(); i != e; ++i) | 
 | 637 |     MBB.insert(MI, NewMIs[i]); | 
 | 638 | } | 
 | 639 |  | 
 | 640 | void PPCInstrInfo::loadRegFromAddr(MachineFunction &MF, unsigned DestReg, | 
| Bill Wendling | 7194aaf | 2008-03-03 22:19:16 +0000 | [diff] [blame] | 641 |                                    SmallVectorImpl<MachineOperand> &Addr, | 
 | 642 |                                    const TargetRegisterClass *RC, | 
 | 643 |                                    SmallVectorImpl<MachineInstr*> &NewMIs)const{ | 
| Dan Gohman | d735b80 | 2008-10-03 15:45:36 +0000 | [diff] [blame] | 644 |   if (Addr[0].isFI()) { | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 645 |     LoadRegFromStackSlot(MF, DebugLoc::getUnknownLoc(), | 
 | 646 |                          DestReg, Addr[0].getIndex(), RC, NewMIs); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 647 |     return; | 
 | 648 |   } | 
 | 649 |  | 
 | 650 |   unsigned Opc = 0; | 
 | 651 |   if (RC == PPC::GPRCRegisterClass) { | 
 | 652 |     assert(DestReg != PPC::LR && "Can't handle this yet!"); | 
 | 653 |     Opc = PPC::LWZ; | 
 | 654 |   } else if (RC == PPC::G8RCRegisterClass) { | 
 | 655 |     assert(DestReg != PPC::LR8 && "Can't handle this yet!"); | 
 | 656 |     Opc = PPC::LD; | 
 | 657 |   } else if (RC == PPC::F8RCRegisterClass) { | 
 | 658 |     Opc = PPC::LFD; | 
 | 659 |   } else if (RC == PPC::F4RCRegisterClass) { | 
 | 660 |     Opc = PPC::LFS; | 
 | 661 |   } else if (RC == PPC::VRRCRegisterClass) { | 
 | 662 |     Opc = PPC::LVX; | 
 | 663 |   } else { | 
 | 664 |     assert(0 && "Unknown regclass!"); | 
 | 665 |     abort(); | 
 | 666 |   } | 
| Dale Johannesen | 21b5541 | 2009-02-12 23:08:38 +0000 | [diff] [blame] | 667 |   DebugLoc DL = DebugLoc::getUnknownLoc(); | 
 | 668 |   MachineInstrBuilder MIB = BuildMI(MF, DL, get(Opc), DestReg); | 
| Dan Gohman | 9735761 | 2009-02-18 05:45:50 +0000 | [diff] [blame] | 669 |   for (unsigned i = 0, e = Addr.size(); i != e; ++i) | 
 | 670 |     MIB.addOperand(Addr[i]); | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 671 |   NewMIs.push_back(MIB); | 
 | 672 |   return; | 
 | 673 | } | 
 | 674 |  | 
| Owen Anderson | 43dbe05 | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 675 | /// foldMemoryOperand - PowerPC (like most RISC's) can only fold spills into | 
 | 676 | /// copy instructions, turning them into load/store instructions. | 
| Dan Gohman | c54baa2 | 2008-12-03 18:43:12 +0000 | [diff] [blame] | 677 | MachineInstr *PPCInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, | 
 | 678 |                                                   MachineInstr *MI, | 
 | 679 |                                            const SmallVectorImpl<unsigned> &Ops, | 
 | 680 |                                                   int FrameIndex) const { | 
| Owen Anderson | 43dbe05 | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 681 |   if (Ops.size() != 1) return NULL; | 
 | 682 |  | 
 | 683 |   // Make sure this is a reg-reg copy.  Note that we can't handle MCRF, because | 
 | 684 |   // it takes more than one instruction to store it. | 
 | 685 |   unsigned Opc = MI->getOpcode(); | 
 | 686 |   unsigned OpNum = Ops[0]; | 
 | 687 |  | 
 | 688 |   MachineInstr *NewMI = NULL; | 
 | 689 |   if ((Opc == PPC::OR && | 
 | 690 |        MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) { | 
 | 691 |     if (OpNum == 0) {  // move -> store | 
 | 692 |       unsigned InReg = MI->getOperand(1).getReg(); | 
| Evan Cheng | 9f1c831 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 693 |       bool isKill = MI->getOperand(1).isKill(); | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 694 |       NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::STW)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 695 |                                 .addReg(InReg, getKillRegState(isKill)), | 
| Owen Anderson | 43dbe05 | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 696 |                                 FrameIndex); | 
 | 697 |     } else {           // move -> load | 
 | 698 |       unsigned OutReg = MI->getOperand(0).getReg(); | 
| Evan Cheng | 9f1c831 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 699 |       bool isDead = MI->getOperand(0).isDead(); | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 700 |       NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::LWZ)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 701 |                                 .addReg(OutReg, | 
 | 702 |                                         RegState::Define | | 
 | 703 |                                         getDeadRegState(isDead)), | 
| Owen Anderson | 43dbe05 | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 704 |                                 FrameIndex); | 
 | 705 |     } | 
 | 706 |   } else if ((Opc == PPC::OR8 && | 
 | 707 |               MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) { | 
 | 708 |     if (OpNum == 0) {  // move -> store | 
 | 709 |       unsigned InReg = MI->getOperand(1).getReg(); | 
| Evan Cheng | 9f1c831 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 710 |       bool isKill = MI->getOperand(1).isKill(); | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 711 |       NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::STD)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 712 |                                 .addReg(InReg, getKillRegState(isKill)), | 
| Owen Anderson | 43dbe05 | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 713 |                                 FrameIndex); | 
 | 714 |     } else {           // move -> load | 
 | 715 |       unsigned OutReg = MI->getOperand(0).getReg(); | 
| Evan Cheng | 9f1c831 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 716 |       bool isDead = MI->getOperand(0).isDead(); | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 717 |       NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::LD)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 718 |                                 .addReg(OutReg, | 
 | 719 |                                         RegState::Define | | 
 | 720 |                                         getDeadRegState(isDead)), | 
| Evan Cheng | 9f1c831 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 721 |                                 FrameIndex); | 
| Owen Anderson | 43dbe05 | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 722 |     } | 
 | 723 |   } else if (Opc == PPC::FMRD) { | 
 | 724 |     if (OpNum == 0) {  // move -> store | 
 | 725 |       unsigned InReg = MI->getOperand(1).getReg(); | 
| Evan Cheng | 9f1c831 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 726 |       bool isKill = MI->getOperand(1).isKill(); | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 727 |       NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::STFD)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 728 |                                 .addReg(InReg, getKillRegState(isKill)), | 
| Owen Anderson | 43dbe05 | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 729 |                                 FrameIndex); | 
 | 730 |     } else {           // move -> load | 
 | 731 |       unsigned OutReg = MI->getOperand(0).getReg(); | 
| Evan Cheng | 9f1c831 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 732 |       bool isDead = MI->getOperand(0).isDead(); | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 733 |       NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::LFD)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 734 |                                 .addReg(OutReg, | 
 | 735 |                                         RegState::Define | | 
 | 736 |                                         getDeadRegState(isDead)), | 
| Evan Cheng | 9f1c831 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 737 |                                 FrameIndex); | 
| Owen Anderson | 43dbe05 | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 738 |     } | 
 | 739 |   } else if (Opc == PPC::FMRS) { | 
 | 740 |     if (OpNum == 0) {  // move -> store | 
 | 741 |       unsigned InReg = MI->getOperand(1).getReg(); | 
| Evan Cheng | 9f1c831 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 742 |       bool isKill = MI->getOperand(1).isKill(); | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 743 |       NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::STFS)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 744 |                                 .addReg(InReg, getKillRegState(isKill)), | 
| Owen Anderson | 43dbe05 | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 745 |                                 FrameIndex); | 
 | 746 |     } else {           // move -> load | 
 | 747 |       unsigned OutReg = MI->getOperand(0).getReg(); | 
| Evan Cheng | 9f1c831 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 748 |       bool isDead = MI->getOperand(0).isDead(); | 
| Bill Wendling | d1c321a | 2009-02-12 00:02:55 +0000 | [diff] [blame] | 749 |       NewMI = addFrameReference(BuildMI(MF, MI->getDebugLoc(), get(PPC::LFS)) | 
| Bill Wendling | 587daed | 2009-05-13 21:33:08 +0000 | [diff] [blame^] | 750 |                                 .addReg(OutReg, | 
 | 751 |                                         RegState::Define | | 
 | 752 |                                         getDeadRegState(isDead)), | 
| Evan Cheng | 9f1c831 | 2008-07-03 09:09:37 +0000 | [diff] [blame] | 753 |                                 FrameIndex); | 
| Owen Anderson | 43dbe05 | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 754 |     } | 
 | 755 |   } | 
 | 756 |  | 
| Owen Anderson | 43dbe05 | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 757 |   return NewMI; | 
 | 758 | } | 
 | 759 |  | 
| Dan Gohman | 8e8b8a2 | 2008-10-16 01:49:15 +0000 | [diff] [blame] | 760 | bool PPCInstrInfo::canFoldMemoryOperand(const MachineInstr *MI, | 
 | 761 |                                   const SmallVectorImpl<unsigned> &Ops) const { | 
| Owen Anderson | 43dbe05 | 2008-01-07 01:35:02 +0000 | [diff] [blame] | 762 |   if (Ops.size() != 1) return false; | 
 | 763 |  | 
 | 764 |   // Make sure this is a reg-reg copy.  Note that we can't handle MCRF, because | 
 | 765 |   // it takes more than one instruction to store it. | 
 | 766 |   unsigned Opc = MI->getOpcode(); | 
 | 767 |  | 
 | 768 |   if ((Opc == PPC::OR && | 
 | 769 |        MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) | 
 | 770 |     return true; | 
 | 771 |   else if ((Opc == PPC::OR8 && | 
 | 772 |               MI->getOperand(1).getReg() == MI->getOperand(2).getReg())) | 
 | 773 |     return true; | 
 | 774 |   else if (Opc == PPC::FMRD || Opc == PPC::FMRS) | 
 | 775 |     return true; | 
 | 776 |  | 
 | 777 |   return false; | 
 | 778 | } | 
 | 779 |  | 
| Owen Anderson | f6372aa | 2008-01-01 21:11:32 +0000 | [diff] [blame] | 780 |  | 
| Dan Gohman | 8e8b8a2 | 2008-10-16 01:49:15 +0000 | [diff] [blame] | 781 | bool PPCInstrInfo::BlockHasNoFallThrough(const MachineBasicBlock &MBB) const { | 
| Chris Lattner | ef13982 | 2006-10-28 17:35:02 +0000 | [diff] [blame] | 782 |   if (MBB.empty()) return false; | 
 | 783 |    | 
 | 784 |   switch (MBB.back().getOpcode()) { | 
| Evan Cheng | 126f17a | 2007-05-21 18:44:17 +0000 | [diff] [blame] | 785 |   case PPC::BLR:   // Return. | 
| Chris Lattner | ef13982 | 2006-10-28 17:35:02 +0000 | [diff] [blame] | 786 |   case PPC::B:     // Uncond branch. | 
 | 787 |   case PPC::BCTR:  // Indirect branch. | 
 | 788 |     return true; | 
 | 789 |   default: return false; | 
 | 790 |   } | 
 | 791 | } | 
 | 792 |  | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 793 | bool PPCInstrInfo:: | 
| Owen Anderson | 44eb65c | 2008-08-14 22:49:33 +0000 | [diff] [blame] | 794 | ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const { | 
| Chris Lattner | 7c4fe25 | 2006-10-21 06:03:11 +0000 | [diff] [blame] | 795 |   assert(Cond.size() == 2 && "Invalid PPC branch opcode!"); | 
 | 796 |   // Leave the CR# the same, but invert the condition. | 
| Chris Lattner | 18258c6 | 2006-11-17 22:37:34 +0000 | [diff] [blame] | 797 |   Cond[0].setImm(PPC::InvertPredicate((PPC::Predicate)Cond[0].getImm())); | 
| Chris Lattner | 7c4fe25 | 2006-10-21 06:03:11 +0000 | [diff] [blame] | 798 |   return false; | 
| Chris Lattner | c50e2bc | 2006-10-13 21:21:17 +0000 | [diff] [blame] | 799 | } | 
| Nicolas Geoffray | 52e724a | 2008-04-16 20:10:13 +0000 | [diff] [blame] | 800 |  | 
 | 801 | /// GetInstSize - Return the number of bytes of code the specified | 
 | 802 | /// instruction may be.  This returns the maximum number of bytes. | 
 | 803 | /// | 
 | 804 | unsigned PPCInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const { | 
 | 805 |   switch (MI->getOpcode()) { | 
 | 806 |   case PPC::INLINEASM: {       // Inline Asm: Variable size. | 
 | 807 |     const MachineFunction *MF = MI->getParent()->getParent(); | 
 | 808 |     const char *AsmStr = MI->getOperand(0).getSymbolName(); | 
 | 809 |     return MF->getTarget().getTargetAsmInfo()->getInlineAsmLength(AsmStr); | 
 | 810 |   } | 
| Dan Gohman | 4406604 | 2008-07-01 00:05:16 +0000 | [diff] [blame] | 811 |   case PPC::DBG_LABEL: | 
 | 812 |   case PPC::EH_LABEL: | 
 | 813 |   case PPC::GC_LABEL: | 
| Nicolas Geoffray | 52e724a | 2008-04-16 20:10:13 +0000 | [diff] [blame] | 814 |     return 0; | 
| Nicolas Geoffray | 52e724a | 2008-04-16 20:10:13 +0000 | [diff] [blame] | 815 |   default: | 
 | 816 |     return 4; // PowerPC instructions are all 4 bytes | 
 | 817 |   } | 
 | 818 | } |