| Nate Begeman | 21e463b | 2005-10-16 05:39:50 +0000 | [diff] [blame] | 1 | //===-- PPCISelDAGToDAG.cpp - PPC --pattern matching inst selector --------===// | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 2 | // | 
 | 3 | //                     The LLVM Compiler Infrastructure | 
 | 4 | // | 
 | 5 | // This file was developed by Chris Lattner and is distributed under | 
 | 6 | // the University of Illinois Open Source License. See LICENSE.TXT for details. | 
 | 7 | // | 
 | 8 | //===----------------------------------------------------------------------===// | 
 | 9 | // | 
| Nate Begeman | 21e463b | 2005-10-16 05:39:50 +0000 | [diff] [blame] | 10 | // This file defines a pattern matching instruction selector for PowerPC, | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 11 | // converting from a legalized dag to a PPC dag. | 
 | 12 | // | 
 | 13 | //===----------------------------------------------------------------------===// | 
 | 14 |  | 
| Chris Lattner | 2668959 | 2005-10-14 23:51:18 +0000 | [diff] [blame] | 15 | #include "PPC.h" | 
| Chris Lattner | 16e71f2 | 2005-10-14 23:59:06 +0000 | [diff] [blame] | 16 | #include "PPCTargetMachine.h" | 
 | 17 | #include "PPCISelLowering.h" | 
| Chris Lattner | 4416f1a | 2005-08-19 22:38:53 +0000 | [diff] [blame] | 18 | #include "llvm/CodeGen/MachineInstrBuilder.h" | 
 | 19 | #include "llvm/CodeGen/MachineFunction.h" | 
 | 20 | #include "llvm/CodeGen/SSARegMap.h" | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 21 | #include "llvm/CodeGen/SelectionDAG.h" | 
 | 22 | #include "llvm/CodeGen/SelectionDAGISel.h" | 
 | 23 | #include "llvm/Target/TargetOptions.h" | 
 | 24 | #include "llvm/ADT/Statistic.h" | 
| Chris Lattner | 2fe76e5 | 2005-08-25 04:47:18 +0000 | [diff] [blame] | 25 | #include "llvm/Constants.h" | 
| Chris Lattner | 4416f1a | 2005-08-19 22:38:53 +0000 | [diff] [blame] | 26 | #include "llvm/GlobalValue.h" | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 27 | #include "llvm/Support/Debug.h" | 
 | 28 | #include "llvm/Support/MathExtras.h" | 
 | 29 | using namespace llvm; | 
 | 30 |  | 
 | 31 | namespace { | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 32 |   Statistic<> FrameOff("ppc-codegen", "Number of frame idx offsets collapsed"); | 
 | 33 |      | 
 | 34 |   //===--------------------------------------------------------------------===// | 
| Nate Begeman | 1d9d742 | 2005-10-18 00:28:58 +0000 | [diff] [blame] | 35 |   /// PPCDAGToDAGISel - PPC specific code to select PPC machine | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 36 |   /// instructions for SelectionDAG operations. | 
 | 37 |   /// | 
| Nate Begeman | 1d9d742 | 2005-10-18 00:28:58 +0000 | [diff] [blame] | 38 |   class PPCDAGToDAGISel : public SelectionDAGISel { | 
| Nate Begeman | 21e463b | 2005-10-16 05:39:50 +0000 | [diff] [blame] | 39 |     PPCTargetLowering PPCLowering; | 
| Chris Lattner | 4416f1a | 2005-08-19 22:38:53 +0000 | [diff] [blame] | 40 |     unsigned GlobalBaseReg; | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 41 |   public: | 
| Nate Begeman | 1d9d742 | 2005-10-18 00:28:58 +0000 | [diff] [blame] | 42 |     PPCDAGToDAGISel(TargetMachine &TM) | 
| Nate Begeman | 21e463b | 2005-10-16 05:39:50 +0000 | [diff] [blame] | 43 |       : SelectionDAGISel(PPCLowering), PPCLowering(TM) {} | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 44 |      | 
| Chris Lattner | 4416f1a | 2005-08-19 22:38:53 +0000 | [diff] [blame] | 45 |     virtual bool runOnFunction(Function &Fn) { | 
 | 46 |       // Make sure we re-emit a set of the global base reg if necessary | 
 | 47 |       GlobalBaseReg = 0; | 
 | 48 |       return SelectionDAGISel::runOnFunction(Fn); | 
 | 49 |     } | 
 | 50 |     | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 51 |     /// getI32Imm - Return a target constant with the specified value, of type | 
 | 52 |     /// i32. | 
 | 53 |     inline SDOperand getI32Imm(unsigned Imm) { | 
 | 54 |       return CurDAG->getTargetConstant(Imm, MVT::i32); | 
 | 55 |     } | 
| Chris Lattner | 4416f1a | 2005-08-19 22:38:53 +0000 | [diff] [blame] | 56 |  | 
 | 57 |     /// getGlobalBaseReg - insert code into the entry mbb to materialize the PIC | 
 | 58 |     /// base register.  Return the virtual register that holds this value. | 
| Chris Lattner | 9944b76 | 2005-08-21 22:31:09 +0000 | [diff] [blame] | 59 |     SDOperand getGlobalBaseReg(); | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 60 |      | 
 | 61 |     // Select - Convert the specified operand from a target-independent to a | 
 | 62 |     // target-specific node if it hasn't already been changed. | 
 | 63 |     SDOperand Select(SDOperand Op); | 
 | 64 |      | 
| Nate Begeman | 02b88a4 | 2005-08-19 00:38:14 +0000 | [diff] [blame] | 65 |     SDNode *SelectBitfieldInsert(SDNode *N); | 
 | 66 |  | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 67 |     /// SelectCC - Select a comparison of the specified values with the | 
 | 68 |     /// specified condition code, returning the CR# of the expression. | 
 | 69 |     SDOperand SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC); | 
 | 70 |  | 
| Nate Begeman | 7fd1edd | 2005-12-19 23:25:09 +0000 | [diff] [blame^] | 71 |     /// SelectAddrImm - Returns true if the address N can be represented by | 
 | 72 |     /// a base register plus a signed 16-bit displacement [r+imm]. | 
 | 73 |     bool SelectAddrImm(SDOperand N, SDOperand &Disp, SDOperand &Base); | 
 | 74 |        | 
 | 75 |     /// SelectAddrIdx - Given the specified addressed, check to see if it can be | 
 | 76 |     /// represented as an indexed [r+r] operation.  Returns false if it can | 
 | 77 |     /// be represented by [r+imm], which are preferred. | 
 | 78 |     bool SelectAddrIdx(SDOperand N, SDOperand &Base, SDOperand &Index); | 
| Nate Begeman | f43a3ca | 2005-11-30 08:22:07 +0000 | [diff] [blame] | 79 |      | 
| Nate Begeman | 7fd1edd | 2005-12-19 23:25:09 +0000 | [diff] [blame^] | 80 |     /// SelectAddrIdxOnly - Given the specified addressed, force it to be | 
 | 81 |     /// represented as an indexed [r+r] operation. | 
 | 82 |     bool SelectAddrIdxOnly(SDOperand N, SDOperand &Base, SDOperand &Index); | 
| Chris Lattner | 9944b76 | 2005-08-21 22:31:09 +0000 | [diff] [blame] | 83 |  | 
| Chris Lattner | 047b952 | 2005-08-25 22:04:30 +0000 | [diff] [blame] | 84 |     SDOperand BuildSDIVSequence(SDNode *N); | 
 | 85 |     SDOperand BuildUDIVSequence(SDNode *N); | 
 | 86 |      | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 87 |     /// InstructionSelectBasicBlock - This callback is invoked by | 
 | 88 |     /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. | 
| Chris Lattner | bd937b9 | 2005-10-06 18:45:51 +0000 | [diff] [blame] | 89 |     virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); | 
 | 90 |      | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 91 |     virtual const char *getPassName() const { | 
 | 92 |       return "PowerPC DAG->DAG Pattern Instruction Selection"; | 
 | 93 |     }  | 
| Chris Lattner | af16538 | 2005-09-13 22:03:06 +0000 | [diff] [blame] | 94 |  | 
 | 95 | // Include the pieces autogenerated from the target description. | 
| Chris Lattner | 4c7b43b | 2005-10-14 23:37:35 +0000 | [diff] [blame] | 96 | #include "PPCGenDAGISel.inc" | 
| Chris Lattner | bd937b9 | 2005-10-06 18:45:51 +0000 | [diff] [blame] | 97 |      | 
 | 98 | private: | 
| Chris Lattner | 222adac | 2005-10-06 19:03:35 +0000 | [diff] [blame] | 99 |     SDOperand SelectDYNAMIC_STACKALLOC(SDOperand Op); | 
 | 100 |     SDOperand SelectADD_PARTS(SDOperand Op); | 
 | 101 |     SDOperand SelectSUB_PARTS(SDOperand Op); | 
 | 102 |     SDOperand SelectSETCC(SDOperand Op); | 
| Chris Lattner | 6a16f6a | 2005-10-06 19:07:45 +0000 | [diff] [blame] | 103 |     SDOperand SelectCALL(SDOperand Op); | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 104 |   }; | 
 | 105 | } | 
 | 106 |  | 
| Chris Lattner | bd937b9 | 2005-10-06 18:45:51 +0000 | [diff] [blame] | 107 | /// InstructionSelectBasicBlock - This callback is invoked by | 
 | 108 | /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. | 
| Nate Begeman | 1d9d742 | 2005-10-18 00:28:58 +0000 | [diff] [blame] | 109 | void PPCDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { | 
| Chris Lattner | bd937b9 | 2005-10-06 18:45:51 +0000 | [diff] [blame] | 110 |   DEBUG(BB->dump()); | 
 | 111 |    | 
 | 112 |   // The selection process is inherently a bottom-up recursive process (users | 
 | 113 |   // select their uses before themselves).  Given infinite stack space, we | 
 | 114 |   // could just start selecting on the root and traverse the whole graph.  In | 
 | 115 |   // practice however, this causes us to run out of stack space on large basic | 
 | 116 |   // blocks.  To avoid this problem, select the entry node, then all its uses, | 
 | 117 |   // iteratively instead of recursively. | 
 | 118 |   std::vector<SDOperand> Worklist; | 
 | 119 |   Worklist.push_back(DAG.getEntryNode()); | 
 | 120 |    | 
 | 121 |   // Note that we can do this in the PPC target (scanning forward across token | 
 | 122 |   // chain edges) because no nodes ever get folded across these edges.  On a | 
 | 123 |   // target like X86 which supports load/modify/store operations, this would | 
 | 124 |   // have to be more careful. | 
 | 125 |   while (!Worklist.empty()) { | 
 | 126 |     SDOperand Node = Worklist.back(); | 
 | 127 |     Worklist.pop_back(); | 
 | 128 |      | 
| Chris Lattner | cf01a70 | 2005-10-07 22:10:27 +0000 | [diff] [blame] | 129 |     // Chose from the least deep of the top two nodes. | 
 | 130 |     if (!Worklist.empty() && | 
 | 131 |         Worklist.back().Val->getNodeDepth() < Node.Val->getNodeDepth()) | 
 | 132 |       std::swap(Worklist.back(), Node); | 
 | 133 |      | 
| Chris Lattner | bd937b9 | 2005-10-06 18:45:51 +0000 | [diff] [blame] | 134 |     if ((Node.Val->getOpcode() >= ISD::BUILTIN_OP_END && | 
 | 135 |          Node.Val->getOpcode() < PPCISD::FIRST_NUMBER) || | 
 | 136 |         CodeGenMap.count(Node)) continue; | 
 | 137 |      | 
 | 138 |     for (SDNode::use_iterator UI = Node.Val->use_begin(), | 
 | 139 |          E = Node.Val->use_end(); UI != E; ++UI) { | 
 | 140 |       // Scan the values.  If this use has a value that is a token chain, add it | 
 | 141 |       // to the worklist. | 
 | 142 |       SDNode *User = *UI; | 
 | 143 |       for (unsigned i = 0, e = User->getNumValues(); i != e; ++i) | 
 | 144 |         if (User->getValueType(i) == MVT::Other) { | 
 | 145 |           Worklist.push_back(SDOperand(User, i)); | 
 | 146 |           break;  | 
 | 147 |         } | 
 | 148 |     } | 
 | 149 |  | 
 | 150 |     // Finally, legalize this node. | 
 | 151 |     Select(Node); | 
 | 152 |   } | 
| Chris Lattner | cf01a70 | 2005-10-07 22:10:27 +0000 | [diff] [blame] | 153 |      | 
| Chris Lattner | bd937b9 | 2005-10-06 18:45:51 +0000 | [diff] [blame] | 154 |   // Select target instructions for the DAG. | 
 | 155 |   DAG.setRoot(Select(DAG.getRoot())); | 
 | 156 |   CodeGenMap.clear(); | 
 | 157 |   DAG.RemoveDeadNodes(); | 
 | 158 |    | 
 | 159 |   // Emit machine code to BB.  | 
 | 160 |   ScheduleAndEmitDAG(DAG); | 
 | 161 | } | 
