This patch enables llvm to switch between compiling for mips32/mips64
[oota-llvm.git] / lib / Target / Mips / MipsSEISelLowering.cpp
1 //===-- MipsSEISelLowering.cpp - MipsSE DAG Lowering Interface --*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Subclass of MipsTargetLowering specialized for mips32/64.
11 //
12 //===----------------------------------------------------------------------===//
13 #include "MipsSEISelLowering.h"
14 #include "MipsRegisterInfo.h"
15 #include "MipsTargetMachine.h"
16 #include "llvm/CodeGen/MachineInstrBuilder.h"
17 #include "llvm/CodeGen/MachineRegisterInfo.h"
18 #include "llvm/Support/CommandLine.h"
19 #include "llvm/Target/TargetInstrInfo.h"
20
21 using namespace llvm;
22
23 static cl::opt<bool>
24 EnableMipsTailCalls("enable-mips-tail-calls", cl::Hidden,
25                     cl::desc("MIPS: Enable tail calls."), cl::init(false));
26
27 MipsSETargetLowering::MipsSETargetLowering(MipsTargetMachine &TM)
28   : MipsTargetLowering(TM) {
29   // Set up the register classes
30
31   clearRegisterClasses();
32
33   addRegisterClass(MVT::i32, &Mips::CPURegsRegClass);
34
35   if (HasMips64)
36     addRegisterClass(MVT::i64, &Mips::CPU64RegsRegClass);
37
38   if (Subtarget->hasDSP()) {
39     MVT::SimpleValueType VecTys[2] = {MVT::v2i16, MVT::v4i8};
40
41     for (unsigned i = 0; i < array_lengthof(VecTys); ++i) {
42       addRegisterClass(VecTys[i], &Mips::DSPRegsRegClass);
43
44       // Expand all builtin opcodes.
45       for (unsigned Opc = 0; Opc < ISD::BUILTIN_OP_END; ++Opc)
46         setOperationAction(Opc, VecTys[i], Expand);
47
48       setOperationAction(ISD::LOAD, VecTys[i], Legal);
49       setOperationAction(ISD::STORE, VecTys[i], Legal);
50       setOperationAction(ISD::BITCAST, VecTys[i], Legal);
51     }
52   }
53
54   if (!TM.Options.UseSoftFloat) {
55     addRegisterClass(MVT::f32, &Mips::FGR32RegClass);
56
57     // When dealing with single precision only, use libcalls
58     if (!Subtarget->isSingleFloat()) {
59       if (HasMips64)
60         addRegisterClass(MVT::f64, &Mips::FGR64RegClass);
61       else
62         addRegisterClass(MVT::f64, &Mips::AFGR64RegClass);
63     }
64   }
65
66   setOperationAction(ISD::SMUL_LOHI,          MVT::i32, Custom);
67   setOperationAction(ISD::UMUL_LOHI,          MVT::i32, Custom);
68   setOperationAction(ISD::MULHS,              MVT::i32, Custom);
69   setOperationAction(ISD::MULHU,              MVT::i32, Custom);
70
71   if (HasMips64)
72     setOperationAction(ISD::MUL,              MVT::i64, Custom);
73
74   setOperationAction(ISD::SDIVREM, MVT::i32, Custom);
75   setOperationAction(ISD::UDIVREM, MVT::i32, Custom);
76   setOperationAction(ISD::SDIVREM, MVT::i64, Custom);
77   setOperationAction(ISD::UDIVREM, MVT::i64, Custom);
78   setOperationAction(ISD::MEMBARRIER,         MVT::Other, Custom);
79   setOperationAction(ISD::ATOMIC_FENCE,       MVT::Other, Custom);
80   setOperationAction(ISD::LOAD,               MVT::i32, Custom);
81   setOperationAction(ISD::STORE,              MVT::i32, Custom);
82
83   setTargetDAGCombine(ISD::ADDE);
84   setTargetDAGCombine(ISD::SUBE);
85
86   computeRegisterProperties();
87 }
88
89 const MipsTargetLowering *
90 llvm::createMipsSETargetLowering(MipsTargetMachine &TM) {
91   return new MipsSETargetLowering(TM);
92 }
93
94
95 bool
96 MipsSETargetLowering::allowsUnalignedMemoryAccesses(EVT VT, bool *Fast) const {
97   MVT::SimpleValueType SVT = VT.getSimpleVT().SimpleTy;
98
99   switch (SVT) {
100   case MVT::i64:
101   case MVT::i32:
102     if (Fast)
103       *Fast = true;
104     return true;
105   default:
106     return false;
107   }
108 }
109
110 SDValue MipsSETargetLowering::LowerOperation(SDValue Op,
111                                              SelectionDAG &DAG) const {
112   switch(Op.getOpcode()) {
113   case ISD::SMUL_LOHI: return lowerMulDiv(Op, MipsISD::Mult, true, true, DAG);
114   case ISD::UMUL_LOHI: return lowerMulDiv(Op, MipsISD::Multu, true, true, DAG);
115   case ISD::MULHS:     return lowerMulDiv(Op, MipsISD::Mult, false, true, DAG);
116   case ISD::MULHU:     return lowerMulDiv(Op, MipsISD::Multu, false, true, DAG);
117   case ISD::MUL:       return lowerMulDiv(Op, MipsISD::Mult, true, false, DAG);
118   case ISD::SDIVREM:   return lowerMulDiv(Op, MipsISD::DivRem, true, true, DAG);
119   case ISD::UDIVREM:   return lowerMulDiv(Op, MipsISD::DivRemU, true, true, DAG);
120   }
121
122   return MipsTargetLowering::LowerOperation(Op, DAG);
123 }
124
125 // selectMADD -
126 // Transforms a subgraph in CurDAG if the following pattern is found:
127 //  (addc multLo, Lo0), (adde multHi, Hi0),
128 // where,
129 //  multHi/Lo: product of multiplication
130 //  Lo0: initial value of Lo register
131 //  Hi0: initial value of Hi register
132 // Return true if pattern matching was successful.
133 static bool selectMADD(SDNode *ADDENode, SelectionDAG *CurDAG) {
134   // ADDENode's second operand must be a flag output of an ADDC node in order
135   // for the matching to be successful.
136   SDNode *ADDCNode = ADDENode->getOperand(2).getNode();
137
138   if (ADDCNode->getOpcode() != ISD::ADDC)
139     return false;
140
141   SDValue MultHi = ADDENode->getOperand(0);
142   SDValue MultLo = ADDCNode->getOperand(0);
143   SDNode *MultNode = MultHi.getNode();
144   unsigned MultOpc = MultHi.getOpcode();
145
146   // MultHi and MultLo must be generated by the same node,
147   if (MultLo.getNode() != MultNode)
148     return false;
149
150   // and it must be a multiplication.
151   if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
152     return false;
153
154   // MultLo amd MultHi must be the first and second output of MultNode
155   // respectively.
156   if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
157     return false;
158
159   // Transform this to a MADD only if ADDENode and ADDCNode are the only users
160   // of the values of MultNode, in which case MultNode will be removed in later
161   // phases.
162   // If there exist users other than ADDENode or ADDCNode, this function returns
163   // here, which will result in MultNode being mapped to a single MULT
164   // instruction node rather than a pair of MULT and MADD instructions being
165   // produced.
166   if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
167     return false;
168
169   DebugLoc DL = ADDENode->getDebugLoc();
170
171   // Initialize accumulator.
172   SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
173                                   ADDCNode->getOperand(1),
174                                   ADDENode->getOperand(1));
175
176   // create MipsMAdd(u) node
177   MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MAddu : MipsISD::MAdd;
178
179   SDValue MAdd = CurDAG->getNode(MultOpc, DL, MVT::Untyped,
180                                  MultNode->getOperand(0),// Factor 0
181                                  MultNode->getOperand(1),// Factor 1
182                                  ACCIn);
183
184   // replace uses of adde and addc here
185   if (!SDValue(ADDCNode, 0).use_empty()) {
186     SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
187     SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
188                                     LoIdx);
189     CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDCNode, 0), LoOut);
190   }
191   if (!SDValue(ADDENode, 0).use_empty()) {
192     SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
193     SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MAdd,
194                                     HiIdx);
195     CurDAG->ReplaceAllUsesOfValueWith(SDValue(ADDENode, 0), HiOut);
196   }
197
198   return true;
199 }
200
201 // selectMSUB -
202 // Transforms a subgraph in CurDAG if the following pattern is found:
203 //  (addc Lo0, multLo), (sube Hi0, multHi),
204 // where,
205 //  multHi/Lo: product of multiplication
206 //  Lo0: initial value of Lo register
207 //  Hi0: initial value of Hi register
208 // Return true if pattern matching was successful.
209 static bool selectMSUB(SDNode *SUBENode, SelectionDAG *CurDAG) {
210   // SUBENode's second operand must be a flag output of an SUBC node in order
211   // for the matching to be successful.
212   SDNode *SUBCNode = SUBENode->getOperand(2).getNode();
213
214   if (SUBCNode->getOpcode() != ISD::SUBC)
215     return false;
216
217   SDValue MultHi = SUBENode->getOperand(1);
218   SDValue MultLo = SUBCNode->getOperand(1);
219   SDNode *MultNode = MultHi.getNode();
220   unsigned MultOpc = MultHi.getOpcode();
221
222   // MultHi and MultLo must be generated by the same node,
223   if (MultLo.getNode() != MultNode)
224     return false;
225
226   // and it must be a multiplication.
227   if (MultOpc != ISD::SMUL_LOHI && MultOpc != ISD::UMUL_LOHI)
228     return false;
229
230   // MultLo amd MultHi must be the first and second output of MultNode
231   // respectively.
232   if (MultHi.getResNo() != 1 || MultLo.getResNo() != 0)
233     return false;
234
235   // Transform this to a MSUB only if SUBENode and SUBCNode are the only users
236   // of the values of MultNode, in which case MultNode will be removed in later
237   // phases.
238   // If there exist users other than SUBENode or SUBCNode, this function returns
239   // here, which will result in MultNode being mapped to a single MULT
240   // instruction node rather than a pair of MULT and MSUB instructions being
241   // produced.
242   if (!MultHi.hasOneUse() || !MultLo.hasOneUse())
243     return false;
244
245   DebugLoc DL = SUBENode->getDebugLoc();
246
247   // Initialize accumulator.
248   SDValue ACCIn = CurDAG->getNode(MipsISD::InsertLOHI, DL, MVT::Untyped,
249                                   SUBCNode->getOperand(0),
250                                   SUBENode->getOperand(0));
251
252   // create MipsSub(u) node
253   MultOpc = MultOpc == ISD::UMUL_LOHI ? MipsISD::MSubu : MipsISD::MSub;
254
255   SDValue MSub = CurDAG->getNode(MultOpc, DL, MVT::Glue,
256                                  MultNode->getOperand(0),// Factor 0
257                                  MultNode->getOperand(1),// Factor 1
258                                  ACCIn);
259
260   // replace uses of sube and subc here
261   if (!SDValue(SUBCNode, 0).use_empty()) {
262     SDValue LoIdx = CurDAG->getConstant(Mips::sub_lo, MVT::i32);
263     SDValue LoOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
264                                     LoIdx);
265     CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBCNode, 0), LoOut);
266   }
267   if (!SDValue(SUBENode, 0).use_empty()) {
268     SDValue HiIdx = CurDAG->getConstant(Mips::sub_hi, MVT::i32);
269     SDValue HiOut = CurDAG->getNode(MipsISD::ExtractLOHI, DL, MVT::i32, MSub,
270                                     HiIdx);
271     CurDAG->ReplaceAllUsesOfValueWith(SDValue(SUBENode, 0), HiOut);
272   }
273
274   return true;
275 }
276
277 static SDValue performADDECombine(SDNode *N, SelectionDAG &DAG,
278                                   TargetLowering::DAGCombinerInfo &DCI,
279                                   const MipsSubtarget *Subtarget) {
280   if (DCI.isBeforeLegalize())
281     return SDValue();
282
283   if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
284       selectMADD(N, &DAG))
285     return SDValue(N, 0);
286
287   return SDValue();
288 }
289
290 static SDValue performSUBECombine(SDNode *N, SelectionDAG &DAG,
291                                   TargetLowering::DAGCombinerInfo &DCI,
292                                   const MipsSubtarget *Subtarget) {
293   if (DCI.isBeforeLegalize())
294     return SDValue();
295
296   if (Subtarget->hasMips32() && N->getValueType(0) == MVT::i32 &&
297       selectMSUB(N, &DAG))
298     return SDValue(N, 0);
299
300   return SDValue();
301 }
302
303 SDValue
304 MipsSETargetLowering::PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
305   SelectionDAG &DAG = DCI.DAG;
306
307   switch (N->getOpcode()) {
308   case ISD::ADDE:
309     return performADDECombine(N, DAG, DCI, Subtarget);
310   case ISD::SUBE:
311     return performSUBECombine(N, DAG, DCI, Subtarget);
312   default:
313     return MipsTargetLowering::PerformDAGCombine(N, DCI);
314   }
315 }
316
317 MachineBasicBlock *
318 MipsSETargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
319                                                   MachineBasicBlock *BB) const {
320   switch (MI->getOpcode()) {
321   default:
322     return MipsTargetLowering::EmitInstrWithCustomInserter(MI, BB);
323   case Mips::BPOSGE32_PSEUDO:
324     return emitBPOSGE32(MI, BB);
325   }
326 }
327
328 bool MipsSETargetLowering::
329 isEligibleForTailCallOptimization(const MipsCC &MipsCCInfo,
330                                   unsigned NextStackOffset,
331                                   const MipsFunctionInfo& FI) const {
332   if (!EnableMipsTailCalls)
333     return false;
334
335   // Return false if either the callee or caller has a byval argument.
336   if (MipsCCInfo.hasByValArg() || FI.hasByvalArg())
337     return false;
338
339   // Return true if the callee's argument area is no larger than the
340   // caller's.
341   return NextStackOffset <= FI.getIncomingArgSize();
342 }
343
344 void MipsSETargetLowering::
345 getOpndList(SmallVectorImpl<SDValue> &Ops,
346             std::deque< std::pair<unsigned, SDValue> > &RegsToPass,
347             bool IsPICCall, bool GlobalOrExternal, bool InternalLinkage,
348             CallLoweringInfo &CLI, SDValue Callee, SDValue Chain) const {
349   // T9 should contain the address of the callee function if
350   // -reloction-model=pic or it is an indirect call.
351   if (IsPICCall || !GlobalOrExternal) {
352     unsigned T9Reg = IsN64 ? Mips::T9_64 : Mips::T9;
353     RegsToPass.push_front(std::make_pair(T9Reg, Callee));
354   } else
355     Ops.push_back(Callee);
356
357   MipsTargetLowering::getOpndList(Ops, RegsToPass, IsPICCall, GlobalOrExternal,
358                                   InternalLinkage, CLI, Callee, Chain);
359 }
360
361 SDValue MipsSETargetLowering::lowerMulDiv(SDValue Op, unsigned NewOpc,
362                                           bool HasLo, bool HasHi,
363                                           SelectionDAG &DAG) const {
364   EVT Ty = Op.getOperand(0).getValueType();
365   DebugLoc DL = Op.getDebugLoc();
366   SDValue Mult = DAG.getNode(NewOpc, DL, MVT::Untyped,
367                              Op.getOperand(0), Op.getOperand(1));
368   SDValue Lo, Hi;
369
370   if (HasLo)
371     Lo = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
372                      DAG.getConstant(Mips::sub_lo, MVT::i32));
373   if (HasHi)
374     Hi = DAG.getNode(MipsISD::ExtractLOHI, DL, Ty, Mult,
375                      DAG.getConstant(Mips::sub_hi, MVT::i32));
376
377   if (!HasLo || !HasHi)
378     return HasLo ? Lo : Hi;
379
380   SDValue Vals[] = { Lo, Hi };
381   return DAG.getMergeValues(Vals, 2, DL);
382 }
383
384 MachineBasicBlock * MipsSETargetLowering::
385 emitBPOSGE32(MachineInstr *MI, MachineBasicBlock *BB) const{
386   // $bb:
387   //  bposge32_pseudo $vr0
388   //  =>
389   // $bb:
390   //  bposge32 $tbb
391   // $fbb:
392   //  li $vr2, 0
393   //  b $sink
394   // $tbb:
395   //  li $vr1, 1
396   // $sink:
397   //  $vr0 = phi($vr2, $fbb, $vr1, $tbb)
398
399   MachineRegisterInfo &RegInfo = BB->getParent()->getRegInfo();
400   const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
401   const TargetRegisterClass *RC = &Mips::CPURegsRegClass;
402   DebugLoc DL = MI->getDebugLoc();
403   const BasicBlock *LLVM_BB = BB->getBasicBlock();
404   MachineFunction::iterator It = llvm::next(MachineFunction::iterator(BB));
405   MachineFunction *F = BB->getParent();
406   MachineBasicBlock *FBB = F->CreateMachineBasicBlock(LLVM_BB);
407   MachineBasicBlock *TBB = F->CreateMachineBasicBlock(LLVM_BB);
408   MachineBasicBlock *Sink  = F->CreateMachineBasicBlock(LLVM_BB);
409   F->insert(It, FBB);
410   F->insert(It, TBB);
411   F->insert(It, Sink);
412
413   // Transfer the remainder of BB and its successor edges to Sink.
414   Sink->splice(Sink->begin(), BB, llvm::next(MachineBasicBlock::iterator(MI)),
415                BB->end());
416   Sink->transferSuccessorsAndUpdatePHIs(BB);
417
418   // Add successors.
419   BB->addSuccessor(FBB);
420   BB->addSuccessor(TBB);
421   FBB->addSuccessor(Sink);
422   TBB->addSuccessor(Sink);
423
424   // Insert the real bposge32 instruction to $BB.
425   BuildMI(BB, DL, TII->get(Mips::BPOSGE32)).addMBB(TBB);
426
427   // Fill $FBB.
428   unsigned VR2 = RegInfo.createVirtualRegister(RC);
429   BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::ADDiu), VR2)
430     .addReg(Mips::ZERO).addImm(0);
431   BuildMI(*FBB, FBB->end(), DL, TII->get(Mips::B)).addMBB(Sink);
432
433   // Fill $TBB.
434   unsigned VR1 = RegInfo.createVirtualRegister(RC);
435   BuildMI(*TBB, TBB->end(), DL, TII->get(Mips::ADDiu), VR1)
436     .addReg(Mips::ZERO).addImm(1);
437
438   // Insert phi function to $Sink.
439   BuildMI(*Sink, Sink->begin(), DL, TII->get(Mips::PHI),
440           MI->getOperand(0).getReg())
441     .addReg(VR2).addMBB(FBB).addReg(VR1).addMBB(TBB);
442
443   MI->eraseFromParent();   // The pseudo instruction is gone now.
444   return Sink;
445 }