73533eb0edfcb70330ef9b001c40645ae3abdcd2
[oota-llvm.git] / lib / Target / Mips / MipsISelDAGToDAG.cpp
1 //===-- MipsISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips --------===//
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 // This file defines an instruction selector for the MIPS target.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #define DEBUG_TYPE "mips-isel"
15 #include "Mips.h"
16 #include "MipsAnalyzeImmediate.h"
17 #include "MipsMachineFunction.h"
18 #include "MipsRegisterInfo.h"
19 #include "MipsSubtarget.h"
20 #include "MipsTargetMachine.h"
21 #include "llvm/GlobalValue.h"
22 #include "llvm/Instructions.h"
23 #include "llvm/Intrinsics.h"
24 #include "llvm/Support/CFG.h"
25 #include "llvm/Type.h"
26 #include "llvm/CodeGen/MachineConstantPool.h"
27 #include "llvm/CodeGen/MachineFunction.h"
28 #include "llvm/CodeGen/MachineFrameInfo.h"
29 #include "llvm/CodeGen/MachineInstrBuilder.h"
30 #include "llvm/CodeGen/MachineRegisterInfo.h"
31 #include "llvm/CodeGen/SelectionDAGISel.h"
32 #include "llvm/Target/TargetMachine.h"
33 #include "llvm/Support/Debug.h"
34 #include "llvm/Support/ErrorHandling.h"
35 #include "llvm/Support/raw_ostream.h"
36 using namespace llvm;
37
38 //===----------------------------------------------------------------------===//
39 // Instruction Selector Implementation
40 //===----------------------------------------------------------------------===//
41
42 //===----------------------------------------------------------------------===//
43 // MipsDAGToDAGISel - MIPS specific code to select MIPS machine
44 // instructions for SelectionDAG operations.
45 //===----------------------------------------------------------------------===//
46 namespace {
47
48 class MipsDAGToDAGISel : public SelectionDAGISel {
49
50   /// TM - Keep a reference to MipsTargetMachine.
51   MipsTargetMachine &TM;
52
53   /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can
54   /// make the right decision when generating code for different targets.
55   const MipsSubtarget &Subtarget;
56
57 public:
58   explicit MipsDAGToDAGISel(MipsTargetMachine &tm) :
59   SelectionDAGISel(tm),
60   TM(tm), Subtarget(tm.getSubtarget<MipsSubtarget>()) {}
61
62   // Pass Name
63   virtual const char *getPassName() const {
64     return "MIPS DAG->DAG Pattern Instruction Selection";
65   }
66
67
68 private:
69   // Include the pieces autogenerated from the target description.
70   #include "MipsGenDAGISel.inc"
71
72   /// getTargetMachine - Return a reference to the TargetMachine, casted
73   /// to the target-specific type.
74   const MipsTargetMachine &getTargetMachine() {
75     return static_cast<const MipsTargetMachine &>(TM);
76   }
77
78   /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
79   /// to the target-specific type.
80   const MipsInstrInfo *getInstrInfo() {
81     return getTargetMachine().getInstrInfo();
82   }
83
84   SDNode *getGlobalBaseReg();
85
86   std::pair<SDNode*, SDNode*> SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl,
87                                          EVT Ty, bool HasLo, bool HasHi);
88
89   SDNode *Select(SDNode *N);
90
91   // Complex Pattern.
92   bool SelectAddr(SDValue N, SDValue &Base, SDValue &Offset);
93
94   // getImm - Return a target constant with the specified value.
95   inline SDValue getImm(const SDNode *Node, unsigned Imm) {
96     return CurDAG->getTargetConstant(Imm, Node->getValueType(0));
97   }
98
99   virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op,
100                                             char ConstraintCode,
101                                             std::vector<SDValue> &OutOps);
102 };
103
104 }
105
106
107 /// getGlobalBaseReg - Output the instructions required to put the
108 /// GOT address into a register.
109 SDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
110   unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
111   return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
112 }
113
114 /// ComplexPattern used on MipsInstrInfo
115 /// Used on Mips Load/Store instructions
116 bool MipsDAGToDAGISel::
117 SelectAddr(SDValue Addr, SDValue &Base, SDValue &Offset) {
118   EVT ValTy = Addr.getValueType();
119   unsigned GPReg = ValTy == MVT::i32 ? Mips::GP : Mips::GP_64;
120
121   // if Address is FI, get the TargetFrameIndex.
122   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
123     Base   = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
124     Offset = CurDAG->getTargetConstant(0, ValTy);
125     return true;
126   }
127
128   // on PIC code Load GA
129   if (Addr.getOpcode() == MipsISD::Wrapper) {
130     Base   = CurDAG->getRegister(GPReg, ValTy);
131     Offset = Addr.getOperand(0);
132     return true;
133   }
134
135   if (TM.getRelocationModel() != Reloc::PIC_) {
136     if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
137         Addr.getOpcode() == ISD::TargetGlobalAddress))
138       return false;
139   }
140
141   // Addresses of the form FI+const or FI|const
142   if (CurDAG->isBaseWithConstantOffset(Addr)) {
143     ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1));
144     if (isInt<16>(CN->getSExtValue())) {
145
146       // If the first operand is a FI, get the TargetFI Node
147       if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>
148                                   (Addr.getOperand(0)))
149         Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy);
150       else
151         Base = Addr.getOperand(0);
152
153       Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy);
154       return true;
155     }
156   }
157
158   // Operand is a result from an ADD.
159   if (Addr.getOpcode() == ISD::ADD) {
160     // When loading from constant pools, load the lower address part in
161     // the instruction itself. Example, instead of:
162     //  lui $2, %hi($CPI1_0)
163     //  addiu $2, $2, %lo($CPI1_0)
164     //  lwc1 $f0, 0($2)
165     // Generate:
166     //  lui $2, %hi($CPI1_0)
167     //  lwc1 $f0, %lo($CPI1_0)($2)
168     if (Addr.getOperand(1).getOpcode() == MipsISD::Lo) {
169       SDValue LoVal = Addr.getOperand(1);
170       if (isa<ConstantPoolSDNode>(LoVal.getOperand(0)) || 
171           isa<GlobalAddressSDNode>(LoVal.getOperand(0))) {
172         Base = Addr.getOperand(0);
173         Offset = LoVal.getOperand(0);
174         return true;
175       }
176     }
177   }
178
179   Base   = Addr;
180   Offset = CurDAG->getTargetConstant(0, ValTy);
181   return true;
182 }
183
184 /// Select multiply instructions.
185 std::pair<SDNode*, SDNode*>
186 MipsDAGToDAGISel::SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl, EVT Ty, 
187                              bool HasLo, bool HasHi) {
188   SDNode *Lo = 0, *Hi = 0;
189   SDNode *Mul = CurDAG->getMachineNode(Opc, dl, MVT::Glue, N->getOperand(0),
190                                        N->getOperand(1));
191   SDValue InFlag = SDValue(Mul, 0);
192
193   if (HasLo) {
194     Lo = CurDAG->getMachineNode(Ty == MVT::i32 ? Mips::MFLO : Mips::MFLO64, dl,
195                                 Ty, MVT::Glue, InFlag);
196     InFlag = SDValue(Lo, 1);
197   }
198   if (HasHi)
199     Hi = CurDAG->getMachineNode(Ty == MVT::i32 ? Mips::MFHI : Mips::MFHI64, dl,
200                                 Ty, InFlag);
201   
202   return std::make_pair(Lo, Hi);
203 }
204
205
206 /// Select instructions not customized! Used for
207 /// expanded, promoted and normal instructions
208 SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
209   unsigned Opcode = Node->getOpcode();
210   DebugLoc dl = Node->getDebugLoc();
211
212   // Dump information about the Node being selected
213   DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n");
214
215   // If we have a custom node, we already have selected!
216   if (Node->isMachineOpcode()) {
217     DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
218     return NULL;
219   }
220
221   ///
222   // Instruction Selection not handled by the auto-generated
223   // tablegen selection should be handled here.
224   ///
225   EVT NodeTy = Node->getValueType(0);
226   unsigned MultOpc;
227
228   switch(Opcode) {
229   default: break;
230
231   case ISD::SUBE:
232   case ISD::ADDE: {
233     SDValue InFlag = Node->getOperand(2), CmpLHS;
234     unsigned Opc = InFlag.getOpcode(); (void)Opc;
235     assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) ||
236             (Opc == ISD::SUBC || Opc == ISD::SUBE)) &&
237            "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn");
238
239     unsigned MOp;
240     if (Opcode == ISD::ADDE) {
241       CmpLHS = InFlag.getValue(0);
242       MOp = Mips::ADDu;
243     } else {
244       CmpLHS = InFlag.getOperand(0);
245       MOp = Mips::SUBu;
246     }
247
248     SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) };
249
250     SDValue LHS = Node->getOperand(0);
251     SDValue RHS = Node->getOperand(1);
252
253     EVT VT = LHS.getValueType();
254     SDNode *Carry = CurDAG->getMachineNode(Mips::SLTu, dl, VT, Ops, 2);
255     SDNode *AddCarry = CurDAG->getMachineNode(Mips::ADDu, dl, VT,
256                                               SDValue(Carry,0), RHS);
257
258     return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue,
259                                 LHS, SDValue(AddCarry,0));
260   }
261
262   /// Mul with two results
263   case ISD::SMUL_LOHI:
264   case ISD::UMUL_LOHI: {
265     if (NodeTy == MVT::i32)
266       MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT);
267     else
268       MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::DMULTu : Mips::DMULT);
269
270     std::pair<SDNode*, SDNode*> LoHi = SelectMULT(Node, MultOpc, dl, NodeTy,
271                                                   true, true);
272
273     if (!SDValue(Node, 0).use_empty())
274       ReplaceUses(SDValue(Node, 0), SDValue(LoHi.first, 0));
275
276     if (!SDValue(Node, 1).use_empty())
277       ReplaceUses(SDValue(Node, 1), SDValue(LoHi.second, 0));
278
279     return NULL;
280   }
281
282   /// Special Muls
283   case ISD::MUL: {
284     // Mips32 has a 32-bit three operand mul instruction.
285     if (Subtarget.hasMips32() && NodeTy == MVT::i32)
286       break;
287     return SelectMULT(Node, NodeTy == MVT::i32 ? Mips::MULT : Mips::DMULT,
288                       dl, NodeTy, true, false).first;
289   }
290   case ISD::MULHS:
291   case ISD::MULHU: {
292     if (NodeTy == MVT::i32)
293       MultOpc = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT);
294     else
295       MultOpc = (Opcode == ISD::MULHU ? Mips::DMULTu : Mips::DMULT);
296
297     return SelectMULT(Node, MultOpc, dl, NodeTy, false, true).second;
298   }
299
300   // Get target GOT address.
301   case ISD::GLOBAL_OFFSET_TABLE:
302     return getGlobalBaseReg();
303
304   case ISD::ConstantFP: {
305     ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node);
306     if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) {
307       if (Subtarget.hasMips64()) {
308         SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
309                                               Mips::ZERO_64, MVT::i64);
310         return CurDAG->getMachineNode(Mips::DMTC1, dl, MVT::f64, Zero);
311       }
312
313       SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl,
314                                             Mips::ZERO, MVT::i32);
315       return CurDAG->getMachineNode(Mips::BuildPairF64, dl, MVT::f64, Zero,
316                                     Zero);
317     }
318     break;
319   }
320
321   case ISD::Constant: {
322     const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Node);
323     unsigned Size = CN->getValueSizeInBits(0);
324
325     if (Size == 32)
326       break;
327
328     MipsAnalyzeImmediate AnalyzeImm;
329     int64_t Imm = CN->getSExtValue();
330
331     const MipsAnalyzeImmediate::InstSeq &Seq =
332       AnalyzeImm.Analyze(Imm, Size, false);
333     
334     MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();
335     DebugLoc DL = CN->getDebugLoc();
336     SDNode *RegOpnd;
337     SDValue ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd),
338                                                 MVT::i64);
339
340     // The first instruction can be a LUi which is different from other
341     // instructions (ADDiu, ORI and SLL) in that it does not have a register
342     // operand.
343     if (Inst->Opc == Mips::LUi64)
344       RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, ImmOpnd);
345     else
346       RegOpnd =
347         CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,
348                                CurDAG->getRegister(Mips::ZERO_64, MVT::i64),
349                                ImmOpnd);
350
351     // The remaining instructions in the sequence are handled here.
352     for (++Inst; Inst != Seq.end(); ++Inst) {
353       ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd),
354                                           MVT::i64);
355       RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64,
356                                        SDValue(RegOpnd, 0), ImmOpnd);
357     }
358
359     return RegOpnd;
360   }
361
362   case MipsISD::ThreadPointer: {
363     EVT PtrVT = TLI.getPointerTy();
364     unsigned RdhwrOpc, SrcReg, DestReg;
365
366     if (PtrVT == MVT::i32) {
367       RdhwrOpc = Mips::RDHWR;
368       SrcReg = Mips::HWR29;
369       DestReg = Mips::V1;
370     } else {
371       RdhwrOpc = Mips::RDHWR64;
372       SrcReg = Mips::HWR29_64;
373       DestReg = Mips::V1_64;
374     }
375   
376     SDNode *Rdhwr =
377       CurDAG->getMachineNode(RdhwrOpc, Node->getDebugLoc(),
378                              Node->getValueType(0),
379                              CurDAG->getRegister(SrcReg, PtrVT));
380     SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, DestReg,
381                                          SDValue(Rdhwr, 0));
382     SDValue ResNode = CurDAG->getCopyFromReg(Chain, dl, DestReg, PtrVT);
383     ReplaceUses(SDValue(Node, 0), ResNode);
384     return ResNode.getNode();
385   }
386   }
387
388   // Select the default instruction
389   SDNode *ResNode = SelectCode(Node);
390
391   DEBUG(errs() << "=> ");
392   if (ResNode == NULL || ResNode == Node)
393     DEBUG(Node->dump(CurDAG));
394   else
395     DEBUG(ResNode->dump(CurDAG));
396   DEBUG(errs() << "\n");
397   return ResNode;
398 }
399
400 bool MipsDAGToDAGISel::
401 SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
402                              std::vector<SDValue> &OutOps) {
403   assert(ConstraintCode == 'm' && "unexpected asm memory constraint");
404   OutOps.push_back(Op);
405   return false;
406 }
407
408 /// createMipsISelDag - This pass converts a legalized DAG into a
409 /// MIPS-specific DAG, ready for instruction scheduling.
410 FunctionPass *llvm::createMipsISelDag(MipsTargetMachine &TM) {
411   return new MipsDAGToDAGISel(TM);
412 }