| Chris Lattner | 6cd40d5 | 2005-09-03 01:17:22 +0000 | [diff] [blame] | 162 |  | 
| Chris Lattner | 4416f1a | 2005-08-19 22:38:53 +0000 | [diff] [blame] | 163 | /// getGlobalBaseReg - Output the instructions required to put the | 
 | 164 | /// base address to use for accessing globals into a register. | 
 | 165 | /// | 
| Nate Begeman | 1d9d742 | 2005-10-18 00:28:58 +0000 | [diff] [blame] | 166 | SDOperand PPCDAGToDAGISel::getGlobalBaseReg() { | 
| Chris Lattner | 4416f1a | 2005-08-19 22:38:53 +0000 | [diff] [blame] | 167 |   if (!GlobalBaseReg) { | 
 | 168 |     // Insert the set of GlobalBaseReg into the first MBB of the function | 
 | 169 |     MachineBasicBlock &FirstMBB = BB->getParent()->front(); | 
 | 170 |     MachineBasicBlock::iterator MBBI = FirstMBB.begin(); | 
 | 171 |     SSARegMap *RegMap = BB->getParent()->getSSARegMap(); | 
| Nate Begeman | 1d9d742 | 2005-10-18 00:28:58 +0000 | [diff] [blame] | 172 |     // FIXME: when we get to LP64, we will need to create the appropriate | 
 | 173 |     // type of register here. | 
 | 174 |     GlobalBaseReg = RegMap->createVirtualRegister(PPC::GPRCRegisterClass); | 
| Chris Lattner | 4416f1a | 2005-08-19 22:38:53 +0000 | [diff] [blame] | 175 |     BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR); | 
 | 176 |     BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg); | 
 | 177 |   } | 
| Chris Lattner | 9944b76 | 2005-08-21 22:31:09 +0000 | [diff] [blame] | 178 |   return CurDAG->getRegister(GlobalBaseReg, MVT::i32); | 
| Chris Lattner | 4416f1a | 2005-08-19 22:38:53 +0000 | [diff] [blame] | 179 | } | 
 | 180 |  | 
 | 181 |  | 
| Nate Begeman | 0f3257a | 2005-08-18 05:00:13 +0000 | [diff] [blame] | 182 | // isIntImmediate - This method tests to see if a constant operand. | 
 | 183 | // If so Imm will receive the 32 bit value. | 
 | 184 | static bool isIntImmediate(SDNode *N, unsigned& Imm) { | 
 | 185 |   if (N->getOpcode() == ISD::Constant) { | 
 | 186 |     Imm = cast<ConstantSDNode>(N)->getValue(); | 
 | 187 |     return true; | 
 | 188 |   } | 
 | 189 |   return false; | 
 | 190 | } | 
 | 191 |  | 
| Nate Begeman | cffc32b | 2005-08-18 07:30:46 +0000 | [diff] [blame] | 192 | // isOprShiftImm - Returns true if the specified operand is a shift opcode with | 
 | 193 | // a immediate shift count less than 32. | 
 | 194 | static bool isOprShiftImm(SDNode *N, unsigned& Opc, unsigned& SH) { | 
 | 195 |   Opc = N->getOpcode(); | 
 | 196 |   return (Opc == ISD::SHL || Opc == ISD::SRL || Opc == ISD::SRA) && | 
 | 197 |     isIntImmediate(N->getOperand(1).Val, SH) && SH < 32; | 
 | 198 | } | 
 | 199 |  | 
 | 200 | // isRunOfOnes - Returns true iff Val consists of one contiguous run of 1s with | 
 | 201 | // any number of 0s on either side.  The 1s are allowed to wrap from LSB to | 
 | 202 | // MSB, so 0x000FFF0, 0x0000FFFF, and 0xFF0000FF are all runs.  0x0F0F0000 is | 
 | 203 | // not, since all 1s are not contiguous. | 
 | 204 | static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) { | 
 | 205 |   if (isShiftedMask_32(Val)) { | 
 | 206 |     // look for the first non-zero bit | 
 | 207 |     MB = CountLeadingZeros_32(Val); | 
 | 208 |     // look for the first zero bit after the run of ones | 
 | 209 |     ME = CountLeadingZeros_32((Val - 1) ^ Val); | 
 | 210 |     return true; | 
| Chris Lattner | 2fe76e5 | 2005-08-25 04:47:18 +0000 | [diff] [blame] | 211 |   } else { | 
 | 212 |     Val = ~Val; // invert mask | 
 | 213 |     if (isShiftedMask_32(Val)) { | 
 | 214 |       // effectively look for the first zero bit | 
 | 215 |       ME = CountLeadingZeros_32(Val) - 1; | 
 | 216 |       // effectively look for the first one bit after the run of zeros | 
 | 217 |       MB = CountLeadingZeros_32((Val - 1) ^ Val) + 1; | 
 | 218 |       return true; | 
 | 219 |     } | 
| Nate Begeman | cffc32b | 2005-08-18 07:30:46 +0000 | [diff] [blame] | 220 |   } | 
 | 221 |   // no run present | 
 | 222 |   return false; | 
 | 223 | } | 
 | 224 |  | 
| Chris Lattner | 65a419a | 2005-10-09 05:36:17 +0000 | [diff] [blame] | 225 | // isRotateAndMask - Returns true if Mask and Shift can be folded into a rotate | 
| Nate Begeman | cffc32b | 2005-08-18 07:30:46 +0000 | [diff] [blame] | 226 | // and mask opcode and mask operation. | 
 | 227 | static bool isRotateAndMask(SDNode *N, unsigned Mask, bool IsShiftMask, | 
 | 228 |                             unsigned &SH, unsigned &MB, unsigned &ME) { | 
| Nate Begeman | da32c9e | 2005-10-19 00:05:37 +0000 | [diff] [blame] | 229 |   // Don't even go down this path for i64, since different logic will be | 
 | 230 |   // necessary for rldicl/rldicr/rldimi. | 
 | 231 |   if (N->getValueType(0) != MVT::i32) | 
 | 232 |     return false; | 
 | 233 |  | 
| Nate Begeman | cffc32b | 2005-08-18 07:30:46 +0000 | [diff] [blame] | 234 |   unsigned Shift  = 32; | 
 | 235 |   unsigned Indeterminant = ~0;  // bit mask marking indeterminant results | 
 | 236 |   unsigned Opcode = N->getOpcode(); | 
| Chris Lattner | 1505573 | 2005-08-30 00:59:16 +0000 | [diff] [blame] | 237 |   if (N->getNumOperands() != 2 || | 
 | 238 |       !isIntImmediate(N->getOperand(1).Val, Shift) || (Shift > 31)) | 
| Nate Begeman | cffc32b | 2005-08-18 07:30:46 +0000 | [diff] [blame] | 239 |     return false; | 
 | 240 |    | 
 | 241 |   if (Opcode == ISD::SHL) { | 
 | 242 |     // apply shift left to mask if it comes first | 
 | 243 |     if (IsShiftMask) Mask = Mask << Shift; | 
 | 244 |     // determine which bits are made indeterminant by shift | 
 | 245 |     Indeterminant = ~(0xFFFFFFFFu << Shift); | 
| Chris Lattner | 651dea7 | 2005-10-15 21:40:12 +0000 | [diff] [blame] | 246 |   } else if (Opcode == ISD::SRL) {  | 
| Nate Begeman | cffc32b | 2005-08-18 07:30:46 +0000 | [diff] [blame] | 247 |     // apply shift right to mask if it comes first | 
 | 248 |     if (IsShiftMask) Mask = Mask >> Shift; | 
 | 249 |     // determine which bits are made indeterminant by shift | 
 | 250 |     Indeterminant = ~(0xFFFFFFFFu >> Shift); | 
 | 251 |     // adjust for the left rotate | 
 | 252 |     Shift = 32 - Shift; | 
 | 253 |   } else { | 
 | 254 |     return false; | 
 | 255 |   } | 
 | 256 |    | 
 | 257 |   // if the mask doesn't intersect any Indeterminant bits | 
 | 258 |   if (Mask && !(Mask & Indeterminant)) { | 
 | 259 |     SH = Shift; | 
 | 260 |     // make sure the mask is still a mask (wrap arounds may not be) | 
 | 261 |     return isRunOfOnes(Mask, MB, ME); | 
 | 262 |   } | 
 | 263 |   return false; | 
 | 264 | } | 
 | 265 |  | 
| Nate Begeman | 0f3257a | 2005-08-18 05:00:13 +0000 | [diff] [blame] | 266 | // isOpcWithIntImmediate - This method tests to see if the node is a specific | 
 | 267 | // opcode and that it has a immediate integer right operand. | 
 | 268 | // If so Imm will receive the 32 bit value. | 
 | 269 | static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned& Imm) { | 
 | 270 |   return N->getOpcode() == Opc && isIntImmediate(N->getOperand(1).Val, Imm); | 
 | 271 | } | 
 | 272 |  | 
 | 273 | // isOprNot - Returns true if the specified operand is an xor with immediate -1. | 
 | 274 | static bool isOprNot(SDNode *N) { | 
 | 275 |   unsigned Imm; | 
 | 276 |   return isOpcWithIntImmediate(N, ISD::XOR, Imm) && (signed)Imm == -1; | 
 | 277 | } | 
 | 278 |  | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 279 | // Immediate constant composers. | 
 | 280 | // Lo16 - grabs the lo 16 bits from a 32 bit constant. | 
 | 281 | // Hi16 - grabs the hi 16 bits from a 32 bit constant. | 
 | 282 | // HA16 - computes the hi bits required if the lo bits are add/subtracted in | 
 | 283 | // arithmethically. | 
 | 284 | static unsigned Lo16(unsigned x)  { return x & 0x0000FFFF; } | 
 | 285 | static unsigned Hi16(unsigned x)  { return Lo16(x >> 16); } | 
 | 286 | static unsigned HA16(unsigned x)  { return Hi16((signed)x - (signed short)x); } | 
 | 287 |  | 
 | 288 | // isIntImmediate - This method tests to see if a constant operand. | 
 | 289 | // If so Imm will receive the 32 bit value. | 
 | 290 | static bool isIntImmediate(SDOperand N, unsigned& Imm) { | 
 | 291 |   if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) { | 
 | 292 |     Imm = (unsigned)CN->getSignExtended(); | 
 | 293 |     return true; | 
 | 294 |   } | 
 | 295 |   return false; | 
 | 296 | } | 
 | 297 |  | 
