blob: 536a07710defdb84a00a2896dbe6e1dabcf1c8f9 [file] [log] [blame]
Nate Begemana9795f82005-03-24 04:41:43 +00001//===-- PPC32ISelPattern.cpp - A pattern matching inst selector for PPC32 -===//
2//
3// The LLVM Compiler Infrastructure
4//
Nate Begeman5e966612005-03-24 06:28:42 +00005// This file was developed by Nate Begeman and is distributed under
Nate Begemana9795f82005-03-24 04:41:43 +00006// the University of Illinois Open Source License. See LICENSE.TXT for details.
Misha Brukmanb5f662f2005-04-21 23:30:14 +00007//
Nate Begemana9795f82005-03-24 04:41:43 +00008//===----------------------------------------------------------------------===//
9//
10// This file defines a pattern matching instruction selector for 32 bit PowerPC.
Nate Begeman815d6da2005-04-06 00:25:27 +000011// Magic number generation for integer divide from the PowerPC Compiler Writer's
12// Guide, section 3.2.3.5
Nate Begemana9795f82005-03-24 04:41:43 +000013//
14//===----------------------------------------------------------------------===//
15
16#include "PowerPC.h"
17#include "PowerPCInstrBuilder.h"
18#include "PowerPCInstrInfo.h"
Nate Begemancd08e4c2005-04-09 20:09:12 +000019#include "PPC32TargetMachine.h"
Nate Begemana9795f82005-03-24 04:41:43 +000020#include "llvm/Constants.h" // FIXME: REMOVE
21#include "llvm/Function.h"
22#include "llvm/CodeGen/MachineConstantPool.h" // FIXME: REMOVE
23#include "llvm/CodeGen/MachineFunction.h"
24#include "llvm/CodeGen/MachineFrameInfo.h"
25#include "llvm/CodeGen/SelectionDAG.h"
26#include "llvm/CodeGen/SelectionDAGISel.h"
27#include "llvm/CodeGen/SSARegMap.h"
28#include "llvm/Target/TargetData.h"
29#include "llvm/Target/TargetLowering.h"
Nate Begeman93075ec2005-04-04 23:40:36 +000030#include "llvm/Target/TargetOptions.h"
Nate Begemana9795f82005-03-24 04:41:43 +000031#include "llvm/Support/Debug.h"
32#include "llvm/Support/MathExtras.h"
33#include "llvm/ADT/Statistic.h"
34#include <set>
35#include <algorithm>
36using namespace llvm;
37
38//===----------------------------------------------------------------------===//
39// PPC32TargetLowering - PPC32 Implementation of the TargetLowering interface
40namespace {
41 class PPC32TargetLowering : public TargetLowering {
42 int VarArgsFrameIndex; // FrameIndex for start of varargs area.
43 int ReturnAddrIndex; // FrameIndex for return slot.
44 public:
45 PPC32TargetLowering(TargetMachine &TM) : TargetLowering(TM) {
Nate Begemana9795f82005-03-24 04:41:43 +000046 // Set up the register classes.
47 addRegisterClass(MVT::i32, PPC32::GPRCRegisterClass);
Nate Begeman7532e2f2005-03-26 08:25:22 +000048 addRegisterClass(MVT::f32, PPC32::FPRCRegisterClass);
Nate Begemana9795f82005-03-24 04:41:43 +000049 addRegisterClass(MVT::f64, PPC32::FPRCRegisterClass);
Misha Brukmanb5f662f2005-04-21 23:30:14 +000050
Nate Begeman74d73452005-03-31 00:15:26 +000051 // PowerPC has no intrinsics for these particular operations
Nate Begeman01d05262005-03-30 01:45:43 +000052 setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
53 setOperationAction(ISD::MEMSET, MVT::Other, Expand);
54 setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
55
Nate Begeman74d73452005-03-31 00:15:26 +000056 // PowerPC has an i16 but no i8 (or i1) SEXTLOAD
57 setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand);
58 setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand);
Misha Brukmanb5f662f2005-04-21 23:30:14 +000059
Nate Begeman815d6da2005-04-06 00:25:27 +000060 // PowerPC has no SREM/UREM instructions
61 setOperationAction(ISD::SREM, MVT::i32, Expand);
62 setOperationAction(ISD::UREM, MVT::i32, Expand);
Chris Lattner43fdea02005-04-02 05:03:24 +000063
Chris Lattner17234b72005-04-30 04:26:06 +000064 // We don't support sin/cos/sqrt
65 setOperationAction(ISD::FSIN , MVT::f64, Expand);
66 setOperationAction(ISD::FCOS , MVT::f64, Expand);
67 setOperationAction(ISD::FSQRT, MVT::f64, Expand);
68 setOperationAction(ISD::FSIN , MVT::f32, Expand);
69 setOperationAction(ISD::FCOS , MVT::f32, Expand);
70 setOperationAction(ISD::FSQRT, MVT::f32, Expand);
71
Nate Begemand7c4a4a2005-05-11 23:43:56 +000072 //PowerPC does not have CTPOP or CTTZ
Andrew Lenharth691ef2b2005-05-03 17:19:30 +000073 setOperationAction(ISD::CTPOP, MVT::i32 , Expand);
74 setOperationAction(ISD::CTTZ , MVT::i32 , Expand);
Andrew Lenharth691ef2b2005-05-03 17:19:30 +000075
Chris Lattnercbd06fc2005-04-07 19:41:49 +000076 setSetCCResultContents(ZeroOrOneSetCCResult);
Nate Begeman3e897162005-03-31 23:55:40 +000077 addLegalFPImmediate(+0.0); // Necessary for FSEL
Misha Brukmanb5f662f2005-04-21 23:30:14 +000078 addLegalFPImmediate(-0.0); //
Nate Begeman3e897162005-03-31 23:55:40 +000079
Nate Begemana9795f82005-03-24 04:41:43 +000080 computeRegisterProperties();
81 }
82
83 /// LowerArguments - This hook must be implemented to indicate how we should
84 /// lower the arguments for the specified function, into the specified DAG.
85 virtual std::vector<SDOperand>
86 LowerArguments(Function &F, SelectionDAG &DAG);
Misha Brukmanb5f662f2005-04-21 23:30:14 +000087
Nate Begemana9795f82005-03-24 04:41:43 +000088 /// LowerCallTo - This hook lowers an abstract call to a function into an
89 /// actual call.
90 virtual std::pair<SDOperand, SDOperand>
Nate Begeman307e7442005-03-26 01:28:53 +000091 LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
92 SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
Misha Brukmanb5f662f2005-04-21 23:30:14 +000093
Nate Begemana9795f82005-03-24 04:41:43 +000094 virtual std::pair<SDOperand, SDOperand>
95 LowerVAStart(SDOperand Chain, SelectionDAG &DAG);
Misha Brukmanb5f662f2005-04-21 23:30:14 +000096
Nate Begemana9795f82005-03-24 04:41:43 +000097 virtual std::pair<SDOperand,SDOperand>
98 LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
99 const Type *ArgTy, SelectionDAG &DAG);
100
101 virtual std::pair<SDOperand, SDOperand>
102 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
103 SelectionDAG &DAG);
104 };
105}
106
107
108std::vector<SDOperand>
109PPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
110 //
111 // add beautiful description of PPC stack frame format, or at least some docs
112 //
113 MachineFunction &MF = DAG.getMachineFunction();
114 MachineFrameInfo *MFI = MF.getFrameInfo();
115 MachineBasicBlock& BB = MF.front();
116 std::vector<SDOperand> ArgValues;
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000117
118 // Due to the rather complicated nature of the PowerPC ABI, rather than a
Nate Begemana9795f82005-03-24 04:41:43 +0000119 // fixed size array of physical args, for the sake of simplicity let the STL
120 // handle tracking them for us.
121 std::vector<unsigned> argVR, argPR, argOp;
122 unsigned ArgOffset = 24;
123 unsigned GPR_remaining = 8;
124 unsigned FPR_remaining = 13;
125 unsigned GPR_idx = 0, FPR_idx = 0;
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000126 static const unsigned GPR[] = {
Nate Begemana9795f82005-03-24 04:41:43 +0000127 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
128 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
129 };
130 static const unsigned FPR[] = {
131 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
132 PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
133 };
134
135 // Add DAG nodes to load the arguments... On entry to a function on PPC,
136 // the arguments start at offset 24, although they are likely to be passed
137 // in registers.
138 for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
139 SDOperand newroot, argt;
140 unsigned ObjSize;
141 bool needsLoad = false;
Nate Begemancd08e4c2005-04-09 20:09:12 +0000142 bool ArgLive = !I->use_empty();
Nate Begemana9795f82005-03-24 04:41:43 +0000143 MVT::ValueType ObjectVT = getValueType(I->getType());
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000144
Nate Begemana9795f82005-03-24 04:41:43 +0000145 switch (ObjectVT) {
146 default: assert(0 && "Unhandled argument type!");
147 case MVT::i1:
148 case MVT::i8:
149 case MVT::i16:
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000150 case MVT::i32:
Nate Begemana9795f82005-03-24 04:41:43 +0000151 ObjSize = 4;
Nate Begemancd08e4c2005-04-09 20:09:12 +0000152 if (!ArgLive) break;
Nate Begemana9795f82005-03-24 04:41:43 +0000153 if (GPR_remaining > 0) {
Nate Begemancd08e4c2005-04-09 20:09:12 +0000154 MF.addLiveIn(GPR[GPR_idx]);
Nate Begemanf70b5762005-03-28 23:08:54 +0000155 argt = newroot = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32,
156 DAG.getRoot());
Nate Begemana9795f82005-03-24 04:41:43 +0000157 if (ObjectVT != MVT::i32)
158 argt = DAG.getNode(ISD::TRUNCATE, ObjectVT, newroot);
Nate Begemana9795f82005-03-24 04:41:43 +0000159 } else {
160 needsLoad = true;
161 }
162 break;
Nate Begemanf7e43382005-03-26 07:46:36 +0000163 case MVT::i64: ObjSize = 8;
Nate Begemancd08e4c2005-04-09 20:09:12 +0000164 if (!ArgLive) break;
Nate Begemanc5b1cd22005-04-10 05:53:14 +0000165 if (GPR_remaining > 0) {
166 SDOperand argHi, argLo;
Nate Begemancd08e4c2005-04-09 20:09:12 +0000167 MF.addLiveIn(GPR[GPR_idx]);
Nate Begemanc5b1cd22005-04-10 05:53:14 +0000168 argHi = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, DAG.getRoot());
169 // If we have two or more remaining argument registers, then both halves
170 // of the i64 can be sourced from there. Otherwise, the lower half will
171 // have to come off the stack. This can happen when an i64 is preceded
172 // by 28 bytes of arguments.
173 if (GPR_remaining > 1) {
174 MF.addLiveIn(GPR[GPR_idx+1]);
175 argLo = DAG.getCopyFromReg(GPR[GPR_idx+1], MVT::i32, argHi);
176 } else {
177 int FI = MFI->CreateFixedObject(4, ArgOffset+4);
178 SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
Andrew Lenharth2d86ea22005-04-27 20:10:01 +0000179 argLo = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN, DAG.getSrcValue(NULL));
Nate Begemanc5b1cd22005-04-10 05:53:14 +0000180 }
Nate Begemanca12a2b2005-03-28 22:28:37 +0000181 // Build the outgoing arg thingy
Nate Begemanf70b5762005-03-28 23:08:54 +0000182 argt = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, argLo, argHi);
183 newroot = argLo;
Nate Begemana9795f82005-03-24 04:41:43 +0000184 } else {
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000185 needsLoad = true;
Nate Begemana9795f82005-03-24 04:41:43 +0000186 }
187 break;
Nate Begemancd08e4c2005-04-09 20:09:12 +0000188 case MVT::f32:
189 case MVT::f64:
190 ObjSize = (ObjectVT == MVT::f64) ? 8 : 4;
191 if (!ArgLive) break;
Nate Begemana9795f82005-03-24 04:41:43 +0000192 if (FPR_remaining > 0) {
Nate Begemancd08e4c2005-04-09 20:09:12 +0000193 MF.addLiveIn(FPR[FPR_idx]);
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000194 argt = newroot = DAG.getCopyFromReg(FPR[FPR_idx], ObjectVT,
Nate Begemanf70b5762005-03-28 23:08:54 +0000195 DAG.getRoot());
Nate Begemana9795f82005-03-24 04:41:43 +0000196 --FPR_remaining;
197 ++FPR_idx;
198 } else {
199 needsLoad = true;
200 }
201 break;
202 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000203
Nate Begemana9795f82005-03-24 04:41:43 +0000204 // We need to load the argument to a virtual register if we determined above
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000205 // that we ran out of physical registers of the appropriate type
Nate Begemana9795f82005-03-24 04:41:43 +0000206 if (needsLoad) {
Nate Begemane5846682005-04-04 06:52:38 +0000207 unsigned SubregOffset = 0;
Nate Begemanc3e2db42005-04-04 09:09:00 +0000208 if (ObjectVT == MVT::i8 || ObjectVT == MVT::i1) SubregOffset = 3;
Nate Begemane5846682005-04-04 06:52:38 +0000209 if (ObjectVT == MVT::i16) SubregOffset = 2;
Nate Begemana9795f82005-03-24 04:41:43 +0000210 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
211 SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000212 FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN,
Nate Begemane5846682005-04-04 06:52:38 +0000213 DAG.getConstant(SubregOffset, MVT::i32));
Andrew Lenharth2d86ea22005-04-27 20:10:01 +0000214 argt = newroot = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN, DAG.getSrcValue(NULL));
Nate Begemana9795f82005-03-24 04:41:43 +0000215 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000216
Nate Begemana9795f82005-03-24 04:41:43 +0000217 // Every 4 bytes of argument space consumes one of the GPRs available for
218 // argument passing.
219 if (GPR_remaining > 0) {
220 unsigned delta = (GPR_remaining > 1 && ObjSize == 8) ? 2 : 1;
221 GPR_remaining -= delta;
222 GPR_idx += delta;
223 }
224 ArgOffset += ObjSize;
Chris Lattner91277ea2005-04-09 21:23:24 +0000225 if (newroot.Val)
226 DAG.setRoot(newroot.getValue(1));
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000227
Nate Begemana9795f82005-03-24 04:41:43 +0000228 ArgValues.push_back(argt);
229 }
230
Nate Begemana9795f82005-03-24 04:41:43 +0000231 // If the function takes variable number of arguments, make a frame index for
232 // the start of the first vararg value... for expansion of llvm.va_start.
Nate Begemanfa554702005-04-03 22:13:27 +0000233 if (F.isVarArg()) {
Nate Begemana9795f82005-03-24 04:41:43 +0000234 VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset);
Nate Begemanfa554702005-04-03 22:13:27 +0000235 SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32);
Nate Begeman6644d4c2005-04-03 23:11:17 +0000236 // If this function is vararg, store any remaining integer argument regs
237 // to their spots on the stack so that they may be loaded by deferencing the
238 // result of va_next.
239 std::vector<SDOperand> MemOps;
240 for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) {
Nate Begemancd08e4c2005-04-09 20:09:12 +0000241 MF.addLiveIn(GPR[GPR_idx]);
Nate Begeman6644d4c2005-04-03 23:11:17 +0000242 SDOperand Val = DAG.getCopyFromReg(GPR[GPR_idx], MVT::i32, DAG.getRoot());
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000243 SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
Andrew Lenharth2d86ea22005-04-27 20:10:01 +0000244 Val, FIN, DAG.getSrcValue(NULL));
Nate Begeman6644d4c2005-04-03 23:11:17 +0000245 MemOps.push_back(Store);
246 // Increment the address by four for the next argument to store
247 SDOperand PtrOff = DAG.getConstant(4, getPointerTy());
248 FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, PtrOff);
249 }
250 DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps));
Nate Begemanfa554702005-04-03 22:13:27 +0000251 }
Nate Begemana9795f82005-03-24 04:41:43 +0000252
Nate Begemancd08e4c2005-04-09 20:09:12 +0000253 // Finally, inform the code generator which regs we return values in.
254 switch (getValueType(F.getReturnType())) {
255 default: assert(0 && "Unknown type!");
256 case MVT::isVoid: break;
257 case MVT::i1:
258 case MVT::i8:
259 case MVT::i16:
260 case MVT::i32:
261 MF.addLiveOut(PPC::R3);
262 break;
263 case MVT::i64:
264 MF.addLiveOut(PPC::R3);
265 MF.addLiveOut(PPC::R4);
266 break;
267 case MVT::f32:
268 case MVT::f64:
269 MF.addLiveOut(PPC::F1);
270 break;
271 }
272
Nate Begemana9795f82005-03-24 04:41:43 +0000273 return ArgValues;
274}
275
276std::pair<SDOperand, SDOperand>
277PPC32TargetLowering::LowerCallTo(SDOperand Chain,
Misha Brukman7847fca2005-04-22 17:54:37 +0000278 const Type *RetTy, bool isVarArg,
279 SDOperand Callee, ArgListTy &Args,
280 SelectionDAG &DAG) {
Nate Begeman307e7442005-03-26 01:28:53 +0000281 // args_to_use will accumulate outgoing args for the ISD::CALL case in
282 // SelectExpr to use to put the arguments in the appropriate registers.
Nate Begemana9795f82005-03-24 04:41:43 +0000283 std::vector<SDOperand> args_to_use;
Nate Begeman307e7442005-03-26 01:28:53 +0000284
285 // Count how many bytes are to be pushed on the stack, including the linkage
286 // area, and parameter passing area.
287 unsigned NumBytes = 24;
288
289 if (Args.empty()) {
Nate Begemana7e11a42005-04-01 05:57:17 +0000290 Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain,
291 DAG.getConstant(NumBytes, getPointerTy()));
Nate Begeman307e7442005-03-26 01:28:53 +0000292 } else {
293 for (unsigned i = 0, e = Args.size(); i != e; ++i)
294 switch (getValueType(Args[i].second)) {
295 default: assert(0 && "Unknown value type!");
296 case MVT::i1:
297 case MVT::i8:
298 case MVT::i16:
299 case MVT::i32:
300 case MVT::f32:
301 NumBytes += 4;
302 break;
303 case MVT::i64:
304 case MVT::f64:
305 NumBytes += 8;
306 break;
307 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000308
309 // Just to be safe, we'll always reserve the full 24 bytes of linkage area
Nate Begeman307e7442005-03-26 01:28:53 +0000310 // plus 32 bytes of argument space in case any called code gets funky on us.
311 if (NumBytes < 56) NumBytes = 56;
312
313 // Adjust the stack pointer for the new arguments...
314 // These operations are automatically eliminated by the prolog/epilog pass
315 Chain = DAG.getNode(ISD::ADJCALLSTACKDOWN, MVT::Other, Chain,
316 DAG.getConstant(NumBytes, getPointerTy()));
317
318 // Set up a copy of the stack pointer for use loading and storing any
319 // arguments that may not fit in the registers available for argument
320 // passing.
321 SDOperand StackPtr = DAG.getCopyFromReg(PPC::R1, MVT::i32,
322 DAG.getEntryNode());
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000323
Nate Begeman307e7442005-03-26 01:28:53 +0000324 // Figure out which arguments are going to go in registers, and which in
325 // memory. Also, if this is a vararg function, floating point operations
326 // must be stored to our stack, and loaded into integer regs as well, if
327 // any integer regs are available for argument passing.
328 unsigned ArgOffset = 24;
329 unsigned GPR_remaining = 8;
330 unsigned FPR_remaining = 13;
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000331
Nate Begeman74d73452005-03-31 00:15:26 +0000332 std::vector<SDOperand> MemOps;
Nate Begeman307e7442005-03-26 01:28:53 +0000333 for (unsigned i = 0, e = Args.size(); i != e; ++i) {
334 // PtrOff will be used to store the current argument to the stack if a
335 // register cannot be found for it.
336 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
337 PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
Nate Begemanf7e43382005-03-26 07:46:36 +0000338 MVT::ValueType ArgVT = getValueType(Args[i].second);
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000339
Nate Begemanf7e43382005-03-26 07:46:36 +0000340 switch (ArgVT) {
Nate Begeman307e7442005-03-26 01:28:53 +0000341 default: assert(0 && "Unexpected ValueType for argument!");
342 case MVT::i1:
343 case MVT::i8:
344 case MVT::i16:
345 // Promote the integer to 32 bits. If the input type is signed use a
346 // sign extend, otherwise use a zero extend.
347 if (Args[i].second->isSigned())
348 Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first);
349 else
350 Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first);
351 // FALL THROUGH
352 case MVT::i32:
353 if (GPR_remaining > 0) {
Nate Begemanfc1b1da2005-04-01 22:34:39 +0000354 args_to_use.push_back(Args[i].first);
Nate Begeman307e7442005-03-26 01:28:53 +0000355 --GPR_remaining;
356 } else {
Nate Begeman74d73452005-03-31 00:15:26 +0000357 MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
Andrew Lenharth2d86ea22005-04-27 20:10:01 +0000358 Args[i].first, PtrOff, DAG.getSrcValue(NULL)));
Nate Begeman307e7442005-03-26 01:28:53 +0000359 }
360 ArgOffset += 4;
361 break;
362 case MVT::i64:
Nate Begemanf7e43382005-03-26 07:46:36 +0000363 // If we have one free GPR left, we can place the upper half of the i64
364 // in it, and store the other half to the stack. If we have two or more
365 // free GPRs, then we can pass both halves of the i64 in registers.
366 if (GPR_remaining > 0) {
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000367 SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32,
Nate Begemanf2622612005-03-26 02:17:46 +0000368 Args[i].first, DAG.getConstant(1, MVT::i32));
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000369 SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32,
Nate Begemanf2622612005-03-26 02:17:46 +0000370 Args[i].first, DAG.getConstant(0, MVT::i32));
Nate Begemanfc1b1da2005-04-01 22:34:39 +0000371 args_to_use.push_back(Hi);
Nate Begeman74d73452005-03-31 00:15:26 +0000372 --GPR_remaining;
Nate Begeman74d73452005-03-31 00:15:26 +0000373 if (GPR_remaining > 0) {
Nate Begemanfc1b1da2005-04-01 22:34:39 +0000374 args_to_use.push_back(Lo);
Nate Begeman74d73452005-03-31 00:15:26 +0000375 --GPR_remaining;
Nate Begemanf7e43382005-03-26 07:46:36 +0000376 } else {
377 SDOperand ConstFour = DAG.getConstant(4, getPointerTy());
378 PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour);
Nate Begeman74d73452005-03-31 00:15:26 +0000379 MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
Andrew Lenharth2d86ea22005-04-27 20:10:01 +0000380 Lo, PtrOff, DAG.getSrcValue(NULL)));
Nate Begemanf7e43382005-03-26 07:46:36 +0000381 }
Nate Begeman307e7442005-03-26 01:28:53 +0000382 } else {
Nate Begeman74d73452005-03-31 00:15:26 +0000383 MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
Andrew Lenharth2d86ea22005-04-27 20:10:01 +0000384 Args[i].first, PtrOff, DAG.getSrcValue(NULL)));
Nate Begeman307e7442005-03-26 01:28:53 +0000385 }
386 ArgOffset += 8;
387 break;
388 case MVT::f32:
Nate Begeman307e7442005-03-26 01:28:53 +0000389 case MVT::f64:
Nate Begemanf7e43382005-03-26 07:46:36 +0000390 if (FPR_remaining > 0) {
Nate Begemanfc1b1da2005-04-01 22:34:39 +0000391 args_to_use.push_back(Args[i].first);
392 --FPR_remaining;
Nate Begemanf7e43382005-03-26 07:46:36 +0000393 if (isVarArg) {
Nate Begeman96fc6812005-03-31 02:05:53 +0000394 SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain,
Andrew Lenharth2d86ea22005-04-27 20:10:01 +0000395 Args[i].first, PtrOff, DAG.getSrcValue(NULL));
Nate Begeman96fc6812005-03-31 02:05:53 +0000396 MemOps.push_back(Store);
Nate Begeman74d73452005-03-31 00:15:26 +0000397 // Float varargs are always shadowed in available integer registers
398 if (GPR_remaining > 0) {
Andrew Lenharth2d86ea22005-04-27 20:10:01 +0000399 SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff, DAG.getSrcValue(NULL));
Nate Begeman74d73452005-03-31 00:15:26 +0000400 MemOps.push_back(Load);
Nate Begemanfc1b1da2005-04-01 22:34:39 +0000401 args_to_use.push_back(Load);
402 --GPR_remaining;
Nate Begeman74d73452005-03-31 00:15:26 +0000403 }
Nate Begemanfc1b1da2005-04-01 22:34:39 +0000404 if (GPR_remaining > 0 && MVT::f64 == ArgVT) {
Nate Begeman74d73452005-03-31 00:15:26 +0000405 SDOperand ConstFour = DAG.getConstant(4, getPointerTy());
406 PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour);
Andrew Lenharth2d86ea22005-04-27 20:10:01 +0000407 SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff, DAG.getSrcValue(NULL));
Nate Begeman74d73452005-03-31 00:15:26 +0000408 MemOps.push_back(Load);
Nate Begemanfc1b1da2005-04-01 22:34:39 +0000409 args_to_use.push_back(Load);
410 --GPR_remaining;
Nate Begeman74d73452005-03-31 00:15:26 +0000411 }
Nate Begemanfc1b1da2005-04-01 22:34:39 +0000412 } else {
413 // If we have any FPRs remaining, we may also have GPRs remaining.
414 // Args passed in FPRs consume either 1 (f32) or 2 (f64) available
415 // GPRs.
416 if (GPR_remaining > 0) {
417 args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32));
418 --GPR_remaining;
419 }
420 if (GPR_remaining > 0 && MVT::f64 == ArgVT) {
421 args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32));
422 --GPR_remaining;
423 }
Nate Begeman74d73452005-03-31 00:15:26 +0000424 }
Nate Begeman307e7442005-03-26 01:28:53 +0000425 } else {
Nate Begeman74d73452005-03-31 00:15:26 +0000426 MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
Andrew Lenharth2d86ea22005-04-27 20:10:01 +0000427 Args[i].first, PtrOff, DAG.getSrcValue(NULL)));
Nate Begeman307e7442005-03-26 01:28:53 +0000428 }
Nate Begemanf7e43382005-03-26 07:46:36 +0000429 ArgOffset += (ArgVT == MVT::f32) ? 4 : 8;
Nate Begeman307e7442005-03-26 01:28:53 +0000430 break;
431 }
Nate Begemana9795f82005-03-24 04:41:43 +0000432 }
Nate Begeman74d73452005-03-31 00:15:26 +0000433 if (!MemOps.empty())
434 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps);
Nate Begemana9795f82005-03-24 04:41:43 +0000435 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000436
Nate Begemana9795f82005-03-24 04:41:43 +0000437 std::vector<MVT::ValueType> RetVals;
438 MVT::ValueType RetTyVT = getValueType(RetTy);
439 if (RetTyVT != MVT::isVoid)
440 RetVals.push_back(RetTyVT);
441 RetVals.push_back(MVT::Other);
442
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000443 SDOperand TheCall = SDOperand(DAG.getCall(RetVals,
Nate Begemana9795f82005-03-24 04:41:43 +0000444 Chain, Callee, args_to_use), 0);
445 Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
446 Chain = DAG.getNode(ISD::ADJCALLSTACKUP, MVT::Other, Chain,
447 DAG.getConstant(NumBytes, getPointerTy()));
448 return std::make_pair(TheCall, Chain);
449}
450
451std::pair<SDOperand, SDOperand>
452PPC32TargetLowering::LowerVAStart(SDOperand Chain, SelectionDAG &DAG) {
453 //vastart just returns the address of the VarArgsFrameIndex slot.
454 return std::make_pair(DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32), Chain);
455}
456
457std::pair<SDOperand,SDOperand> PPC32TargetLowering::
458LowerVAArgNext(bool isVANext, SDOperand Chain, SDOperand VAList,
459 const Type *ArgTy, SelectionDAG &DAG) {
Nate Begemanc7b09f12005-03-25 08:34:25 +0000460 MVT::ValueType ArgVT = getValueType(ArgTy);
461 SDOperand Result;
462 if (!isVANext) {
Andrew Lenharth2d86ea22005-04-27 20:10:01 +0000463 Result = DAG.getLoad(ArgVT, DAG.getEntryNode(), VAList, DAG.getSrcValue(NULL));
Nate Begemanc7b09f12005-03-25 08:34:25 +0000464 } else {
465 unsigned Amt;
466 if (ArgVT == MVT::i32 || ArgVT == MVT::f32)
467 Amt = 4;
468 else {
469 assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) &&
470 "Other types should have been promoted for varargs!");
471 Amt = 8;
472 }
473 Result = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList,
474 DAG.getConstant(Amt, VAList.getValueType()));
475 }
476 return std::make_pair(Result, Chain);
Nate Begemana9795f82005-03-24 04:41:43 +0000477}
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000478
Nate Begemana9795f82005-03-24 04:41:43 +0000479
480std::pair<SDOperand, SDOperand> PPC32TargetLowering::
481LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
482 SelectionDAG &DAG) {
Nate Begeman01d05262005-03-30 01:45:43 +0000483 assert(0 && "LowerFrameReturnAddress unimplemented");
Nate Begemana9795f82005-03-24 04:41:43 +0000484 abort();
485}
486
487namespace {
Nate Begemanc7bd4822005-04-11 06:34:10 +0000488Statistic<>Recorded("ppc-codegen", "Number of recording ops emitted");
Nate Begeman93075ec2005-04-04 23:40:36 +0000489Statistic<>FusedFP("ppc-codegen", "Number of fused fp operations");
Nate Begeman7bfba7d2005-04-14 09:45:08 +0000490Statistic<>MultiBranch("ppc-codegen", "Number of setcc logical ops collapsed");
Nate Begemana9795f82005-03-24 04:41:43 +0000491//===--------------------------------------------------------------------===//
492/// ISel - PPC32 specific code to select PPC32 machine instructions for
493/// SelectionDAG operations.
494//===--------------------------------------------------------------------===//
495class ISel : public SelectionDAGISel {
Nate Begemana9795f82005-03-24 04:41:43 +0000496 PPC32TargetLowering PPC32Lowering;
Nate Begeman815d6da2005-04-06 00:25:27 +0000497 SelectionDAG *ISelDAG; // Hack to support us having a dag->dag transform
498 // for sdiv and udiv until it is put into the future
499 // dag combiner.
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000500
Nate Begemana9795f82005-03-24 04:41:43 +0000501 /// ExprMap - As shared expressions are codegen'd, we keep track of which
502 /// vreg the value is produced in, so we only emit one copy of each compiled
503 /// tree.
504 std::map<SDOperand, unsigned> ExprMap;
Nate Begemanc7b09f12005-03-25 08:34:25 +0000505
506 unsigned GlobalBaseReg;
507 bool GlobalBaseInitialized;
Nate Begemanc7bd4822005-04-11 06:34:10 +0000508 bool RecordSuccess;
Nate Begemana9795f82005-03-24 04:41:43 +0000509public:
Nate Begeman815d6da2005-04-06 00:25:27 +0000510 ISel(TargetMachine &TM) : SelectionDAGISel(PPC32Lowering), PPC32Lowering(TM),
511 ISelDAG(0) {}
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000512
Nate Begemanc7b09f12005-03-25 08:34:25 +0000513 /// runOnFunction - Override this function in order to reset our per-function
514 /// variables.
515 virtual bool runOnFunction(Function &Fn) {
516 // Make sure we re-emit a set of the global base reg if necessary
517 GlobalBaseInitialized = false;
518 return SelectionDAGISel::runOnFunction(Fn);
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000519 }
520
Nate Begemana9795f82005-03-24 04:41:43 +0000521 /// InstructionSelectBasicBlock - This callback is invoked by
522 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
523 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG) {
524 DEBUG(BB->dump());
525 // Codegen the basic block.
Nate Begeman815d6da2005-04-06 00:25:27 +0000526 ISelDAG = &DAG;
Nate Begemana9795f82005-03-24 04:41:43 +0000527 Select(DAG.getRoot());
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000528
Nate Begemana9795f82005-03-24 04:41:43 +0000529 // Clear state used for selection.
530 ExprMap.clear();
Nate Begeman815d6da2005-04-06 00:25:27 +0000531 ISelDAG = 0;
Nate Begemana9795f82005-03-24 04:41:43 +0000532 }
Nate Begeman815d6da2005-04-06 00:25:27 +0000533
534 // dag -> dag expanders for integer divide by constant
535 SDOperand BuildSDIVSequence(SDOperand N);
536 SDOperand BuildUDIVSequence(SDOperand N);
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000537
Nate Begemandffcfcc2005-04-01 00:32:34 +0000538 unsigned getGlobalBaseReg();
Nate Begeman6b559972005-04-01 02:59:27 +0000539 unsigned getConstDouble(double floatVal, unsigned Result);
Nate Begeman1cbf3ab2005-04-18 07:48:09 +0000540 void MoveCRtoGPR(unsigned CCReg, bool Inv, unsigned Idx, unsigned Result);
Nate Begeman7ddecb42005-04-06 23:51:40 +0000541 bool SelectBitfieldInsert(SDOperand OR, unsigned Result);
Nate Begeman3664cef2005-04-13 22:14:14 +0000542 unsigned FoldIfWideZeroExtend(SDOperand N);
Nate Begeman1cbf3ab2005-04-18 07:48:09 +0000543 unsigned SelectCC(SDOperand CC, unsigned &Opc, bool &Inv, unsigned &Idx);
544 unsigned SelectCCExpr(SDOperand N, unsigned& Opc, bool &Inv, unsigned &Idx);
Nate Begemanc7bd4822005-04-11 06:34:10 +0000545 unsigned SelectExpr(SDOperand N, bool Recording=false);
Nate Begemana9795f82005-03-24 04:41:43 +0000546 unsigned SelectExprFP(SDOperand N, unsigned Result);
547 void Select(SDOperand N);
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000548
Nate Begeman04730362005-04-01 04:45:11 +0000549 bool SelectAddr(SDOperand N, unsigned& Reg, int& offset);
Nate Begemana9795f82005-03-24 04:41:43 +0000550 void SelectBranchCC(SDOperand N);
551};
552
Nate Begeman80196b12005-04-05 00:15:08 +0000553/// ExactLog2 - This function solves for (Val == 1 << (N-1)) and returns N. It
554/// returns zero when the input is not exactly a power of two.
555static unsigned ExactLog2(unsigned Val) {
556 if (Val == 0 || (Val & (Val-1))) return 0;
557 unsigned Count = 0;
558 while (Val != 1) {
559 Val >>= 1;
560 ++Count;
561 }
562 return Count;
563}
564
Nate Begeman7ddecb42005-04-06 23:51:40 +0000565// IsRunOfOnes - returns true if Val consists of one contiguous run of 1's with
566// any number of 0's on either side. the 1's are allowed to wrap from LSB to
567// MSB. so 0x000FFF0, 0x0000FFFF, and 0xFF0000FF are all runs. 0x0F0F0000 is
568// not, since all 1's are not contiguous.
569static bool IsRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) {
570 bool isRun = true;
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000571 MB = 0;
Nate Begeman7ddecb42005-04-06 23:51:40 +0000572 ME = 0;
573
574 // look for first set bit
575 int i = 0;
576 for (; i < 32; i++) {
577 if ((Val & (1 << (31 - i))) != 0) {
578 MB = i;
579 ME = i;
580 break;
581 }
582 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000583
Nate Begeman7ddecb42005-04-06 23:51:40 +0000584 // look for last set bit
585 for (; i < 32; i++) {
586 if ((Val & (1 << (31 - i))) == 0)
587 break;
588 ME = i;
589 }
590
591 // look for next set bit
592 for (; i < 32; i++) {
593 if ((Val & (1 << (31 - i))) != 0)
594 break;
595 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000596
Nate Begeman7ddecb42005-04-06 23:51:40 +0000597 // if we exhausted all the bits, we found a match at this point for 0*1*0*
598 if (i == 32)
599 return true;
600
601 // since we just encountered more 1's, if it doesn't wrap around to the
602 // most significant bit of the word, then we did not find a match to 1*0*1* so
603 // exit.
604 if (MB != 0)
605 return false;
606
607 // look for last set bit
608 for (MB = i; i < 32; i++) {
609 if ((Val & (1 << (31 - i))) == 0)
610 break;
611 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000612
Nate Begeman7ddecb42005-04-06 23:51:40 +0000613 // if we exhausted all the bits, then we found a match for 1*0*1*, otherwise,
614 // the value is not a run of ones.
615 if (i == 32)
616 return true;
617 return false;
618}
619
Nate Begeman439b4442005-04-05 04:22:58 +0000620/// getImmediateForOpcode - This method returns a value indicating whether
Nate Begemana9795f82005-03-24 04:41:43 +0000621/// the ConstantSDNode N can be used as an immediate to Opcode. The return
622/// values are either 0, 1 or 2. 0 indicates that either N is not a
Nate Begeman9f833d32005-04-12 00:10:02 +0000623/// ConstantSDNode, or is not suitable for use by that opcode.
624/// Return value codes for turning into an enum someday:
625/// 1: constant may be used in normal immediate form.
626/// 2: constant may be used in shifted immediate form.
627/// 3: log base 2 of the constant may be used.
628/// 4: constant is suitable for integer division conversion
629/// 5: constant is a bitfield mask
Nate Begemana9795f82005-03-24 04:41:43 +0000630///
Nate Begeman439b4442005-04-05 04:22:58 +0000631static unsigned getImmediateForOpcode(SDOperand N, unsigned Opcode,
632 unsigned& Imm, bool U = false) {
Nate Begemana9795f82005-03-24 04:41:43 +0000633 if (N.getOpcode() != ISD::Constant) return 0;
634
635 int v = (int)cast<ConstantSDNode>(N)->getSignExtended();
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000636
Nate Begemana9795f82005-03-24 04:41:43 +0000637 switch(Opcode) {
638 default: return 0;
639 case ISD::ADD:
640 if (v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; }
641 if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; }
642 break;
Nate Begeman9f833d32005-04-12 00:10:02 +0000643 case ISD::AND: {
644 unsigned MB, ME;
645 if (IsRunOfOnes(v, MB, ME)) { Imm = MB << 16 | ME & 0xFFFF; return 5; }
646 if (v >= 0 && v <= 65535) { Imm = v & 0xFFFF; return 1; }
647 if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; }
648 break;
649 }
Nate Begemana9795f82005-03-24 04:41:43 +0000650 case ISD::XOR:
651 case ISD::OR:
652 if (v >= 0 && v <= 65535) { Imm = v & 0xFFFF; return 1; }
653 if ((v & 0x0000FFFF) == 0) { Imm = v >> 16; return 2; }
654 break;
Nate Begeman307e7442005-03-26 01:28:53 +0000655 case ISD::MUL:
656 if (v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; }
657 break;
Nate Begemand7c4a4a2005-05-11 23:43:56 +0000658 case ISD::SUB:
659 // handle subtract-from separately from subtract, since subi is really addi
660 if (U && v <= 32767 && v >= -32768) { Imm = v & 0xFFFF; return 1; }
661 if (!U && v <= 32768 && v >= -32767) { Imm = (-v) & 0xFFFF; return 1; }
662 break;
Nate Begeman3e897162005-03-31 23:55:40 +0000663 case ISD::SETCC:
664 if (U && (v >= 0 && v <= 65535)) { Imm = v & 0xFFFF; return 1; }
665 if (!U && (v <= 32767 && v >= -32768)) { Imm = v & 0xFFFF; return 1; }
666 break;
Nate Begeman80196b12005-04-05 00:15:08 +0000667 case ISD::SDIV:
Nate Begeman439b4442005-04-05 04:22:58 +0000668 if ((Imm = ExactLog2(v))) { return 3; }
Nate Begeman9f833d32005-04-12 00:10:02 +0000669 if ((Imm = ExactLog2(-v))) { Imm = -Imm; return 3; }
Nate Begeman815d6da2005-04-06 00:25:27 +0000670 if (v <= -2 || v >= 2) { return 4; }
671 break;
672 case ISD::UDIV:
Nate Begeman27b4c232005-04-06 06:44:57 +0000673 if (v > 1) { return 4; }
Nate Begeman80196b12005-04-05 00:15:08 +0000674 break;
Nate Begemana9795f82005-03-24 04:41:43 +0000675 }
676 return 0;
677}
Nate Begeman3e897162005-03-31 23:55:40 +0000678
Nate Begemanc7bd4822005-04-11 06:34:10 +0000679/// NodeHasRecordingVariant - If SelectExpr can always produce code for
680/// NodeOpcode that also sets CR0 as a side effect, return true. Otherwise,
681/// return false.
682static bool NodeHasRecordingVariant(unsigned NodeOpcode) {
683 switch(NodeOpcode) {
684 default: return false;
685 case ISD::AND:
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000686 case ISD::OR:
Chris Lattner519f40b2005-04-13 02:46:17 +0000687 return true;
Nate Begemanc7bd4822005-04-11 06:34:10 +0000688 }
689}
690
Nate Begeman3e897162005-03-31 23:55:40 +0000691/// getBCCForSetCC - Returns the PowerPC condition branch mnemonic corresponding
692/// to Condition. If the Condition is unordered or unsigned, the bool argument
693/// U is set to true, otherwise it is set to false.
694static unsigned getBCCForSetCC(unsigned Condition, bool& U) {
695 U = false;
696 switch (Condition) {
697 default: assert(0 && "Unknown condition!"); abort();
698 case ISD::SETEQ: return PPC::BEQ;
699 case ISD::SETNE: return PPC::BNE;
700 case ISD::SETULT: U = true;
701 case ISD::SETLT: return PPC::BLT;
702 case ISD::SETULE: U = true;
703 case ISD::SETLE: return PPC::BLE;
704 case ISD::SETUGT: U = true;
705 case ISD::SETGT: return PPC::BGT;
706 case ISD::SETUGE: U = true;
707 case ISD::SETGE: return PPC::BGE;
708 }
Nate Begeman04730362005-04-01 04:45:11 +0000709 return 0;
710}
711
Nate Begeman7bfba7d2005-04-14 09:45:08 +0000712/// getCROpForOp - Return the condition register opcode (or inverted opcode)
713/// associated with the SelectionDAG opcode.
714static unsigned getCROpForSetCC(unsigned Opcode, bool Inv1, bool Inv2) {
715 switch (Opcode) {
716 default: assert(0 && "Unknown opcode!"); abort();
717 case ISD::AND:
718 if (Inv1 && Inv2) return PPC::CRNOR; // De Morgan's Law
719 if (!Inv1 && !Inv2) return PPC::CRAND;
720 if (Inv1 ^ Inv2) return PPC::CRANDC;
721 case ISD::OR:
722 if (Inv1 && Inv2) return PPC::CRNAND; // De Morgan's Law
723 if (!Inv1 && !Inv2) return PPC::CROR;
724 if (Inv1 ^ Inv2) return PPC::CRORC;
725 }
726 return 0;
727}
728
729/// getCRIdxForSetCC - Return the index of the condition register field
730/// associated with the SetCC condition, and whether or not the field is
731/// treated as inverted. That is, lt = 0; ge = 0 inverted.
732static unsigned getCRIdxForSetCC(unsigned Condition, bool& Inv) {
733 switch (Condition) {
734 default: assert(0 && "Unknown condition!"); abort();
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000735 case ISD::SETULT:
Nate Begeman7bfba7d2005-04-14 09:45:08 +0000736 case ISD::SETLT: Inv = false; return 0;
737 case ISD::SETUGE:
738 case ISD::SETGE: Inv = true; return 0;
739 case ISD::SETUGT:
740 case ISD::SETGT: Inv = false; return 1;
741 case ISD::SETULE:
742 case ISD::SETLE: Inv = true; return 1;
743 case ISD::SETEQ: Inv = false; return 2;
744 case ISD::SETNE: Inv = true; return 2;
745 }
746 return 0;
747}
748
Nate Begeman04730362005-04-01 04:45:11 +0000749/// IndexedOpForOp - Return the indexed variant for each of the PowerPC load
750/// and store immediate instructions.
751static unsigned IndexedOpForOp(unsigned Opcode) {
752 switch(Opcode) {
753 default: assert(0 && "Unknown opcode!"); abort();
754 case PPC::LBZ: return PPC::LBZX; case PPC::STB: return PPC::STBX;
755 case PPC::LHZ: return PPC::LHZX; case PPC::STH: return PPC::STHX;
756 case PPC::LHA: return PPC::LHAX; case PPC::STW: return PPC::STWX;
757 case PPC::LWZ: return PPC::LWZX; case PPC::STFS: return PPC::STFSX;
758 case PPC::LFS: return PPC::LFSX; case PPC::STFD: return PPC::STFDX;
759 case PPC::LFD: return PPC::LFDX;
760 }
761 return 0;
Nate Begeman3e897162005-03-31 23:55:40 +0000762}
Nate Begeman815d6da2005-04-06 00:25:27 +0000763
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000764// Structure used to return the necessary information to codegen an SDIV as
Nate Begeman815d6da2005-04-06 00:25:27 +0000765// a multiply.
766struct ms {
767 int m; // magic number
768 int s; // shift amount
769};
770
771struct mu {
772 unsigned int m; // magic number
773 int a; // add indicator
774 int s; // shift amount
775};
776
777/// magic - calculate the magic numbers required to codegen an integer sdiv as
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000778/// a sequence of multiply and shifts. Requires that the divisor not be 0, 1,
Nate Begeman815d6da2005-04-06 00:25:27 +0000779/// or -1.
780static struct ms magic(int d) {
781 int p;
782 unsigned int ad, anc, delta, q1, r1, q2, r2, t;
783 const unsigned int two31 = 2147483648U; // 2^31
784 struct ms mag;
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000785
Nate Begeman815d6da2005-04-06 00:25:27 +0000786 ad = abs(d);
787 t = two31 + ((unsigned int)d >> 31);
788 anc = t - 1 - t%ad; // absolute value of nc
789 p = 31; // initialize p
790 q1 = two31/anc; // initialize q1 = 2p/abs(nc)
791 r1 = two31 - q1*anc; // initialize r1 = rem(2p,abs(nc))
792 q2 = two31/ad; // initialize q2 = 2p/abs(d)
793 r2 = two31 - q2*ad; // initialize r2 = rem(2p,abs(d))
794 do {
795 p = p + 1;
796 q1 = 2*q1; // update q1 = 2p/abs(nc)
797 r1 = 2*r1; // update r1 = rem(2p/abs(nc))
798 if (r1 >= anc) { // must be unsigned comparison
799 q1 = q1 + 1;
800 r1 = r1 - anc;
801 }
802 q2 = 2*q2; // update q2 = 2p/abs(d)
803 r2 = 2*r2; // update r2 = rem(2p/abs(d))
804 if (r2 >= ad) { // must be unsigned comparison
805 q2 = q2 + 1;
806 r2 = r2 - ad;
807 }
808 delta = ad - r2;
809 } while (q1 < delta || (q1 == delta && r1 == 0));
810
811 mag.m = q2 + 1;
812 if (d < 0) mag.m = -mag.m; // resulting magic number
813 mag.s = p - 32; // resulting shift
814 return mag;
815}
816
817/// magicu - calculate the magic numbers required to codegen an integer udiv as
818/// a sequence of multiply, add and shifts. Requires that the divisor not be 0.
819static struct mu magicu(unsigned d)
820{
821 int p;
822 unsigned int nc, delta, q1, r1, q2, r2;
823 struct mu magu;
824 magu.a = 0; // initialize "add" indicator
825 nc = - 1 - (-d)%d;
826 p = 31; // initialize p
827 q1 = 0x80000000/nc; // initialize q1 = 2p/nc
828 r1 = 0x80000000 - q1*nc; // initialize r1 = rem(2p,nc)
829 q2 = 0x7FFFFFFF/d; // initialize q2 = (2p-1)/d
830 r2 = 0x7FFFFFFF - q2*d; // initialize r2 = rem((2p-1),d)
831 do {
832 p = p + 1;
833 if (r1 >= nc - r1 ) {
834 q1 = 2*q1 + 1; // update q1
835 r1 = 2*r1 - nc; // update r1
836 }
837 else {
838 q1 = 2*q1; // update q1
839 r1 = 2*r1; // update r1
840 }
841 if (r2 + 1 >= d - r2) {
842 if (q2 >= 0x7FFFFFFF) magu.a = 1;
843 q2 = 2*q2 + 1; // update q2
844 r2 = 2*r2 + 1 - d; // update r2
845 }
846 else {
847 if (q2 >= 0x80000000) magu.a = 1;
848 q2 = 2*q2; // update q2
849 r2 = 2*r2 + 1; // update r2
850 }
851 delta = d - 1 - r2;
852 } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0)));
853 magu.m = q2 + 1; // resulting magic number
854 magu.s = p - 32; // resulting shift
855 return magu;
856}
857}
858
859/// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant,
860/// return a DAG expression to select that will generate the same value by
861/// multiplying by a magic number. See:
862/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
863SDOperand ISel::BuildSDIVSequence(SDOperand N) {
864 int d = (int)cast<ConstantSDNode>(N.getOperand(1))->getSignExtended();
865 ms magics = magic(d);
866 // Multiply the numerator (operand 0) by the magic value
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000867 SDOperand Q = ISelDAG->getNode(ISD::MULHS, MVT::i32, N.getOperand(0),
Nate Begeman815d6da2005-04-06 00:25:27 +0000868 ISelDAG->getConstant(magics.m, MVT::i32));
869 // If d > 0 and m < 0, add the numerator
870 if (d > 0 && magics.m < 0)
871 Q = ISelDAG->getNode(ISD::ADD, MVT::i32, Q, N.getOperand(0));
872 // If d < 0 and m > 0, subtract the numerator.
873 if (d < 0 && magics.m > 0)
874 Q = ISelDAG->getNode(ISD::SUB, MVT::i32, Q, N.getOperand(0));
875 // Shift right algebraic if shift value is nonzero
876 if (magics.s > 0)
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000877 Q = ISelDAG->getNode(ISD::SRA, MVT::i32, Q,
Nate Begeman815d6da2005-04-06 00:25:27 +0000878 ISelDAG->getConstant(magics.s, MVT::i32));
879 // Extract the sign bit and add it to the quotient
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000880 SDOperand T =
Nate Begeman815d6da2005-04-06 00:25:27 +0000881 ISelDAG->getNode(ISD::SRL, MVT::i32, Q, ISelDAG->getConstant(31, MVT::i32));
Nate Begeman27b4c232005-04-06 06:44:57 +0000882 return ISelDAG->getNode(ISD::ADD, MVT::i32, Q, T);
Nate Begeman815d6da2005-04-06 00:25:27 +0000883}
884
885/// BuildUDIVSequence - Given an ISD::UDIV node expressing a divide by constant,
886/// return a DAG expression to select that will generate the same value by
887/// multiplying by a magic number. See:
888/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
889SDOperand ISel::BuildUDIVSequence(SDOperand N) {
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000890 unsigned d =
Nate Begeman815d6da2005-04-06 00:25:27 +0000891 (unsigned)cast<ConstantSDNode>(N.getOperand(1))->getSignExtended();
892 mu magics = magicu(d);
893 // Multiply the numerator (operand 0) by the magic value
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000894 SDOperand Q = ISelDAG->getNode(ISD::MULHU, MVT::i32, N.getOperand(0),
Nate Begeman815d6da2005-04-06 00:25:27 +0000895 ISelDAG->getConstant(magics.m, MVT::i32));
896 if (magics.a == 0) {
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000897 Q = ISelDAG->getNode(ISD::SRL, MVT::i32, Q,
Nate Begeman815d6da2005-04-06 00:25:27 +0000898 ISelDAG->getConstant(magics.s, MVT::i32));
899 } else {
900 SDOperand NPQ = ISelDAG->getNode(ISD::SUB, MVT::i32, N.getOperand(0), Q);
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000901 NPQ = ISelDAG->getNode(ISD::SRL, MVT::i32, NPQ,
Nate Begeman815d6da2005-04-06 00:25:27 +0000902 ISelDAG->getConstant(1, MVT::i32));
903 NPQ = ISelDAG->getNode(ISD::ADD, MVT::i32, NPQ, Q);
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000904 Q = ISelDAG->getNode(ISD::SRL, MVT::i32, NPQ,
Nate Begeman815d6da2005-04-06 00:25:27 +0000905 ISelDAG->getConstant(magics.s-1, MVT::i32));
906 }
Nate Begeman27b4c232005-04-06 06:44:57 +0000907 return Q;
Nate Begemana9795f82005-03-24 04:41:43 +0000908}
909
Nate Begemanc7b09f12005-03-25 08:34:25 +0000910/// getGlobalBaseReg - Output the instructions required to put the
911/// base address to use for accessing globals into a register.
912///
913unsigned ISel::getGlobalBaseReg() {
914 if (!GlobalBaseInitialized) {
915 // Insert the set of GlobalBaseReg into the first MBB of the function
916 MachineBasicBlock &FirstMBB = BB->getParent()->front();
917 MachineBasicBlock::iterator MBBI = FirstMBB.begin();
918 GlobalBaseReg = MakeReg(MVT::i32);
919 BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR);
920 BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg).addReg(PPC::LR);
921 GlobalBaseInitialized = true;
922 }
923 return GlobalBaseReg;
924}
925
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000926/// getConstDouble - Loads a floating point value into a register, via the
Nate Begeman6b559972005-04-01 02:59:27 +0000927/// Constant Pool. Optionally takes a register in which to load the value.
928unsigned ISel::getConstDouble(double doubleVal, unsigned Result=0) {
929 unsigned Tmp1 = MakeReg(MVT::i32);
930 if (0 == Result) Result = MakeReg(MVT::f64);
931 MachineConstantPool *CP = BB->getParent()->getConstantPool();
932 ConstantFP *CFP = ConstantFP::get(Type::DoubleTy, doubleVal);
933 unsigned CPI = CP->getConstantPoolIndex(CFP);
934 BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(getGlobalBaseReg())
935 .addConstantPoolIndex(CPI);
936 BuildMI(BB, PPC::LFD, 2, Result).addConstantPoolIndex(CPI).addReg(Tmp1);
937 return Result;
938}
939
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000940/// MoveCRtoGPR - Move CCReg[Idx] to the least significant bit of Result. If
Nate Begeman1cbf3ab2005-04-18 07:48:09 +0000941/// Inv is true, then invert the result.
942void ISel::MoveCRtoGPR(unsigned CCReg, bool Inv, unsigned Idx, unsigned Result){
943 unsigned IntCR = MakeReg(MVT::i32);
944 BuildMI(BB, PPC::MCRF, 1, PPC::CR7).addReg(CCReg);
945 BuildMI(BB, PPC::MFCR, 1, IntCR).addReg(PPC::CR7);
946 if (Inv) {
947 unsigned Tmp1 = MakeReg(MVT::i32);
948 BuildMI(BB, PPC::RLWINM, 4, Tmp1).addReg(IntCR).addImm(32-(3-Idx))
949 .addImm(31).addImm(31);
950 BuildMI(BB, PPC::XORI, 2, Result).addReg(Tmp1).addImm(1);
951 } else {
952 BuildMI(BB, PPC::RLWINM, 4, Result).addReg(IntCR).addImm(32-(3-Idx))
953 .addImm(31).addImm(31);
954 }
955}
956
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000957/// SelectBitfieldInsert - turn an or of two masked values into
Nate Begeman7ddecb42005-04-06 23:51:40 +0000958/// the rotate left word immediate then mask insert (rlwimi) instruction.
959/// Returns true on success, false if the caller still needs to select OR.
960///
961/// Patterns matched:
962/// 1. or shl, and 5. or and, and
963/// 2. or and, shl 6. or shl, shr
964/// 3. or shr, and 7. or shr, shl
965/// 4. or and, shr
966bool ISel::SelectBitfieldInsert(SDOperand OR, unsigned Result) {
Nate Begemancd08e4c2005-04-09 20:09:12 +0000967 bool IsRotate = false;
Nate Begeman7ddecb42005-04-06 23:51:40 +0000968 unsigned TgtMask = 0xFFFFFFFF, InsMask = 0xFFFFFFFF, Amount = 0;
969 unsigned Op0Opc = OR.getOperand(0).getOpcode();
970 unsigned Op1Opc = OR.getOperand(1).getOpcode();
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000971
Nate Begeman7ddecb42005-04-06 23:51:40 +0000972 // Verify that we have the correct opcodes
973 if (ISD::SHL != Op0Opc && ISD::SRL != Op0Opc && ISD::AND != Op0Opc)
974 return false;
975 if (ISD::SHL != Op1Opc && ISD::SRL != Op1Opc && ISD::AND != Op1Opc)
976 return false;
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000977
Nate Begeman7ddecb42005-04-06 23:51:40 +0000978 // Generate Mask value for Target
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000979 if (ConstantSDNode *CN =
Nate Begeman7ddecb42005-04-06 23:51:40 +0000980 dyn_cast<ConstantSDNode>(OR.getOperand(0).getOperand(1).Val)) {
981 switch(Op0Opc) {
982 case ISD::SHL: TgtMask <<= (unsigned)CN->getValue(); break;
983 case ISD::SRL: TgtMask >>= (unsigned)CN->getValue(); break;
984 case ISD::AND: TgtMask &= (unsigned)CN->getValue(); break;
985 }
986 } else {
987 return false;
988 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000989
Nate Begeman7ddecb42005-04-06 23:51:40 +0000990 // Generate Mask value for Insert
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000991 if (ConstantSDNode *CN =
Nate Begeman7ddecb42005-04-06 23:51:40 +0000992 dyn_cast<ConstantSDNode>(OR.getOperand(1).getOperand(1).Val)) {
993 switch(Op1Opc) {
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000994 case ISD::SHL:
995 Amount = CN->getValue();
Nate Begemancd08e4c2005-04-09 20:09:12 +0000996 InsMask <<= Amount;
997 if (Op0Opc == ISD::SRL) IsRotate = true;
Nate Begeman7ddecb42005-04-06 23:51:40 +0000998 break;
Misha Brukmanb5f662f2005-04-21 23:30:14 +0000999 case ISD::SRL:
1000 Amount = CN->getValue();
1001 InsMask >>= Amount;
Nate Begeman7ddecb42005-04-06 23:51:40 +00001002 Amount = 32-Amount;
Nate Begemancd08e4c2005-04-09 20:09:12 +00001003 if (Op0Opc == ISD::SHL) IsRotate = true;
Nate Begeman7ddecb42005-04-06 23:51:40 +00001004 break;
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001005 case ISD::AND:
Nate Begeman7ddecb42005-04-06 23:51:40 +00001006 InsMask &= (unsigned)CN->getValue();
1007 break;
1008 }
1009 } else {
1010 return false;
1011 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001012
Nate Begeman7ddecb42005-04-06 23:51:40 +00001013 // Verify that the Target mask and Insert mask together form a full word mask
1014 // and that the Insert mask is a run of set bits (which implies both are runs
1015 // of set bits). Given that, Select the arguments and generate the rlwimi
1016 // instruction.
1017 unsigned MB, ME;
1018 if (((TgtMask ^ InsMask) == 0xFFFFFFFF) && IsRunOfOnes(InsMask, MB, ME)) {
1019 unsigned Tmp1, Tmp2;
Nate Begemancd08e4c2005-04-09 20:09:12 +00001020 // Check for rotlwi / rotrwi here, a special case of bitfield insert
1021 // where both bitfield halves are sourced from the same value.
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001022 if (IsRotate &&
Nate Begemancd08e4c2005-04-09 20:09:12 +00001023 OR.getOperand(0).getOperand(0) == OR.getOperand(1).getOperand(0)) {
Nate Begemancd08e4c2005-04-09 20:09:12 +00001024 Tmp1 = SelectExpr(OR.getOperand(0).getOperand(0));
1025 BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(Amount)
1026 .addImm(0).addImm(31);
1027 return true;
1028 }
Nate Begeman7ddecb42005-04-06 23:51:40 +00001029 if (Op0Opc == ISD::AND)
1030 Tmp1 = SelectExpr(OR.getOperand(0).getOperand(0));
1031 else
1032 Tmp1 = SelectExpr(OR.getOperand(0));
1033 Tmp2 = SelectExpr(OR.getOperand(1).getOperand(0));
1034 BuildMI(BB, PPC::RLWIMI, 5, Result).addReg(Tmp1).addReg(Tmp2)
1035 .addImm(Amount).addImm(MB).addImm(ME);
1036 return true;
1037 }
1038 return false;
1039}
1040
Nate Begeman3664cef2005-04-13 22:14:14 +00001041/// FoldIfWideZeroExtend - 32 bit PowerPC implicit masks shift amounts to the
1042/// low six bits. If the shift amount is an ISD::AND node with a mask that is
1043/// wider than the implicit mask, then we can get rid of the AND and let the
1044/// shift do the mask.
1045unsigned ISel::FoldIfWideZeroExtend(SDOperand N) {
1046 unsigned C;
1047 if (N.getOpcode() == ISD::AND &&
1048 5 == getImmediateForOpcode(N.getOperand(1), ISD::AND, C) && // isMask
1049 31 == (C & 0xFFFF) && // ME
1050 26 >= (C >> 16)) // MB
1051 return SelectExpr(N.getOperand(0));
1052 else
1053 return SelectExpr(N);
1054}
1055
Nate Begeman1cbf3ab2005-04-18 07:48:09 +00001056unsigned ISel::SelectCC(SDOperand CC, unsigned& Opc, bool &Inv, unsigned& Idx) {
Nate Begeman1b7f7fb2005-04-13 23:15:44 +00001057 unsigned Result, Tmp1, Tmp2;
Nate Begeman9765c252005-04-12 21:22:28 +00001058 bool AlreadySelected = false;
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001059 static const unsigned CompareOpcodes[] =
Nate Begemandffcfcc2005-04-01 00:32:34 +00001060 { PPC::FCMPU, PPC::FCMPU, PPC::CMPW, PPC::CMPLW };
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001061
Nate Begeman1b7f7fb2005-04-13 23:15:44 +00001062 // Allocate a condition register for this expression
1063 Result = RegMap->createVirtualRegister(PPC32::CRRCRegisterClass);
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001064
Nate Begemandffcfcc2005-04-01 00:32:34 +00001065 // If the first operand to the select is a SETCC node, then we can fold it
1066 // into the branch that selects which value to return.
Nate Begeman16ac7092005-04-18 02:43:24 +00001067 if (SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(CC.Val)) {
Nate Begemandffcfcc2005-04-01 00:32:34 +00001068 bool U;
1069 Opc = getBCCForSetCC(SetCC->getCondition(), U);
Nate Begeman1cbf3ab2005-04-18 07:48:09 +00001070 Idx = getCRIdxForSetCC(SetCC->getCondition(), Inv);
Nate Begemandffcfcc2005-04-01 00:32:34 +00001071
Nate Begeman439b4442005-04-05 04:22:58 +00001072 // Pass the optional argument U to getImmediateForOpcode for SETCC,
Nate Begemandffcfcc2005-04-01 00:32:34 +00001073 // so that it knows whether the SETCC immediate range is signed or not.
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001074 if (1 == getImmediateForOpcode(SetCC->getOperand(1), ISD::SETCC,
Nate Begeman439b4442005-04-05 04:22:58 +00001075 Tmp2, U)) {
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001076 // For comparisons against zero, we can implicity set CR0 if a recording
Nate Begemanc7bd4822005-04-11 06:34:10 +00001077 // variant (e.g. 'or.' instead of 'or') of the instruction that defines
1078 // operand zero of the SetCC node is available.
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001079 if (0 == Tmp2 &&
Nate Begeman9765c252005-04-12 21:22:28 +00001080 NodeHasRecordingVariant(SetCC->getOperand(0).getOpcode()) &&
1081 SetCC->getOperand(0).Val->hasOneUse()) {
Nate Begemanc7bd4822005-04-11 06:34:10 +00001082 RecordSuccess = false;
1083 Tmp1 = SelectExpr(SetCC->getOperand(0), true);
1084 if (RecordSuccess) {
1085 ++Recorded;
Nate Begeman7bfba7d2005-04-14 09:45:08 +00001086 BuildMI(BB, PPC::MCRF, 1, Result).addReg(PPC::CR0);
1087 return Result;
Nate Begemanc7bd4822005-04-11 06:34:10 +00001088 }
1089 AlreadySelected = true;
1090 }
1091 // If we could not implicitly set CR0, then emit a compare immediate
1092 // instead.
1093 if (!AlreadySelected) Tmp1 = SelectExpr(SetCC->getOperand(0));
Nate Begemandffcfcc2005-04-01 00:32:34 +00001094 if (U)
Nate Begeman1b7f7fb2005-04-13 23:15:44 +00001095 BuildMI(BB, PPC::CMPLWI, 2, Result).addReg(Tmp1).addImm(Tmp2);
Nate Begemandffcfcc2005-04-01 00:32:34 +00001096 else
Nate Begeman1b7f7fb2005-04-13 23:15:44 +00001097 BuildMI(BB, PPC::CMPWI, 2, Result).addReg(Tmp1).addSImm(Tmp2);
Nate Begemandffcfcc2005-04-01 00:32:34 +00001098 } else {
1099 bool IsInteger = MVT::isInteger(SetCC->getOperand(0).getValueType());
1100 unsigned CompareOpc = CompareOpcodes[2 * IsInteger + U];
Nate Begemanc7bd4822005-04-11 06:34:10 +00001101 Tmp1 = SelectExpr(SetCC->getOperand(0));
Nate Begemandffcfcc2005-04-01 00:32:34 +00001102 Tmp2 = SelectExpr(SetCC->getOperand(1));
Nate Begeman1b7f7fb2005-04-13 23:15:44 +00001103 BuildMI(BB, CompareOpc, 2, Result).addReg(Tmp1).addReg(Tmp2);
Nate Begemandffcfcc2005-04-01 00:32:34 +00001104 }
1105 } else {
Nate Begemanf8b02942005-04-15 22:12:16 +00001106 if (PPCCRopts)
Nate Begeman1cbf3ab2005-04-18 07:48:09 +00001107 return SelectCCExpr(CC, Opc, Inv, Idx);
1108 // If this isn't a SetCC, then select the value and compare it against zero,
1109 // treating it as if it were a boolean.
Nate Begeman9765c252005-04-12 21:22:28 +00001110 Opc = PPC::BNE;
Nate Begeman1cbf3ab2005-04-18 07:48:09 +00001111 Idx = getCRIdxForSetCC(ISD::SETNE, Inv);
Nate Begemandffcfcc2005-04-01 00:32:34 +00001112 Tmp1 = SelectExpr(CC);
Nate Begeman1b7f7fb2005-04-13 23:15:44 +00001113 BuildMI(BB, PPC::CMPLWI, 2, Result).addReg(Tmp1).addImm(0);
Nate Begemandffcfcc2005-04-01 00:32:34 +00001114 }
Nate Begeman1b7f7fb2005-04-13 23:15:44 +00001115 return Result;
Nate Begemandffcfcc2005-04-01 00:32:34 +00001116}
1117
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001118unsigned ISel::SelectCCExpr(SDOperand N, unsigned& Opc, bool &Inv,
Nate Begeman1cbf3ab2005-04-18 07:48:09 +00001119 unsigned &Idx) {
1120 bool Inv0, Inv1;
1121 unsigned Idx0, Idx1, CROpc, Opc1, Tmp1, Tmp2;
1122
1123 // Allocate a condition register for this expression
1124 unsigned Result = RegMap->createVirtualRegister(PPC32::CRRCRegisterClass);
1125
1126 // Check for the operations we support:
1127 switch(N.getOpcode()) {
1128 default:
1129 Opc = PPC::BNE;
1130 Idx = getCRIdxForSetCC(ISD::SETNE, Inv);
1131 Tmp1 = SelectExpr(N);
1132 BuildMI(BB, PPC::CMPLWI, 2, Result).addReg(Tmp1).addImm(0);
1133 break;
1134 case ISD::OR:
1135 case ISD::AND:
1136 ++MultiBranch;
1137 Tmp1 = SelectCCExpr(N.getOperand(0), Opc, Inv0, Idx0);
1138 Tmp2 = SelectCCExpr(N.getOperand(1), Opc1, Inv1, Idx1);
1139 CROpc = getCROpForSetCC(N.getOpcode(), Inv0, Inv1);
1140 if (Inv0 && !Inv1) {
1141 std::swap(Tmp1, Tmp2);
1142 std::swap(Idx0, Idx1);
1143 Opc = Opc1;
1144 }
1145 if (Inv0 && Inv1) Opc = PPC32InstrInfo::invertPPCBranchOpcode(Opc);
1146 BuildMI(BB, CROpc, 5, Result).addImm(Idx0).addReg(Tmp1).addImm(Idx0)
1147 .addReg(Tmp2).addImm(Idx1);
1148 Inv = false;
1149 Idx = Idx0;
1150 break;
1151 case ISD::SETCC:
1152 Tmp1 = SelectCC(N, Opc, Inv, Idx);
1153 Result = Tmp1;
1154 break;
1155 }
1156 return Result;
1157}
1158
Nate Begemandffcfcc2005-04-01 00:32:34 +00001159/// Check to see if the load is a constant offset from a base register
Nate Begeman04730362005-04-01 04:45:11 +00001160bool ISel::SelectAddr(SDOperand N, unsigned& Reg, int& offset)
Nate Begemana9795f82005-03-24 04:41:43 +00001161{
Nate Begeman96fc6812005-03-31 02:05:53 +00001162 unsigned imm = 0, opcode = N.getOpcode();
Nate Begeman04730362005-04-01 04:45:11 +00001163 if (N.getOpcode() == ISD::ADD) {
1164 Reg = SelectExpr(N.getOperand(0));
Nate Begeman439b4442005-04-05 04:22:58 +00001165 if (1 == getImmediateForOpcode(N.getOperand(1), opcode, imm)) {
Nate Begeman96fc6812005-03-31 02:05:53 +00001166 offset = imm;
Nate Begeman04730362005-04-01 04:45:11 +00001167 return false;
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001168 }
Nate Begeman04730362005-04-01 04:45:11 +00001169 offset = SelectExpr(N.getOperand(1));
1170 return true;
1171 }
Nate Begemana9795f82005-03-24 04:41:43 +00001172 Reg = SelectExpr(N);
1173 offset = 0;
Nate Begeman04730362005-04-01 04:45:11 +00001174 return false;
Nate Begemana9795f82005-03-24 04:41:43 +00001175}
1176
1177void ISel::SelectBranchCC(SDOperand N)
1178{
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001179 MachineBasicBlock *Dest =
Nate Begemana9795f82005-03-24 04:41:43 +00001180 cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
Nate Begeman3e897162005-03-31 23:55:40 +00001181
Nate Begeman1cbf3ab2005-04-18 07:48:09 +00001182 bool Inv;
1183 unsigned Opc, CCReg, Idx;
Nate Begemana9795f82005-03-24 04:41:43 +00001184 Select(N.getOperand(0)); //chain
Nate Begeman1cbf3ab2005-04-18 07:48:09 +00001185 CCReg = SelectCC(N.getOperand(1), Opc, Inv, Idx);
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001186
Nate Begemancd08e4c2005-04-09 20:09:12 +00001187 // Iterate to the next basic block, unless we're already at the end of the
1188 ilist<MachineBasicBlock>::iterator It = BB, E = BB->getParent()->end();
Nate Begeman706471e2005-04-09 23:35:05 +00001189 if (++It == E) It = BB;
Nate Begemancd08e4c2005-04-09 20:09:12 +00001190
1191 // If this is a two way branch, then grab the fallthrough basic block argument
1192 // and build a PowerPC branch pseudo-op, suitable for long branch conversion
1193 // if necessary by the branch selection pass. Otherwise, emit a standard
1194 // conditional branch.
1195 if (N.getOpcode() == ISD::BRCONDTWOWAY) {
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001196 MachineBasicBlock *Fallthrough =
Nate Begemancd08e4c2005-04-09 20:09:12 +00001197 cast<BasicBlockSDNode>(N.getOperand(3))->getBasicBlock();
1198 if (Dest != It) {
Nate Begeman1b7f7fb2005-04-13 23:15:44 +00001199 BuildMI(BB, PPC::COND_BRANCH, 4).addReg(CCReg).addImm(Opc)
Nate Begemancd08e4c2005-04-09 20:09:12 +00001200 .addMBB(Dest).addMBB(Fallthrough);
1201 if (Fallthrough != It)
1202 BuildMI(BB, PPC::B, 1).addMBB(Fallthrough);
1203 } else {
1204 if (Fallthrough != It) {
1205 Opc = PPC32InstrInfo::invertPPCBranchOpcode(Opc);
Nate Begeman1b7f7fb2005-04-13 23:15:44 +00001206 BuildMI(BB, PPC::COND_BRANCH, 4).addReg(CCReg).addImm(Opc)
Nate Begemancd08e4c2005-04-09 20:09:12 +00001207 .addMBB(Fallthrough).addMBB(Dest);
1208 }
1209 }
1210 } else {
Nate Begeman1b7f7fb2005-04-13 23:15:44 +00001211 BuildMI(BB, PPC::COND_BRANCH, 4).addReg(CCReg).addImm(Opc)
Nate Begeman27499e32005-04-10 01:48:29 +00001212 .addMBB(Dest).addMBB(It);
Nate Begemancd08e4c2005-04-09 20:09:12 +00001213 }
Nate Begemana9795f82005-03-24 04:41:43 +00001214 return;
1215}
1216
1217unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
1218{
1219 unsigned Tmp1, Tmp2, Tmp3;
1220 unsigned Opc = 0;
1221 SDNode *Node = N.Val;
1222 MVT::ValueType DestType = N.getValueType();
1223 unsigned opcode = N.getOpcode();
1224
1225 switch (opcode) {
1226 default:
1227 Node->dump();
1228 assert(0 && "Node not handled!\n");
1229
Nate Begeman23afcfb2005-03-29 22:48:55 +00001230 case ISD::SELECT: {
Nate Begeman3e897162005-03-31 23:55:40 +00001231 // Attempt to generate FSEL. We can do this whenever we have an FP result,
1232 // and an FP comparison in the SetCC node.
1233 SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(N.getOperand(0).Val);
1234 if (SetCC && N.getOperand(0).getOpcode() == ISD::SETCC &&
1235 !MVT::isInteger(SetCC->getOperand(0).getValueType()) &&
1236 SetCC->getCondition() != ISD::SETEQ &&
1237 SetCC->getCondition() != ISD::SETNE) {
1238 MVT::ValueType VT = SetCC->getOperand(0).getValueType();
Nate Begeman3e897162005-03-31 23:55:40 +00001239 unsigned TV = SelectExpr(N.getOperand(1)); // Use if TRUE
1240 unsigned FV = SelectExpr(N.getOperand(2)); // Use if FALSE
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001241
Nate Begeman3e897162005-03-31 23:55:40 +00001242 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(SetCC->getOperand(1));
1243 if (CN && (CN->isExactlyValue(-0.0) || CN->isExactlyValue(0.0))) {
1244 switch(SetCC->getCondition()) {
1245 default: assert(0 && "Invalid FSEL condition"); abort();
1246 case ISD::SETULT:
1247 case ISD::SETLT:
Nate Begemanaf4ab1b2005-04-09 09:33:07 +00001248 std::swap(TV, FV); // fsel is natively setge, swap operands for setlt
Nate Begeman3e897162005-03-31 23:55:40 +00001249 case ISD::SETUGE:
1250 case ISD::SETGE:
Nate Begemanaf4ab1b2005-04-09 09:33:07 +00001251 Tmp1 = SelectExpr(SetCC->getOperand(0)); // Val to compare against
Nate Begeman3e897162005-03-31 23:55:40 +00001252 BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp1).addReg(TV).addReg(FV);
1253 return Result;
1254 case ISD::SETUGT:
Nate Begemanaf4ab1b2005-04-09 09:33:07 +00001255 case ISD::SETGT:
1256 std::swap(TV, FV); // fsel is natively setge, swap operands for setlt
Nate Begeman3e897162005-03-31 23:55:40 +00001257 case ISD::SETULE:
1258 case ISD::SETLE: {
Nate Begemanaf4ab1b2005-04-09 09:33:07 +00001259 if (SetCC->getOperand(0).getOpcode() == ISD::FNEG) {
1260 Tmp2 = SelectExpr(SetCC->getOperand(0).getOperand(0));
1261 } else {
1262 Tmp2 = MakeReg(VT);
1263 Tmp1 = SelectExpr(SetCC->getOperand(0)); // Val to compare against
1264 BuildMI(BB, PPC::FNEG, 1, Tmp2).addReg(Tmp1);
1265 }
Nate Begeman3e897162005-03-31 23:55:40 +00001266 BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp2).addReg(TV).addReg(FV);
1267 return Result;
1268 }
1269 }
1270 } else {
1271 Opc = (MVT::f64 == VT) ? PPC::FSUB : PPC::FSUBS;
Nate Begemanaf4ab1b2005-04-09 09:33:07 +00001272 Tmp1 = SelectExpr(SetCC->getOperand(0)); // Val to compare against
Nate Begeman3e897162005-03-31 23:55:40 +00001273 Tmp2 = SelectExpr(SetCC->getOperand(1));
1274 Tmp3 = MakeReg(VT);
1275 switch(SetCC->getCondition()) {
1276 default: assert(0 && "Invalid FSEL condition"); abort();
1277 case ISD::SETULT:
1278 case ISD::SETLT:
1279 BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
1280 BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(FV).addReg(TV);
1281 return Result;
1282 case ISD::SETUGE:
1283 case ISD::SETGE:
1284 BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
1285 BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(TV).addReg(FV);
1286 return Result;
1287 case ISD::SETUGT:
1288 case ISD::SETGT:
1289 BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp2).addReg(Tmp1);
1290 BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(FV).addReg(TV);
1291 return Result;
1292 case ISD::SETULE:
1293 case ISD::SETLE:
1294 BuildMI(BB, Opc, 2, Tmp3).addReg(Tmp2).addReg(Tmp1);
1295 BuildMI(BB, PPC::FSEL, 3, Result).addReg(Tmp3).addReg(TV).addReg(FV);
1296 return Result;
1297 }
1298 }
1299 assert(0 && "Should never get here");
1300 return 0;
1301 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001302
Nate Begeman1cbf3ab2005-04-18 07:48:09 +00001303 bool Inv;
Nate Begeman31318e42005-04-01 07:21:30 +00001304 unsigned TrueValue = SelectExpr(N.getOperand(1)); //Use if TRUE
1305 unsigned FalseValue = SelectExpr(N.getOperand(2)); //Use if FALSE
Nate Begeman1cbf3ab2005-04-18 07:48:09 +00001306 unsigned CCReg = SelectCC(N.getOperand(0), Opc, Inv, Tmp3);
Nate Begeman31318e42005-04-01 07:21:30 +00001307
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001308 // Create an iterator with which to insert the MBB for copying the false
Nate Begeman23afcfb2005-03-29 22:48:55 +00001309 // value and the MBB to hold the PHI instruction for this SetCC.
1310 MachineBasicBlock *thisMBB = BB;
1311 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1312 ilist<MachineBasicBlock>::iterator It = BB;
1313 ++It;
1314
1315 // thisMBB:
1316 // ...
1317 // TrueVal = ...
Nate Begeman1b7f7fb2005-04-13 23:15:44 +00001318 // cmpTY ccX, r1, r2
Nate Begeman23afcfb2005-03-29 22:48:55 +00001319 // bCC copy1MBB
1320 // fallthrough --> copy0MBB
Nate Begeman23afcfb2005-03-29 22:48:55 +00001321 MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
1322 MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
Nate Begeman1b7f7fb2005-04-13 23:15:44 +00001323 BuildMI(BB, Opc, 2).addReg(CCReg).addMBB(sinkMBB);
Nate Begeman23afcfb2005-03-29 22:48:55 +00001324 MachineFunction *F = BB->getParent();
1325 F->getBasicBlockList().insert(It, copy0MBB);
1326 F->getBasicBlockList().insert(It, sinkMBB);
1327 // Update machine-CFG edges
1328 BB->addSuccessor(copy0MBB);
1329 BB->addSuccessor(sinkMBB);
1330
1331 // copy0MBB:
1332 // %FalseValue = ...
1333 // # fallthrough to sinkMBB
1334 BB = copy0MBB;
Nate Begeman23afcfb2005-03-29 22:48:55 +00001335 // Update machine-CFG edges
1336 BB->addSuccessor(sinkMBB);
1337
1338 // sinkMBB:
1339 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1340 // ...
1341 BB = sinkMBB;
1342 BuildMI(BB, PPC::PHI, 4, Result).addReg(FalseValue)
1343 .addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB);
1344 return Result;
1345 }
Nate Begeman27eeb002005-04-02 05:59:34 +00001346
1347 case ISD::FNEG:
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001348 if (!NoExcessFPPrecision &&
Nate Begeman93075ec2005-04-04 23:40:36 +00001349 ISD::ADD == N.getOperand(0).getOpcode() &&
1350 N.getOperand(0).Val->hasOneUse() &&
1351 ISD::MUL == N.getOperand(0).getOperand(0).getOpcode() &&
1352 N.getOperand(0).getOperand(0).Val->hasOneUse()) {
Nate Begeman80196b12005-04-05 00:15:08 +00001353 ++FusedFP; // Statistic
Nate Begeman93075ec2005-04-04 23:40:36 +00001354 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(0));
1355 Tmp2 = SelectExpr(N.getOperand(0).getOperand(0).getOperand(1));
1356 Tmp3 = SelectExpr(N.getOperand(0).getOperand(1));
1357 Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS;
1358 BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001359 } else if (!NoExcessFPPrecision &&
Nate Begemane88aa5b2005-04-09 03:05:51 +00001360 ISD::ADD == N.getOperand(0).getOpcode() &&
Nate Begeman93075ec2005-04-04 23:40:36 +00001361 N.getOperand(0).Val->hasOneUse() &&
Nate Begemane88aa5b2005-04-09 03:05:51 +00001362 ISD::MUL == N.getOperand(0).getOperand(1).getOpcode() &&
1363 N.getOperand(0).getOperand(1).Val->hasOneUse()) {
Nate Begeman80196b12005-04-05 00:15:08 +00001364 ++FusedFP; // Statistic
Nate Begemane88aa5b2005-04-09 03:05:51 +00001365 Tmp1 = SelectExpr(N.getOperand(0).getOperand(1).getOperand(0));
1366 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1).getOperand(1));
1367 Tmp3 = SelectExpr(N.getOperand(0).getOperand(0));
1368 Opc = DestType == MVT::f64 ? PPC::FNMADD : PPC::FNMADDS;
Nate Begeman93075ec2005-04-04 23:40:36 +00001369 BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
1370 } else if (ISD::FABS == N.getOperand(0).getOpcode()) {
Nate Begeman27eeb002005-04-02 05:59:34 +00001371 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
1372 BuildMI(BB, PPC::FNABS, 1, Result).addReg(Tmp1);
1373 } else {
1374 Tmp1 = SelectExpr(N.getOperand(0));
1375 BuildMI(BB, PPC::FNEG, 1, Result).addReg(Tmp1);
1376 }
1377 return Result;
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001378
Nate Begeman27eeb002005-04-02 05:59:34 +00001379 case ISD::FABS:
1380 Tmp1 = SelectExpr(N.getOperand(0));
1381 BuildMI(BB, PPC::FABS, 1, Result).addReg(Tmp1);
1382 return Result;
1383
Nate Begemana9795f82005-03-24 04:41:43 +00001384 case ISD::FP_ROUND:
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001385 assert (DestType == MVT::f32 &&
1386 N.getOperand(0).getValueType() == MVT::f64 &&
Nate Begemana9795f82005-03-24 04:41:43 +00001387 "only f64 to f32 conversion supported here");
1388 Tmp1 = SelectExpr(N.getOperand(0));
1389 BuildMI(BB, PPC::FRSP, 1, Result).addReg(Tmp1);
1390 return Result;
1391
1392 case ISD::FP_EXTEND:
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001393 assert (DestType == MVT::f64 &&
1394 N.getOperand(0).getValueType() == MVT::f32 &&
Nate Begemana9795f82005-03-24 04:41:43 +00001395 "only f32 to f64 conversion supported here");
1396 Tmp1 = SelectExpr(N.getOperand(0));
1397 BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1);
1398 return Result;
1399
1400 case ISD::CopyFromReg:
Nate Begemanf2622612005-03-26 02:17:46 +00001401 if (Result == 1)
1402 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
1403 Tmp1 = dyn_cast<RegSDNode>(Node)->getReg();
1404 BuildMI(BB, PPC::FMR, 1, Result).addReg(Tmp1);
1405 return Result;
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001406
Nate Begeman6d369cc2005-04-01 01:08:07 +00001407 case ISD::ConstantFP: {
Nate Begeman6d369cc2005-04-01 01:08:07 +00001408 ConstantFPSDNode *CN = cast<ConstantFPSDNode>(N);
Nate Begeman6b559972005-04-01 02:59:27 +00001409 Result = getConstDouble(CN->getValue(), Result);
Nate Begeman6d369cc2005-04-01 01:08:07 +00001410 return Result;
1411 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001412
Nate Begemana9795f82005-03-24 04:41:43 +00001413 case ISD::ADD:
Nate Begeman93075ec2005-04-04 23:40:36 +00001414 if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL &&
1415 N.getOperand(0).Val->hasOneUse()) {
1416 ++FusedFP; // Statistic
1417 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
1418 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
1419 Tmp3 = SelectExpr(N.getOperand(1));
1420 Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS;
1421 BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
1422 return Result;
1423 }
Nate Begemane88aa5b2005-04-09 03:05:51 +00001424 if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::MUL &&
1425 N.getOperand(1).Val->hasOneUse()) {
1426 ++FusedFP; // Statistic
1427 Tmp1 = SelectExpr(N.getOperand(1).getOperand(0));
1428 Tmp2 = SelectExpr(N.getOperand(1).getOperand(1));
1429 Tmp3 = SelectExpr(N.getOperand(0));
1430 Opc = DestType == MVT::f64 ? PPC::FMADD : PPC::FMADDS;
1431 BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
1432 return Result;
1433 }
Nate Begeman93075ec2005-04-04 23:40:36 +00001434 Opc = DestType == MVT::f64 ? PPC::FADD : PPC::FADDS;
1435 Tmp1 = SelectExpr(N.getOperand(0));
1436 Tmp2 = SelectExpr(N.getOperand(1));
1437 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1438 return Result;
1439
Nate Begemana9795f82005-03-24 04:41:43 +00001440 case ISD::SUB:
Nate Begeman93075ec2005-04-04 23:40:36 +00001441 if (!NoExcessFPPrecision && N.getOperand(0).getOpcode() == ISD::MUL &&
1442 N.getOperand(0).Val->hasOneUse()) {
1443 ++FusedFP; // Statistic
1444 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
1445 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
1446 Tmp3 = SelectExpr(N.getOperand(1));
1447 Opc = DestType == MVT::f64 ? PPC::FMSUB : PPC::FMSUBS;
1448 BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
1449 return Result;
1450 }
Nate Begemane88aa5b2005-04-09 03:05:51 +00001451 if (!NoExcessFPPrecision && N.getOperand(1).getOpcode() == ISD::MUL &&
1452 N.getOperand(1).Val->hasOneUse()) {
1453 ++FusedFP; // Statistic
1454 Tmp1 = SelectExpr(N.getOperand(1).getOperand(0));
1455 Tmp2 = SelectExpr(N.getOperand(1).getOperand(1));
1456 Tmp3 = SelectExpr(N.getOperand(0));
1457 Opc = DestType == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS;
1458 BuildMI(BB, Opc, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
1459 return Result;
1460 }
Nate Begeman93075ec2005-04-04 23:40:36 +00001461 Opc = DestType == MVT::f64 ? PPC::FSUB : PPC::FSUBS;
1462 Tmp1 = SelectExpr(N.getOperand(0));
1463 Tmp2 = SelectExpr(N.getOperand(1));
1464 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1465 return Result;
1466
1467 case ISD::MUL:
Nate Begemana9795f82005-03-24 04:41:43 +00001468 case ISD::SDIV:
1469 switch( opcode ) {
1470 case ISD::MUL: Opc = DestType == MVT::f64 ? PPC::FMUL : PPC::FMULS; break;
Nate Begemana9795f82005-03-24 04:41:43 +00001471 case ISD::SDIV: Opc = DestType == MVT::f64 ? PPC::FDIV : PPC::FDIVS; break;
1472 };
Nate Begemana9795f82005-03-24 04:41:43 +00001473 Tmp1 = SelectExpr(N.getOperand(0));
1474 Tmp2 = SelectExpr(N.getOperand(1));
1475 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
1476 return Result;
1477
Nate Begemana9795f82005-03-24 04:41:43 +00001478 case ISD::UINT_TO_FP:
Nate Begemanfdcf3412005-03-30 19:38:35 +00001479 case ISD::SINT_TO_FP: {
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001480 assert (N.getOperand(0).getValueType() == MVT::i32
Nate Begemanfdcf3412005-03-30 19:38:35 +00001481 && "int to float must operate on i32");
1482 bool IsUnsigned = (ISD::UINT_TO_FP == opcode);
1483 Tmp1 = SelectExpr(N.getOperand(0)); // Get the operand register
1484 Tmp2 = MakeReg(MVT::f64); // temp reg to load the integer value into
1485 Tmp3 = MakeReg(MVT::i32); // temp reg to hold the conversion constant
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001486
Nate Begemanfdcf3412005-03-30 19:38:35 +00001487 int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8);
1488 MachineConstantPool *CP = BB->getParent()->getConstantPool();
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001489
Nate Begemanfdcf3412005-03-30 19:38:35 +00001490 if (IsUnsigned) {
Nate Begeman709c8062005-04-10 06:06:10 +00001491 unsigned ConstF = getConstDouble(0x1.000000p52);
Nate Begemanfdcf3412005-03-30 19:38:35 +00001492 // Store the hi & low halves of the fp value, currently in int regs
1493 BuildMI(BB, PPC::LIS, 1, Tmp3).addSImm(0x4330);
1494 addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(Tmp3), FrameIdx);
1495 addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(Tmp1), FrameIdx, 4);
1496 addFrameReference(BuildMI(BB, PPC::LFD, 2, Tmp2), FrameIdx);
1497 // Generate the return value with a subtract
1498 BuildMI(BB, PPC::FSUB, 2, Result).addReg(Tmp2).addReg(ConstF);
1499 } else {
Nate Begeman709c8062005-04-10 06:06:10 +00001500 unsigned ConstF = getConstDouble(0x1.000008p52);
Nate Begemanfdcf3412005-03-30 19:38:35 +00001501 unsigned TmpL = MakeReg(MVT::i32);
Nate Begemanfdcf3412005-03-30 19:38:35 +00001502 // Store the hi & low halves of the fp value, currently in int regs
1503 BuildMI(BB, PPC::LIS, 1, Tmp3).addSImm(0x4330);
1504 addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(Tmp3), FrameIdx);
1505 BuildMI(BB, PPC::XORIS, 2, TmpL).addReg(Tmp1).addImm(0x8000);
1506 addFrameReference(BuildMI(BB, PPC::STW, 3).addReg(TmpL), FrameIdx, 4);
1507 addFrameReference(BuildMI(BB, PPC::LFD, 2, Tmp2), FrameIdx);
1508 // Generate the return value with a subtract
1509 BuildMI(BB, PPC::FSUB, 2, Result).addReg(Tmp2).addReg(ConstF);
1510 }
1511 return Result;
1512 }
Nate Begemana9795f82005-03-24 04:41:43 +00001513 }
Nate Begeman6b559972005-04-01 02:59:27 +00001514 assert(0 && "Should never get here");
Nate Begemana9795f82005-03-24 04:41:43 +00001515 return 0;
1516}
1517
Nate Begemanc7bd4822005-04-11 06:34:10 +00001518unsigned ISel::SelectExpr(SDOperand N, bool Recording) {
Nate Begemana9795f82005-03-24 04:41:43 +00001519 unsigned Result;
1520 unsigned Tmp1, Tmp2, Tmp3;
1521 unsigned Opc = 0;
1522 unsigned opcode = N.getOpcode();
1523
1524 SDNode *Node = N.Val;
1525 MVT::ValueType DestType = N.getValueType();
1526
1527 unsigned &Reg = ExprMap[N];
1528 if (Reg) return Reg;
1529
Nate Begeman27eeb002005-04-02 05:59:34 +00001530 switch (N.getOpcode()) {
1531 default:
Nate Begemana9795f82005-03-24 04:41:43 +00001532 Reg = Result = (N.getValueType() != MVT::Other) ?
Nate Begeman27eeb002005-04-02 05:59:34 +00001533 MakeReg(N.getValueType()) : 1;
1534 break;
1535 case ISD::CALL:
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001536 // If this is a call instruction, make sure to prepare ALL of the result
1537 // values as well as the chain.
Nate Begeman27eeb002005-04-02 05:59:34 +00001538 if (Node->getNumValues() == 1)
1539 Reg = Result = 1; // Void call, just a chain.
1540 else {
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001541 Result = MakeReg(Node->getValueType(0));
1542 ExprMap[N.getValue(0)] = Result;
Nate Begeman27eeb002005-04-02 05:59:34 +00001543 for (unsigned i = 1, e = N.Val->getNumValues()-1; i != e; ++i)
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001544 ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
Nate Begeman27eeb002005-04-02 05:59:34 +00001545 ExprMap[SDOperand(Node, Node->getNumValues()-1)] = 1;
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001546 }
Nate Begeman27eeb002005-04-02 05:59:34 +00001547 break;
1548 case ISD::ADD_PARTS:
1549 case ISD::SUB_PARTS:
1550 case ISD::SHL_PARTS:
1551 case ISD::SRL_PARTS:
1552 case ISD::SRA_PARTS:
1553 Result = MakeReg(Node->getValueType(0));
1554 ExprMap[N.getValue(0)] = Result;
1555 for (unsigned i = 1, e = N.Val->getNumValues(); i != e; ++i)
1556 ExprMap[N.getValue(i)] = MakeReg(Node->getValueType(i));
1557 break;
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001558 }
1559
Nate Begemane5846682005-04-04 06:52:38 +00001560 if (ISD::CopyFromReg == opcode)
1561 DestType = N.getValue(0).getValueType();
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001562
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001563 if (DestType == MVT::f64 || DestType == MVT::f32)
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001564 if (ISD::LOAD != opcode && ISD::EXTLOAD != opcode &&
Nate Begemana0e3e942005-04-10 01:14:13 +00001565 ISD::UNDEF != opcode && ISD::CALL != opcode)
Nate Begeman74d73452005-03-31 00:15:26 +00001566 return SelectExprFP(N, Result);
Nate Begemana9795f82005-03-24 04:41:43 +00001567
1568 switch (opcode) {
1569 default:
1570 Node->dump();
1571 assert(0 && "Node not handled!\n");
Nate Begemanfc1b1da2005-04-01 22:34:39 +00001572 case ISD::UNDEF:
Nate Begemanfc1b1da2005-04-01 22:34:39 +00001573 BuildMI(BB, PPC::IMPLICIT_DEF, 0, Result);
1574 return Result;
Nate Begemana9795f82005-03-24 04:41:43 +00001575 case ISD::DYNAMIC_STACKALLOC:
Nate Begeman5e966612005-03-24 06:28:42 +00001576 // Generate both result values. FIXME: Need a better commment here?
1577 if (Result != 1)
1578 ExprMap[N.getValue(1)] = 1;
1579 else
1580 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
1581
1582 // FIXME: We are currently ignoring the requested alignment for handling
1583 // greater than the stack alignment. This will need to be revisited at some
1584 // point. Align = N.getOperand(2);
1585 if (!isa<ConstantSDNode>(N.getOperand(2)) ||
1586 cast<ConstantSDNode>(N.getOperand(2))->getValue() != 0) {
1587 std::cerr << "Cannot allocate stack object with greater alignment than"
1588 << " the stack alignment yet!";
1589 abort();
1590 }
1591 Select(N.getOperand(0));
1592 Tmp1 = SelectExpr(N.getOperand(1));
1593 // Subtract size from stack pointer, thereby allocating some space.
1594 BuildMI(BB, PPC::SUBF, 2, PPC::R1).addReg(Tmp1).addReg(PPC::R1);
1595 // Put a pointer to the space into the result register by copying the SP
1596 BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R1).addReg(PPC::R1);
1597 return Result;
Nate Begemana9795f82005-03-24 04:41:43 +00001598
1599 case ISD::ConstantPool:
Nate Begemanca12a2b2005-03-28 22:28:37 +00001600 Tmp1 = cast<ConstantPoolSDNode>(N)->getIndex();
1601 Tmp2 = MakeReg(MVT::i32);
1602 BuildMI(BB, PPC::LOADHiAddr, 2, Tmp2).addReg(getGlobalBaseReg())
1603 .addConstantPoolIndex(Tmp1);
1604 BuildMI(BB, PPC::LA, 2, Result).addReg(Tmp2).addConstantPoolIndex(Tmp1);
1605 return Result;
Nate Begemana9795f82005-03-24 04:41:43 +00001606
1607 case ISD::FrameIndex:
Nate Begemanf3d08f32005-03-29 00:03:27 +00001608 Tmp1 = cast<FrameIndexSDNode>(N)->getIndex();
Nate Begeman58f718c2005-03-30 02:23:08 +00001609 addFrameReference(BuildMI(BB, PPC::ADDI, 2, Result), (int)Tmp1, 0, false);
Nate Begemanf3d08f32005-03-29 00:03:27 +00001610 return Result;
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001611
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001612 case ISD::GlobalAddress: {
1613 GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
Nate Begemanca12a2b2005-03-28 22:28:37 +00001614 Tmp1 = MakeReg(MVT::i32);
Nate Begemanc7b09f12005-03-25 08:34:25 +00001615 BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(getGlobalBaseReg())
1616 .addGlobalAddress(GV);
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001617 if (GV->hasWeakLinkage() || GV->isExternal()) {
1618 BuildMI(BB, PPC::LWZ, 2, Result).addGlobalAddress(GV).addReg(Tmp1);
1619 } else {
1620 BuildMI(BB, PPC::LA, 2, Result).addReg(Tmp1).addGlobalAddress(GV);
1621 }
1622 return Result;
1623 }
1624
Nate Begeman5e966612005-03-24 06:28:42 +00001625 case ISD::LOAD:
Nate Begemana9795f82005-03-24 04:41:43 +00001626 case ISD::EXTLOAD:
1627 case ISD::ZEXTLOAD:
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001628 case ISD::SEXTLOAD: {
Nate Begeman9db505c2005-03-28 19:36:43 +00001629 MVT::ValueType TypeBeingLoaded = (ISD::LOAD == opcode) ?
1630 Node->getValueType(0) : cast<MVTSDNode>(Node)->getExtraValueType();
Nate Begeman74d73452005-03-31 00:15:26 +00001631 bool sext = (ISD::SEXTLOAD == opcode);
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001632
Nate Begeman5e966612005-03-24 06:28:42 +00001633 // Make sure we generate both values.
1634 if (Result != 1)
1635 ExprMap[N.getValue(1)] = 1; // Generate the token
1636 else
1637 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
1638
1639 SDOperand Chain = N.getOperand(0);
1640 SDOperand Address = N.getOperand(1);
1641 Select(Chain);
1642
Nate Begeman9db505c2005-03-28 19:36:43 +00001643 switch (TypeBeingLoaded) {
Nate Begeman74d73452005-03-31 00:15:26 +00001644 default: Node->dump(); assert(0 && "Cannot load this type!");
Nate Begeman9db505c2005-03-28 19:36:43 +00001645 case MVT::i1: Opc = PPC::LBZ; break;
1646 case MVT::i8: Opc = PPC::LBZ; break;
1647 case MVT::i16: Opc = sext ? PPC::LHA : PPC::LHZ; break;
1648 case MVT::i32: Opc = PPC::LWZ; break;
Nate Begeman74d73452005-03-31 00:15:26 +00001649 case MVT::f32: Opc = PPC::LFS; break;
1650 case MVT::f64: Opc = PPC::LFD; break;
Nate Begeman5e966612005-03-24 06:28:42 +00001651 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001652
Nate Begeman74d73452005-03-31 00:15:26 +00001653 if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Address)) {
1654 Tmp1 = MakeReg(MVT::i32);
1655 int CPI = CP->getIndex();
1656 BuildMI(BB, PPC::LOADHiAddr, 2, Tmp1).addReg(getGlobalBaseReg())
1657 .addConstantPoolIndex(CPI);
1658 BuildMI(BB, Opc, 2, Result).addConstantPoolIndex(CPI).addReg(Tmp1);
Nate Begeman9db505c2005-03-28 19:36:43 +00001659 }
Nate Begeman74d73452005-03-31 00:15:26 +00001660 else if(Address.getOpcode() == ISD::FrameIndex) {
Nate Begeman58f718c2005-03-30 02:23:08 +00001661 Tmp1 = cast<FrameIndexSDNode>(Address)->getIndex();
1662 addFrameReference(BuildMI(BB, Opc, 2, Result), (int)Tmp1);
Nate Begeman5e966612005-03-24 06:28:42 +00001663 } else {
1664 int offset;
Nate Begeman04730362005-04-01 04:45:11 +00001665 bool idx = SelectAddr(Address, Tmp1, offset);
1666 if (idx) {
1667 Opc = IndexedOpForOp(Opc);
1668 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(offset);
1669 } else {
1670 BuildMI(BB, Opc, 2, Result).addSImm(offset).addReg(Tmp1);
1671 }
Nate Begeman5e966612005-03-24 06:28:42 +00001672 }
1673 return Result;
1674 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001675
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001676 case ISD::CALL: {
Nate Begemanfc1b1da2005-04-01 22:34:39 +00001677 unsigned GPR_idx = 0, FPR_idx = 0;
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001678 static const unsigned GPR[] = {
Nate Begemanfc1b1da2005-04-01 22:34:39 +00001679 PPC::R3, PPC::R4, PPC::R5, PPC::R6,
1680 PPC::R7, PPC::R8, PPC::R9, PPC::R10,
1681 };
1682 static const unsigned FPR[] = {
1683 PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
1684 PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
1685 };
1686
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001687 // Lower the chain for this call.
1688 Select(N.getOperand(0));
1689 ExprMap[N.getValue(Node->getNumValues()-1)] = 1;
Nate Begeman74d73452005-03-31 00:15:26 +00001690
Nate Begemand860aa62005-04-04 22:17:48 +00001691 MachineInstr *CallMI;
1692 // Emit the correct call instruction based on the type of symbol called.
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001693 if (GlobalAddressSDNode *GASD =
Nate Begemand860aa62005-04-04 22:17:48 +00001694 dyn_cast<GlobalAddressSDNode>(N.getOperand(1))) {
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001695 CallMI = BuildMI(PPC::CALLpcrel, 1).addGlobalAddress(GASD->getGlobal(),
Nate Begemand860aa62005-04-04 22:17:48 +00001696 true);
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001697 } else if (ExternalSymbolSDNode *ESSDN =
Nate Begemand860aa62005-04-04 22:17:48 +00001698 dyn_cast<ExternalSymbolSDNode>(N.getOperand(1))) {
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001699 CallMI = BuildMI(PPC::CALLpcrel, 1).addExternalSymbol(ESSDN->getSymbol(),
Nate Begemand860aa62005-04-04 22:17:48 +00001700 true);
1701 } else {
1702 Tmp1 = SelectExpr(N.getOperand(1));
1703 BuildMI(BB, PPC::OR, 2, PPC::R12).addReg(Tmp1).addReg(Tmp1);
1704 BuildMI(BB, PPC::MTCTR, 1).addReg(PPC::R12);
1705 CallMI = BuildMI(PPC::CALLindirect, 3).addImm(20).addImm(0)
1706 .addReg(PPC::R12);
1707 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001708
Nate Begemanfc1b1da2005-04-01 22:34:39 +00001709 // Load the register args to virtual regs
1710 std::vector<unsigned> ArgVR;
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001711 for(int i = 2, e = Node->getNumOperands(); i < e; ++i)
Nate Begemanfc1b1da2005-04-01 22:34:39 +00001712 ArgVR.push_back(SelectExpr(N.getOperand(i)));
1713
1714 // Copy the virtual registers into the appropriate argument register
1715 for(int i = 0, e = ArgVR.size(); i < e; ++i) {
1716 switch(N.getOperand(i+2).getValueType()) {
1717 default: Node->dump(); assert(0 && "Unknown value type for call");
1718 case MVT::i1:
1719 case MVT::i8:
1720 case MVT::i16:
1721 case MVT::i32:
1722 assert(GPR_idx < 8 && "Too many int args");
Nate Begemand860aa62005-04-04 22:17:48 +00001723 if (N.getOperand(i+2).getOpcode() != ISD::UNDEF) {
Nate Begemanfc1b1da2005-04-01 22:34:39 +00001724 BuildMI(BB, PPC::OR,2,GPR[GPR_idx]).addReg(ArgVR[i]).addReg(ArgVR[i]);
Nate Begemand860aa62005-04-04 22:17:48 +00001725 CallMI->addRegOperand(GPR[GPR_idx], MachineOperand::Use);
1726 }
Nate Begemanfc1b1da2005-04-01 22:34:39 +00001727 ++GPR_idx;
1728 break;
1729 case MVT::f64:
1730 case MVT::f32:
1731 assert(FPR_idx < 13 && "Too many fp args");
1732 BuildMI(BB, PPC::FMR, 1, FPR[FPR_idx]).addReg(ArgVR[i]);
Nate Begemand860aa62005-04-04 22:17:48 +00001733 CallMI->addRegOperand(FPR[FPR_idx], MachineOperand::Use);
Nate Begemanfc1b1da2005-04-01 22:34:39 +00001734 ++FPR_idx;
1735 break;
1736 }
1737 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001738
Nate Begemand860aa62005-04-04 22:17:48 +00001739 // Put the call instruction in the correct place in the MachineBasicBlock
1740 BB->push_back(CallMI);
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001741
1742 switch (Node->getValueType(0)) {
1743 default: assert(0 && "Unknown value type for call result!");
1744 case MVT::Other: return 1;
1745 case MVT::i1:
1746 case MVT::i8:
1747 case MVT::i16:
1748 case MVT::i32:
Nate Begemane5846682005-04-04 06:52:38 +00001749 if (Node->getValueType(1) == MVT::i32) {
1750 BuildMI(BB, PPC::OR, 2, Result+1).addReg(PPC::R3).addReg(PPC::R3);
1751 BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R4).addReg(PPC::R4);
1752 } else {
1753 BuildMI(BB, PPC::OR, 2, Result).addReg(PPC::R3).addReg(PPC::R3);
1754 }
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001755 break;
1756 case MVT::f32:
1757 case MVT::f64:
1758 BuildMI(BB, PPC::FMR, 1, Result).addReg(PPC::F1);
1759 break;
1760 }
1761 return Result+N.ResNo;
1762 }
Nate Begemana9795f82005-03-24 04:41:43 +00001763
1764 case ISD::SIGN_EXTEND:
1765 case ISD::SIGN_EXTEND_INREG:
1766 Tmp1 = SelectExpr(N.getOperand(0));
Nate Begeman9db505c2005-03-28 19:36:43 +00001767 switch(cast<MVTSDNode>(Node)->getExtraValueType()) {
1768 default: Node->dump(); assert(0 && "Unhandled SIGN_EXTEND type"); break;
Nate Begemanc7bd4822005-04-11 06:34:10 +00001769 case MVT::i16:
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001770 BuildMI(BB, PPC::EXTSH, 1, Result).addReg(Tmp1);
Nate Begeman9db505c2005-03-28 19:36:43 +00001771 break;
Nate Begemanc7bd4822005-04-11 06:34:10 +00001772 case MVT::i8:
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001773 BuildMI(BB, PPC::EXTSB, 1, Result).addReg(Tmp1);
Nate Begeman9db505c2005-03-28 19:36:43 +00001774 break;
Nate Begeman74747862005-03-29 22:24:51 +00001775 case MVT::i1:
1776 BuildMI(BB, PPC::SUBFIC, 2, Result).addReg(Tmp1).addSImm(0);
1777 break;
Nate Begeman9db505c2005-03-28 19:36:43 +00001778 }
Nate Begemana9795f82005-03-24 04:41:43 +00001779 return Result;
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001780
Nate Begemana9795f82005-03-24 04:41:43 +00001781 case ISD::CopyFromReg:
1782 if (Result == 1)
1783 Result = ExprMap[N.getValue(0)] = MakeReg(N.getValue(0).getValueType());
1784 Tmp1 = dyn_cast<RegSDNode>(Node)->getReg();
1785 BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp1).addReg(Tmp1);
1786 return Result;
1787
1788 case ISD::SHL:
Nate Begeman5e966612005-03-24 06:28:42 +00001789 Tmp1 = SelectExpr(N.getOperand(0));
1790 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
1791 Tmp2 = CN->getValue() & 0x1F;
Nate Begeman33162522005-03-29 21:54:38 +00001792 BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(Tmp2).addImm(0)
Nate Begeman5e966612005-03-24 06:28:42 +00001793 .addImm(31-Tmp2);
1794 } else {
Nate Begeman3664cef2005-04-13 22:14:14 +00001795 Tmp2 = FoldIfWideZeroExtend(N.getOperand(1));
Nate Begeman5e966612005-03-24 06:28:42 +00001796 BuildMI(BB, PPC::SLW, 2, Result).addReg(Tmp1).addReg(Tmp2);
1797 }
1798 return Result;
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001799
Nate Begeman5e966612005-03-24 06:28:42 +00001800 case ISD::SRL:
1801 Tmp1 = SelectExpr(N.getOperand(0));
1802 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
1803 Tmp2 = CN->getValue() & 0x1F;
Nate Begeman33162522005-03-29 21:54:38 +00001804 BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(32-Tmp2)
Nate Begeman5e966612005-03-24 06:28:42 +00001805 .addImm(Tmp2).addImm(31);
1806 } else {
Nate Begeman3664cef2005-04-13 22:14:14 +00001807 Tmp2 = FoldIfWideZeroExtend(N.getOperand(1));
Nate Begeman5e966612005-03-24 06:28:42 +00001808 BuildMI(BB, PPC::SRW, 2, Result).addReg(Tmp1).addReg(Tmp2);
1809 }
1810 return Result;
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001811
Nate Begeman5e966612005-03-24 06:28:42 +00001812 case ISD::SRA:
1813 Tmp1 = SelectExpr(N.getOperand(0));
1814 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
1815 Tmp2 = CN->getValue() & 0x1F;
1816 BuildMI(BB, PPC::SRAWI, 2, Result).addReg(Tmp1).addImm(Tmp2);
1817 } else {
Nate Begeman3664cef2005-04-13 22:14:14 +00001818 Tmp2 = FoldIfWideZeroExtend(N.getOperand(1));
Nate Begeman5e966612005-03-24 06:28:42 +00001819 BuildMI(BB, PPC::SRAW, 2, Result).addReg(Tmp1).addReg(Tmp2);
1820 }
1821 return Result;
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001822
Nate Begemand7c4a4a2005-05-11 23:43:56 +00001823 case ISD::CTLZ:
1824 Tmp1 = SelectExpr(N.getOperand(0));
1825 BuildMI(BB, PPC::CNTLZW, 1, Result).addReg(Tmp1);
1826 return Result;
1827
Nate Begemana9795f82005-03-24 04:41:43 +00001828 case ISD::ADD:
1829 assert (DestType == MVT::i32 && "Only do arithmetic on i32s!");
1830 Tmp1 = SelectExpr(N.getOperand(0));
Nate Begeman439b4442005-04-05 04:22:58 +00001831 switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) {
Nate Begemana9795f82005-03-24 04:41:43 +00001832 default: assert(0 && "unhandled result code");
1833 case 0: // No immediate
1834 Tmp2 = SelectExpr(N.getOperand(1));
1835 BuildMI(BB, PPC::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2);
1836 break;
1837 case 1: // Low immediate
1838 BuildMI(BB, PPC::ADDI, 2, Result).addReg(Tmp1).addSImm(Tmp2);
1839 break;
1840 case 2: // Shifted immediate
1841 BuildMI(BB, PPC::ADDIS, 2, Result).addReg(Tmp1).addSImm(Tmp2);
1842 break;
1843 }
1844 return Result;
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001845
Nate Begemana9795f82005-03-24 04:41:43 +00001846 case ISD::AND:
Nate Begeman1cbf3ab2005-04-18 07:48:09 +00001847 if (PPCCRopts) {
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001848 if (N.getOperand(0).getOpcode() == ISD::SETCC ||
Nate Begeman1cbf3ab2005-04-18 07:48:09 +00001849 N.getOperand(1).getOpcode() == ISD::SETCC) {
1850 bool Inv;
1851 Tmp1 = SelectCCExpr(N, Opc, Inv, Tmp2);
1852 MoveCRtoGPR(Tmp1, Inv, Tmp2, Result);
1853 return Result;
1854 }
1855 }
Nate Begeman7ddecb42005-04-06 23:51:40 +00001856 // FIXME: should add check in getImmediateForOpcode to return a value
1857 // indicating the immediate is a run of set bits so we can emit a bitfield
1858 // clear with RLWINM instead.
1859 switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) {
1860 default: assert(0 && "unhandled result code");
1861 case 0: // No immediate
Nate Begemand7c4a4a2005-05-11 23:43:56 +00001862 // Check for andc: and, (xor a, -1), b
1863 if (N.getOperand(0).getOpcode() == ISD::XOR &&
1864 N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
1865 cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->isAllOnesValue()) {
1866 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
1867 Tmp2 = SelectExpr(N.getOperand(1));
1868 BuildMI(BB, PPC::ANDC, 2, Result).addReg(Tmp2).addReg(Tmp1);
1869 return Result;
1870 }
1871 // It wasn't and-with-complement, emit a regular and
Chris Lattnercafb67b2005-05-09 17:39:48 +00001872 Tmp1 = SelectExpr(N.getOperand(0));
Nate Begeman7ddecb42005-04-06 23:51:40 +00001873 Tmp2 = SelectExpr(N.getOperand(1));
Nate Begemanc7bd4822005-04-11 06:34:10 +00001874 Opc = Recording ? PPC::ANDo : PPC::AND;
1875 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
Nate Begeman7ddecb42005-04-06 23:51:40 +00001876 break;
1877 case 1: // Low immediate
Chris Lattnercafb67b2005-05-09 17:39:48 +00001878 Tmp1 = SelectExpr(N.getOperand(0));
Nate Begeman7ddecb42005-04-06 23:51:40 +00001879 BuildMI(BB, PPC::ANDIo, 2, Result).addReg(Tmp1).addImm(Tmp2);
1880 break;
1881 case 2: // Shifted immediate
Chris Lattnercafb67b2005-05-09 17:39:48 +00001882 Tmp1 = SelectExpr(N.getOperand(0));
Nate Begeman7ddecb42005-04-06 23:51:40 +00001883 BuildMI(BB, PPC::ANDISo, 2, Result).addReg(Tmp1).addImm(Tmp2);
1884 break;
Nate Begeman9f833d32005-04-12 00:10:02 +00001885 case 5: // Bitfield mask
1886 Opc = Recording ? PPC::RLWINMo : PPC::RLWINM;
1887 Tmp3 = Tmp2 >> 16; // MB
1888 Tmp2 &= 0xFFFF; // ME
Chris Lattnercafb67b2005-05-09 17:39:48 +00001889
1890 if (N.getOperand(0).getOpcode() == ISD::SRL)
1891 if (ConstantSDNode *SA =
1892 dyn_cast<ConstantSDNode>(N.getOperand(0).getOperand(1))) {
1893
1894 // We can fold the RLWINM and the SRL together if the mask is
1895 // clearing the top bits which are rotated around.
1896 unsigned RotAmt = 32-(SA->getValue() & 31);
1897 if (Tmp2 <= RotAmt) {
1898 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
1899 BuildMI(BB, Opc, 4, Result).addReg(Tmp1).addImm(RotAmt)
1900 .addImm(Tmp3).addImm(Tmp2);
1901 break;
1902 }
1903 }
1904
1905 Tmp1 = SelectExpr(N.getOperand(0));
Nate Begeman9f833d32005-04-12 00:10:02 +00001906 BuildMI(BB, Opc, 4, Result).addReg(Tmp1).addImm(0)
1907 .addImm(Tmp3).addImm(Tmp2);
1908 break;
Nate Begeman7ddecb42005-04-06 23:51:40 +00001909 }
Nate Begemanc7bd4822005-04-11 06:34:10 +00001910 RecordSuccess = true;
Nate Begeman7ddecb42005-04-06 23:51:40 +00001911 return Result;
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001912
Nate Begemana9795f82005-03-24 04:41:43 +00001913 case ISD::OR:
Nate Begeman7ddecb42005-04-06 23:51:40 +00001914 if (SelectBitfieldInsert(N, Result))
1915 return Result;
Nate Begeman1cbf3ab2005-04-18 07:48:09 +00001916 if (PPCCRopts) {
Misha Brukmanb5f662f2005-04-21 23:30:14 +00001917 if (N.getOperand(0).getOpcode() == ISD::SETCC ||
Nate Begeman1cbf3ab2005-04-18 07:48:09 +00001918 N.getOperand(1).getOpcode() == ISD::SETCC) {
1919 bool Inv;
1920 Tmp1 = SelectCCExpr(N, Opc, Inv, Tmp2);
1921 MoveCRtoGPR(Tmp1, Inv, Tmp2, Result);
1922 return Result;
1923 }
1924 }
Nate Begemana9795f82005-03-24 04:41:43 +00001925 Tmp1 = SelectExpr(N.getOperand(0));
Nate Begeman439b4442005-04-05 04:22:58 +00001926 switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) {
Nate Begemana9795f82005-03-24 04:41:43 +00001927 default: assert(0 && "unhandled result code");
1928 case 0: // No immediate
1929 Tmp2 = SelectExpr(N.getOperand(1));
Nate Begemanc7bd4822005-04-11 06:34:10 +00001930 Opc = Recording ? PPC::ORo : PPC::OR;
1931 RecordSuccess = true;
1932 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
Nate Begemana9795f82005-03-24 04:41:43 +00001933 break;
1934 case 1: // Low immediate
Nate Begeman7ddecb42005-04-06 23:51:40 +00001935 BuildMI(BB, PPC::ORI, 2, Result).addReg(Tmp1).addImm(Tmp2);
Nate Begemana9795f82005-03-24 04:41:43 +00001936 break;
1937 case 2: // Shifted immediate
Nate Begeman7ddecb42005-04-06 23:51:40 +00001938 BuildMI(BB, PPC::ORIS, 2, Result).addReg(Tmp1).addImm(Tmp2);
Nate Begemana9795f82005-03-24 04:41:43 +00001939 break;
1940 }
1941 return Result;
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001942
Nate Begemanaa73a9f2005-04-03 11:20:20 +00001943 case ISD::XOR: {
1944 // Check for EQV: xor, (xor a, -1), b
1945 if (N.getOperand(0).getOpcode() == ISD::XOR &&
1946 N.getOperand(0).getOperand(1).getOpcode() == ISD::Constant &&
1947 cast<ConstantSDNode>(N.getOperand(0).getOperand(1))->isAllOnesValue()) {
Nate Begemanaa73a9f2005-04-03 11:20:20 +00001948 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
1949 Tmp2 = SelectExpr(N.getOperand(1));
1950 BuildMI(BB, PPC::EQV, 2, Result).addReg(Tmp1).addReg(Tmp2);
1951 return Result;
1952 }
Chris Lattner837a5212005-04-21 21:09:11 +00001953 // Check for NOT, NOR, EQV, and NAND: xor (copy, or, xor, and), -1
Nate Begemanaa73a9f2005-04-03 11:20:20 +00001954 if (N.getOperand(1).getOpcode() == ISD::Constant &&
1955 cast<ConstantSDNode>(N.getOperand(1))->isAllOnesValue()) {
Nate Begemanaa73a9f2005-04-03 11:20:20 +00001956 switch(N.getOperand(0).getOpcode()) {
1957 case ISD::OR:
1958 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
1959 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
1960 BuildMI(BB, PPC::NOR, 2, Result).addReg(Tmp1).addReg(Tmp2);
1961 break;
1962 case ISD::AND:
1963 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
1964 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
1965 BuildMI(BB, PPC::NAND, 2, Result).addReg(Tmp1).addReg(Tmp2);
1966 break;
Chris Lattner837a5212005-04-21 21:09:11 +00001967 case ISD::XOR:
1968 Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
1969 Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
1970 BuildMI(BB, PPC::EQV, 2, Result).addReg(Tmp1).addReg(Tmp2);
1971 break;
Nate Begemanaa73a9f2005-04-03 11:20:20 +00001972 default:
1973 Tmp1 = SelectExpr(N.getOperand(0));
1974 BuildMI(BB, PPC::NOR, 2, Result).addReg(Tmp1).addReg(Tmp1);
1975 break;
1976 }
1977 return Result;
1978 }
1979 Tmp1 = SelectExpr(N.getOperand(0));
Nate Begeman439b4442005-04-05 04:22:58 +00001980 switch(getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) {
Nate Begemanaa73a9f2005-04-03 11:20:20 +00001981 default: assert(0 && "unhandled result code");
1982 case 0: // No immediate
1983 Tmp2 = SelectExpr(N.getOperand(1));
1984 BuildMI(BB, PPC::XOR, 2, Result).addReg(Tmp1).addReg(Tmp2);
1985 break;
1986 case 1: // Low immediate
1987 BuildMI(BB, PPC::XORI, 2, Result).addReg(Tmp1).addImm(Tmp2);
1988 break;
1989 case 2: // Shifted immediate
1990 BuildMI(BB, PPC::XORIS, 2, Result).addReg(Tmp1).addImm(Tmp2);
1991 break;
1992 }
1993 return Result;
1994 }
1995
Nate Begeman9e3e1b52005-03-24 23:35:30 +00001996 case ISD::SUB:
Nate Begemand7c4a4a2005-05-11 23:43:56 +00001997 if (1 == getImmediateForOpcode(N.getOperand(0), opcode, Tmp1, true)) {
1998 Tmp2 = SelectExpr(N.getOperand(1));
Nate Begeman27523a12005-04-02 00:42:16 +00001999 BuildMI(BB, PPC::SUBFIC, 2, Result).addReg(Tmp2).addSImm(Tmp1);
Nate Begemand7c4a4a2005-05-11 23:43:56 +00002000 } else if (1 == getImmediateForOpcode(N.getOperand(1), opcode, Tmp2)) {
Nate Begeman27523a12005-04-02 00:42:16 +00002001 Tmp1 = SelectExpr(N.getOperand(0));
Nate Begemand7c4a4a2005-05-11 23:43:56 +00002002 BuildMI(BB, PPC::ADDI, 2, Result).addReg(Tmp1).addSImm(Tmp2);
2003 } else {
2004 Tmp1 = SelectExpr(N.getOperand(0));
2005 Tmp2 = SelectExpr(N.getOperand(1));
Nate Begeman27523a12005-04-02 00:42:16 +00002006 BuildMI(BB, PPC::SUBF, 2, Result).addReg(Tmp2).addReg(Tmp1);
2007 }
Nate Begeman9e3e1b52005-03-24 23:35:30 +00002008 return Result;
Misha Brukmanb5f662f2005-04-21 23:30:14 +00002009
Nate Begeman5e966612005-03-24 06:28:42 +00002010 case ISD::MUL:
Nate Begeman9e3e1b52005-03-24 23:35:30 +00002011 Tmp1 = SelectExpr(N.getOperand(0));
Nate Begeman439b4442005-04-05 04:22:58 +00002012 if (1 == getImmediateForOpcode(N.getOperand(1), opcode, Tmp2))
Nate Begeman307e7442005-03-26 01:28:53 +00002013 BuildMI(BB, PPC::MULLI, 2, Result).addReg(Tmp1).addSImm(Tmp2);
2014 else {
2015 Tmp2 = SelectExpr(N.getOperand(1));
2016 BuildMI(BB, PPC::MULLW, 2, Result).addReg(Tmp1).addReg(Tmp2);
2017 }
Nate Begeman9e3e1b52005-03-24 23:35:30 +00002018 return Result;
2019
Nate Begeman815d6da2005-04-06 00:25:27 +00002020 case ISD::MULHS:
2021 case ISD::MULHU:
2022 Tmp1 = SelectExpr(N.getOperand(0));
2023 Tmp2 = SelectExpr(N.getOperand(1));
2024 Opc = (ISD::MULHU == opcode) ? PPC::MULHWU : PPC::MULHW;
2025 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
2026 return Result;
2027
Nate Begemanf3d08f32005-03-29 00:03:27 +00002028 case ISD::SDIV:
2029 case ISD::UDIV:
Nate Begeman815d6da2005-04-06 00:25:27 +00002030 switch (getImmediateForOpcode(N.getOperand(1), opcode, Tmp3)) {
2031 default: break;
2032 // If this is an sdiv by a power of two, we can use an srawi/addze pair.
2033 case 3:
Nate Begeman80196b12005-04-05 00:15:08 +00002034 Tmp1 = MakeReg(MVT::i32);
2035 Tmp2 = SelectExpr(N.getOperand(0));
Nate Begeman9f833d32005-04-12 00:10:02 +00002036 if ((int)Tmp3 < 0) {
2037 unsigned Tmp4 = MakeReg(MVT::i32);
2038 BuildMI(BB, PPC::SRAWI, 2, Tmp1).addReg(Tmp2).addImm(-Tmp3);
2039 BuildMI(BB, PPC::ADDZE, 1, Tmp4).addReg(Tmp1);
2040 BuildMI(BB, PPC::NEG, 1, Result).addReg(Tmp4);
2041 } else {
2042 BuildMI(BB, PPC::SRAWI, 2, Tmp1).addReg(Tmp2).addImm(Tmp3);
2043 BuildMI(BB, PPC::ADDZE, 1, Result).addReg(Tmp1);
2044 }
Nate Begeman80196b12005-04-05 00:15:08 +00002045 return Result;
Nate Begeman815d6da2005-04-06 00:25:27 +00002046 // If this is a divide by constant, we can emit code using some magic
2047 // constants to implement it as a multiply instead.
Nate Begeman27b4c232005-04-06 06:44:57 +00002048 case 4:
2049 ExprMap.erase(N);
Misha Brukmanb5f662f2005-04-21 23:30:14 +00002050 if (opcode == ISD::SDIV)
Nate Begeman27b4c232005-04-06 06:44:57 +00002051 return SelectExpr(BuildSDIVSequence(N));
2052 else
2053 return SelectExpr(BuildUDIVSequence(N));
Nate Begeman80196b12005-04-05 00:15:08 +00002054 }
Nate Begemanf3d08f32005-03-29 00:03:27 +00002055 Tmp1 = SelectExpr(N.getOperand(0));
2056 Tmp2 = SelectExpr(N.getOperand(1));
2057 Opc = (ISD::UDIV == opcode) ? PPC::DIVWU : PPC::DIVW;
2058 BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
2059 return Result;
2060
Nate Begeman9e3e1b52005-03-24 23:35:30 +00002061 case ISD::ADD_PARTS:
Nate Begemanca12a2b2005-03-28 22:28:37 +00002062 case ISD::SUB_PARTS: {
2063 assert(N.getNumOperands() == 4 && N.getValueType() == MVT::i32 &&
2064 "Not an i64 add/sub!");
2065 // Emit all of the operands.
2066 std::vector<unsigned> InVals;
2067 for (unsigned i = 0, e = N.getNumOperands(); i != e; ++i)
2068 InVals.push_back(SelectExpr(N.getOperand(i)));
2069 if (N.getOpcode() == ISD::ADD_PARTS) {
Nate Begeman27eeb002005-04-02 05:59:34 +00002070 BuildMI(BB, PPC::ADDC, 2, Result).addReg(InVals[0]).addReg(InVals[2]);
2071 BuildMI(BB, PPC::ADDE, 2, Result+1).addReg(InVals[1]).addReg(InVals[3]);
Nate Begemanca12a2b2005-03-28 22:28:37 +00002072 } else {
Nate Begeman27eeb002005-04-02 05:59:34 +00002073 BuildMI(BB, PPC::SUBFC, 2, Result).addReg(InVals[2]).addReg(InVals[0]);
2074 BuildMI(BB, PPC::SUBFE, 2, Result+1).addReg(InVals[3]).addReg(InVals[1]);
2075 }
2076 return Result+N.ResNo;
2077 }
2078
2079 case ISD::SHL_PARTS:
2080 case ISD::SRA_PARTS:
2081 case ISD::SRL_PARTS: {
2082 assert(N.getNumOperands() == 3 && N.getValueType() == MVT::i32 &&
2083 "Not an i64 shift!");
2084 unsigned ShiftOpLo = SelectExpr(N.getOperand(0));
2085 unsigned ShiftOpHi = SelectExpr(N.getOperand(1));
Nate Begeman3664cef2005-04-13 22:14:14 +00002086 unsigned SHReg = FoldIfWideZeroExtend(N.getOperand(2));
2087 Tmp1 = MakeReg(MVT::i32);
2088 Tmp2 = MakeReg(MVT::i32);
Nate Begeman27eeb002005-04-02 05:59:34 +00002089 Tmp3 = MakeReg(MVT::i32);
2090 unsigned Tmp4 = MakeReg(MVT::i32);
2091 unsigned Tmp5 = MakeReg(MVT::i32);
2092 unsigned Tmp6 = MakeReg(MVT::i32);
2093 BuildMI(BB, PPC::SUBFIC, 2, Tmp1).addReg(SHReg).addSImm(32);
2094 if (ISD::SHL_PARTS == opcode) {
2095 BuildMI(BB, PPC::SLW, 2, Tmp2).addReg(ShiftOpHi).addReg(SHReg);
2096 BuildMI(BB, PPC::SRW, 2, Tmp3).addReg(ShiftOpLo).addReg(Tmp1);
2097 BuildMI(BB, PPC::OR, 2, Tmp4).addReg(Tmp2).addReg(Tmp3);
2098 BuildMI(BB, PPC::ADDI, 2, Tmp5).addReg(SHReg).addSImm(-32);
Nate Begemanfa554702005-04-03 22:13:27 +00002099 BuildMI(BB, PPC::SLW, 2, Tmp6).addReg(ShiftOpLo).addReg(Tmp5);
Nate Begeman27eeb002005-04-02 05:59:34 +00002100 BuildMI(BB, PPC::OR, 2, Result+1).addReg(Tmp4).addReg(Tmp6);
2101 BuildMI(BB, PPC::SLW, 2, Result).addReg(ShiftOpLo).addReg(SHReg);
2102 } else if (ISD::SRL_PARTS == opcode) {
2103 BuildMI(BB, PPC::SRW, 2, Tmp2).addReg(ShiftOpLo).addReg(SHReg);
2104 BuildMI(BB, PPC::SLW, 2, Tmp3).addReg(ShiftOpHi).addReg(Tmp1);
2105 BuildMI(BB, PPC::OR, 2, Tmp4).addReg(Tmp2).addReg(Tmp3);
2106 BuildMI(BB, PPC::ADDI, 2, Tmp5).addReg(SHReg).addSImm(-32);
2107 BuildMI(BB, PPC::SRW, 2, Tmp6).addReg(ShiftOpHi).addReg(Tmp5);
2108 BuildMI(BB, PPC::OR, 2, Result).addReg(Tmp4).addReg(Tmp6);
2109 BuildMI(BB, PPC::SRW, 2, Result+1).addReg(ShiftOpHi).addReg(SHReg);
2110 } else {
2111 MachineBasicBlock *TmpMBB = new MachineBasicBlock(BB->getBasicBlock());
2112 MachineBasicBlock *PhiMBB = new MachineBasicBlock(BB->getBasicBlock());
2113 MachineBasicBlock *OldMBB = BB;
2114 MachineFunction *F = BB->getParent();
2115 ilist<MachineBasicBlock>::iterator It = BB; ++It;
2116 F->getBasicBlockList().insert(It, TmpMBB);
2117 F->getBasicBlockList().insert(It, PhiMBB);
2118 BB->addSuccessor(TmpMBB);
2119 BB->addSuccessor(PhiMBB);
2120 BuildMI(BB, PPC::SRW, 2, Tmp2).addReg(ShiftOpLo).addReg(SHReg);
2121 BuildMI(BB, PPC::SLW, 2, Tmp3).addReg(ShiftOpHi).addReg(Tmp1);
2122 BuildMI(BB, PPC::OR, 2, Tmp4).addReg(Tmp2).addReg(Tmp3);
2123 BuildMI(BB, PPC::ADDICo, 2, Tmp5).addReg(SHReg).addSImm(-32);
2124 BuildMI(BB, PPC::SRAW, 2, Tmp6).addReg(ShiftOpHi).addReg(Tmp5);
2125 BuildMI(BB, PPC::SRAW, 2, Result+1).addReg(ShiftOpHi).addReg(SHReg);
2126 BuildMI(BB, PPC::BLE, 2).addReg(PPC::CR0).addMBB(PhiMBB);
2127 // Select correct least significant half if the shift amount > 32
2128 BB = TmpMBB;
2129 unsigned Tmp7 = MakeReg(MVT::i32);
2130 BuildMI(BB, PPC::OR, 2, Tmp7).addReg(Tmp6).addReg(Tmp6);
2131 TmpMBB->addSuccessor(PhiMBB);
2132 BB = PhiMBB;
2133 BuildMI(BB, PPC::PHI, 4, Result).addReg(Tmp4).addMBB(OldMBB)
2134 .addReg(Tmp7).addMBB(TmpMBB);
Nate Begemanca12a2b2005-03-28 22:28:37 +00002135 }
2136 return Result+N.ResNo;
2137 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +00002138
Nate Begemana9795f82005-03-24 04:41:43 +00002139 case ISD::FP_TO_UINT:
Nate Begeman6b559972005-04-01 02:59:27 +00002140 case ISD::FP_TO_SINT: {
2141 bool U = (ISD::FP_TO_UINT == opcode);
2142 Tmp1 = SelectExpr(N.getOperand(0));
2143 if (!U) {
2144 Tmp2 = MakeReg(MVT::f64);
2145 BuildMI(BB, PPC::FCTIWZ, 1, Tmp2).addReg(Tmp1);
2146 int FrameIdx = BB->getParent()->getFrameInfo()->CreateStackObject(8, 8);
2147 addFrameReference(BuildMI(BB, PPC::STFD, 3).addReg(Tmp2), FrameIdx);
2148 addFrameReference(BuildMI(BB, PPC::LWZ, 2, Result), FrameIdx, 4);
2149 return Result;
2150 } else {
2151 unsigned Zero = getConstDouble(0.0);
2152 unsigned MaxInt = getConstDouble((1LL << 32) - 1);
2153 unsigned Border = getConstDouble(1LL << 31);
2154 unsigned UseZero = MakeReg(MVT::f64);
2155 unsigned UseMaxInt = MakeReg(MVT::f64);
2156 unsigned UseChoice = MakeReg(MVT::f64);
2157 unsigned TmpReg = MakeReg(MVT::f64);
2158 unsigned TmpReg2 = MakeReg(MVT::f64);
2159 unsigned ConvReg = MakeReg(MVT::f64);
2160 unsigned IntTmp = MakeReg(MVT::i32);
2161 unsigned XorReg = MakeReg(MVT::i32);
2162 MachineFunction *F = BB->getParent();
2163 int FrameIdx = F->getFrameInfo()->CreateStackObject(8, 8);
2164 // Update machine-CFG edges
2165 MachineBasicBlock *XorMBB = new MachineBasicBlock(BB->getBasicBlock());
2166 MachineBasicBlock *PhiMBB = new MachineBasicBlock(BB->getBasicBlock());
2167 MachineBasicBlock *OldMBB = BB;
2168 ilist<MachineBasicBlock>::iterator It = BB; ++It;
2169 F->getBasicBlockList().insert(It, XorMBB);
2170 F->getBasicBlockList().insert(It, PhiMBB);
2171 BB->addSuccessor(XorMBB);
2172 BB->addSuccessor(PhiMBB);
2173 // Convert from floating point to unsigned 32-bit value
2174 // Use 0 if incoming value is < 0.0
2175 BuildMI(BB, PPC::FSEL, 3, UseZero).addReg(Tmp1).addReg(Tmp1).addReg(Zero);
2176 // Use 2**32 - 1 if incoming value is >= 2**32
2177 BuildMI(BB, PPC::FSUB, 2, UseMaxInt).addReg(MaxInt).addReg(Tmp1);
2178 BuildMI(BB, PPC::FSEL, 3, UseChoice).addReg(UseMaxInt).addReg(UseZero)
2179 .addReg(MaxInt);
2180 // Subtract 2**31
2181 BuildMI(BB, PPC::FSUB, 2, TmpReg).addReg(UseChoice).addReg(Border);
2182 // Use difference if >= 2**31
2183 BuildMI(BB, PPC::FCMPU, 2, PPC::CR0).addReg(UseChoice).addReg(Border);
2184 BuildMI(BB, PPC::FSEL, 3, TmpReg2).addReg(TmpReg).addReg(TmpReg)
2185 .addReg(UseChoice);
2186 // Convert to integer
2187 BuildMI(BB, PPC::FCTIWZ, 1, ConvReg).addReg(TmpReg2);
2188 addFrameReference(BuildMI(BB, PPC::STFD, 3).addReg(ConvReg), FrameIdx);
2189 addFrameReference(BuildMI(BB, PPC::LWZ, 2, IntTmp), FrameIdx, 4);
2190 BuildMI(BB, PPC::BLT, 2).addReg(PPC::CR0).addMBB(PhiMBB);
2191 BuildMI(BB, PPC::B, 1).addMBB(XorMBB);
2192
2193 // XorMBB:
2194 // add 2**31 if input was >= 2**31
2195 BB = XorMBB;
2196 BuildMI(BB, PPC::XORIS, 2, XorReg).addReg(IntTmp).addImm(0x8000);
2197 XorMBB->addSuccessor(PhiMBB);
2198
2199 // PhiMBB:
2200 // DestReg = phi [ IntTmp, OldMBB ], [ XorReg, XorMBB ]
2201 BB = PhiMBB;
2202 BuildMI(BB, PPC::PHI, 4, Result).addReg(IntTmp).addMBB(OldMBB)
2203 .addReg(XorReg).addMBB(XorMBB);
2204 return Result;
2205 }
2206 assert(0 && "Should never get here");
2207 return 0;
2208 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +00002209
Nate Begeman9e3e1b52005-03-24 23:35:30 +00002210 case ISD::SETCC:
Nate Begeman33162522005-03-29 21:54:38 +00002211 if (SetCCSDNode *SetCC = dyn_cast<SetCCSDNode>(Node)) {
Misha Brukmanb5f662f2005-04-21 23:30:14 +00002212 if (ConstantSDNode *CN =
Nate Begeman7e7fadd2005-04-07 20:30:01 +00002213 dyn_cast<ConstantSDNode>(SetCC->getOperand(1).Val)) {
Nate Begeman9765c252005-04-12 21:22:28 +00002214 // We can codegen setcc op, imm very efficiently compared to a brcond.
2215 // Check for those cases here.
2216 // setcc op, 0
Nate Begeman7e7fadd2005-04-07 20:30:01 +00002217 if (CN->getValue() == 0) {
2218 Tmp1 = SelectExpr(SetCC->getOperand(0));
2219 switch (SetCC->getCondition()) {
Nate Begeman7bfba7d2005-04-14 09:45:08 +00002220 default: SetCC->dump(); assert(0 && "Unhandled SetCC condition"); abort();
Nate Begeman7e7fadd2005-04-07 20:30:01 +00002221 case ISD::SETEQ:
Nate Begeman7e7fadd2005-04-07 20:30:01 +00002222 Tmp2 = MakeReg(MVT::i32);
2223 BuildMI(BB, PPC::CNTLZW, 1, Tmp2).addReg(Tmp1);
2224 BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp2).addImm(27)
2225 .addImm(5).addImm(31);
2226 break;
2227 case ISD::SETNE:
Nate Begeman7e7fadd2005-04-07 20:30:01 +00002228 Tmp2 = MakeReg(MVT::i32);
2229 BuildMI(BB, PPC::ADDIC, 2, Tmp2).addReg(Tmp1).addSImm(-1);
2230 BuildMI(BB, PPC::SUBFE, 2, Result).addReg(Tmp2).addReg(Tmp1);
2231 break;
Nate Begeman7e7fadd2005-04-07 20:30:01 +00002232 case ISD::SETLT:
2233 BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp1).addImm(1)
2234 .addImm(31).addImm(31);
2235 break;
Nate Begeman7e7fadd2005-04-07 20:30:01 +00002236 case ISD::SETGT:
2237 Tmp2 = MakeReg(MVT::i32);
2238 Tmp3 = MakeReg(MVT::i32);
2239 BuildMI(BB, PPC::NEG, 2, Tmp2).addReg(Tmp1);
2240 BuildMI(BB, PPC::ANDC, 2, Tmp3).addReg(Tmp2).addReg(Tmp1);
2241 BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp3).addImm(1)
2242 .addImm(31).addImm(31);
2243 break;
Nate Begeman9765c252005-04-12 21:22:28 +00002244 }
2245 return Result;
2246 }
2247 // setcc op, -1
2248 if (CN->isAllOnesValue()) {
2249 Tmp1 = SelectExpr(SetCC->getOperand(0));
2250 switch (SetCC->getCondition()) {
2251 default: assert(0 && "Unhandled SetCC condition"); abort();
2252 case ISD::SETEQ:
2253 Tmp2 = MakeReg(MVT::i32);
2254 Tmp3 = MakeReg(MVT::i32);
2255 BuildMI(BB, PPC::ADDIC, 2, Tmp2).addReg(Tmp1).addSImm(1);
2256 BuildMI(BB, PPC::LI, 1, Tmp3).addSImm(0);
2257 BuildMI(BB, PPC::ADDZE, 1, Result).addReg(Tmp3);
Nate Begeman7e7fadd2005-04-07 20:30:01 +00002258 break;
Nate Begeman9765c252005-04-12 21:22:28 +00002259 case ISD::SETNE:
2260 Tmp2 = MakeReg(MVT::i32);
2261 Tmp3 = MakeReg(MVT::i32);
2262 BuildMI(BB, PPC::NOR, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
2263 BuildMI(BB, PPC::ADDIC, 2, Tmp3).addReg(Tmp2).addSImm(-1);
2264 BuildMI(BB, PPC::SUBFE, 2, Result).addReg(Tmp3).addReg(Tmp2);
2265 break;
2266 case ISD::SETLT:
2267 Tmp2 = MakeReg(MVT::i32);
2268 Tmp3 = MakeReg(MVT::i32);
2269 BuildMI(BB, PPC::ADDI, 2, Tmp2).addReg(Tmp1).addSImm(1);
2270 BuildMI(BB, PPC::AND, 2, Tmp3).addReg(Tmp2).addReg(Tmp1);
2271 BuildMI(BB, PPC::RLWINM, 4, Result).addReg(Tmp3).addImm(1)
2272 .addImm(31).addImm(31);
2273 break;
2274 case ISD::SETGT:
2275 Tmp2 = MakeReg(MVT::i32);
Nate Begeman7e7fadd2005-04-07 20:30:01 +00002276 BuildMI(BB, PPC::RLWINM, 4, Tmp2).addReg(Tmp1).addImm(1)
2277 .addImm(31).addImm(31);
2278 BuildMI(BB, PPC::XORI, 2, Result).addReg(Tmp2).addImm(1);
2279 break;
2280 }
2281 return Result;
2282 }
2283 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +00002284
Nate Begeman1cbf3ab2005-04-18 07:48:09 +00002285 bool Inv;
2286 unsigned CCReg = SelectCC(N, Opc, Inv, Tmp2);
2287 MoveCRtoGPR(CCReg, Inv, Tmp2, Result);
Nate Begeman33162522005-03-29 21:54:38 +00002288 return Result;
2289 }
2290 assert(0 && "Is this legal?");
2291 return 0;
Misha Brukmanb5f662f2005-04-21 23:30:14 +00002292
Nate Begeman74747862005-03-29 22:24:51 +00002293 case ISD::SELECT: {
Nate Begeman1cbf3ab2005-04-18 07:48:09 +00002294 bool Inv;
Chris Lattner30710192005-04-01 07:10:02 +00002295 unsigned TrueValue = SelectExpr(N.getOperand(1)); //Use if TRUE
2296 unsigned FalseValue = SelectExpr(N.getOperand(2)); //Use if FALSE
Nate Begeman1cbf3ab2005-04-18 07:48:09 +00002297 unsigned CCReg = SelectCC(N.getOperand(0), Opc, Inv, Tmp3);
Chris Lattner30710192005-04-01 07:10:02 +00002298
Misha Brukmanb5f662f2005-04-21 23:30:14 +00002299 // Create an iterator with which to insert the MBB for copying the false
Nate Begeman74747862005-03-29 22:24:51 +00002300 // value and the MBB to hold the PHI instruction for this SetCC.
2301 MachineBasicBlock *thisMBB = BB;
2302 const BasicBlock *LLVM_BB = BB->getBasicBlock();
2303 ilist<MachineBasicBlock>::iterator It = BB;
2304 ++It;
2305
2306 // thisMBB:
2307 // ...
2308 // TrueVal = ...
Nate Begeman1b7f7fb2005-04-13 23:15:44 +00002309 // cmpTY ccX, r1, r2
Nate Begeman74747862005-03-29 22:24:51 +00002310 // bCC copy1MBB
2311 // fallthrough --> copy0MBB
Nate Begeman74747862005-03-29 22:24:51 +00002312 MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
2313 MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
Nate Begeman1b7f7fb2005-04-13 23:15:44 +00002314 BuildMI(BB, Opc, 2).addReg(CCReg).addMBB(sinkMBB);
Nate Begeman74747862005-03-29 22:24:51 +00002315 MachineFunction *F = BB->getParent();
2316 F->getBasicBlockList().insert(It, copy0MBB);
2317 F->getBasicBlockList().insert(It, sinkMBB);
2318 // Update machine-CFG edges
2319 BB->addSuccessor(copy0MBB);
2320 BB->addSuccessor(sinkMBB);
2321
2322 // copy0MBB:
2323 // %FalseValue = ...
2324 // # fallthrough to sinkMBB
2325 BB = copy0MBB;
Nate Begeman74747862005-03-29 22:24:51 +00002326 // Update machine-CFG edges
2327 BB->addSuccessor(sinkMBB);
2328
2329 // sinkMBB:
2330 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
2331 // ...
2332 BB = sinkMBB;
2333 BuildMI(BB, PPC::PHI, 4, Result).addReg(FalseValue)
2334 .addMBB(copy0MBB).addReg(TrueValue).addMBB(thisMBB);
Nate Begeman74747862005-03-29 22:24:51 +00002335 return Result;
2336 }
Nate Begemana9795f82005-03-24 04:41:43 +00002337
2338 case ISD::Constant:
2339 switch (N.getValueType()) {
2340 default: assert(0 && "Cannot use constants of this type!");
2341 case MVT::i1:
2342 BuildMI(BB, PPC::LI, 1, Result)
2343 .addSImm(!cast<ConstantSDNode>(N)->isNullValue());
2344 break;
2345 case MVT::i32:
2346 {
2347 int v = (int)cast<ConstantSDNode>(N)->getSignExtended();
2348 if (v < 32768 && v >= -32768) {
2349 BuildMI(BB, PPC::LI, 1, Result).addSImm(v);
2350 } else {
Nate Begeman5e966612005-03-24 06:28:42 +00002351 Tmp1 = MakeReg(MVT::i32);
2352 BuildMI(BB, PPC::LIS, 1, Tmp1).addSImm(v >> 16);
2353 BuildMI(BB, PPC::ORI, 2, Result).addReg(Tmp1).addImm(v & 0xFFFF);
Nate Begemana9795f82005-03-24 04:41:43 +00002354 }
2355 }
2356 }
2357 return Result;
2358 }
2359
2360 return 0;
2361}
2362
2363void ISel::Select(SDOperand N) {
2364 unsigned Tmp1, Tmp2, Opc;
2365 unsigned opcode = N.getOpcode();
2366
2367 if (!ExprMap.insert(std::make_pair(N, 1)).second)
2368 return; // Already selected.
2369
2370 SDNode *Node = N.Val;
Misha Brukmanb5f662f2005-04-21 23:30:14 +00002371
Nate Begemana9795f82005-03-24 04:41:43 +00002372 switch (Node->getOpcode()) {
2373 default:
2374 Node->dump(); std::cerr << "\n";
2375 assert(0 && "Node not handled yet!");
2376 case ISD::EntryToken: return; // Noop
2377 case ISD::TokenFactor:
2378 for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
2379 Select(Node->getOperand(i));
2380 return;
2381 case ISD::ADJCALLSTACKDOWN:
2382 case ISD::ADJCALLSTACKUP:
2383 Select(N.getOperand(0));
2384 Tmp1 = cast<ConstantSDNode>(N.getOperand(1))->getValue();
2385 Opc = N.getOpcode() == ISD::ADJCALLSTACKDOWN ? PPC::ADJCALLSTACKDOWN :
2386 PPC::ADJCALLSTACKUP;
2387 BuildMI(BB, Opc, 1).addImm(Tmp1);
2388 return;
2389 case ISD::BR: {
2390 MachineBasicBlock *Dest =
2391 cast<BasicBlockSDNode>(N.getOperand(1))->getBasicBlock();
Nate Begemana9795f82005-03-24 04:41:43 +00002392 Select(N.getOperand(0));
2393 BuildMI(BB, PPC::B, 1).addMBB(Dest);
2394 return;
2395 }
Misha Brukmanb5f662f2005-04-21 23:30:14 +00002396 case ISD::BRCOND:
Nate Begemancd08e4c2005-04-09 20:09:12 +00002397 case ISD::BRCONDTWOWAY:
Nate Begemana9795f82005-03-24 04:41:43 +00002398 SelectBranchCC(N);
2399 return;
2400 case ISD::CopyToReg:
2401 Select(N.getOperand(0));
2402 Tmp1 = SelectExpr(N.getOperand(1));
2403 Tmp2 = cast<RegSDNode>(N)->getReg();
Misha Brukmanb5f662f2005-04-21 23:30:14 +00002404
Nate Begemana9795f82005-03-24 04:41:43 +00002405 if (Tmp1 != Tmp2) {
Misha Brukmanb5f662f2005-04-21 23:30:14 +00002406 if (N.getOperand(1).getValueType() == MVT::f64 ||
Nate Begemana9795f82005-03-24 04:41:43 +00002407 N.getOperand(1).getValueType() == MVT::f32)
2408 BuildMI(BB, PPC::FMR, 1, Tmp2).addReg(Tmp1);
2409 else
2410 BuildMI(BB, PPC::OR, 2, Tmp2).addReg(Tmp1).addReg(Tmp1);
2411 }
2412 return;
2413 case ISD::ImplicitDef:
2414 Select(N.getOperand(0));
2415 BuildMI(BB, PPC::IMPLICIT_DEF, 0, cast<RegSDNode>(N)->getReg());
2416 return;
2417 case ISD::RET:
2418 switch (N.getNumOperands()) {
2419 default:
2420 assert(0 && "Unknown return instruction!");
2421 case 3:
2422 assert(N.getOperand(1).getValueType() == MVT::i32 &&
2423 N.getOperand(2).getValueType() == MVT::i32 &&
Misha Brukman7847fca2005-04-22 17:54:37 +00002424 "Unknown two-register value!");
Nate Begemana9795f82005-03-24 04:41:43 +00002425 Select(N.getOperand(0));
2426 Tmp1 = SelectExpr(N.getOperand(1));
2427 Tmp2 = SelectExpr(N.getOperand(2));
Nate Begeman27523a12005-04-02 00:42:16 +00002428 BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp2).addReg(Tmp2);
2429 BuildMI(BB, PPC::OR, 2, PPC::R4).addReg(Tmp1).addReg(Tmp1);
Nate Begemana9795f82005-03-24 04:41:43 +00002430 break;
2431 case 2:
2432 Select(N.getOperand(0));
2433 Tmp1 = SelectExpr(N.getOperand(1));
2434 switch (N.getOperand(1).getValueType()) {
2435 default:
2436 assert(0 && "Unknown return type!");
2437 case MVT::f64:
2438 case MVT::f32:
2439 BuildMI(BB, PPC::FMR, 1, PPC::F1).addReg(Tmp1);
2440 break;
2441 case MVT::i32:
2442 BuildMI(BB, PPC::OR, 2, PPC::R3).addReg(Tmp1).addReg(Tmp1);
2443 break;
2444 }
Nate Begeman9e3e1b52005-03-24 23:35:30 +00002445 case 1:
2446 Select(N.getOperand(0));
2447 break;
Nate Begemana9795f82005-03-24 04:41:43 +00002448 }
2449 BuildMI(BB, PPC::BLR, 0); // Just emit a 'ret' instruction
2450 return;
Misha Brukmanb5f662f2005-04-21 23:30:14 +00002451 case ISD::TRUNCSTORE:
2452 case ISD::STORE:
Nate Begemana9795f82005-03-24 04:41:43 +00002453 {
2454 SDOperand Chain = N.getOperand(0);
2455 SDOperand Value = N.getOperand(1);
2456 SDOperand Address = N.getOperand(2);
2457 Select(Chain);
2458
2459 Tmp1 = SelectExpr(Value); //value
2460
2461 if (opcode == ISD::STORE) {
2462 switch(Value.getValueType()) {
2463 default: assert(0 && "unknown Type in store");
2464 case MVT::i32: Opc = PPC::STW; break;
2465 case MVT::f64: Opc = PPC::STFD; break;
2466 case MVT::f32: Opc = PPC::STFS; break;
2467 }
2468 } else { //ISD::TRUNCSTORE
2469 switch(cast<MVTSDNode>(Node)->getExtraValueType()) {
2470 default: assert(0 && "unknown Type in store");
Nate Begeman7e7fadd2005-04-07 20:30:01 +00002471 case MVT::i1:
Nate Begemana9795f82005-03-24 04:41:43 +00002472 case MVT::i8: Opc = PPC::STB; break;
2473 case MVT::i16: Opc = PPC::STH; break;
2474 }
2475 }
2476
Nate Begemana7e11a42005-04-01 05:57:17 +00002477 if(Address.getOpcode() == ISD::FrameIndex)
Nate Begemana9795f82005-03-24 04:41:43 +00002478 {
Nate Begeman58f718c2005-03-30 02:23:08 +00002479 Tmp2 = cast<FrameIndexSDNode>(Address)->getIndex();
2480 addFrameReference(BuildMI(BB, Opc, 3).addReg(Tmp1), (int)Tmp2);
Nate Begemana9795f82005-03-24 04:41:43 +00002481 }
2482 else
2483 {
2484 int offset;
Nate Begeman04730362005-04-01 04:45:11 +00002485 bool idx = SelectAddr(Address, Tmp2, offset);
Misha Brukmanb5f662f2005-04-21 23:30:14 +00002486 if (idx) {
Nate Begeman04730362005-04-01 04:45:11 +00002487 Opc = IndexedOpForOp(Opc);
2488 BuildMI(BB, Opc, 3).addReg(Tmp1).addReg(Tmp2).addReg(offset);
2489 } else {
2490 BuildMI(BB, Opc, 3).addReg(Tmp1).addImm(offset).addReg(Tmp2);
2491 }
Nate Begemana9795f82005-03-24 04:41:43 +00002492 }
2493 return;
2494 }
2495 case ISD::EXTLOAD:
2496 case ISD::SEXTLOAD:
2497 case ISD::ZEXTLOAD:
2498 case ISD::LOAD:
2499 case ISD::CopyFromReg:
2500 case ISD::CALL:
2501 case ISD::DYNAMIC_STACKALLOC:
2502 ExprMap.erase(N);
2503 SelectExpr(N);
2504 return;
2505 }
2506 assert(0 && "Should not be reached!");
2507}
2508
2509
2510/// createPPC32PatternInstructionSelector - This pass converts an LLVM function
2511/// into a machine code representation using pattern matching and a machine
2512/// description file.
2513///
2514FunctionPass *llvm::createPPC32ISelPattern(TargetMachine &TM) {
Misha Brukmanb5f662f2005-04-21 23:30:14 +00002515 return new ISel(TM);
Chris Lattner246fa632005-03-24 06:16:18 +00002516}
2517