Add initial support for global variables, and fix a bug in addr mode selection
[oota-llvm.git] / lib / Target / SparcV8 / SparcV8ISelDAGToDAG.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     R1 = Select(Addr.getOperand(0));
313     R2 = Select(Addr.getOperand(1));
314     return true;
315   }
316
317   R1 = Select(Addr);
318   R2 = CurDAG->getRegister(V8::G0, MVT::i32);
319   return true;
320 }
321
322 bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base,
323                                        SDOperand &Offset) {
324   if (Addr.getOpcode() == ISD::ADD) {
325     if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
326       if (Predicate_simm13(CN)) {
327         Base = Select(Addr.getOperand(0));
328         Offset = CurDAG->getTargetConstant(CN->getValue(), MVT::i32);
329         return true;
330       }
331   }
332   Base = Select(Addr);
333   Offset = CurDAG->getTargetConstant(0, MVT::i32);
334   return true;
335 }
336
337
338 SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) {
339   SDNode *N = Op.Val;
340   if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
341       N->getOpcode() < V8ISD::FIRST_NUMBER)
342     return Op;   // Already selected.
343                  // If this has already been converted, use it.
344   std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
345   if (CGMI != CodeGenMap.end()) return CGMI->second;
346   
347   switch (N->getOpcode()) {
348   default: break;
349   case ISD::BasicBlock:         return CodeGenMap[Op] = Op;
350   case V8ISD::CMPICC: {
351     // FIXME: Handle compare with immediate.
352     SDOperand LHS = Select(N->getOperand(0));
353     SDOperand RHS = Select(N->getOperand(1));
354     SDOperand Result = CurDAG->getTargetNode(V8::SUBCCrr, MVT::i32, MVT::Flag,
355                                              LHS, RHS);
356     return CodeGenMap[Op] = Result.getValue(1);
357   }
358   case ISD::ADD_PARTS: {
359     SDOperand LHSL = Select(N->getOperand(0));
360     SDOperand LHSH = Select(N->getOperand(1));
361     SDOperand RHSL = Select(N->getOperand(2));
362     SDOperand RHSH = Select(N->getOperand(3));
363     // FIXME, handle immediate RHS.
364     SDOperand Low = CurDAG->getTargetNode(V8::ADDCCrr, MVT::i32, MVT::Flag,
365                                           LHSL, RHSL);
366     SDOperand Hi  = CurDAG->getTargetNode(V8::ADDXrr, MVT::i32, LHSH, RHSH, 
367                                           Low.getValue(1));
368     CodeGenMap[SDOperand(N, 0)] = Low;
369     CodeGenMap[SDOperand(N, 1)] = Hi;
370     return Op.ResNo ? Hi : Low;
371   }
372   case ISD::SUB_PARTS: {
373     SDOperand LHSL = Select(N->getOperand(0));
374     SDOperand LHSH = Select(N->getOperand(1));
375     SDOperand RHSL = Select(N->getOperand(2));
376     SDOperand RHSH = Select(N->getOperand(3));
377     // FIXME, handle immediate RHS.
378     SDOperand Low = CurDAG->getTargetNode(V8::SUBCCrr, MVT::i32, MVT::Flag,
379                                           LHSL, RHSL);
380     SDOperand Hi  = CurDAG->getTargetNode(V8::SUBXrr, MVT::i32, LHSH, RHSH, 
381                                           Low.getValue(1));
382     CodeGenMap[SDOperand(N, 0)] = Low;
383     CodeGenMap[SDOperand(N, 1)] = Hi;
384     return Op.ResNo ? Hi : Low;
385   }
386   case ISD::SDIV:
387   case ISD::UDIV: {
388     // FIXME: should use a custom expander to expose the SRA to the dag.
389     SDOperand DivLHS = Select(N->getOperand(0));
390     SDOperand DivRHS = Select(N->getOperand(1));
391     
392     // Set the Y register to the high-part.
393     SDOperand TopPart;
394     if (N->getOpcode() == ISD::SDIV) {
395       TopPart = CurDAG->getTargetNode(V8::SRAri, MVT::i32, DivLHS,
396                                       CurDAG->getTargetConstant(31, MVT::i32));
397     } else {
398       TopPart = CurDAG->getRegister(V8::G0, MVT::i32);
399     }
400     TopPart = CurDAG->getTargetNode(V8::WRYrr, MVT::Flag, TopPart,
401                                     CurDAG->getRegister(V8::G0, MVT::i32));
402
403     // FIXME: Handle div by immediate.
404     unsigned Opcode = N->getOpcode() == ISD::SDIV ? V8::SDIVrr : V8::UDIVrr;
405     return CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart);
406   }    
407   case ISD::MULHU:
408   case ISD::MULHS: {
409     // FIXME: Handle mul by immediate.
410     SDOperand MulLHS = Select(N->getOperand(0));
411     SDOperand MulRHS = Select(N->getOperand(1));
412     unsigned Opcode = N->getOpcode() == ISD::MULHU ? V8::UMULrr : V8::SMULrr;
413     SDOperand Mul = CurDAG->getTargetNode(Opcode, MVT::i32, MVT::Flag,
414                                           MulLHS, MulRHS);
415     // The high part is in the Y register.
416     return CurDAG->SelectNodeTo(N, V8::RDY, MVT::i32, Mul.getValue(1));
417   }
418     
419   case ISD::RET: {
420     if (N->getNumOperands() == 2) {
421       SDOperand Chain = Select(N->getOperand(0));     // Token chain.
422       SDOperand Val = Select(N->getOperand(1));
423       if (N->getOperand(1).getValueType() == MVT::i32) {
424         Chain = CurDAG->getCopyToReg(Chain, V8::I0, Val);
425       } else if (N->getOperand(1).getValueType() == MVT::f32) {
426         Chain = CurDAG->getCopyToReg(Chain, V8::F0, Val);
427       } else {
428         assert(N->getOperand(1).getValueType() == MVT::f64);
429         Chain = CurDAG->getCopyToReg(Chain, V8::D0, Val);
430       }
431       return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain);
432     } else if (N->getNumOperands() > 1) {
433       SDOperand Chain = Select(N->getOperand(0));     // Token chain.
434       assert(N->getOperand(1).getValueType() == MVT::i32 &&
435              N->getOperand(2).getValueType() == MVT::i32 &&
436              N->getNumOperands() == 3 && "Unknown two-register ret value!");
437       Chain = CurDAG->getCopyToReg(Chain, V8::I1, Select(N->getOperand(1)));
438       Chain = CurDAG->getCopyToReg(Chain, V8::I0, Select(N->getOperand(2)));
439       return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain);
440     }
441     break;  // Generated code handles the void case.
442   }
443   }
444   
445   return SelectCode(Op);
446 }
447
448
449 /// createPPCISelDag - This pass converts a legalized DAG into a 
450 /// PowerPC-specific DAG, ready for instruction scheduling.
451 ///
452 FunctionPass *llvm::createSparcV8ISelDag(TargetMachine &TM) {
453   return new SparcV8DAGToDAGISel(TM);
454 }