| Nate Begeman | 02b88a4 | 2005-08-19 00:38:14 +0000 | [diff] [blame] | 298 | /// SelectBitfieldInsert - turn an or of two masked values into | 
 | 299 | /// the rotate left word immediate then mask insert (rlwimi) instruction. | 
 | 300 | /// Returns true on success, false if the caller still needs to select OR. | 
 | 301 | /// | 
 | 302 | /// Patterns matched: | 
 | 303 | /// 1. or shl, and   5. or and, and | 
 | 304 | /// 2. or and, shl   6. or shl, shr | 
 | 305 | /// 3. or shr, and   7. or shr, shl | 
 | 306 | /// 4. or and, shr | 
| Nate Begeman | 1d9d742 | 2005-10-18 00:28:58 +0000 | [diff] [blame] | 307 | SDNode *PPCDAGToDAGISel::SelectBitfieldInsert(SDNode *N) { | 
| Nate Begeman | 02b88a4 | 2005-08-19 00:38:14 +0000 | [diff] [blame] | 308 |   bool IsRotate = false; | 
 | 309 |   unsigned TgtMask = 0xFFFFFFFF, InsMask = 0xFFFFFFFF, SH = 0; | 
 | 310 |   unsigned Value; | 
 | 311 |    | 
 | 312 |   SDOperand Op0 = N->getOperand(0); | 
 | 313 |   SDOperand Op1 = N->getOperand(1); | 
 | 314 |    | 
 | 315 |   unsigned Op0Opc = Op0.getOpcode(); | 
 | 316 |   unsigned Op1Opc = Op1.getOpcode(); | 
 | 317 |    | 
 | 318 |   // Verify that we have the correct opcodes | 
 | 319 |   if (ISD::SHL != Op0Opc && ISD::SRL != Op0Opc && ISD::AND != Op0Opc) | 
 | 320 |     return false; | 
 | 321 |   if (ISD::SHL != Op1Opc && ISD::SRL != Op1Opc && ISD::AND != Op1Opc) | 
 | 322 |     return false; | 
 | 323 |    | 
 | 324 |   // Generate Mask value for Target | 
 | 325 |   if (isIntImmediate(Op0.getOperand(1), Value)) { | 
 | 326 |     switch(Op0Opc) { | 
| Chris Lattner | 1368721 | 2005-08-30 18:37:48 +0000 | [diff] [blame] | 327 |     case ISD::SHL: TgtMask <<= Value; break; | 
 | 328 |     case ISD::SRL: TgtMask >>= Value; break; | 
 | 329 |     case ISD::AND: TgtMask &= Value; break; | 
| Nate Begeman | 02b88a4 | 2005-08-19 00:38:14 +0000 | [diff] [blame] | 330 |     } | 
 | 331 |   } else { | 
 | 332 |     return 0; | 
 | 333 |   } | 
 | 334 |    | 
 | 335 |   // Generate Mask value for Insert | 
| Chris Lattner | 1368721 | 2005-08-30 18:37:48 +0000 | [diff] [blame] | 336 |   if (!isIntImmediate(Op1.getOperand(1), Value)) | 
| Nate Begeman | 02b88a4 | 2005-08-19 00:38:14 +0000 | [diff] [blame] | 337 |     return 0; | 
| Chris Lattner | 1368721 | 2005-08-30 18:37:48 +0000 | [diff] [blame] | 338 |    | 
 | 339 |   switch(Op1Opc) { | 
 | 340 |   case ISD::SHL: | 
 | 341 |     SH = Value; | 
 | 342 |     InsMask <<= SH; | 
 | 343 |     if (Op0Opc == ISD::SRL) IsRotate = true; | 
 | 344 |     break; | 
 | 345 |   case ISD::SRL: | 
 | 346 |     SH = Value; | 
 | 347 |     InsMask >>= SH; | 
 | 348 |     SH = 32-SH; | 
 | 349 |     if (Op0Opc == ISD::SHL) IsRotate = true; | 
 | 350 |     break; | 
 | 351 |   case ISD::AND: | 
 | 352 |     InsMask &= Value; | 
 | 353 |     break; | 
| Nate Begeman | 02b88a4 | 2005-08-19 00:38:14 +0000 | [diff] [blame] | 354 |   } | 
 | 355 |    | 
 | 356 |   // If both of the inputs are ANDs and one of them has a logical shift by | 
 | 357 |   // constant as its input, make that AND the inserted value so that we can | 
 | 358 |   // combine the shift into the rotate part of the rlwimi instruction | 
 | 359 |   bool IsAndWithShiftOp = false; | 
 | 360 |   if (Op0Opc == ISD::AND && Op1Opc == ISD::AND) { | 
 | 361 |     if (Op1.getOperand(0).getOpcode() == ISD::SHL || | 
 | 362 |         Op1.getOperand(0).getOpcode() == ISD::SRL) { | 
 | 363 |       if (isIntImmediate(Op1.getOperand(0).getOperand(1), Value)) { | 
 | 364 |         SH = Op1.getOperand(0).getOpcode() == ISD::SHL ? Value : 32 - Value; | 
 | 365 |         IsAndWithShiftOp = true; | 
 | 366 |       } | 
 | 367 |     } else if (Op0.getOperand(0).getOpcode() == ISD::SHL || | 
 | 368 |                Op0.getOperand(0).getOpcode() == ISD::SRL) { | 
 | 369 |       if (isIntImmediate(Op0.getOperand(0).getOperand(1), Value)) { | 
 | 370 |         std::swap(Op0, Op1); | 
 | 371 |         std::swap(TgtMask, InsMask); | 
 | 372 |         SH = Op1.getOperand(0).getOpcode() == ISD::SHL ? Value : 32 - Value; | 
 | 373 |         IsAndWithShiftOp = true; | 
 | 374 |       } | 
 | 375 |     } | 
 | 376 |   } | 
 | 377 |    | 
 | 378 |   // Verify that the Target mask and Insert mask together form a full word mask | 
 | 379 |   // and that the Insert mask is a run of set bits (which implies both are runs | 
 | 380 |   // of set bits).  Given that, Select the arguments and generate the rlwimi | 
 | 381 |   // instruction. | 
 | 382 |   unsigned MB, ME; | 
 | 383 |   if (((TgtMask & InsMask) == 0) && isRunOfOnes(InsMask, MB, ME)) { | 
 | 384 |     bool fullMask = (TgtMask ^ InsMask) == 0xFFFFFFFF; | 
 | 385 |     bool Op0IsAND = Op0Opc == ISD::AND; | 
 | 386 |     // Check for rotlwi / rotrwi here, a special case of bitfield insert | 
 | 387 |     // where both bitfield halves are sourced from the same value. | 
 | 388 |     if (IsRotate && fullMask && | 
 | 389 |         N->getOperand(0).getOperand(0) == N->getOperand(1).getOperand(0)) { | 
 | 390 |       Op0 = CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, | 
 | 391 |                                   Select(N->getOperand(0).getOperand(0)), | 
 | 392 |                                   getI32Imm(SH), getI32Imm(0), getI32Imm(31)); | 
 | 393 |       return Op0.Val; | 
 | 394 |     } | 
 | 395 |     SDOperand Tmp1 = (Op0IsAND && fullMask) ? Select(Op0.getOperand(0)) | 
 | 396 |                                             : Select(Op0); | 
 | 397 |     SDOperand Tmp2 = IsAndWithShiftOp ? Select(Op1.getOperand(0).getOperand(0))  | 
 | 398 |                                       : Select(Op1.getOperand(0)); | 
 | 399 |     Op0 = CurDAG->getTargetNode(PPC::RLWIMI, MVT::i32, Tmp1, Tmp2, | 
 | 400 |                                 getI32Imm(SH), getI32Imm(MB), getI32Imm(ME)); | 
 | 401 |     return Op0.Val; | 
 | 402 |   } | 
 | 403 |   return 0; | 
 | 404 | } | 
 | 405 |  | 
| Nate Begeman | 7fd1edd | 2005-12-19 23:25:09 +0000 | [diff] [blame^] | 406 | /// SelectAddrImm - Returns true if the address N can be represented by | 
 | 407 | /// a base register plus a signed 16-bit displacement [r+imm]. | 
 | 408 | bool PPCDAGToDAGISel::SelectAddrImm(SDOperand N, SDOperand &Disp,  | 
 | 409 |                                     SDOperand &Base) { | 
 | 410 |   if (N.getOpcode() == ISD::ADD) { | 
 | 411 |     unsigned imm = 0; | 
 | 412 |     if (isIntImmediate(N.getOperand(1), imm) && isInt16(imm)) { | 
 | 413 |       Disp = getI32Imm(Lo16(imm)); | 
 | 414 |       if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0))) { | 
 | 415 |         Base = CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32); | 
| Chris Lattner | 9944b76 | 2005-08-21 22:31:09 +0000 | [diff] [blame] | 416 |       } else { | 
| Nate Begeman | 7fd1edd | 2005-12-19 23:25:09 +0000 | [diff] [blame^] | 417 |         Base = Select(N.getOperand(0)); | 
| Chris Lattner | 9944b76 | 2005-08-21 22:31:09 +0000 | [diff] [blame] | 418 |       } | 
| Nate Begeman | 7fd1edd | 2005-12-19 23:25:09 +0000 | [diff] [blame^] | 419 |       return true; // [r+i] | 
 | 420 |     } else if (N.getOperand(1).getOpcode() == PPCISD::Lo) { | 
| Chris Lattner | 4f0f86d | 2005-11-17 18:02:16 +0000 | [diff] [blame] | 421 |       // Match LOAD (ADD (X, Lo(G))). | 
| Nate Begeman | 7fd1edd | 2005-12-19 23:25:09 +0000 | [diff] [blame^] | 422 |       assert(!cast<ConstantSDNode>(N.getOperand(1).getOperand(1))->getValue() | 
| Chris Lattner | 4f0f86d | 2005-11-17 18:02:16 +0000 | [diff] [blame] | 423 |              && "Cannot handle constant offsets yet!"); | 
| Nate Begeman | 7fd1edd | 2005-12-19 23:25:09 +0000 | [diff] [blame^] | 424 |       Disp = N.getOperand(1).getOperand(0);  // The global address. | 
 | 425 |       assert(Disp.getOpcode() == ISD::TargetGlobalAddress || | 
 | 426 |              Disp.getOpcode() == ISD::TargetConstantPool); | 
 | 427 |       Base = Select(N.getOperand(0)); | 
 | 428 |       return true;  // [&g+r] | 
| Chris Lattner | 9944b76 | 2005-08-21 22:31:09 +0000 | [diff] [blame] | 429 |     } | 
| Nate Begeman | 7fd1edd | 2005-12-19 23:25:09 +0000 | [diff] [blame^] | 430 |     return false;   // [r+r] | 
| Chris Lattner | 9944b76 | 2005-08-21 22:31:09 +0000 | [diff] [blame] | 431 |   } | 
| Nate Begeman | 7fd1edd | 2005-12-19 23:25:09 +0000 | [diff] [blame^] | 432 |   Disp = getI32Imm(0); | 
 | 433 |   if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N)) | 
 | 434 |     Base = CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32); | 
| Nate Begeman | 28a6b02 | 2005-12-10 02:36:00 +0000 | [diff] [blame] | 435 |   else | 
| Nate Begeman | 7fd1edd | 2005-12-19 23:25:09 +0000 | [diff] [blame^] | 436 |     Base = Select(N); | 
 | 437 |   return true;      // [r+0] | 
