a7216582fb3feffb27dee6885c298ca3f6027335
[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 "MipsISelLowering.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   virtual void InstructionSelect();
63
64   // Pass Name
65   virtual const char *getPassName() const {
66     return "MIPS DAG->DAG Pattern Instruction Selection";
67   } 
68   
69
70 private:  
71   // Include the pieces autogenerated from the target description.
72   #include "MipsGenDAGISel.inc"
73
74   /// getTargetMachine - Return a reference to the TargetMachine, casted
75   /// to the target-specific type.
76   const MipsTargetMachine &getTargetMachine() {
77     return static_cast<const MipsTargetMachine &>(TM);
78   }
79
80   /// getInstrInfo - Return a reference to the TargetInstrInfo, casted
81   /// to the target-specific type.
82   const MipsInstrInfo *getInstrInfo() {
83     return getTargetMachine().getInstrInfo();
84   }
85
86   SDNode *getGlobalBaseReg();
87   SDNode *Select(SDValue N);
88
89   // Complex Pattern.
90   bool SelectAddr(SDValue Op, SDValue N, 
91                   SDValue &Base, SDValue &Offset);
92
93
94   // getI32Imm - Return a target constant with the specified
95   // value, of type i32.
96   inline SDValue getI32Imm(unsigned Imm) {
97     return CurDAG->getTargetConstant(Imm, MVT::i32);
98   }
99
100
101   #ifndef NDEBUG
102   unsigned Indent;
103   #endif
104 };
105
106 }
107
108 /// InstructionSelect - This callback is invoked by
109 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
110 void MipsDAGToDAGISel::InstructionSelect() {
111   // Codegen the basic block.
112   DEBUG(errs() << "===== Instruction selection begins:\n");
113   DEBUG(Indent = 0);
114
115   // Select target instructions for the DAG.
116   SelectRoot(*CurDAG);
117
118   DEBUG(errs() << "===== Instruction selection ends:\n");
119
120   CurDAG->RemoveDeadNodes();
121 }
122
123 /// getGlobalBaseReg - Output the instructions required to put the
124 /// GOT address into a register.
125 SDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
126   unsigned GlobalBaseReg = getInstrInfo()->getGlobalBaseReg(MF);
127   return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode();
128 }
129
130 /// ComplexPattern used on MipsInstrInfo
131 /// Used on Mips Load/Store instructions
132 bool MipsDAGToDAGISel::
133 SelectAddr(SDValue Op, SDValue Addr, SDValue &Offset, SDValue &Base)
134 {
135   // if Address is FI, get the TargetFrameIndex.
136   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
137     Base   = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
138     Offset = CurDAG->getTargetConstant(0, MVT::i32);
139     return true;
140   }
141     
142   // on PIC code Load GA
143   if (TM.getRelocationModel() == Reloc::PIC_) {
144     if ((Addr.getOpcode() == ISD::TargetGlobalAddress) || 
145         (Addr.getOpcode() == ISD::TargetJumpTable)){
146       Base   = CurDAG->getRegister(Mips::GP, MVT::i32);
147       Offset = Addr;
148       return true;
149     }
150   } else {
151     if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
152         Addr.getOpcode() == ISD::TargetGlobalAddress))
153       return false;
154   }    
155   
156   // Operand is a result from an ADD.
157   if (Addr.getOpcode() == ISD::ADD) {
158     if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) {
159       if (Predicate_immSExt16(CN)) {
160
161         // If the first operand is a FI, get the TargetFI Node
162         if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>
163                                     (Addr.getOperand(0))) {
164           Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32);
165         } else {
166           Base = Addr.getOperand(0);
167         }
168
169         Offset = CurDAG->getTargetConstant(CN->getZExtValue(), MVT::i32);
170         return true;
171       }
172     }
173   }
174
175   Base   = Addr;
176   Offset = CurDAG->getTargetConstant(0, MVT::i32);
177   return true;
178 }
179
180 /// Select instructions not customized! Used for
181 /// expanded, promoted and normal instructions
182 SDNode* MipsDAGToDAGISel::Select(SDValue N) {
183   SDNode *Node = N.getNode();
184   unsigned Opcode = Node->getOpcode();
185   DebugLoc dl = Node->getDebugLoc();
186
187   // Dump information about the Node being selected
188   DEBUG(errs().indent(Indent) << "Selecting: ";
189         Node->dump(CurDAG);
190         errs() << "\n");
191   DEBUG(Indent += 2);
192
193   // If we have a custom node, we already have selected!
194   if (Node->isMachineOpcode()) {
195     DEBUG(errs().indent(Indent-2) << "== ";
196           Node->dump(CurDAG);
197           errs() << "\n");
198     DEBUG(Indent -= 2);
199     return NULL;
200   }
201
202   ///
203   // Instruction Selection not handled by the auto-generated 
204   // tablegen selection should be handled here.
205   /// 
206   switch(Opcode) {
207
208     default: break;
209
210     case ISD::SUBE: 
211     case ISD::ADDE: {
212       SDValue InFlag = Node->getOperand(2), CmpLHS;
213       unsigned Opc = InFlag.getOpcode(); Opc=Opc;
214       assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) || 
215               (Opc == ISD::SUBC || Opc == ISD::SUBE)) &&  
216              "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn");
217
218       unsigned MOp;
219       if (Opcode == ISD::ADDE) {
220         CmpLHS = InFlag.getValue(0);
221         MOp = Mips::ADDu;
222       } else { 
223         CmpLHS = InFlag.getOperand(0);
224         MOp = Mips::SUBu;
225       }
226
227       SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) };
228
229       SDValue LHS = Node->getOperand(0);
230       SDValue RHS = Node->getOperand(1);
231
232       EVT VT = LHS.getValueType();
233       SDNode *Carry = CurDAG->getMachineNode(Mips::SLTu, dl, VT, Ops, 2);
234       SDNode *AddCarry = CurDAG->getMachineNode(Mips::ADDu, dl, VT, 
235                                                 SDValue(Carry,0), RHS);
236
237       return CurDAG->SelectNodeTo(N.getNode(), MOp, VT, MVT::Flag,
238                                   LHS, SDValue(AddCarry,0));
239     }
240
241     /// Mul/Div with two results
242     case ISD::SDIVREM:
243     case ISD::UDIVREM:
244     case ISD::SMUL_LOHI:
245     case ISD::UMUL_LOHI: {
246       SDValue Op1 = Node->getOperand(0);
247       SDValue Op2 = Node->getOperand(1);
248
249       unsigned Op;
250       if (Opcode == ISD::UMUL_LOHI || Opcode == ISD::SMUL_LOHI)
251         Op = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT);
252       else
253         Op = (Opcode == ISD::UDIVREM ? Mips::DIVu : Mips::DIV);
254
255       SDNode *Node = CurDAG->getMachineNode(Op, dl, MVT::Flag, Op1, Op2);
256
257       SDValue InFlag = SDValue(Node, 0);
258       SDNode *Lo = CurDAG->getMachineNode(Mips::MFLO, dl, MVT::i32, 
259                                           MVT::Flag, InFlag);
260       InFlag = SDValue(Lo,1);
261       SDNode *Hi = CurDAG->getMachineNode(Mips::MFHI, dl, MVT::i32, InFlag);
262
263       if (!N.getValue(0).use_empty()) 
264         ReplaceUses(N.getValue(0), SDValue(Lo,0));
265
266       if (!N.getValue(1).use_empty()) 
267         ReplaceUses(N.getValue(1), SDValue(Hi,0));
268
269       return NULL;
270     }
271
272     /// Special Muls
273     case ISD::MUL: 
274     case ISD::MULHS:
275     case ISD::MULHU: {
276       SDValue MulOp1 = Node->getOperand(0);
277       SDValue MulOp2 = Node->getOperand(1);
278
279       unsigned MulOp  = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT);
280       SDNode *MulNode = CurDAG->getMachineNode(MulOp, dl, 
281                                                MVT::Flag, MulOp1, MulOp2);
282
283       SDValue InFlag = SDValue(MulNode, 0);
284
285       if (MulOp == ISD::MUL)
286         return CurDAG->getMachineNode(Mips::MFLO, dl, MVT::i32, InFlag);
287       else
288         return CurDAG->getMachineNode(Mips::MFHI, dl, MVT::i32, InFlag);
289     }
290
291     /// Div/Rem operations
292     case ISD::SREM:
293     case ISD::UREM:
294     case ISD::SDIV: 
295     case ISD::UDIV: {
296       SDValue Op1 = Node->getOperand(0);
297       SDValue Op2 = Node->getOperand(1);
298
299       unsigned Op, MOp;
300       if (Opcode == ISD::SDIV || Opcode == ISD::UDIV) {
301         Op  = (Opcode == ISD::SDIV ? Mips::DIV : Mips::DIVu);
302         MOp = Mips::MFLO;
303       } else {
304         Op  = (Opcode == ISD::SREM ? Mips::DIV : Mips::DIVu);
305         MOp = Mips::MFHI;
306       }
307       SDNode *Node = CurDAG->getMachineNode(Op, dl, MVT::Flag, Op1, Op2);
308
309       SDValue InFlag = SDValue(Node, 0);
310       return CurDAG->getMachineNode(MOp, dl, MVT::i32, InFlag);
311     }
312
313     // Get target GOT address.
314     case ISD::GLOBAL_OFFSET_TABLE:
315       return getGlobalBaseReg();
316
317     /// Handle direct and indirect calls when using PIC. On PIC, when 
318     /// GOT is smaller than about 64k (small code) the GA target is 
319     /// loaded with only one instruction. Otherwise GA's target must 
320     /// be loaded with 3 instructions. 
321     case MipsISD::JmpLink: {
322       if (TM.getRelocationModel() == Reloc::PIC_) {
323         SDValue Chain  = Node->getOperand(0);
324         SDValue Callee = Node->getOperand(1);
325         SDValue T9Reg = CurDAG->getRegister(Mips::T9, MVT::i32);
326         SDValue InFlag(0, 0);
327
328         if ( (isa<GlobalAddressSDNode>(Callee)) ||
329              (isa<ExternalSymbolSDNode>(Callee)) )
330         {
331           /// Direct call for global addresses and external symbols
332           SDValue GPReg = CurDAG->getRegister(Mips::GP, MVT::i32);
333
334           // Use load to get GOT target
335           SDValue Ops[] = { Callee, GPReg, Chain };
336           SDValue Load = SDValue(CurDAG->getMachineNode(Mips::LW, dl, MVT::i32, 
337                                      MVT::Other, Ops, 3), 0);
338           Chain = Load.getValue(1);
339
340           // Call target must be on T9
341           Chain = CurDAG->getCopyToReg(Chain, dl, T9Reg, Load, InFlag);
342         } else 
343           /// Indirect call
344           Chain = CurDAG->getCopyToReg(Chain, dl, T9Reg, Callee, InFlag);
345
346         // Emit Jump and Link Register
347         SDNode *ResNode = CurDAG->getMachineNode(Mips::JALR, dl, MVT::Other,
348                                   MVT::Flag, T9Reg, Chain);
349         Chain  = SDValue(ResNode, 0);
350         InFlag = SDValue(ResNode, 1);
351         ReplaceUses(SDValue(Node, 0), Chain);
352         ReplaceUses(SDValue(Node, 1), InFlag);
353         return ResNode;
354       } 
355     }
356   }
357
358   // Select the default instruction
359   SDNode *ResNode = SelectCode(N);
360
361   DEBUG(errs().indent(Indent-2) << "=> ");
362   if (ResNode == NULL || ResNode == N.getNode())
363     DEBUG(N.getNode()->dump(CurDAG));
364   else
365     DEBUG(ResNode->dump(CurDAG));
366   DEBUG(errs() << "\n");
367   DEBUG(Indent -= 2);
368
369   return ResNode;
370 }
371
372 /// createMipsISelDag - This pass converts a legalized DAG into a 
373 /// MIPS-specific DAG, ready for instruction scheduling.
374 FunctionPass *llvm::createMipsISelDag(MipsTargetMachine &TM) {
375   return new MipsDAGToDAGISel(TM);
376 }