Teach the addressing mode stuff to fold "%lo" into 'ri' addressing modes,
[oota-llvm.git] / lib / Target / Sparc / SparcISelDAGToDAG.cpp
1 //===-- SparcV8ISelDAGToDAG.cpp - A dag to dag inst selector for SparcV8 --===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Chris Lattner and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines an instruction selector for the V8 target
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "SparcV8.h"
15 #include "SparcV8TargetMachine.h"
16 #include "llvm/Function.h"
17 #include "llvm/CodeGen/MachineFunction.h"
18 #include "llvm/CodeGen/SelectionDAG.h"
19 #include "llvm/CodeGen/SelectionDAGISel.h"
20 #include "llvm/CodeGen/SSARegMap.h"
21 #include "llvm/Target/TargetLowering.h"
22 #include "llvm/Support/Debug.h"
23 #include <iostream>
24 using namespace llvm;
25
26 //===----------------------------------------------------------------------===//
27 // TargetLowering Implementation
28 //===----------------------------------------------------------------------===//
29
30 namespace V8ISD {
31   enum {
32     FIRST_NUMBER = ISD::BUILTIN_OP_END+V8::INSTRUCTION_LIST_END,
33     CMPICC,   // Compare two GPR operands, set icc.
34     CMPFCC,   // Compare two FP operands, set fcc.
35     BRICC,    // Branch to dest on icc condition
36     BRFCC,    // Branch to dest on fcc condition
37     
38     Hi, Lo,   // Hi/Lo operations, typically on a global address.
39   };
40 }
41
42 namespace {
43   class SparcV8TargetLowering : public TargetLowering {
44   public:
45     SparcV8TargetLowering(TargetMachine &TM);
46     virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
47     virtual std::vector<SDOperand>
48       LowerArguments(Function &F, SelectionDAG &DAG);
49     virtual std::pair<SDOperand, SDOperand>
50       LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
51                   unsigned CC,
52                   bool isTailCall, SDOperand Callee, ArgListTy &Args,
53                   SelectionDAG &DAG);
54     
55     virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
56                                     SelectionDAG &DAG);
57     virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
58                                    Value *VAListV, SelectionDAG &DAG);
59     virtual std::pair<SDOperand,SDOperand>
60       LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
61                  const Type *ArgTy, SelectionDAG &DAG);
62     virtual std::pair<SDOperand, SDOperand>
63       LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
64                               SelectionDAG &DAG);
65   };
66 }
67
68 SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM)
69   : TargetLowering(TM) {
70   
71   // Set up the register classes.
72   addRegisterClass(MVT::i32, V8::IntRegsRegisterClass);
73   addRegisterClass(MVT::f32, V8::FPRegsRegisterClass);
74   addRegisterClass(MVT::f64, V8::DFPRegsRegisterClass);
75
76   // Custom legalize GlobalAddress nodes into LO/HI parts.
77   setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
78   
79   // Sparc doesn't have sext_inreg, replace them with shl/sra
80   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16  , Expand);
81   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8   , Expand);
82   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1   , Expand);
83
84   // Sparc has no REM operation.
85   setOperationAction(ISD::UREM, MVT::i32, Expand);
86   setOperationAction(ISD::SREM, MVT::i32, Expand);
87   
88   // Sparc has no select or setcc: expand to SELECT_CC.
89   setOperationAction(ISD::SELECT, MVT::i32, Expand);
90   setOperationAction(ISD::SELECT, MVT::f32, Expand);
91   setOperationAction(ISD::SELECT, MVT::f64, Expand);
92   setOperationAction(ISD::SETCC, MVT::i32, Expand);
93   setOperationAction(ISD::SETCC, MVT::f32, Expand);
94   setOperationAction(ISD::SETCC, MVT::f64, Expand);
95   
96   // Sparc doesn't have BRCOND either, it has BR_CC.
97   setOperationAction(ISD::BRCOND, MVT::Other, Expand);
98   setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
99   setOperationAction(ISD::BRTWOWAY_CC, MVT::Other, Expand);
100   setOperationAction(ISD::BR_CC, MVT::i32, Custom);
101   setOperationAction(ISD::BR_CC, MVT::f32, Custom);
102   setOperationAction(ISD::BR_CC, MVT::f64, Custom);
103   
104   computeRegisterProperties();
105 }
106
107 std::vector<SDOperand>
108 SparcV8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
109   MachineFunction &MF = DAG.getMachineFunction();
110   SSARegMap *RegMap = MF.getSSARegMap();
111   std::vector<SDOperand> ArgValues;
112   
113   static const unsigned GPR[] = {
114     V8::I0, V8::I1, V8::I2, V8::I3, V8::I4, V8::I5
115   };
116   unsigned ArgNo = 0;
117   for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
118     MVT::ValueType ObjectVT = getValueType(I->getType());
119     assert(ArgNo < 6 && "Only args in regs for now");
120     
121     switch (ObjectVT) {
122     default: assert(0 && "Unhandled argument type!");
123     // TODO: MVT::i64 & FP
124     case MVT::i1:
125     case MVT::i8:
126     case MVT::i16:
127     case MVT::i32: {
128       unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
129       MF.addLiveIn(GPR[ArgNo++], VReg);
130       SDOperand Arg = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
131       DAG.setRoot(Arg.getValue(1));
132       if (ObjectVT != MVT::i32) {
133         unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext 
134                                                      : ISD::AssertZext;
135         Arg = DAG.getNode(AssertOp, MVT::i32, Arg, 
136                           DAG.getValueType(ObjectVT));
137         Arg = DAG.getNode(ISD::TRUNCATE, ObjectVT, Arg);
138       }
139       ArgValues.push_back(Arg);
140       break;
141     }
142     case MVT::i64: {
143       unsigned VRegHi = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
144       MF.addLiveIn(GPR[ArgNo++], VRegHi);
145       unsigned VRegLo = RegMap->createVirtualRegister(&V8::IntRegsRegClass);
146       MF.addLiveIn(GPR[ArgNo++], VRegLo);
147       SDOperand ArgLo = DAG.getCopyFromReg(DAG.getRoot(), VRegLo, MVT::i32);
148       SDOperand ArgHi = DAG.getCopyFromReg(ArgLo.getValue(1), VRegHi, MVT::i32);
149       DAG.setRoot(ArgHi.getValue(1));
150       ArgValues.push_back(DAG.getNode(ISD::BUILD_PAIR, MVT::i64, ArgLo, ArgHi));
151       break;
152     }
153     }
154   }
155   
156   assert(!F.isVarArg() && "Unimp");
157   
158   // Finally, inform the code generator which regs we return values in.
159   switch (getValueType(F.getReturnType())) {
160   default: assert(0 && "Unknown type!");
161   case MVT::isVoid: break;
162   case MVT::i1:
163   case MVT::i8:
164   case MVT::i16:
165   case MVT::i32:
166     MF.addLiveOut(V8::I0);
167     break;
168   case MVT::i64:
169     MF.addLiveOut(V8::I0);
170     MF.addLiveOut(V8::I1);
171     break;
172   case MVT::f32:
173     MF.addLiveOut(V8::F0);
174     break;
175   case MVT::f64:
176     MF.addLiveOut(V8::D0);
177     break;
178   }
179   
180   return ArgValues;
181 }
182
183 std::pair<SDOperand, SDOperand>
184 SparcV8TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
185                                    bool isVarArg, unsigned CC,
186                                    bool isTailCall, SDOperand Callee, 
187                                    ArgListTy &Args, SelectionDAG &DAG) {
188   assert(0 && "Unimp");
189   abort();
190 }
191
192 SDOperand SparcV8TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
193                                                SelectionDAG &DAG) {
194   if (Op.getValueType() == MVT::i64) {
195     SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, 
196                                DAG.getConstant(1, MVT::i32));
197     SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
198                                DAG.getConstant(0, MVT::i32));
199     return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Hi);
200   } else {
201     return DAG.getNode(ISD::RET, MVT::Other, Chain, Op);
202   }
203 }
204
205 SDOperand SparcV8TargetLowering::
206 LowerVAStart(SDOperand Chain, SDOperand VAListP, Value *VAListV, 
207              SelectionDAG &DAG) {
208              
209   assert(0 && "Unimp");
210   abort();
211 }
212
213 std::pair<SDOperand,SDOperand> SparcV8TargetLowering::
214 LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
215            const Type *ArgTy, SelectionDAG &DAG) {
216   assert(0 && "Unimp");
217   abort();
218 }
219
220 std::pair<SDOperand, SDOperand> SparcV8TargetLowering::
221 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
222                         SelectionDAG &DAG) {
223   assert(0 && "Unimp");
224   abort();
225 }
226
227 SDOperand SparcV8TargetLowering::
228 LowerOperation(SDOperand Op, SelectionDAG &DAG) {
229   switch (Op.getOpcode()) {
230   default: assert(0 && "Should not custom lower this!");
231   case ISD::BR_CC: {
232     SDOperand Chain = Op.getOperand(0);
233     SDOperand CC = Op.getOperand(1);
234     SDOperand LHS = Op.getOperand(2);
235     SDOperand RHS = Op.getOperand(3);
236     SDOperand Dest = Op.getOperand(4);
237     
238     // Get the condition flag.
239     if (LHS.getValueType() == MVT::i32) {
240       SDOperand Cond = DAG.getNode(V8ISD::CMPICC, MVT::Flag, LHS, RHS);
241       return DAG.getNode(V8ISD::BRICC, MVT::Other, Chain, Dest, CC, Cond);
242     } else {
243       SDOperand Cond = DAG.getNode(V8ISD::CMPFCC, MVT::Flag, LHS, RHS);
244       return DAG.getNode(V8ISD::BRFCC, MVT::Other, Chain, Dest, CC, Cond);
245     }
246   }
247   case ISD::GlobalAddress: {
248     GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
249     SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32);
250     SDOperand Hi = DAG.getNode(V8ISD::Hi, MVT::i32, GA);
251     SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, GA);
252     return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi);
253   }
254   }  
255 }
256
257
258 //===----------------------------------------------------------------------===//
259 // Instruction Selector Implementation
260 //===----------------------------------------------------------------------===//
261
262 //===--------------------------------------------------------------------===//
263 /// SparcV8DAGToDAGISel - PPC specific code to select Sparc V8 machine
264 /// instructions for SelectionDAG operations.
265 ///
266 namespace {
267 class SparcV8DAGToDAGISel : public SelectionDAGISel {
268   SparcV8TargetLowering V8Lowering;
269 public:
270   SparcV8DAGToDAGISel(TargetMachine &TM)
271     : SelectionDAGISel(V8Lowering), V8Lowering(TM) {}
272
273   SDOperand Select(SDOperand Op);
274
275   // Complex Pattern Selectors.
276   bool SelectADDRrr(SDOperand N, SDOperand &R1, SDOperand &R2);
277   bool SelectADDRri(SDOperand N, SDOperand &Base, SDOperand &Offset);
278   
279   /// InstructionSelectBasicBlock - This callback is invoked by
280   /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
281   virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
282   
283   virtual const char *getPassName() const {
284     return "PowerPC DAG->DAG Pattern Instruction Selection";
285   } 
286   
287   // Include the pieces autogenerated from the target description.
288 #include "SparcV8GenDAGISel.inc"
289 };
290 }  // end anonymous namespace
291
292 /// InstructionSelectBasicBlock - This callback is invoked by
293 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
294 void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
295   DEBUG(BB->dump());
296   
297   // Select target instructions for the DAG.
298   DAG.setRoot(Select(DAG.getRoot()));
299   CodeGenMap.clear();
300   DAG.RemoveDeadNodes();
301   
302   // Emit machine code to BB. 
303   ScheduleAndEmitDAG(DAG);
304 }
305
306 bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1, 
307                                        SDOperand &R2) {
308   if (Addr.getOpcode() == ISD::ADD) {
309     if (isa<ConstantSDNode>(Addr.getOperand(1)) &&
310         Predicate_simm13(Addr.getOperand(1).Val))
311       return false;  // Let the reg+imm pattern catch this!
312     if (Addr.getOperand(0).getOpcode() == V8ISD::Lo ||
313         Addr.getOperand(1).getOpcode() == V8ISD::Lo)
314       return false;  // Let the reg+imm pattern catch this!
315     R1 = Select(Addr.getOperand(0));
316     R2 = Select(Addr.getOperand(1));
317     return true;
318   }
319
320   R1 = Select(Addr);
321   R2 = CurDAG->getRegister(V8::G0, MVT::i32);
322   return true;
323 }
324
325 bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
326                                        SDOperand &Offset) {
327   if (Addr.getOpcode() == ISD::ADD) {
328     if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
329       if (Predicate_simm13(CN)) {
330         Base = Select(Addr.getOperand(0));
331         Offset = CurDAG->getTargetConstant(CN->getValue(), MVT::i32);
332         return true;
333       }
334     if (Addr.getOperand(0).getOpcode() == V8ISD::Lo) {
335       Base = Select(Addr.getOperand(1));
336       Offset = Addr.getOperand(0).getOperand(0);
337       return true;
338     }
339     if (Addr.getOperand(1).getOpcode() == V8ISD::Lo) {
340       Base = Select(Addr.getOperand(0));
341       Offset = Addr.getOperand(1).getOperand(0);
342       return true;
343     }
344   }
345   Base = Select(Addr);
346   Offset = CurDAG->getTargetConstant(0, MVT::i32);
347   return true;
348 }
349
350
351 SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
352   SDNode *N = Op.Val;
353   if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
354       N->getOpcode() < V8ISD::FIRST_NUMBER)
355     return Op;   // Already selected.
356                  // If this has already been converted, use it.
357   std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
358   if (CGMI != CodeGenMap.end()) return CGMI->second;
359   
360   switch (N->getOpcode()) {
361   default: break;
362   case ISD::BasicBlock:         return CodeGenMap[Op] = Op;
363   case V8ISD::CMPICC: {
364     // FIXME: Handle compare with immediate.
365     SDOperand LHS = Select(N->getOperand(0));
366     SDOperand RHS = Select(N->getOperand(1));
367     SDOperand Result = CurDAG->getTargetNode(V8::SUBCCrr, MVT::i32, MVT::Flag,
368                                              LHS, RHS);
369     return CodeGenMap[Op] = Result.getValue(1);
370   }
371   case ISD::ADD_PARTS: {
372     SDOperand LHSL = Select(N->getOperand(0));
373     SDOperand LHSH = Select(N->getOperand(1));
374     SDOperand RHSL = Select(N->getOperand(2));
375     SDOperand RHSH = Select(N->getOperand(3));
376     // FIXME, handle immediate RHS.
377     SDOperand Low = CurDAG->getTargetNode(V8::ADDCCrr, MVT::i32, MVT::Flag,
378                                           LHSL, RHSL);
379     SDOperand Hi  = CurDAG->getTargetNode(V8::ADDXrr, MVT::i32, LHSH, RHSH, 
380                                           Low.getValue(1));
381     CodeGenMap[SDOperand(N, 0)] = Low;
382     CodeGenMap[SDOperand(N, 1)] = Hi;
383     return Op.ResNo ? Hi : Low;
384   }
385   case ISD::SUB_PARTS: {
386     SDOperand LHSL = Select(N->getOperand(0));
387     SDOperand LHSH = Select(N->getOperand(1));
388     SDOperand RHSL = Select(N->getOperand(2));
389     SDOperand RHSH = Select(N->getOperand(3));
390     // FIXME, handle immediate RHS.
391     SDOperand Low = CurDAG->getTargetNode(V8::SUBCCrr, MVT::i32, MVT::Flag,
392                                           LHSL, RHSL);
393     SDOperand Hi  = CurDAG->getTargetNode(V8::SUBXrr, MVT::i32, LHSH, RHSH, 
394                                           Low.getValue(1));
395     CodeGenMap[SDOperand(N, 0)] = Low;
396     CodeGenMap[SDOperand(N, 1)] = Hi;
397     return Op.ResNo ? Hi : Low;
398   }
399   case ISD::SDIV:
400   case ISD::UDIV: {
401     // FIXME: should use a custom expander to expose the SRA to the dag.
402     SDOperand DivLHS = Select(N->getOperand(0));
403     SDOperand DivRHS = Select(N->getOperand(1));
404     
405     // Set the Y register to the high-part.
406     SDOperand TopPart;
407     if (N->getOpcode() == ISD::SDIV) {
408       TopPart = CurDAG->getTargetNode(V8::SRAri, MVT::i32, DivLHS,
409                                       CurDAG->getTargetConstant(31, MVT::i32));
410     } else {
411       TopPart = CurDAG->getRegister(V8::G0, MVT::i32);
412     }
413     TopPart = CurDAG->getTargetNode(V8::WRYrr, MVT::Flag, TopPart,
414                                     CurDAG->getRegister(V8::G0, MVT::i32));
415
416     // FIXME: Handle div by immediate.
417     unsigned Opcode = N->getOpcode() == ISD::SDIV ? V8::SDIVrr : V8::UDIVrr;
418     return CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart);
419   }    
420   case ISD::MULHU:
421   case ISD::MULHS: {
422     // FIXME: Handle mul by immediate.
423     SDOperand MulLHS = Select(N->getOperand(0));
424     SDOperand MulRHS = Select(N->getOperand(1));
425     unsigned Opcode = N->getOpcode() == ISD::MULHU ? V8::UMULrr : V8::SMULrr;
426     SDOperand Mul = CurDAG->getTargetNode(Opcode, MVT::i32, MVT::Flag,
427                                           MulLHS, MulRHS);
428     // The high part is in the Y register.
429     return CurDAG->SelectNodeTo(N, V8::RDY, MVT::i32, Mul.getValue(1));
430   }
431     
432   case ISD::RET: {
433     if (N->getNumOperands() == 2) {
434       SDOperand Chain = Select(N->getOperand(0));     // Token chain.
435       SDOperand Val = Select(N->getOperand(1));
436       if (N->getOperand(1).getValueType() == MVT::i32) {
437         Chain = CurDAG->getCopyToReg(Chain, V8::I0, Val);
438       } else if (N->getOperand(1).getValueType() == MVT::f32) {
439         Chain = CurDAG->getCopyToReg(Chain, V8::F0, Val);
440       } else {
441         assert(N->getOperand(1).getValueType() == MVT::f64);
442         Chain = CurDAG->getCopyToReg(Chain, V8::D0, Val);
443       }
444       return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain);
445     } else if (N->getNumOperands() > 1) {
446       SDOperand Chain = Select(N->getOperand(0));     // Token chain.
447       assert(N->getOperand(1).getValueType() == MVT::i32 &&
448              N->getOperand(2).getValueType() == MVT::i32 &&
449              N->getNumOperands() == 3 && "Unknown two-register ret value!");
450       Chain = CurDAG->getCopyToReg(Chain, V8::I1, Select(N->getOperand(1)));
451       Chain = CurDAG->getCopyToReg(Chain, V8::I0, Select(N->getOperand(2)));
452       return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain);
453     }
454     break;  // Generated code handles the void case.
455   }
456   }
457   
458   return SelectCode(Op);
459 }
460
461
462 /// createPPCISelDag - This pass converts a legalized DAG into a 
463 /// PowerPC-specific DAG, ready for instruction scheduling.
464 ///
465 FunctionPass *llvm::createSparcV8ISelDag(TargetMachine &TM) {
466   return new SparcV8DAGToDAGISel(TM);
467 }