| Chris Lattner | 9944b76 | 2005-08-21 22:31:09 +0000 | [diff] [blame] | 438 | } | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 439 |  | 
| Nate Begeman | 7fd1edd | 2005-12-19 23:25:09 +0000 | [diff] [blame^] | 440 | /// SelectAddrIdx - Given the specified addressed, check to see if it can be | 
 | 441 | /// represented as an indexed [r+r] operation.  Returns false if it can | 
 | 442 | /// be represented by [r+imm], which are preferred. | 
 | 443 | bool PPCDAGToDAGISel::SelectAddrIdx(SDOperand N, SDOperand &Base,  | 
 | 444 |                                     SDOperand &Index) { | 
 | 445 |   // Check to see if we can represent this as an [r+imm] address instead,  | 
 | 446 |   // which will fail if the address is more profitably represented as an | 
 | 447 |   // [r+r] address. | 
 | 448 |   if (SelectAddrImm(N, Base, Index)) | 
 | 449 |     return false; | 
 | 450 |    | 
 | 451 |   if (N.getOpcode() == ISD::ADD) { | 
 | 452 |     Base = Select(N.getOperand(0)); | 
 | 453 |     Index = Select(N.getOperand(1)); | 
 | 454 |     return true; | 
 | 455 |   } | 
 | 456 |   | 
 | 457 |   // FIXME: This should be a CopyFromReg R0 rather than a load of 0. | 
 | 458 |   Base = CurDAG->getTargetNode(PPC::LI, MVT::i32, getI32Imm(0)); | 
 | 459 |   Index = Select(N); | 
 | 460 |   return true; | 
 | 461 | } | 
 | 462 |  | 
 | 463 | /// SelectAddrIdxOnly - Given the specified addressed, force it to be | 
 | 464 | /// represented as an indexed [r+r] operation. | 
 | 465 | bool PPCDAGToDAGISel::SelectAddrIdxOnly(SDOperand N, SDOperand &Base,  | 
 | 466 |                                         SDOperand &Index) { | 
 | 467 |   if (N.getOpcode() == ISD::ADD) { | 
 | 468 |     Base = Select(N.getOperand(0)); | 
 | 469 |     Index = Select(N.getOperand(1)); | 
 | 470 |     return true; | 
| Nate Begeman | f43a3ca | 2005-11-30 08:22:07 +0000 | [diff] [blame] | 471 |   } | 
 | 472 |    | 
| Nate Begeman | 7fd1edd | 2005-12-19 23:25:09 +0000 | [diff] [blame^] | 473 |   // FIXME: This should be a CopyFromReg R0 rather than a load of 0. | 
 | 474 |   Base = CurDAG->getTargetNode(PPC::LI, MVT::i32, getI32Imm(0)); | 
 | 475 |   Index = Select(N); | 
 | 476 |   return true; | 
| Nate Begeman | f43a3ca | 2005-11-30 08:22:07 +0000 | [diff] [blame] | 477 | } | 
 | 478 |  | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 479 | /// SelectCC - Select a comparison of the specified values with the specified | 
 | 480 | /// condition code, returning the CR# of the expression. | 
| Nate Begeman | 1d9d742 | 2005-10-18 00:28:58 +0000 | [diff] [blame] | 481 | SDOperand PPCDAGToDAGISel::SelectCC(SDOperand LHS, SDOperand RHS, | 
 | 482 |                                     ISD::CondCode CC) { | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 483 |   // Always select the LHS. | 
 | 484 |   LHS = Select(LHS); | 
 | 485 |  | 
 | 486 |   // Use U to determine whether the SETCC immediate range is signed or not. | 
 | 487 |   if (MVT::isInteger(LHS.getValueType())) { | 
 | 488 |     bool U = ISD::isUnsignedIntSetCC(CC); | 
 | 489 |     unsigned Imm; | 
 | 490 |     if (isIntImmediate(RHS, Imm) &&  | 
 | 491 |         ((U && isUInt16(Imm)) || (!U && isInt16(Imm)))) | 
 | 492 |       return CurDAG->getTargetNode(U ? PPC::CMPLWI : PPC::CMPWI, MVT::i32, | 
 | 493 |                                    LHS, getI32Imm(Lo16(Imm))); | 
 | 494 |     return CurDAG->getTargetNode(U ? PPC::CMPLW : PPC::CMPW, MVT::i32, | 
 | 495 |                                  LHS, Select(RHS)); | 
| Chris Lattner | 919c032 | 2005-10-01 01:35:02 +0000 | [diff] [blame] | 496 |   } else if (LHS.getValueType() == MVT::f32) { | 
 | 497 |     return CurDAG->getTargetNode(PPC::FCMPUS, MVT::i32, LHS, Select(RHS)); | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 498 |   } else { | 
| Chris Lattner | 919c032 | 2005-10-01 01:35:02 +0000 | [diff] [blame] | 499 |     return CurDAG->getTargetNode(PPC::FCMPUD, MVT::i32, LHS, Select(RHS)); | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 500 |   } | 
 | 501 | } | 
 | 502 |  | 
 | 503 | /// getBCCForSetCC - Returns the PowerPC condition branch mnemonic corresponding | 
 | 504 | /// to Condition. | 
 | 505 | static unsigned getBCCForSetCC(ISD::CondCode CC) { | 
 | 506 |   switch (CC) { | 
 | 507 |   default: assert(0 && "Unknown condition!"); abort(); | 
| Chris Lattner | ed048c0 | 2005-10-28 20:49:47 +0000 | [diff] [blame] | 508 |   case ISD::SETOEQ:    // FIXME: This is incorrect see PR642. | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 509 |   case ISD::SETEQ:  return PPC::BEQ; | 
| Chris Lattner | ed048c0 | 2005-10-28 20:49:47 +0000 | [diff] [blame] | 510 |   case ISD::SETONE:    // FIXME: This is incorrect see PR642. | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 511 |   case ISD::SETNE:  return PPC::BNE; | 
| Chris Lattner | ed048c0 | 2005-10-28 20:49:47 +0000 | [diff] [blame] | 512 |   case ISD::SETOLT:    // FIXME: This is incorrect see PR642. | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 513 |   case ISD::SETULT: | 
 | 514 |   case ISD::SETLT:  return PPC::BLT; | 
| Chris Lattner | ed048c0 | 2005-10-28 20:49:47 +0000 | [diff] [blame] | 515 |   case ISD::SETOLE:    // FIXME: This is incorrect see PR642. | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 516 |   case ISD::SETULE: | 
 | 517 |   case ISD::SETLE:  return PPC::BLE; | 
| Chris Lattner | ed048c0 | 2005-10-28 20:49:47 +0000 | [diff] [blame] | 518 |   case ISD::SETOGT:    // FIXME: This is incorrect see PR642. | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 519 |   case ISD::SETUGT: | 
 | 520 |   case ISD::SETGT:  return PPC::BGT; | 
| Chris Lattner | ed048c0 | 2005-10-28 20:49:47 +0000 | [diff] [blame] | 521 |   case ISD::SETOGE:    // FIXME: This is incorrect see PR642. | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 522 |   case ISD::SETUGE: | 
 | 523 |   case ISD::SETGE:  return PPC::BGE; | 
| Chris Lattner | 6df2507 | 2005-10-28 20:32:44 +0000 | [diff] [blame] | 524 |      | 
 | 525 |   case ISD::SETO:   return PPC::BUN; | 
 | 526 |   case ISD::SETUO:  return PPC::BNU; | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 527 |   } | 
 | 528 |   return 0; | 
 | 529 | } | 
 | 530 |  | 
| Chris Lattner | 64906a0 | 2005-08-25 20:08:18 +0000 | [diff] [blame] | 531 | /// getCRIdxForSetCC - Return the index of the condition register field | 
 | 532 | /// associated with the SetCC condition, and whether or not the field is | 
 | 533 | /// treated as inverted.  That is, lt = 0; ge = 0 inverted. | 
 | 534 | static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool& Inv) { | 
 | 535 |   switch (CC) { | 
 | 536 |   default: assert(0 && "Unknown condition!"); abort(); | 
| Chris Lattner | ed048c0 | 2005-10-28 20:49:47 +0000 | [diff] [blame] | 537 |   case ISD::SETOLT:  // FIXME: This is incorrect see PR642. | 
| Chris Lattner | 64906a0 | 2005-08-25 20:08:18 +0000 | [diff] [blame] | 538 |   case ISD::SETULT: | 
 | 539 |   case ISD::SETLT:  Inv = false;  return 0; | 
| Chris Lattner | ed048c0 | 2005-10-28 20:49:47 +0000 | [diff] [blame] | 540 |   case ISD::SETOGE:  // FIXME: This is incorrect see PR642. | 
| Chris Lattner | 64906a0 | 2005-08-25 20:08:18 +0000 | [diff] [blame] | 541 |   case ISD::SETUGE: | 
 | 542 |   case ISD::SETGE:  Inv = true;   return 0; | 
| Chris Lattner | ed048c0 | 2005-10-28 20:49:47 +0000 | [diff] [blame] | 543 |   case ISD::SETOGT:  // FIXME: This is incorrect see PR642. | 
| Chris Lattner | 64906a0 | 2005-08-25 20:08:18 +0000 | [diff] [blame] | 544 |   case ISD::SETUGT: | 
 | 545 |   case ISD::SETGT:  Inv = false;  return 1; | 
| Chris Lattner | ed048c0 | 2005-10-28 20:49:47 +0000 | [diff] [blame] | 546 |   case ISD::SETOLE:  // FIXME: This is incorrect see PR642. | 
| Chris Lattner | 64906a0 | 2005-08-25 20:08:18 +0000 | [diff] [blame] | 547 |   case ISD::SETULE: | 
 | 548 |   case ISD::SETLE:  Inv = true;   return 1; | 
| Chris Lattner | ed048c0 | 2005-10-28 20:49:47 +0000 | [diff] [blame] | 549 |   case ISD::SETOEQ:  // FIXME: This is incorrect see PR642. | 
| Chris Lattner | 64906a0 | 2005-08-25 20:08:18 +0000 | [diff] [blame] | 550 |   case ISD::SETEQ:  Inv = false;  return 2; | 
| Chris Lattner | ed048c0 | 2005-10-28 20:49:47 +0000 | [diff] [blame] | 551 |   case ISD::SETONE:  // FIXME: This is incorrect see PR642. | 
| Chris Lattner | 64906a0 | 2005-08-25 20:08:18 +0000 | [diff] [blame] | 552 |   case ISD::SETNE:  Inv = true;   return 2; | 
| Chris Lattner | 6df2507 | 2005-10-28 20:32:44 +0000 | [diff] [blame] | 553 |   case ISD::SETO:   Inv = true;   return 3; | 
 | 554 |   case ISD::SETUO:  Inv = false;  return 3; | 
| Chris Lattner | 64906a0 | 2005-08-25 20:08:18 +0000 | [diff] [blame] | 555 |   } | 
 | 556 |   return 0; | 
 | 557 | } | 
| Chris Lattner | 9944b76 | 2005-08-21 22:31:09 +0000 | [diff] [blame] | 558 |  | 
| Nate Begeman | 1d9d742 | 2005-10-18 00:28:58 +0000 | [diff] [blame] | 559 | SDOperand PPCDAGToDAGISel::SelectDYNAMIC_STACKALLOC(SDOperand Op) { | 
| Chris Lattner | bd937b9 | 2005-10-06 18:45:51 +0000 | [diff] [blame] | 560 |   SDNode *N = Op.Val; | 
 | 561 |  | 
 | 562 |   // FIXME: We are currently ignoring the requested alignment for handling | 
 | 563 |   // greater than the stack alignment.  This will need to be revisited at some | 
 | 564 |   // point.  Align = N.getOperand(2); | 
 | 565 |   if (!isa<ConstantSDNode>(N->getOperand(2)) || | 
 | 566 |       cast<ConstantSDNode>(N->getOperand(2))->getValue() != 0) { | 
 | 567 |     std::cerr << "Cannot allocate stack object with greater alignment than" | 
 | 568 |     << " the stack alignment yet!"; | 
 | 569 |     abort(); | 
 | 570 |   } | 
 | 571 |   SDOperand Chain = Select(N->getOperand(0)); | 
 | 572 |   SDOperand Amt   = Select(N->getOperand(1)); | 
 | 573 |    | 
 | 574 |   SDOperand R1Reg = CurDAG->getRegister(PPC::R1, MVT::i32); | 
 | 575 |    | 
 | 576 |   SDOperand R1Val = CurDAG->getCopyFromReg(Chain, PPC::R1, MVT::i32); | 
 | 577 |   Chain = R1Val.getValue(1); | 
 | 578 |    | 
 | 579 |   // Subtract the amount (guaranteed to be a multiple of the stack alignment) | 
 | 580 |   // from the stack pointer, giving us the result pointer. | 
 | 581 |   SDOperand Result = CurDAG->getTargetNode(PPC::SUBF, MVT::i32, Amt, R1Val); | 
 | 582 |    | 
 | 583 |   // Copy this result back into R1. | 
 | 584 |   Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, R1Reg, Result); | 
 | 585 |    | 
 | 586 |   // Copy this result back out of R1 to make sure we're not using the stack | 
 | 587 |   // space without decrementing the stack pointer. | 
 | 588 |   Result = CurDAG->getCopyFromReg(Chain, PPC::R1, MVT::i32); | 
 | 589 |    | 
 | 590 |   // Finally, replace the DYNAMIC_STACKALLOC with the copyfromreg. | 
 | 591 |   CodeGenMap[Op.getValue(0)] = Result; | 
 | 592 |   CodeGenMap[Op.getValue(1)] = Result.getValue(1); | 
 | 593 |   return SDOperand(Result.Val, Op.ResNo); | 
 | 594 | } | 
 | 595 |  | 
