Adding files for Microchip's PIC16 target.
[oota-llvm.git] / lib / Target / PIC16 / PIC16ISelLowering.cpp
1 //===-- PIC16ISelLowering.cpp - PIC16 DAG Lowering Implementation ---------===//
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 the interfaces that PIC16 uses to lower LLVM code into a
11 // selection DAG.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #define DEBUG_TYPE "pic16-lower"
16
17 #include "PIC16ISelLowering.h"
18 #include "PIC16TargetMachine.h"
19 #include "llvm/DerivedTypes.h"
20 #include "llvm/Function.h"
21 #include "llvm/Intrinsics.h"
22 #include "llvm/CallingConv.h"
23 #include "llvm/CodeGen/CallingConvLower.h"
24 #include "llvm/CodeGen/MachineFrameInfo.h"
25 #include "llvm/CodeGen/MachineFunction.h"
26 #include "llvm/CodeGen/MachineInstrBuilder.h"
27 #include "llvm/CodeGen/MachineRegisterInfo.h"
28 #include "llvm/CodeGen/SelectionDAGISel.h"
29 #include "llvm/CodeGen/ValueTypes.h"
30 #include "llvm/Support/Debug.h"
31 #include <queue>
32 #include <set>
33
34 using namespace llvm;
35
36 const char *PIC16TargetLowering:: getTargetNodeName(unsigned Opcode) const 
37 {
38   switch (Opcode) 
39   {
40     case PIC16ISD::Hi        : return "PIC16ISD::Hi";
41     case PIC16ISD::Lo        : return "PIC16ISD::Lo";
42     case PIC16ISD::Package   : return "PIC16ISD::Package";
43     case PIC16ISD::Wrapper   : return "PIC16ISD::Wrapper";
44     case PIC16ISD::SetBank   : return "PIC16ISD::SetBank";
45     case PIC16ISD::SetPage   : return "PIC16ISD::SetPage";
46     case PIC16ISD::Branch    : return "PIC16ISD::Branch";
47     case PIC16ISD::Cmp       : return "PIC16ISD::Cmp";
48     case PIC16ISD::BTFSS     : return "PIC16ISD::BTFSS";
49     case PIC16ISD::BTFSC     : return "PIC16ISD::BTFSC";
50     case PIC16ISD::XORCC     : return "PIC16ISD::XORCC";
51     case PIC16ISD::SUBCC     : return "PIC16ISD::SUBCC";
52     default                  : return NULL;
53   }
54 }
55
56 PIC16TargetLowering::
57 PIC16TargetLowering(PIC16TargetMachine &TM): TargetLowering(TM) 
58 {
59   // PIC16 does not have i1 type, so use i8 for
60   // setcc operations results (slt, sgt, ...). 
61   // setSetCCResultType(MVT::i8);
62   // setSetCCResultContents(ZeroOrOneSetCCResult);
63
64   // Set up the register classes
65   addRegisterClass(MVT::i8,  PIC16::CPURegsRegisterClass);
66   addRegisterClass(MVT::i16, PIC16::PTRRegsRegisterClass);
67   // Custom
68
69   // Load extented operations for i1 types must be promoted 
70   setLoadXAction(ISD::EXTLOAD,  MVT::i1,  Promote);
71   setLoadXAction(ISD::ZEXTLOAD, MVT::i1,  Promote);
72   setLoadXAction(ISD::SEXTLOAD, MVT::i1,  Promote);
73
74   // Store operations for i1 types must be promoted
75   // setStoreXAction(MVT::i1, Promote);
76   // setStoreXAction(MVT::i8, Legal);
77   // setStoreXAction(MVT::i16, Custom);
78   // setStoreXAction(MVT::i32, Expand);
79
80   // setOperationAction(ISD::BUILD_PAIR,     MVT::i32,  Expand);
81   // setOperationAction(ISD::BUILD_PAIR,     MVT::i16,  Expand);
82
83   setOperationAction(ISD::ADD,     MVT::i1,  Promote);
84   setOperationAction(ISD::ADD,     MVT::i8,  Legal);
85   setOperationAction(ISD::ADD,     MVT::i16, Custom);
86   setOperationAction(ISD::ADD,     MVT::i32, Expand);
87   setOperationAction(ISD::ADD,     MVT::i64, Expand);
88
89   setOperationAction(ISD::SUB,     MVT::i1,  Promote);
90   setOperationAction(ISD::SUB,     MVT::i8,  Legal);
91   setOperationAction(ISD::SUB,     MVT::i16, Custom);
92   setOperationAction(ISD::SUB,     MVT::i32, Expand);
93   setOperationAction(ISD::SUB,     MVT::i64, Expand);
94
95   setOperationAction(ISD::ADDC,     MVT::i1,  Promote);
96   setOperationAction(ISD::ADDC,     MVT::i8,  Legal);
97   setOperationAction(ISD::ADDC,     MVT::i16, Custom);
98   setOperationAction(ISD::ADDC,     MVT::i32, Expand);
99   setOperationAction(ISD::ADDC,     MVT::i64, Expand);
100
101   setOperationAction(ISD::ADDE,     MVT::i1,  Promote);
102   setOperationAction(ISD::ADDE,     MVT::i8,  Legal);
103   setOperationAction(ISD::ADDE,     MVT::i16, Custom);
104   setOperationAction(ISD::ADDE,     MVT::i32, Expand);
105   setOperationAction(ISD::ADDE,     MVT::i64, Expand);
106
107   setOperationAction(ISD::SUBC,     MVT::i1,  Promote);
108   setOperationAction(ISD::SUBC,     MVT::i8,  Legal);
109   setOperationAction(ISD::SUBC,     MVT::i16, Custom);
110   setOperationAction(ISD::SUBC,     MVT::i32, Expand);
111   setOperationAction(ISD::SUBC,     MVT::i64, Expand);
112
113   setOperationAction(ISD::SUBE,     MVT::i1,  Promote);
114   setOperationAction(ISD::SUBE,     MVT::i8,  Legal);
115   setOperationAction(ISD::SUBE,     MVT::i16, Custom);
116   setOperationAction(ISD::SUBE,     MVT::i32, Expand);
117   setOperationAction(ISD::SUBE,     MVT::i64, Expand);
118
119   // PIC16 does not have these NodeTypes below.
120   setOperationAction(ISD::SETCC,     MVT::i1,   Expand);
121   setOperationAction(ISD::SETCC,     MVT::i8,   Expand);
122   setOperationAction(ISD::SETCC,     MVT::Other,   Expand);
123   setOperationAction(ISD::SELECT_CC, MVT::i1, Custom);
124   setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);
125
126   setOperationAction(ISD::BRCOND,     MVT::i1,   Expand);
127   setOperationAction(ISD::BRCOND,     MVT::i8,   Expand);
128   setOperationAction(ISD::BRCOND,     MVT::Other,   Expand);
129   setOperationAction(ISD::BR_CC,     MVT::i1, Custom);
130   setOperationAction(ISD::BR_CC,     MVT::i8, Custom);
131
132   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
133
134   
135   // Do we really need to Custom lower the GA ??
136   // setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
137   setOperationAction(ISD::GlobalAddress, MVT::i8, Custom);
138   setOperationAction(ISD::RET, MVT::Other, Custom);
139
140   // PIC16 not supported intrinsics.
141   // setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
142   // setOperationAction(ISD::MEMSET, MVT::Other, Expand);
143   // setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
144
145   setOperationAction(ISD::CTPOP, MVT::i32, Expand);
146   setOperationAction(ISD::CTTZ , MVT::i32, Expand);
147   setOperationAction(ISD::CTLZ , MVT::i32, Expand);
148   setOperationAction(ISD::ROTL , MVT::i32, Expand);
149   setOperationAction(ISD::ROTR , MVT::i32, Expand);
150   setOperationAction(ISD::BSWAP, MVT::i32, Expand);
151
152   setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
153   setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
154   setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
155
156   // We don't have line number support yet.
157   setOperationAction(ISD::LOCATION, MVT::Other, Expand);
158   setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
159   setOperationAction(ISD::LABEL, MVT::Other, Expand);
160
161   // Use the default for now
162   setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
163   setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
164
165   setOperationAction(ISD::LOAD, MVT::i1, Promote);
166   setOperationAction(ISD::LOAD, MVT::i8, Legal);
167   // setOperationAction(ISD::LOAD, MVT::i16, Expand);
168   // setOperationAction(ISD::LOAD, MVT::i32, Expand);
169
170   setTargetDAGCombine(ISD::LOAD);
171   setTargetDAGCombine(ISD::STORE);
172   setTargetDAGCombine(ISD::ADDE);
173   setTargetDAGCombine(ISD::ADDC);
174   setTargetDAGCombine(ISD::ADD);
175   setTargetDAGCombine(ISD::SUBE);
176   setTargetDAGCombine(ISD::SUBC);
177   setTargetDAGCombine(ISD::SUB);
178
179   // We must find a way to get rid of Package nodes in the map
180   // setTargetDAGCombine(PIC16ISD::Package);
181
182   // getValueTypeActions().setTypeAction((MVT::ValueType)MVT::i16, Expand);
183
184   setStackPointerRegisterToSaveRestore(PIC16::STKPTR);
185   computeRegisterProperties();
186 }
187
188
189 SDOperand PIC16TargetLowering:: LowerOperation(SDOperand Op, SelectionDAG &DAG) 
190 {
191   SDVTList VTList16 = DAG.getVTList(MVT::i16, MVT::i16, MVT::Other);
192   switch (Op.getOpcode()) 
193   {
194     case ISD::STORE: 
195       cout << "reduce store\n"; 
196         break;
197     case ISD::FORMAL_ARGUMENTS:   
198       cout<<"==== lowering formal args\n";
199       return LowerFORMAL_ARGUMENTS(Op, DAG);
200     case ISD::GlobalAddress:      
201       cout<<"==== lowering GA\n";
202       return LowerGlobalAddress(Op, DAG);
203     case ISD::RET:                
204       cout<<"==== lowering ret\n";
205       return LowerRET(Op, DAG);
206     case ISD::FrameIndex:         
207       cout<<"==== lowering frame index\n";
208       return LowerFrameIndex(Op, DAG);
209     case ISD::ADDE: 
210       cout <<"==== lowering adde\n"; 
211       break;
212     case ISD::LOAD:
213     case ISD::ADD: 
214       break;
215     case ISD::BR_CC:            
216       cout << "==== lowering BR_CC\n"; 
217       return LowerBR_CC(Op, DAG); 
218   } //end swithch
219   return SDOperand();
220 }
221
222
223 //===----------------------------------------------------------------------===//
224 //  Lower helper functions
225 //===----------------------------------------------------------------------===//
226
227
228 SDOperand 
229 PIC16TargetLowering::LowerBR_CC(SDOperand Op, SelectionDAG &DAG) 
230 {
231   MVT::ValueType VT = Op.getValueType();
232   SDOperand Chain = Op.getOperand(0);
233   ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
234   SDOperand LHS = Op.getOperand(2);
235   SDOperand RHS = Op.getOperand(3);
236   SDOperand JumpVal = Op.getOperand(4);
237   SDOperand Result;
238   unsigned  cmpOpcode;
239   unsigned  branchOpcode;
240   SDOperand branchOperand;
241
242   SDOperand StatusReg = DAG.getRegister(PIC16::STATUSREG,MVT::i8);
243   SDOperand CPUReg = DAG.getRegister(PIC16::WREG,MVT::i8);
244   switch(CC) 
245   {
246     default:
247       assert(0 && "This condition code is not handled yet!!");
248       abort();
249     case ISD::SETNE:
250     {
251       cout << "setne\n";
252       cmpOpcode = PIC16ISD::XORCC;
253       branchOpcode = PIC16ISD::BTFSS;
254       branchOperand = DAG.getConstant(2,MVT::i8);
255       break;
256     }
257     case ISD::SETEQ:
258     {
259       cout << "seteq\n";
260       cmpOpcode = PIC16ISD::XORCC;
261       branchOpcode = PIC16ISD::BTFSC;
262       branchOperand = DAG.getConstant(2,MVT::i8);
263       break;
264     }
265     case ISD::SETGT:
266     {
267       assert(0 && "Greater Than condition code is not handled yet!!");
268       abort();
269     }
270     case ISD::SETGE:
271     {
272       cout << "setge\n";
273       cmpOpcode = PIC16ISD::SUBCC;
274       branchOpcode = PIC16ISD::BTFSS;
275       branchOperand = DAG.getConstant(1, MVT::i8);
276       break;
277     }
278     case ISD::SETLT:
279     {
280       cout << "setlt\n";
281       cmpOpcode = PIC16ISD::SUBCC;
282       branchOpcode = PIC16ISD::BTFSC;
283       branchOperand = DAG.getConstant(1,MVT::i8);
284       break;
285     }
286     case ISD::SETLE:
287     {
288       assert(0 && "Less Than Equal condition code is not handled yet!!");
289       abort();
290     }
291   }  // End of Switch
292
293    SDVTList VTList = DAG.getVTList(MVT::i8, MVT::Flag);
294    SDOperand CmpValue = DAG.getNode(cmpOpcode, VTList, LHS, RHS).getValue(1);
295    // SDOperand CCOper = DAG.getConstant(CC,MVT::i8);
296    // Result = DAG.getNode(branchOpcode,VT, Chain, JumpVal, CCOper, StatusReg, 
297    //                      CmpValue);
298    Result = DAG.getNode(branchOpcode, VT, Chain, JumpVal, branchOperand, 
299                         StatusReg, CmpValue);
300    return Result;
301         
302   // return SDOperand();
303 }
304
305
306 //===----------------------------------------------------------------------===//
307 //  Misc Lower Operation implementation
308 //===----------------------------------------------------------------------===//
309 // Create a constant pool entry for global value and wrap it in a wrapper node.
310 SDOperand
311 PIC16TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) 
312 {
313   MVT::ValueType PtrVT = getPointerTy();
314   GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
315   GlobalValue *GV = GSDN->getGlobal();
316
317   //for now only do the ram.
318   SDOperand CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 2);
319   SDOperand CPBank = DAG.getNode(PIC16ISD::SetBank, MVT::i8, CPAddr);
320   CPAddr = DAG.getNode(PIC16ISD::Wrapper, MVT::i8, CPAddr,CPBank);
321
322   return CPAddr;
323 }
324
325 SDOperand
326 PIC16TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) 
327 {
328   switch(Op.getNumOperands()) 
329   {
330     default:
331       assert(0 && "Do not know how to return this many arguments!");
332       abort();
333     case 1:
334       return SDOperand(); // ret void is legal
335   }
336 }
337
338 SDOperand
339 PIC16TargetLowering::LowerFrameIndex(SDOperand N, SelectionDAG &DAG) 
340 {
341   if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N)) {
342     return DAG.getTargetFrameIndex(FIN->getIndex(), MVT::i32);
343   }
344
345   return N;
346 }
347
348 SDOperand
349 PIC16TargetLowering::LowerLOAD(SDNode *N,
350                                SelectionDAG &DAG,
351                                DAGCombinerInfo &DCI) const
352 {
353   SDOperand Outs[2];
354   SDOperand TF; //TokenFactor
355   SDOperand OutChains[2];
356   SDOperand Chain = N->getOperand(0);  
357   SDOperand Src   = N->getOperand(1);
358   SDOperand retVal;
359   SDVTList VTList;
360
361   // If this load is directly stored, replace the load value with the stored
362   // value.
363   // TODO: Handle store large -> read small portion.
364   // TODO: Handle TRUNCSTORE/LOADEXT
365   LoadSDNode *LD  = cast<LoadSDNode>(N);
366   SDOperand Ptr   = LD->getBasePtr();
367   if (LD->getExtensionType() == ISD::NON_EXTLOAD) {
368     if (ISD::isNON_TRUNCStore(Chain.Val)) {
369       StoreSDNode *PrevST = cast<StoreSDNode>(Chain);
370       if (PrevST->getBasePtr() == Ptr &&
371           PrevST->getValue().getValueType() == N->getValueType(0))
372         return DCI.CombineTo(N, Chain.getOperand(1), Chain);
373     }
374   }
375
376   if (N->getValueType(0) != MVT::i16)
377     return SDOperand();
378
379   SDOperand toWorklist;
380   Outs[0] = DAG.getLoad(MVT::i8, Chain, Src, NULL, 0);
381   toWorklist = DAG.getNode(ISD::ADD, MVT::i16, Src,
382                            DAG.getConstant(1, MVT::i16));
383   Outs[1] = DAG.getLoad(MVT::i8, Chain, toWorklist, NULL, 0);
384   // Add to worklist may not be needed. 
385   // It is meant to merge sequences of add with constant into one. 
386   DCI.AddToWorklist(toWorklist.Val);   
387   
388   // Create the tokenfactors and carry it on to the build_pair node
389   OutChains[0] = Outs[0].getValue(1);
390   OutChains[1] = Outs[1].getValue(1);
391   TF = DAG.getNode(ISD::TokenFactor, MVT::Other, &OutChains[0], 2);
392   
393   VTList = DAG.getVTList(MVT::i16, MVT::Flag);
394   retVal = DAG.getNode (PIC16ISD::Package, VTList, &Outs[0], 2);
395
396   DCI.CombineTo (N, retVal, TF);
397
398   return retVal;
399 }
400
401 SDOperand
402 PIC16TargetLowering::LowerADDSUB(SDNode *N, SelectionDAG &DAG,
403                                  DAGCombinerInfo &DCI) const
404 {
405   bool changed = false;
406   int i;
407   SDOperand LoOps[3], HiOps[3];
408   SDOperand OutOps[3]; //[0]:left, [1]:right, [2]:carry
409   SDOperand InOp[2];
410   SDOperand retVal;
411   SDOperand as1,as2;
412   SDVTList VTList;
413   unsigned AS,ASE,ASC;
414
415   InOp[0] = N->getOperand(0);
416   InOp[1] = N->getOperand(1);  
417
418   switch (N->getOpcode())
419   {
420     case ISD::ADD:
421       if (InOp[0].getOpcode() == ISD::Constant &&
422           InOp[1].getOpcode() == ISD::Constant) {
423         ConstantSDNode *CST0 = dyn_cast<ConstantSDNode>(InOp[0]);
424         ConstantSDNode *CST1 = dyn_cast<ConstantSDNode>(InOp[1]);
425         return DAG.getConstant(CST0->getValue() + CST1->getValue(), MVT::i16);
426       }
427     case ISD::ADDE:
428     case ISD::ADDC:
429       AS  = ISD::ADD;
430       ASE = ISD::ADDE;
431       ASC = ISD::ADDC;
432       break;
433     case ISD::SUB:
434       if (InOp[0].getOpcode() == ISD::Constant &&
435           InOp[1].getOpcode() == ISD::Constant) {
436         ConstantSDNode *CST0 = dyn_cast<ConstantSDNode>(InOp[0]);
437         ConstantSDNode *CST1 = dyn_cast<ConstantSDNode>(InOp[1]);
438         return DAG.getConstant(CST0->getValue() - CST1->getValue(), MVT::i16);
439       }
440     case ISD::SUBE:
441     case ISD::SUBC:
442       AS  = ISD::SUB;
443       ASE = ISD::SUBE;
444       ASC = ISD::SUBC;
445       break;
446     }
447
448   assert ((N->getValueType(0) == MVT::i16) 
449            && "expecting an MVT::i16 node for lowering");
450   assert ((N->getOperand(0).getValueType() == MVT::i16) 
451            && (N->getOperand(1).getValueType() == MVT::i16) 
452            && "both inputs to addx/subx:i16 must be i16");
453
454   for (i = 0; i < 2; i++) {
455     if (InOp[i].getOpcode() == ISD::GlobalAddress) {
456       //we don't want to lower subs/adds with global address (at least not yet)
457       return SDOperand();
458     }
459     else if (InOp[i].getOpcode() == ISD::Constant) {
460       changed = true;
461       ConstantSDNode *CST = dyn_cast<ConstantSDNode>(InOp[i]);
462       LoOps[i] = DAG.getConstant(CST->getValue() & 0xFF, MVT::i8);
463       HiOps[i] = DAG.getConstant(CST->getValue() >> 8, MVT::i8);
464     }
465     else if (InOp[i].getOpcode() == PIC16ISD::Package) {
466       LoOps[i] = InOp[i].getOperand(0);
467       HiOps[i] = InOp[i].getOperand(1);
468     }
469     else if (InOp[i].getOpcode() == ISD::LOAD) {
470       changed = true;
471       // LowerLOAD returns a Package node or it may combine and return 
472       // anything else
473       SDOperand lowered = LowerLOAD(InOp[i].Val, DAG, DCI);
474
475       // So If LowerLOAD returns something other than Package, 
476       // then just call ADD again
477       if (lowered.getOpcode() != PIC16ISD::Package)
478         return LowerADDSUB(N, DAG, DCI);
479           
480       LoOps[i] = lowered.getOperand(0);
481       HiOps[i] = lowered.getOperand(1);
482     }
483     else if ((InOp[i].getOpcode() == ISD::ADD) || 
484              (InOp[i].getOpcode() == ISD::ADDE) ||
485              (InOp[i].getOpcode() == ISD::ADDC) ||
486              (InOp[i].getOpcode() == ISD::SUB) ||
487              (InOp[i].getOpcode() == ISD::SUBE) ||
488              (InOp[i].getOpcode() == ISD::SUBC)) {
489       changed = true;
490       //must call LowerADDSUB recursively here....
491       //LowerADDSUB returns a Package node
492       SDOperand lowered = LowerADDSUB(InOp[i].Val, DAG, DCI);
493
494       LoOps[i] = lowered.getOperand(0);
495       HiOps[i] = lowered.getOperand(1);
496     }
497     else if (InOp[i].getOpcode() == ISD::SIGN_EXTEND) {
498       //FIXME: I am just zero extending. for now.
499       changed = true;
500       LoOps[i] = InOp[i].getOperand(0);
501       HiOps[i] = DAG.getConstant(0, MVT::i8);
502     }
503     else {
504       DAG.setGraphColor(N, "blue");
505       DAG.viewGraph();
506       assert (0 && "not implemented yet");
507     }
508   } //end for
509
510   assert (changed && "nothing changed while lowering SUBx/ADDx");
511
512   VTList = DAG.getVTList(MVT::i8, MVT::Flag);
513   if (N->getOpcode() == ASE) { 
514     //we must take in the existing carry
515     //if this node is part of an existing subx/addx sequence
516     LoOps[2] = N->getOperand(2).getValue(1);
517     as1 = DAG.getNode (ASE, VTList, LoOps, 3);
518   }
519   else {
520     as1 = DAG.getNode (ASC, VTList, LoOps, 2);
521   }
522   HiOps[2] = as1.getValue(1);
523   as2 = DAG.getNode (ASE, VTList, HiOps, 3);
524   //we must build a pair that also provides the carry from sube/adde
525   OutOps[0] = as1;
526   OutOps[1] = as2;
527   OutOps[2] = as2.getValue(1);
528   //breaking an original i16 so lets make the Package also an i16
529   if (N->getOpcode() == ASE) {
530     VTList = DAG.getVTList(MVT::i16, MVT::Flag);
531     retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 3);
532     DCI.CombineTo (N, retVal, OutOps[2]);
533   }
534   else if (N->getOpcode() == ASC) {
535     VTList = DAG.getVTList(MVT::i16, MVT::Flag);
536     retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 2);
537     DCI.CombineTo (N, retVal, OutOps[2]);
538   }
539   else if (N->getOpcode() == AS) {
540     VTList = DAG.getVTList(MVT::i16);
541     retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 2);
542     DCI.CombineTo (N, retVal);
543   }
544
545   return retVal;
546 }
547
548
549 //===----------------------------------------------------------------------===//
550 //                      Calling Convention Implementation
551 //
552 //  The lower operations present on calling convention works on this order:
553 //      LowerCALL (virt regs --> phys regs, virt regs --> stack) 
554 //      LowerFORMAL_ARGUMENTS (phys --> virt regs, stack --> virt regs)
555 //      LowerRET (virt regs --> phys regs)
556 //      LowerCALL (phys regs --> virt regs)
557 //
558 //===----------------------------------------------------------------------===//
559
560 #include "PIC16GenCallingConv.inc"
561
562 //===----------------------------------------------------------------------===//
563 //                  CALL Calling Convention Implementation
564 //===----------------------------------------------------------------------===//
565
566
567 //===----------------------------------------------------------------------===//
568 //             FORMAL_ARGUMENTS Calling Convention Implementation
569 //===----------------------------------------------------------------------===//
570 SDOperand PIC16TargetLowering::
571 LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG)
572 {
573   SmallVector<SDOperand, 8> ArgValues;
574   SDOperand Root = Op.getOperand(0);
575
576   // Return the new list of results.
577   // Just copy right now.
578   ArgValues.push_back(Root);
579
580   return DAG.getNode(ISD::MERGE_VALUES, Op.Val->getVTList(), &ArgValues[0], 
581                      ArgValues.size()).getValue(Op.ResNo);
582 }
583
584
585 //===----------------------------------------------------------------------===//
586 //               Return Value Calling Convention Implementation
587 //===----------------------------------------------------------------------===//
588
589 //===----------------------------------------------------------------------===//
590 //                           PIC16 Inline Assembly Support
591 //===----------------------------------------------------------------------===//
592
593 //===----------------------------------------------------------------------===//
594 // Target Optimization Hooks
595 //===----------------------------------------------------------------------===//
596
597 SDOperand PIC16TargetLowering::PerformDAGCombine(SDNode *N, 
598                                                  DAGCombinerInfo &DCI) const 
599 {
600   int i;
601   ConstantSDNode *CST;
602   SelectionDAG &DAG = DCI.DAG;
603
604   switch (N->getOpcode()) 
605   {
606   default: break;
607   case PIC16ISD::Package  :
608     cout <<"==== combining PIC16ISD::Package\n";
609     return SDOperand();
610   case ISD::ADD  :
611   case ISD::SUB  :
612     if ((N->getOperand(0).getOpcode() == ISD::GlobalAddress) ||
613         (N->getOperand(0).getOpcode() == ISD::FrameIndex)) {
614       //do not touch pointer adds
615       return SDOperand ();
616     }
617   case ISD::ADDE :
618   case ISD::ADDC :
619   case ISD::SUBE :
620   case ISD::SUBC :
621     if (N->getValueType(0) == MVT::i16) {
622       SDOperand retVal = LowerADDSUB(N, DAG,DCI); 
623       // LowerADDSUB has already combined the result, 
624       // so we just return nothing to avoid assertion failure from llvm 
625       // if N has been deleted already
626       return SDOperand();
627     }
628     else if (N->getValueType(0) == MVT::i8) { 
629       //sanity check ....
630       for (int i=0; i<2; i++) {
631         if (N->getOperand (i).getOpcode() == PIC16ISD::Package) {
632           assert (0 && 
633                   "don't want to have PIC16ISD::Package as intput to add:i8");
634         }
635       }
636     }
637     break;
638   case ISD::STORE :
639   {
640     SDOperand Chain = N->getOperand(0);  
641     SDOperand Src = N->getOperand(1);
642     SDOperand Dest = N->getOperand(2);
643     unsigned int DstOff = 0;
644     int NUM_STORES;
645     SDOperand Stores[6];
646
647
648     // if source operand is expected to be extended to 
649     // some higher type then - remove this extension 
650     // SDNode and do the extension manually
651     if ((Src.getOpcode() == ISD::ANY_EXTEND) ||
652         (Src.getOpcode() == ISD::SIGN_EXTEND) || 
653         (Src.getOpcode() == ISD::ZERO_EXTEND)) {
654       Src = Src.Val->getOperand(0);
655       Stores[0] = DAG.getStore(Chain, Src, Dest, NULL,0);
656       return Stores[0];
657     }
658
659     switch(Src.getValueType()) 
660     {
661       case MVT::i8:  
662         break;
663       case MVT::i16: 
664         NUM_STORES = 2;
665         break;
666       case MVT::i32: 
667         NUM_STORES = 4;
668         break;
669       case MVT::i64: 
670         NUM_STORES = 8; 
671         break;
672     }
673
674     if (isa<GlobalAddressSDNode>(Dest) && isa<LoadSDNode>(Src) && 
675         (Src.getValueType() != MVT::i8)) {
676       //create direct addressing a = b
677       Chain = Src.getOperand(0);
678       for (i=0; i<NUM_STORES; i++) {
679         SDOperand ADN = DAG.getNode(ISD::ADD, MVT::i16, Src.getOperand(1),
680                                     DAG.getConstant(DstOff, MVT::i16));
681         SDOperand LDN = DAG.getLoad(MVT::i8, Chain, ADN, NULL, 0);
682         SDOperand DSTADDR = DAG.getNode(ISD::ADD, MVT::i16, Dest,
683                                         DAG.getConstant(DstOff, MVT::i16));
684         Stores[i] = DAG.getStore(Chain, LDN, DSTADDR, NULL, 0);
685         Chain = Stores[i];
686         DstOff += 1;
687       } 
688         
689       Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i);
690       return Chain;
691     }
692     else if (isa<GlobalAddressSDNode>(Dest) && isa<ConstantSDNode>(Src) 
693              && (Src.getValueType() != MVT::i8))
694     {
695       //create direct addressing a = CONST
696       CST = dyn_cast<ConstantSDNode>(Src);
697       for (i = 0; i < NUM_STORES; i++) {
698         SDOperand CNST = DAG.getConstant(CST->getValue() >> i*8, MVT::i8);
699         SDOperand ADN = DAG.getNode(ISD::ADD, MVT::i16, Dest,
700                                     DAG.getConstant(DstOff, MVT::i16));
701         Stores[i] = DAG.getStore(Chain, CNST, ADN, NULL, 0);
702         Chain = Stores[i];
703         DstOff += 1;
704       } 
705           
706       Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i);
707       return Chain;
708     }
709     else if (isa<LoadSDNode>(Dest) && isa<ConstantSDNode>(Src) 
710             && (Src.getValueType() != MVT::i8)) {
711       //create indirect addressing
712       CST = dyn_cast<ConstantSDNode>(Src);
713       Chain = Dest.getOperand(0);  
714       SDOperand Load;
715       Load = DAG.getLoad(MVT::i16, Chain,Dest.getOperand(1), NULL, 0);
716       Chain = Load.getValue(1);
717       for (i=0; i<NUM_STORES; i++) {
718         SDOperand CNST = DAG.getConstant(CST->getValue() >> i*8, MVT::i8);
719         Stores[i] = DAG.getStore(Chain, CNST, Load, NULL, 0);
720         Chain = Stores[i];
721         DstOff += 1;
722       } 
723           
724       Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i);
725       return Chain;
726     }
727     else if (isa<LoadSDNode>(Dest) && isa<GlobalAddressSDNode>(Src)) {
728       // GlobalAddressSDNode *GAD = dyn_cast<GlobalAddressSDNode>(Src);
729       return SDOperand();
730     }
731     else if (Src.getOpcode() == PIC16ISD::Package) {
732       StoreSDNode *st = dyn_cast<StoreSDNode>(N);
733       SDOperand toWorkList, retVal;
734       Chain = N->getOperand(0);
735
736       if (st->isTruncatingStore()) {
737         retVal = DAG.getStore(Chain, Src.getOperand(0), Dest, NULL, 0);
738       }
739       else {
740         toWorkList = DAG.getNode(ISD::ADD, MVT::i16, Dest,
741                                  DAG.getConstant(1, MVT::i16));
742         Stores[1] = DAG.getStore(Chain, Src.getOperand(0), Dest, NULL, 0);
743         Stores[0] = DAG.getStore(Chain, Src.getOperand(1), toWorkList, NULL, 0);
744
745        // We want to merge sequence of add with constant to one add and a 
746        // constant, so add the ADD node to worklist to have llvm do that 
747        // automatically.
748        DCI.AddToWorklist(toWorkList.Val); 
749
750        // We don't need the Package so add to worklist so llvm deletes it
751        DCI.AddToWorklist(Src.Val);
752        retVal = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], 2);
753       }
754
755       return retVal;
756     }
757     else if (Src.getOpcode() == ISD::TRUNCATE) {
758     }
759     else {
760       // DAG.setGraphColor(N, "blue");
761       // DAG.viewGraph();
762       // assert (0 && "input to store not implemented yet");
763     }
764   } //end ISD::STORE
765
766   break;
767   case ISD::LOAD :
768   {
769     SDOperand Ptr = N->getOperand(1);
770     if (Ptr.getOpcode() == PIC16ISD::Package) {
771       // DAG.setGraphColor(N, "blue");
772       // DAG.viewGraph();
773       // Here we must make so that:
774       // Ptr.getOperand(0) --> fsrl
775       // Ptr.getOperand(1) --> fsrh
776       assert (0 && "not implemented yet");
777      }
778      //return SDOperand();
779      //break;
780   }
781   }//end switch
782
783   return SDOperand();
784 }
785
786 //===----------------------------------------------------------------------===//
787 //               Utility functions
788 //===----------------------------------------------------------------------===//
789 const SDOperand *PIC16TargetLowering::
790 findLoadi8(const SDOperand &Src, SelectionDAG &DAG) const
791 {
792   unsigned int i;
793   if ((Src.getOpcode() == ISD::LOAD) && (Src.getValueType() == MVT::i8))
794     return &Src;
795   for (i=0; i<Src.getNumOperands(); i++) {
796      const SDOperand *retVal = findLoadi8(Src.getOperand(i),DAG);
797      if (retVal) return retVal;
798   }
799
800   return NULL;
801 }