| Nate Begeman | 1d9d742 | 2005-10-18 00:28:58 +0000 | [diff] [blame] | 596 | SDOperand PPCDAGToDAGISel::SelectADD_PARTS(SDOperand Op) { | 
| Chris Lattner | 2b63e4c | 2005-10-06 18:56:10 +0000 | [diff] [blame] | 597 |   SDNode *N = Op.Val; | 
 | 598 |   SDOperand LHSL = Select(N->getOperand(0)); | 
 | 599 |   SDOperand LHSH = Select(N->getOperand(1)); | 
 | 600 |    | 
 | 601 |   unsigned Imm; | 
 | 602 |   bool ME = false, ZE = false; | 
 | 603 |   if (isIntImmediate(N->getOperand(3), Imm)) { | 
 | 604 |     ME = (signed)Imm == -1; | 
 | 605 |     ZE = Imm == 0; | 
 | 606 |   } | 
 | 607 |    | 
 | 608 |   std::vector<SDOperand> Result; | 
 | 609 |   SDOperand CarryFromLo; | 
 | 610 |   if (isIntImmediate(N->getOperand(2), Imm) && | 
 | 611 |       ((signed)Imm >= -32768 || (signed)Imm < 32768)) { | 
 | 612 |     // Codegen the low 32 bits of the add.  Interestingly, there is no | 
 | 613 |     // shifted form of add immediate carrying. | 
 | 614 |     CarryFromLo = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, | 
 | 615 |                                         LHSL, getI32Imm(Imm)); | 
 | 616 |   } else { | 
 | 617 |     CarryFromLo = CurDAG->getTargetNode(PPC::ADDC, MVT::i32, MVT::Flag, | 
 | 618 |                                         LHSL, Select(N->getOperand(2))); | 
 | 619 |   } | 
 | 620 |   CarryFromLo = CarryFromLo.getValue(1); | 
 | 621 |    | 
 | 622 |   // Codegen the high 32 bits, adding zero, minus one, or the full value | 
 | 623 |   // along with the carry flag produced by addc/addic. | 
 | 624 |   SDOperand ResultHi; | 
 | 625 |   if (ZE) | 
 | 626 |     ResultHi = CurDAG->getTargetNode(PPC::ADDZE, MVT::i32, LHSH, CarryFromLo); | 
 | 627 |   else if (ME) | 
 | 628 |     ResultHi = CurDAG->getTargetNode(PPC::ADDME, MVT::i32, LHSH, CarryFromLo); | 
 | 629 |   else | 
 | 630 |     ResultHi = CurDAG->getTargetNode(PPC::ADDE, MVT::i32, LHSH, | 
 | 631 |                                      Select(N->getOperand(3)), CarryFromLo); | 
 | 632 |   Result.push_back(CarryFromLo.getValue(0)); | 
 | 633 |   Result.push_back(ResultHi); | 
 | 634 |    | 
 | 635 |   CodeGenMap[Op.getValue(0)] = Result[0]; | 
 | 636 |   CodeGenMap[Op.getValue(1)] = Result[1]; | 
 | 637 |   return Result[Op.ResNo]; | 
 | 638 | } | 
| Nate Begeman | 1d9d742 | 2005-10-18 00:28:58 +0000 | [diff] [blame] | 639 | SDOperand PPCDAGToDAGISel::SelectSUB_PARTS(SDOperand Op) { | 
| Chris Lattner | 2b63e4c | 2005-10-06 18:56:10 +0000 | [diff] [blame] | 640 |   SDNode *N = Op.Val; | 
 | 641 |   SDOperand LHSL = Select(N->getOperand(0)); | 
 | 642 |   SDOperand LHSH = Select(N->getOperand(1)); | 
 | 643 |   SDOperand RHSL = Select(N->getOperand(2)); | 
 | 644 |   SDOperand RHSH = Select(N->getOperand(3)); | 
 | 645 |    | 
 | 646 |   std::vector<SDOperand> Result; | 
 | 647 |   Result.push_back(CurDAG->getTargetNode(PPC::SUBFC, MVT::i32, MVT::Flag, | 
 | 648 |                                          RHSL, LHSL)); | 
 | 649 |   Result.push_back(CurDAG->getTargetNode(PPC::SUBFE, MVT::i32, RHSH, LHSH, | 
 | 650 |                                          Result[0].getValue(1))); | 
 | 651 |   CodeGenMap[Op.getValue(0)] = Result[0]; | 
 | 652 |   CodeGenMap[Op.getValue(1)] = Result[1]; | 
 | 653 |   return Result[Op.ResNo]; | 
 | 654 | } | 
 | 655 |  | 
| Nate Begeman | 1d9d742 | 2005-10-18 00:28:58 +0000 | [diff] [blame] | 656 | SDOperand PPCDAGToDAGISel::SelectSETCC(SDOperand Op) { | 
| Chris Lattner | 222adac | 2005-10-06 19:03:35 +0000 | [diff] [blame] | 657 |   SDNode *N = Op.Val; | 
 | 658 |   unsigned Imm; | 
 | 659 |   ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get(); | 
 | 660 |   if (isIntImmediate(N->getOperand(1), Imm)) { | 
 | 661 |     // We can codegen setcc op, imm very efficiently compared to a brcond. | 
 | 662 |     // Check for those cases here. | 
 | 663 |     // setcc op, 0 | 
 | 664 |     if (Imm == 0) { | 
 | 665 |       SDOperand Op = Select(N->getOperand(0)); | 
 | 666 |       switch (CC) { | 
| Chris Lattner | dabb829 | 2005-10-21 21:17:10 +0000 | [diff] [blame] | 667 |       default: break; | 
 | 668 |       case ISD::SETEQ: | 
 | 669 |         Op = CurDAG->getTargetNode(PPC::CNTLZW, MVT::i32, Op); | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 670 |         return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Op, getI32Imm(27), | 
 | 671 |                                     getI32Imm(5), getI32Imm(31)); | 
| Chris Lattner | dabb829 | 2005-10-21 21:17:10 +0000 | [diff] [blame] | 672 |       case ISD::SETNE: { | 
 | 673 |         SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, | 
 | 674 |                                              Op, getI32Imm(~0U)); | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 675 |         return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op,  | 
 | 676 |                                     AD.getValue(1)); | 
| Chris Lattner | 222adac | 2005-10-06 19:03:35 +0000 | [diff] [blame] | 677 |       } | 
| Chris Lattner | dabb829 | 2005-10-21 21:17:10 +0000 | [diff] [blame] | 678 |       case ISD::SETLT: | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 679 |         return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Op, getI32Imm(1), | 
 | 680 |                                     getI32Imm(31), getI32Imm(31)); | 
| Chris Lattner | dabb829 | 2005-10-21 21:17:10 +0000 | [diff] [blame] | 681 |       case ISD::SETGT: { | 
 | 682 |         SDOperand T = CurDAG->getTargetNode(PPC::NEG, MVT::i32, Op); | 
 | 683 |         T = CurDAG->getTargetNode(PPC::ANDC, MVT::i32, T, Op);; | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 684 |         return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, T, getI32Imm(1), | 
 | 685 |                                     getI32Imm(31), getI32Imm(31)); | 
| Chris Lattner | dabb829 | 2005-10-21 21:17:10 +0000 | [diff] [blame] | 686 |       } | 
 | 687 |       } | 
| Chris Lattner | 222adac | 2005-10-06 19:03:35 +0000 | [diff] [blame] | 688 |     } else if (Imm == ~0U) {        // setcc op, -1 | 
 | 689 |       SDOperand Op = Select(N->getOperand(0)); | 
 | 690 |       switch (CC) { | 
| Chris Lattner | dabb829 | 2005-10-21 21:17:10 +0000 | [diff] [blame] | 691 |       default: break; | 
 | 692 |       case ISD::SETEQ: | 
 | 693 |         Op = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, | 
 | 694 |                                    Op, getI32Imm(1)); | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 695 |         return CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32,  | 
 | 696 |                                     CurDAG->getTargetNode(PPC::LI, MVT::i32, | 
 | 697 |                                                           getI32Imm(0)), | 
 | 698 |                                     Op.getValue(1)); | 
| Chris Lattner | dabb829 | 2005-10-21 21:17:10 +0000 | [diff] [blame] | 699 |       case ISD::SETNE: { | 
 | 700 |         Op = CurDAG->getTargetNode(PPC::NOR, MVT::i32, Op, Op); | 
 | 701 |         SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, | 
 | 702 |                                              Op, getI32Imm(~0U)); | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 703 |         return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op,  | 
 | 704 |                                     AD.getValue(1)); | 
| Chris Lattner | 222adac | 2005-10-06 19:03:35 +0000 | [diff] [blame] | 705 |       } | 
| Chris Lattner | dabb829 | 2005-10-21 21:17:10 +0000 | [diff] [blame] | 706 |       case ISD::SETLT: { | 
 | 707 |         SDOperand AD = CurDAG->getTargetNode(PPC::ADDI, MVT::i32, Op, | 
 | 708 |                                              getI32Imm(1)); | 
 | 709 |         SDOperand AN = CurDAG->getTargetNode(PPC::AND, MVT::i32, AD, Op); | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 710 |         return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, AN, getI32Imm(1), | 
 | 711 |                                     getI32Imm(31), getI32Imm(31)); | 
| Chris Lattner | dabb829 | 2005-10-21 21:17:10 +0000 | [diff] [blame] | 712 |       } | 
 | 713 |       case ISD::SETGT: | 
 | 714 |         Op = CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, Op, getI32Imm(1), | 
 | 715 |                                    getI32Imm(31), getI32Imm(31)); | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 716 |         return CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Op, getI32Imm(1)); | 
| Chris Lattner | dabb829 | 2005-10-21 21:17:10 +0000 | [diff] [blame] | 717 |       } | 
| Chris Lattner | 222adac | 2005-10-06 19:03:35 +0000 | [diff] [blame] | 718 |     } | 
 | 719 |   } | 
 | 720 |    | 
 | 721 |   bool Inv; | 
 | 722 |   unsigned Idx = getCRIdxForSetCC(CC, Inv); | 
 | 723 |   SDOperand CCReg = SelectCC(N->getOperand(0), N->getOperand(1), CC); | 
 | 724 |   SDOperand IntCR; | 
 | 725 |    | 
 | 726 |   // Force the ccreg into CR7. | 
 | 727 |   SDOperand CR7Reg = CurDAG->getRegister(PPC::CR7, MVT::i32); | 
 | 728 |    | 
| Chris Lattner | 85961d5 | 2005-12-06 20:56:18 +0000 | [diff] [blame] | 729 |   SDOperand InFlag(0, 0);  // Null incoming flag value. | 
| Chris Lattner | db1cb2b | 2005-12-01 03:50:19 +0000 | [diff] [blame] | 730 |   CCReg = CurDAG->getCopyToReg(CurDAG->getEntryNode(), CR7Reg, CCReg,  | 
 | 731 |                                InFlag).getValue(1); | 
| Chris Lattner | 222adac | 2005-10-06 19:03:35 +0000 | [diff] [blame] | 732 |    | 
 | 733 |   if (TLI.getTargetMachine().getSubtarget<PPCSubtarget>().isGigaProcessor()) | 
 | 734 |     IntCR = CurDAG->getTargetNode(PPC::MFOCRF, MVT::i32, CR7Reg, CCReg); | 
 | 735 |   else | 
 | 736 |     IntCR = CurDAG->getTargetNode(PPC::MFCR, MVT::i32, CCReg); | 
 | 737 |    | 
 | 738 |   if (!Inv) { | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 739 |     return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, IntCR, | 
 | 740 |                                 getI32Imm((32-(3-Idx)) & 31), | 
 | 741 |                                 getI32Imm(31), getI32Imm(31)); | 
| Chris Lattner | 222adac | 2005-10-06 19:03:35 +0000 | [diff] [blame] | 742 |   } else { | 
 | 743 |     SDOperand Tmp = | 
 | 744 |     CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, IntCR, | 
| Chris Lattner | 7d7b967 | 2005-10-28 22:58:07 +0000 | [diff] [blame] | 745 |                           getI32Imm((32-(3-Idx)) & 31), | 
 | 746 |                           getI32Imm(31),getI32Imm(31)); | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 747 |     return CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Tmp, getI32Imm(1)); | 
| Chris Lattner | 222adac | 2005-10-06 19:03:35 +0000 | [diff] [blame] | 748 |   } | 
| Chris Lattner | 222adac | 2005-10-06 19:03:35 +0000 | [diff] [blame] | 749 | } | 
| Chris Lattner | 2b63e4c | 2005-10-06 18:56:10 +0000 | [diff] [blame] | 750 |  | 
| Nate Begeman | 422b0ce | 2005-11-16 00:48:01 +0000 | [diff] [blame] | 751 | /// isCallCompatibleAddress - Return true if the specified 32-bit value is | 
 | 752 | /// representable in the immediate field of a Bx instruction. | 
 | 753 | static bool isCallCompatibleAddress(ConstantSDNode *C) { | 
 | 754 |   int Addr = C->getValue(); | 
 | 755 |   if (Addr & 3) return false;  // Low 2 bits are implicitly zero. | 
 | 756 |   return (Addr << 6 >> 6) == Addr;  // Top 6 bits have to be sext of immediate. | 
 | 757 | } | 
 | 758 |  | 
| Nate Begeman | 1d9d742 | 2005-10-18 00:28:58 +0000 | [diff] [blame] | 759 | SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) { | 
| Chris Lattner | 6a16f6a | 2005-10-06 19:07:45 +0000 | [diff] [blame] | 760 |   SDNode *N = Op.Val; | 
 | 761 |   SDOperand Chain = Select(N->getOperand(0)); | 
 | 762 |    | 
 | 763 |   unsigned CallOpcode; | 
 | 764 |   std::vector<SDOperand> CallOperands; | 
 | 765 |    | 
 | 766 |   if (GlobalAddressSDNode *GASD = | 
 | 767 |       dyn_cast<GlobalAddressSDNode>(N->getOperand(1))) { | 
| Nate Begeman | 422b0ce | 2005-11-16 00:48:01 +0000 | [diff] [blame] | 768 |     CallOpcode = PPC::BL; | 
| Chris Lattner | 2823b3e | 2005-11-17 05:56:14 +0000 | [diff] [blame] | 769 |     CallOperands.push_back(N->getOperand(1)); | 
| Chris Lattner | 6a16f6a | 2005-10-06 19:07:45 +0000 | [diff] [blame] | 770 |   } else if (ExternalSymbolSDNode *ESSDN = | 
 | 771 |              dyn_cast<ExternalSymbolSDNode>(N->getOperand(1))) { | 
| Nate Begeman | 422b0ce | 2005-11-16 00:48:01 +0000 | [diff] [blame] | 772 |     CallOpcode = PPC::BL; | 
| Chris Lattner | 6a16f6a | 2005-10-06 19:07:45 +0000 | [diff] [blame] | 773 |     CallOperands.push_back(N->getOperand(1)); | 
| Nate Begeman | 422b0ce | 2005-11-16 00:48:01 +0000 | [diff] [blame] | 774 |   } else if (isa<ConstantSDNode>(N->getOperand(1)) && | 
 | 775 |              isCallCompatibleAddress(cast<ConstantSDNode>(N->getOperand(1)))) { | 
 | 776 |     ConstantSDNode *C = cast<ConstantSDNode>(N->getOperand(1)); | 
 | 777 |     CallOpcode = PPC::BLA; | 
 | 778 |     CallOperands.push_back(getI32Imm((int)C->getValue() >> 2)); | 
| Chris Lattner | 6a16f6a | 2005-10-06 19:07:45 +0000 | [diff] [blame] | 779 |   } else { | 
 | 780 |     // Copy the callee address into the CTR register. | 
 | 781 |     SDOperand Callee = Select(N->getOperand(1)); | 
 | 782 |     Chain = CurDAG->getTargetNode(PPC::MTCTR, MVT::Other, Callee, Chain); | 
 | 783 |      | 
 | 784 |     // Copy the callee address into R12 on darwin. | 
 | 785 |     SDOperand R12 = CurDAG->getRegister(PPC::R12, MVT::i32); | 
 | 786 |     Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, R12, Callee); | 
| Nate Begeman | 422b0ce | 2005-11-16 00:48:01 +0000 | [diff] [blame] | 787 |  | 
| Chris Lattner | 6a16f6a | 2005-10-06 19:07:45 +0000 | [diff] [blame] | 788 |     CallOperands.push_back(R12); | 
| Nate Begeman | 422b0ce | 2005-11-16 00:48:01 +0000 | [diff] [blame] | 789 |     CallOpcode = PPC::BCTRL; | 
| Chris Lattner | 6a16f6a | 2005-10-06 19:07:45 +0000 | [diff] [blame] | 790 |   } | 
 | 791 |    | 
 | 792 |   unsigned GPR_idx = 0, FPR_idx = 0; | 
 | 793 |   static const unsigned GPR[] = { | 
 | 794 |     PPC::R3, PPC::R4, PPC::R5, PPC::R6, | 
 | 795 |     PPC::R7, PPC::R8, PPC::R9, PPC::R10, | 
 | 796 |   }; | 
 | 797 |   static const unsigned FPR[] = { | 
 | 798 |     PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, | 
 | 799 |     PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 | 
 | 800 |   }; | 
 | 801 |    | 
 | 802 |   SDOperand InFlag;  // Null incoming flag value. | 
 | 803 |    | 
 | 804 |   for (unsigned i = 2, e = N->getNumOperands(); i != e; ++i) { | 
 | 805 |     unsigned DestReg = 0; | 
 | 806 |     MVT::ValueType RegTy = N->getOperand(i).getValueType(); | 
 | 807 |     if (RegTy == MVT::i32) { | 
 | 808 |       assert(GPR_idx < 8 && "Too many int args"); | 
 | 809 |       DestReg = GPR[GPR_idx++]; | 
 | 810 |     } else { | 
 | 811 |       assert(MVT::isFloatingPoint(N->getOperand(i).getValueType()) && | 
 | 812 |              "Unpromoted integer arg?"); | 
 | 813 |       assert(FPR_idx < 13 && "Too many fp args"); | 
 | 814 |       DestReg = FPR[FPR_idx++]; | 
 | 815 |     } | 
 | 816 |      | 
 | 817 |     if (N->getOperand(i).getOpcode() != ISD::UNDEF) { | 
 | 818 |       SDOperand Val = Select(N->getOperand(i)); | 
 | 819 |       Chain = CurDAG->getCopyToReg(Chain, DestReg, Val, InFlag); | 
 | 820 |       InFlag = Chain.getValue(1); | 
 | 821 |       CallOperands.push_back(CurDAG->getRegister(DestReg, RegTy)); | 
 | 822 |     } | 
 | 823 |   } | 
 | 824 |    | 
 | 825 |   // Finally, once everything is in registers to pass to the call, emit the | 
 | 826 |   // call itself. | 
 | 827 |   if (InFlag.Val) | 
 | 828 |     CallOperands.push_back(InFlag);   // Strong dep on register copies. | 
 | 829 |   else | 
 | 830 |     CallOperands.push_back(Chain);    // Weak dep on whatever occurs before | 
 | 831 |   Chain = CurDAG->getTargetNode(CallOpcode, MVT::Other, MVT::Flag, | 
 | 832 |                                 CallOperands); | 
 | 833 |    | 
 | 834 |   std::vector<SDOperand> CallResults; | 
 | 835 |    | 
 | 836 |   // If the call has results, copy the values out of the ret val registers. | 
 | 837 |   switch (N->getValueType(0)) { | 
 | 838 |     default: assert(0 && "Unexpected ret value!"); | 
 | 839 |     case MVT::Other: break; | 
 | 840 |     case MVT::i32: | 
 | 841 |       if (N->getValueType(1) == MVT::i32) { | 
 | 842 |         Chain = CurDAG->getCopyFromReg(Chain, PPC::R4, MVT::i32,  | 
 | 843 |                                        Chain.getValue(1)).getValue(1); | 
 | 844 |         CallResults.push_back(Chain.getValue(0)); | 
 | 845 |         Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32, | 
 | 846 |                                        Chain.getValue(2)).getValue(1); | 
 | 847 |         CallResults.push_back(Chain.getValue(0)); | 
 | 848 |       } else { | 
 | 849 |         Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32, | 
 | 850 |                                        Chain.getValue(1)).getValue(1); | 
 | 851 |         CallResults.push_back(Chain.getValue(0)); | 
 | 852 |       } | 
 | 853 |       break; | 
 | 854 |     case MVT::f32: | 
 | 855 |     case MVT::f64: | 
 | 856 |       Chain = CurDAG->getCopyFromReg(Chain, PPC::F1, N->getValueType(0), | 
 | 857 |                                      Chain.getValue(1)).getValue(1); | 
 | 858 |       CallResults.push_back(Chain.getValue(0)); | 
 | 859 |       break; | 
 | 860 |   } | 
 | 861 |    | 
 | 862 |   CallResults.push_back(Chain); | 
 | 863 |   for (unsigned i = 0, e = CallResults.size(); i != e; ++i) | 
 | 864 |     CodeGenMap[Op.getValue(i)] = CallResults[i]; | 
 | 865 |   return CallResults[Op.ResNo]; | 
 | 866 | } | 
 | 867 |  | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 868 | // Select - Convert the specified operand from a target-independent to a | 
 | 869 | // target-specific node if it hasn't already been changed. | 
| Nate Begeman | 1d9d742 | 2005-10-18 00:28:58 +0000 | [diff] [blame] | 870 | SDOperand PPCDAGToDAGISel::Select(SDOperand Op) { | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 871 |   SDNode *N = Op.Val; | 
| Chris Lattner | 0bbea95 | 2005-08-26 20:25:03 +0000 | [diff] [blame] | 872 |   if (N->getOpcode() >= ISD::BUILTIN_OP_END && | 
 | 873 |       N->getOpcode() < PPCISD::FIRST_NUMBER) | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 874 |     return Op;   // Already selected. | 
| Chris Lattner | d3d2cf5 | 2005-09-29 00:59:32 +0000 | [diff] [blame] | 875 |  | 
 | 876 |   // If this has already been converted, use it. | 
 | 877 |   std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op); | 
 | 878 |   if (CGMI != CodeGenMap.end()) return CGMI->second; | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 879 |    | 
 | 880 |   switch (N->getOpcode()) { | 
| Chris Lattner | 19c0907 | 2005-09-07 23:45:15 +0000 | [diff] [blame] | 881 |   default: break; | 
| Chris Lattner | 222adac | 2005-10-06 19:03:35 +0000 | [diff] [blame] | 882 |   case ISD::DYNAMIC_STACKALLOC: return SelectDYNAMIC_STACKALLOC(Op); | 
 | 883 |   case ISD::ADD_PARTS:          return SelectADD_PARTS(Op); | 
 | 884 |   case ISD::SUB_PARTS:          return SelectSUB_PARTS(Op); | 
 | 885 |   case ISD::SETCC:              return SelectSETCC(Op); | 
| Chris Lattner | 6a16f6a | 2005-10-06 19:07:45 +0000 | [diff] [blame] | 886 |   case ISD::CALL:               return SelectCALL(Op); | 
 | 887 |   case ISD::TAILCALL:           return SelectCALL(Op); | 
| Chris Lattner | 860e886 | 2005-11-17 07:30:41 +0000 | [diff] [blame] | 888 |   case PPCISD::GlobalBaseReg:   return getGlobalBaseReg(); | 
 | 889 |      | 
| Chris Lattner | e28e40a | 2005-08-25 00:45:43 +0000 | [diff] [blame] | 890 |   case ISD::FrameIndex: { | 
 | 891 |     int FI = cast<FrameIndexSDNode>(N)->getIndex(); | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 892 |     if (N->hasOneUse()) | 
 | 893 |       return CurDAG->SelectNodeTo(N, PPC::ADDI, MVT::i32, | 
 | 894 |                                   CurDAG->getTargetFrameIndex(FI, MVT::i32), | 
 | 895 |                                   getI32Imm(0)); | 
| Chris Lattner | 05f56a5 | 2005-12-01 18:09:22 +0000 | [diff] [blame] | 896 |     return CodeGenMap[Op] =  | 
 | 897 |       CurDAG->getTargetNode(PPC::ADDI, MVT::i32, | 
 | 898 |                             CurDAG->getTargetFrameIndex(FI, MVT::i32), | 
 | 899 |                             getI32Imm(0)); | 
| Chris Lattner | e28e40a | 2005-08-25 00:45:43 +0000 | [diff] [blame] | 900 |   } | 
| Chris Lattner | 88add10 | 2005-09-28 22:50:24 +0000 | [diff] [blame] | 901 |   case ISD::SDIV: { | 
| Nate Begeman | 405e3ec | 2005-10-21 00:02:42 +0000 | [diff] [blame] | 902 |     // FIXME: since this depends on the setting of the carry flag from the srawi | 
 | 903 |     //        we should really be making notes about that for the scheduler. | 
 | 904 |     // FIXME: It sure would be nice if we could cheaply recognize the  | 
 | 905 |     //        srl/add/sra pattern the dag combiner will generate for this as | 
 | 906 |     //        sra/addze rather than having to handle sdiv ourselves.  oh well. | 
| Chris Lattner | 8784a23 | 2005-08-25 17:50:06 +0000 | [diff] [blame] | 907 |     unsigned Imm; | 
 | 908 |     if (isIntImmediate(N->getOperand(1), Imm)) { | 
 | 909 |       if ((signed)Imm > 0 && isPowerOf2_32(Imm)) { | 
 | 910 |         SDOperand Op = | 
 | 911 |           CurDAG->getTargetNode(PPC::SRAWI, MVT::i32, MVT::Flag, | 
 | 912 |                                 Select(N->getOperand(0)), | 
 | 913 |                                 getI32Imm(Log2_32(Imm))); | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 914 |         return CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32,  | 
 | 915 |                                     Op.getValue(0), Op.getValue(1)); | 
| Chris Lattner | 8784a23 | 2005-08-25 17:50:06 +0000 | [diff] [blame] | 916 |       } else if ((signed)Imm < 0 && isPowerOf2_32(-Imm)) { | 
 | 917 |         SDOperand Op = | 
| Chris Lattner | 2501d5e | 2005-08-30 17:13:58 +0000 | [diff] [blame] | 918 |           CurDAG->getTargetNode(PPC::SRAWI, MVT::i32, MVT::Flag, | 
| Chris Lattner | 8784a23 | 2005-08-25 17:50:06 +0000 | [diff] [blame] | 919 |                                 Select(N->getOperand(0)), | 
 | 920 |                                 getI32Imm(Log2_32(-Imm))); | 
 | 921 |         SDOperand PT = | 
| Chris Lattner | 2501d5e | 2005-08-30 17:13:58 +0000 | [diff] [blame] | 922 |           CurDAG->getTargetNode(PPC::ADDZE, MVT::i32, Op.getValue(0), | 
 | 923 |                                 Op.getValue(1)); | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 924 |         return CurDAG->SelectNodeTo(N, PPC::NEG, MVT::i32, PT); | 
| Chris Lattner | 8784a23 | 2005-08-25 17:50:06 +0000 | [diff] [blame] | 925 |       } | 
 | 926 |     } | 
| Chris Lattner | 047b952 | 2005-08-25 22:04:30 +0000 | [diff] [blame] | 927 |      | 
| Chris Lattner | 237733e | 2005-09-29 23:33:31 +0000 | [diff] [blame] | 928 |     // Other cases are autogenerated. | 
 | 929 |     break; | 
| Chris Lattner | 047b952 | 2005-08-25 22:04:30 +0000 | [diff] [blame] | 930 |   } | 
| Nate Begeman | cffc32b | 2005-08-18 07:30:46 +0000 | [diff] [blame] | 931 |   case ISD::AND: { | 
| Nate Begeman | a694047 | 2005-08-18 18:01:39 +0000 | [diff] [blame] | 932 |     unsigned Imm; | 
| Nate Begeman | cffc32b | 2005-08-18 07:30:46 +0000 | [diff] [blame] | 933 |     // If this is an and of a value rotated between 0 and 31 bits and then and'd | 
 | 934 |     // with a mask, emit rlwinm | 
 | 935 |     if (isIntImmediate(N->getOperand(1), Imm) && (isShiftedMask_32(Imm) || | 
 | 936 |                                                   isShiftedMask_32(~Imm))) { | 
 | 937 |       SDOperand Val; | 
| Nate Begeman | a694047 | 2005-08-18 18:01:39 +0000 | [diff] [blame] | 938 |       unsigned SH, MB, ME; | 
| Nate Begeman | cffc32b | 2005-08-18 07:30:46 +0000 | [diff] [blame] | 939 |       if (isRotateAndMask(N->getOperand(0).Val, Imm, false, SH, MB, ME)) { | 
 | 940 |         Val = Select(N->getOperand(0).getOperand(0)); | 
| Chris Lattner | 3393e80 | 2005-10-25 19:32:37 +0000 | [diff] [blame] | 941 |       } else if (Imm == 0) { | 
 | 942 |         // AND X, 0 -> 0, not "rlwinm 32". | 
 | 943 |         return Select(N->getOperand(1)); | 
 | 944 |       } else {         | 
| Nate Begeman | cffc32b | 2005-08-18 07:30:46 +0000 | [diff] [blame] | 945 |         Val = Select(N->getOperand(0)); | 
 | 946 |         isRunOfOnes(Imm, MB, ME); | 
 | 947 |         SH = 0; | 
 | 948 |       } | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 949 |       return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Val, getI32Imm(SH), | 
 | 950 |                                   getI32Imm(MB), getI32Imm(ME)); | 
| Nate Begeman | cffc32b | 2005-08-18 07:30:46 +0000 | [diff] [blame] | 951 |     } | 
| Chris Lattner | 237733e | 2005-09-29 23:33:31 +0000 | [diff] [blame] | 952 |      | 
 | 953 |     // Other cases are autogenerated. | 
 | 954 |     break; | 
| Nate Begeman | cffc32b | 2005-08-18 07:30:46 +0000 | [diff] [blame] | 955 |   } | 
| Nate Begeman | 02b88a4 | 2005-08-19 00:38:14 +0000 | [diff] [blame] | 956 |   case ISD::OR: | 
| Chris Lattner | d3d2cf5 | 2005-09-29 00:59:32 +0000 | [diff] [blame] | 957 |     if (SDNode *I = SelectBitfieldInsert(N)) | 
 | 958 |       return CodeGenMap[Op] = SDOperand(I, 0); | 
| Chris Lattner | d3d2cf5 | 2005-09-29 00:59:32 +0000 | [diff] [blame] | 959 |        | 
| Chris Lattner | 237733e | 2005-09-29 23:33:31 +0000 | [diff] [blame] | 960 |     // Other cases are autogenerated. | 
 | 961 |     break; | 
| Nate Begeman | c15ed44 | 2005-08-18 23:38:00 +0000 | [diff] [blame] | 962 |   case ISD::SHL: { | 
 | 963 |     unsigned Imm, SH, MB, ME; | 
 | 964 |     if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) && | 
| Nate Begeman | 2d5aff7 | 2005-10-19 18:42:01 +0000 | [diff] [blame] | 965 |         isRotateAndMask(N, Imm, true, SH, MB, ME)) { | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 966 |       return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32,  | 
 | 967 |                                   Select(N->getOperand(0).getOperand(0)), | 
 | 968 |                                   getI32Imm(SH), getI32Imm(MB), getI32Imm(ME)); | 
| Nate Begeman | 8d94832 | 2005-10-19 01:12:32 +0000 | [diff] [blame] | 969 |     } | 
| Nate Begeman | 2d5aff7 | 2005-10-19 18:42:01 +0000 | [diff] [blame] | 970 |      | 
 | 971 |     // Other cases are autogenerated. | 
 | 972 |     break; | 
| Nate Begeman | c15ed44 | 2005-08-18 23:38:00 +0000 | [diff] [blame] | 973 |   } | 
 | 974 |   case ISD::SRL: { | 
 | 975 |     unsigned Imm, SH, MB, ME; | 
 | 976 |     if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) && | 
| Nate Begeman | 2d5aff7 | 2005-10-19 18:42:01 +0000 | [diff] [blame] | 977 |         isRotateAndMask(N, Imm, true, SH, MB, ME)) {  | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 978 |       return CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32,  | 
 | 979 |                                   Select(N->getOperand(0).getOperand(0)), | 
 | 980 |                                   getI32Imm(SH & 0x1F), getI32Imm(MB), | 
 | 981 |                                   getI32Imm(ME)); | 
| Nate Begeman | 8d94832 | 2005-10-19 01:12:32 +0000 | [diff] [blame] | 982 |     } | 
| Nate Begeman | 2d5aff7 | 2005-10-19 18:42:01 +0000 | [diff] [blame] | 983 |      | 
 | 984 |     // Other cases are autogenerated. | 
 | 985 |     break; | 
| Nate Begeman | c15ed44 | 2005-08-18 23:38:00 +0000 | [diff] [blame] | 986 |   } | 
| Nate Begeman | 2665350 | 2005-08-17 23:46:35 +0000 | [diff] [blame] | 987 |   case ISD::FNEG: { | 
 | 988 |     SDOperand Val = Select(N->getOperand(0)); | 
 | 989 |     MVT::ValueType Ty = N->getValueType(0); | 
| Chris Lattner | 4cb5a1b | 2005-10-15 22:06:18 +0000 | [diff] [blame] | 990 |     if (N->getOperand(0).Val->hasOneUse()) { | 
| Nate Begeman | 2665350 | 2005-08-17 23:46:35 +0000 | [diff] [blame] | 991 |       unsigned Opc; | 
| Chris Lattner | 528f58e | 2005-08-28 23:39:22 +0000 | [diff] [blame] | 992 |       switch (Val.isTargetOpcode() ? Val.getTargetOpcode() : 0) { | 
| Nate Begeman | 2665350 | 2005-08-17 23:46:35 +0000 | [diff] [blame] | 993 |       default:          Opc = 0;            break; | 
| Chris Lattner | 919c032 | 2005-10-01 01:35:02 +0000 | [diff] [blame] | 994 |       case PPC::FABSS:  Opc = PPC::FNABSS;  break; | 
 | 995 |       case PPC::FABSD:  Opc = PPC::FNABSD;  break; | 
| Nate Begeman | 2665350 | 2005-08-17 23:46:35 +0000 | [diff] [blame] | 996 |       case PPC::FMADD:  Opc = PPC::FNMADD;  break; | 
 | 997 |       case PPC::FMADDS: Opc = PPC::FNMADDS; break; | 
 | 998 |       case PPC::FMSUB:  Opc = PPC::FNMSUB;  break; | 
 | 999 |       case PPC::FMSUBS: Opc = PPC::FNMSUBS; break; | 
 | 1000 |       } | 
 | 1001 |       // If we inverted the opcode, then emit the new instruction with the | 
 | 1002 |       // inverted opcode and the original instruction's operands.  Otherwise,  | 
 | 1003 |       // fall through and generate a fneg instruction. | 
 | 1004 |       if (Opc) { | 
| Chris Lattner | 919c032 | 2005-10-01 01:35:02 +0000 | [diff] [blame] | 1005 |         if (Opc == PPC::FNABSS || Opc == PPC::FNABSD) | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 1006 |           return CurDAG->SelectNodeTo(N, Opc, Ty, Val.getOperand(0)); | 
| Nate Begeman | 2665350 | 2005-08-17 23:46:35 +0000 | [diff] [blame] | 1007 |         else | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 1008 |           return CurDAG->SelectNodeTo(N, Opc, Ty, Val.getOperand(0), | 
 | 1009 |                                       Val.getOperand(1), Val.getOperand(2)); | 
| Nate Begeman | 2665350 | 2005-08-17 23:46:35 +0000 | [diff] [blame] | 1010 |       } | 
 | 1011 |     } | 
| Chris Lattner | bead661 | 2005-12-04 19:04:38 +0000 | [diff] [blame] | 1012 |     // Other cases are autogenerated. | 
 | 1013 |     break; | 
| Nate Begeman | 2665350 | 2005-08-17 23:46:35 +0000 | [diff] [blame] | 1014 |   } | 
| Chris Lattner | 13794f5 | 2005-08-26 18:46:49 +0000 | [diff] [blame] | 1015 |   case ISD::SELECT_CC: { | 
 | 1016 |     ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(4))->get(); | 
 | 1017 |      | 
 | 1018 |     // handle the setcc cases here.  select_cc lhs, 0, 1, 0, cc | 
 | 1019 |     if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1))) | 
 | 1020 |       if (ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N->getOperand(2))) | 
 | 1021 |         if (ConstantSDNode *N3C = dyn_cast<ConstantSDNode>(N->getOperand(3))) | 
 | 1022 |           if (N1C->isNullValue() && N3C->isNullValue() && | 
 | 1023 |               N2C->getValue() == 1ULL && CC == ISD::SETNE) { | 
 | 1024 |             SDOperand LHS = Select(N->getOperand(0)); | 
 | 1025 |             SDOperand Tmp = | 
 | 1026 |               CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, | 
 | 1027 |                                     LHS, getI32Imm(~0U)); | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 1028 |             return CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, Tmp, LHS, | 
 | 1029 |                                         Tmp.getValue(1)); | 
| Chris Lattner | 13794f5 | 2005-08-26 18:46:49 +0000 | [diff] [blame] | 1030 |           } | 
| Chris Lattner | 8a2d3ca | 2005-08-26 21:23:58 +0000 | [diff] [blame] | 1031 |  | 
| Chris Lattner | 50ff55c | 2005-09-01 19:20:44 +0000 | [diff] [blame] | 1032 |     SDOperand CCReg = SelectCC(N->getOperand(0), N->getOperand(1), CC); | 
| Chris Lattner | 8a2d3ca | 2005-08-26 21:23:58 +0000 | [diff] [blame] | 1033 |     unsigned BROpc = getBCCForSetCC(CC); | 
 | 1034 |  | 
 | 1035 |     bool isFP = MVT::isFloatingPoint(N->getValueType(0)); | 
| Chris Lattner | 919c032 | 2005-10-01 01:35:02 +0000 | [diff] [blame] | 1036 |     unsigned SelectCCOp; | 
 | 1037 |     if (MVT::isInteger(N->getValueType(0))) | 
 | 1038 |       SelectCCOp = PPC::SELECT_CC_Int; | 
 | 1039 |     else if (N->getValueType(0) == MVT::f32) | 
 | 1040 |       SelectCCOp = PPC::SELECT_CC_F4; | 
 | 1041 |     else | 
 | 1042 |       SelectCCOp = PPC::SELECT_CC_F8; | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 1043 |     return CurDAG->SelectNodeTo(N, SelectCCOp, N->getValueType(0), CCReg, | 
 | 1044 |                                 Select(N->getOperand(2)),  | 
 | 1045 |                                 Select(N->getOperand(3)), | 
 | 1046 |                                 getI32Imm(BROpc)); | 
| Chris Lattner | 13794f5 | 2005-08-26 18:46:49 +0000 | [diff] [blame] | 1047 |   } | 
 | 1048 |      | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 1049 |   case ISD::RET: { | 
 | 1050 |     SDOperand Chain = Select(N->getOperand(0));     // Token chain. | 
 | 1051 |  | 
| Chris Lattner | 7a49fdc | 2005-08-31 01:34:29 +0000 | [diff] [blame] | 1052 |     if (N->getNumOperands() == 2) { | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 1053 |       SDOperand Val = Select(N->getOperand(1)); | 
| Chris Lattner | eb80fe8 | 2005-08-30 22:59:48 +0000 | [diff] [blame] | 1054 |       if (N->getOperand(1).getValueType() == MVT::i32) { | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 1055 |         Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Val); | 
| Chris Lattner | eb80fe8 | 2005-08-30 22:59:48 +0000 | [diff] [blame] | 1056 |       } else { | 
 | 1057 |         assert(MVT::isFloatingPoint(N->getOperand(1).getValueType())); | 
 | 1058 |         Chain = CurDAG->getCopyToReg(Chain, PPC::F1, Val); | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 1059 |       } | 
| Chris Lattner | 7a49fdc | 2005-08-31 01:34:29 +0000 | [diff] [blame] | 1060 |     } else if (N->getNumOperands() > 1) { | 
 | 1061 |       assert(N->getOperand(1).getValueType() == MVT::i32 && | 
 | 1062 |              N->getOperand(2).getValueType() == MVT::i32 && | 
 | 1063 |              N->getNumOperands() == 3 && "Unknown two-register ret value!"); | 
 | 1064 |       Chain = CurDAG->getCopyToReg(Chain, PPC::R4, Select(N->getOperand(1))); | 
 | 1065 |       Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Select(N->getOperand(2))); | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 1066 |     } | 
 | 1067 |  | 
 | 1068 |     // Finally, select this to a blr (return) instruction. | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 1069 |     return CurDAG->SelectNodeTo(N, PPC::BLR, MVT::Other, Chain); | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 1070 |   } | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 1071 |   case ISD::BR_CC: | 
 | 1072 |   case ISD::BRTWOWAY_CC: { | 
 | 1073 |     SDOperand Chain = Select(N->getOperand(0)); | 
 | 1074 |     MachineBasicBlock *Dest = | 
 | 1075 |       cast<BasicBlockSDNode>(N->getOperand(4))->getBasicBlock(); | 
 | 1076 |     ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get(); | 
 | 1077 |     SDOperand CondCode = SelectCC(N->getOperand(2), N->getOperand(3), CC); | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 1078 |  | 
 | 1079 |     // If this is a two way branch, then grab the fallthrough basic block | 
 | 1080 |     // argument and build a PowerPC branch pseudo-op, suitable for long branch | 
 | 1081 |     // conversion if necessary by the branch selection pass.  Otherwise, emit a | 
 | 1082 |     // standard conditional branch. | 
 | 1083 |     if (N->getOpcode() == ISD::BRTWOWAY_CC) { | 
| Chris Lattner | ca0a477 | 2005-10-01 23:06:26 +0000 | [diff] [blame] | 1084 |       SDOperand CondTrueBlock = N->getOperand(4); | 
 | 1085 |       SDOperand CondFalseBlock = N->getOperand(5); | 
 | 1086 |        | 
 | 1087 |       // If the false case is the current basic block, then this is a self loop. | 
 | 1088 |       // We do not want to emit "Loop: ... brcond Out; br Loop", as it adds an | 
 | 1089 |       // extra dispatch group to the loop.  Instead, invert the condition and | 
 | 1090 |       // emit "Loop: ... br!cond Loop; br Out | 
 | 1091 |       if (cast<BasicBlockSDNode>(CondFalseBlock)->getBasicBlock() == BB) { | 
 | 1092 |         std::swap(CondTrueBlock, CondFalseBlock); | 
 | 1093 |         CC = getSetCCInverse(CC, | 
 | 1094 |                              MVT::isInteger(N->getOperand(2).getValueType())); | 
 | 1095 |       } | 
 | 1096 |        | 
 | 1097 |       unsigned Opc = getBCCForSetCC(CC); | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 1098 |       SDOperand CB = CurDAG->getTargetNode(PPC::COND_BRANCH, MVT::Other, | 
 | 1099 |                                            CondCode, getI32Imm(Opc), | 
| Chris Lattner | ca0a477 | 2005-10-01 23:06:26 +0000 | [diff] [blame] | 1100 |                                            CondTrueBlock, CondFalseBlock, | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 1101 |                                            Chain); | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 1102 |       return CurDAG->SelectNodeTo(N, PPC::B, MVT::Other, CondFalseBlock, CB); | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 1103 |     } else { | 
 | 1104 |       // Iterate to the next basic block | 
 | 1105 |       ilist<MachineBasicBlock>::iterator It = BB; | 
 | 1106 |       ++It; | 
 | 1107 |  | 
 | 1108 |       // If the fallthrough path is off the end of the function, which would be | 
 | 1109 |       // undefined behavior, set it to be the same as the current block because | 
 | 1110 |       // we have nothing better to set it to, and leaving it alone will cause | 
 | 1111 |       // the PowerPC Branch Selection pass to crash. | 
 | 1112 |       if (It == BB->getParent()->end()) It = Dest; | 
| Chris Lattner | 71d3d50 | 2005-11-30 22:53:06 +0000 | [diff] [blame] | 1113 |       return CurDAG->SelectNodeTo(N, PPC::COND_BRANCH, MVT::Other, CondCode, | 
 | 1114 |                                   getI32Imm(getBCCForSetCC(CC)),  | 
 | 1115 |                                   N->getOperand(4), CurDAG->getBasicBlock(It),  | 
 | 1116 |                                   Chain); | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 1117 |     } | 
| Chris Lattner | 2fbb457 | 2005-08-21 18:50:37 +0000 | [diff] [blame] | 1118 |   } | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 1119 |   } | 
| Chris Lattner | 25dae72 | 2005-09-03 00:53:47 +0000 | [diff] [blame] | 1120 |    | 
| Chris Lattner | 19c0907 | 2005-09-07 23:45:15 +0000 | [diff] [blame] | 1121 |   return SelectCode(Op); | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 1122 | } | 
 | 1123 |  | 
 | 1124 |  | 
| Nate Begeman | 1d9d742 | 2005-10-18 00:28:58 +0000 | [diff] [blame] | 1125 | /// createPPCISelDag - This pass converts a legalized DAG into a  | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 1126 | /// PowerPC-specific DAG, ready for instruction scheduling. | 
 | 1127 | /// | 
| Nate Begeman | 1d9d742 | 2005-10-18 00:28:58 +0000 | [diff] [blame] | 1128 | FunctionPass *llvm::createPPCISelDag(TargetMachine &TM) { | 
 | 1129 |   return new PPCDAGToDAGISel(TM); | 
| Chris Lattner | a5a91b1 | 2005-08-17 19:33:03 +0000 | [diff] [blame] | 1130 | } | 
 | 1131 |  |