Add include files needed when building with
[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/GlobalValue.h"
21 #include "llvm/Function.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include <cstdio>
25
26
27 using namespace llvm;
28
29
30 // PIC16TargetLowering Constructor.
31 PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM)
32   : TargetLowering(TM) {
33   
34   Subtarget = &TM.getSubtarget<PIC16Subtarget>();
35
36   addRegisterClass(MVT::i8, PIC16::GPRRegisterClass);
37
38   setShiftAmountType(MVT::i8);
39   setShiftAmountFlavor(Extend);
40
41
42   setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
43
44   setOperationAction(ISD::LOAD,   MVT::i8,  Legal);
45   setOperationAction(ISD::LOAD,   MVT::i16, Custom);
46   setOperationAction(ISD::LOAD,   MVT::i32, Custom);
47
48   setOperationAction(ISD::STORE,  MVT::i8,  Legal);
49   setOperationAction(ISD::STORE,  MVT::i16, Custom);
50   setOperationAction(ISD::STORE,  MVT::i32, Custom);
51
52   setOperationAction(ISD::ADDE,    MVT::i8,  Custom);
53   setOperationAction(ISD::ADDC,    MVT::i8,  Custom);
54   setOperationAction(ISD::SUBE,    MVT::i8,  Custom);
55   setOperationAction(ISD::SUBC,    MVT::i8,  Custom);
56   setOperationAction(ISD::ADD,    MVT::i8,  Legal);
57   setOperationAction(ISD::ADD,    MVT::i16, Custom);
58
59   setOperationAction(ISD::OR,     MVT::i8,  Custom);
60   setOperationAction(ISD::AND,    MVT::i8,  Custom);
61   setOperationAction(ISD::XOR,    MVT::i8,  Custom);
62
63   setOperationAction(ISD::SHL,    MVT::i16, Custom);
64   setOperationAction(ISD::SHL,    MVT::i32, Custom);
65
66   //setOperationAction(ISD::TRUNCATE, MVT::i16, Custom);
67   setTruncStoreAction(MVT::i16,   MVT::i8,  Custom);
68
69   // Now deduce the information based on the above mentioned 
70   // actions
71   computeRegisterProperties();
72 }
73
74 const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode) const {
75   switch (Opcode) {
76   default:                         return NULL;
77   case PIC16ISD::Lo:               return "PIC16ISD::Lo";
78   case PIC16ISD::Hi:               return "PIC16ISD::Hi";
79   case PIC16ISD::MTLO:             return "PIC16ISD::MTLO";
80   case PIC16ISD::MTHI:             return "PIC16ISD::MTHI";
81   case PIC16ISD::Banksel:          return "PIC16ISD::Banksel";
82   case PIC16ISD::PIC16Load:        return "PIC16ISD::PIC16Load";
83   case PIC16ISD::PIC16Store:       return "PIC16ISD::PIC16Store";
84   case PIC16ISD::BCF:              return "PIC16ISD::BCF";
85   case PIC16ISD::LSLF:             return "PIC16ISD::LSLF";
86   case PIC16ISD::LRLF:             return "PIC16ISD::LRLF";
87   case PIC16ISD::RLF:              return "PIC16ISD::RLF";
88   case PIC16ISD::RRF:              return "PIC16ISD::RRF";
89   case PIC16ISD::Dummy:            return "PIC16ISD::Dummy";
90   }
91 }
92
93 SDNode *PIC16TargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) {
94   switch (N->getOpcode()) {
95     case ISD::GlobalAddress:
96       return ExpandGlobalAddress(N, DAG);
97     case ISD::STORE:
98       return ExpandStore(N, DAG);
99     case ISD::LOAD:
100       return ExpandLoad(N, DAG);
101     case ISD::ADD:
102       return ExpandAdd(N, DAG);
103     case ISD::SHL:
104       return ExpandShift(N, DAG);
105     default:
106       assert (0 && "not implemented");
107   }
108 }
109
110 SDNode *PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) { 
111   StoreSDNode *St = cast<StoreSDNode>(N);
112   SDValue Chain = St->getChain();
113   SDValue Src = St->getValue();
114   SDValue Ptr = St->getBasePtr();
115   MVT ValueType = Src.getValueType();
116   unsigned StoreOffset = 0;
117
118   SDValue PtrLo, PtrHi;
119   LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, StoreOffset);
120  
121   if (ValueType == MVT::i8) {
122     SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, MVT::Other, Chain, Src,
123                                  PtrLo, PtrHi, DAG.getConstant (0, MVT::i8));
124     return Store.getNode();
125   }
126   else if (ValueType == MVT::i16) {
127     // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
128     SDValue SrcLo, SrcHi;
129     GetExpandedParts(Src, DAG, SrcLo, SrcHi);
130     SDValue ChainLo = Chain, ChainHi = Chain;
131     if (Chain.getOpcode() == ISD::TokenFactor) {
132       ChainLo = Chain.getOperand(0);
133       ChainHi = Chain.getOperand(1);
134     }
135     SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other,
136                                  ChainLo,
137                                  SrcLo, PtrLo, PtrHi,
138                                  DAG.getConstant (0 + StoreOffset, MVT::i8));
139
140     SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi, 
141                                  SrcHi, PtrLo, PtrHi,
142                                  DAG.getConstant (1 + StoreOffset, MVT::i8));
143
144     return DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1),
145                        getChain(Store2)).getNode();
146   }
147   else if (ValueType == MVT::i32) {
148     // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
149     SDValue SrcLo, SrcHi;
150     GetExpandedParts(Src, DAG, SrcLo, SrcHi);
151
152     // Get the expanded parts of each of SrcLo and SrcHi.
153     SDValue SrcLo1, SrcLo2, SrcHi1, SrcHi2;
154     GetExpandedParts(SrcLo, DAG, SrcLo1, SrcLo2);
155     GetExpandedParts(SrcHi, DAG, SrcHi1, SrcHi2);
156
157     SDValue ChainLo = Chain, ChainHi = Chain;
158     if (Chain.getOpcode() == ISD::TokenFactor) {  
159       ChainLo = Chain.getOperand(0);
160       ChainHi = Chain.getOperand(1);
161     }
162     SDValue ChainLo1 = ChainLo, ChainLo2 = ChainLo, ChainHi1 = ChainHi,
163             ChainHi2 = ChainHi;
164     if (ChainLo.getOpcode() == ISD::TokenFactor) {
165       ChainLo1 = ChainLo.getOperand(0);
166       ChainLo2 = ChainLo.getOperand(1);
167     }
168     if (ChainHi.getOpcode() == ISD::TokenFactor) {
169       ChainHi1 = ChainHi.getOperand(0);
170       ChainHi2 = ChainHi.getOperand(1);
171     }
172     SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other,
173                                  ChainLo1,
174                                  SrcLo1, PtrLo, PtrHi,
175                                  DAG.getConstant (0 + StoreOffset, MVT::i8));
176
177     SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainLo2,
178                                  SrcLo2, PtrLo, PtrHi,
179                                  DAG.getConstant (1 + StoreOffset, MVT::i8));
180
181     SDValue Store3 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi1,
182                                  SrcHi1, PtrLo, PtrHi,
183                                  DAG.getConstant (2 + StoreOffset, MVT::i8));
184
185     SDValue Store4 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi2,
186                                  SrcHi2, PtrLo, PtrHi,
187                                  DAG.getConstant (3 + StoreOffset, MVT::i8));
188
189     SDValue RetLo =  DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1),
190                                  getChain(Store2));
191     SDValue RetHi =  DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store3),
192                                 getChain(Store4));
193     return  DAG.getNode(ISD::TokenFactor, MVT::Other, RetLo, RetHi).getNode();
194
195   }
196   else {
197     assert (0 && "value type not supported");
198   }
199 }
200
201 // ExpandGlobalAddress - 
202 SDNode *PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) {
203   GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(SDValue(N, 0));
204   
205   SDValue TGA = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i8,
206                                            G->getOffset());
207
208   SDValue Lo = DAG.getNode(PIC16ISD::Lo, MVT::i8, TGA);
209   SDValue Hi = DAG.getNode(PIC16ISD::Hi, MVT::i8, TGA);
210
211   SDValue BP = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, Lo, Hi);
212   return BP.getNode();
213 }
214
215 bool PIC16TargetLowering::isDirectAddress(const SDValue &Op) {
216   assert (Op.getNode() != NULL && "Can't operate on NULL SDNode!!");
217
218   if (Op.getOpcode() == ISD::BUILD_PAIR) {
219    if (Op.getOperand(0).getOpcode() == PIC16ISD::Lo) 
220      return true;
221   }
222   return false;
223 }
224
225 // Return true if DirectAddress is in ROM_SPACE
226 bool PIC16TargetLowering::isRomAddress(const SDValue &Op) {
227
228   // RomAddress is a GlobalAddress in ROM_SPACE_
229   // If the Op is not a GlobalAddress return NULL without checking
230   // anything further.
231   if (!isDirectAddress(Op))
232     return false; 
233
234   // Its a GlobalAddress.
235   // It is BUILD_PAIR((PIC16Lo TGA), (PIC16Hi TGA)) and Op is BUILD_PAIR
236   SDValue TGA = Op.getOperand(0).getOperand(0);
237   GlobalAddressSDNode *GSDN = dyn_cast<GlobalAddressSDNode>(TGA);
238   const Type *ValueType = GSDN->getGlobal()->getType();
239
240   if (!isa<PointerType>(ValueType)) {
241     assert(0 && "TGA must be of a PointerType");
242   }
243
244   int AddrSpace = dyn_cast<PointerType>(ValueType)->getAddressSpace();
245   if (AddrSpace == PIC16ISD::ROM_SPACE)
246     return true;
247
248   // Any other address space return it false
249   return false;
250 }
251
252 // To extract chain value from the SDValue Nodes
253 // This function will help to maintain the chain extracting
254 // code at one place. In case of any change in future it will
255 // help maintain the code.
256 SDValue PIC16TargetLowering::getChain(SDValue &Op) { 
257   SDValue Chain = Op.getValue(Op.getNode()->getNumValues() - 1);
258
259   // All nodes may not produce a chain. Therefore following assert
260   // verifies that the node is returning a chain only.
261   assert (Chain.getValueType() == MVT::Other && "Node does not have a chain");
262
263   return Chain;
264 }
265
266 void PIC16TargetLowering::GetExpandedParts(SDValue Op, SelectionDAG &DAG,
267                                            SDValue &Lo, SDValue &Hi) {  
268   SDNode *N = Op.getNode();
269   unsigned NumValues = N->getNumValues();
270   std::vector<MVT> VTs;
271   MVT NewVT;
272   std::vector<SDValue> Opers;
273
274   // EXTRACT_ELEMENT should have same number and type of values that the 
275   // node replacing the EXTRACT_ELEMENT should have. (i.e. extracted element)
276   // Some nodes such as LOAD and PIC16Load have more than one values. In such 
277   // cases EXTRACT_ELEMENT should have more than one values. Therefore creating
278   // vector of Values for EXTRACT_ELEMENT. This list will have same number of 
279   // values as the extracted element will have.
280
281   for (unsigned i=0;i < NumValues; ++i) {
282     NewVT = getTypeToTransformTo(N->getValueType(i));
283     VTs.push_back(NewVT);
284   }
285
286   // extract the lo component
287   Opers.push_back(Op);
288   Opers.push_back(DAG.getConstant(0,MVT::i8));
289   Lo = DAG.getNode(ISD::EXTRACT_ELEMENT,VTs,&Opers[0],Opers.size());
290
291   // extract the hi component
292   Opers.clear();
293   Opers.push_back(Op);
294   Opers.push_back(DAG.getConstant(1,MVT::i8));
295   Hi = DAG.getNode(ISD::EXTRACT_ELEMENT,VTs,&Opers[0],Opers.size());
296 }
297
298 // This function legalizes the PIC16 Addresses. If the Pointer is  
299 //  -- Direct address variable residing 
300 //     --> then a Banksel for that variable will be created.
301 //  -- Rom variable            
302 //     --> then it will be treated as an indirect address.
303 //  -- Indirect address 
304 //     --> then the address will be loaded into FSR
305 //  -- ADD with constant operand
306 //     --> then constant operand of ADD will be returned as Offset
307 //         and non-constant operand of ADD will be treated as pointer.
308 // Returns the high and lo part of the address, and the offset(in case of ADD).
309
310 void PIC16TargetLowering:: LegalizeAddress(SDValue Ptr, SelectionDAG &DAG, 
311                                            SDValue &Lo, SDValue &Hi,
312                                            unsigned &Offset) {
313
314   // Offset, by default, should be 0
315   Offset = 0;
316
317   // If the pointer is ADD with constant,
318   // return the constant value as the offset  
319   if (Ptr.getOpcode() == ISD::ADD) {
320     SDValue OperLeft = Ptr.getOperand(0);
321     SDValue OperRight = Ptr.getOperand(1);
322     if (OperLeft.getOpcode() == ISD::Constant) {
323       Offset = dyn_cast<ConstantSDNode>(OperLeft)->getZExtValue();
324       Ptr = OperRight;
325     } else {
326       Ptr = OperLeft;
327       Offset = dyn_cast<ConstantSDNode>(OperRight)->getZExtValue();
328     }
329   }
330
331   if (isDirectAddress(Ptr) && !isRomAddress(Ptr)) {
332     // Direct addressing case for RAM variables. The Hi part is constant
333     // and the Lo part is the TGA itself.
334     Lo = Ptr.getOperand(0).getOperand(0);
335
336     // For direct addresses Hi is a constant. Value 1 for the constant
337     // signifies that banksel needs to generated for it. Value 0 for
338     // the constant signifies that banksel does not need to be generated 
339     // for it. Mark it as 1 now and optimize later. 
340     Hi = DAG.getConstant(1, MVT::i8);
341     return; 
342   }
343
344   // Indirect addresses. Get the hi and lo parts of ptr. 
345   GetExpandedParts(Ptr, DAG, Lo, Hi);
346
347   // Put the hi and lo parts into FSR.
348   Lo = DAG.getNode(PIC16ISD::MTLO, MVT::i8, Lo);
349   Hi = DAG.getNode(PIC16ISD::MTHI, MVT::i8, Hi);
350
351   return;
352 }
353
354 SDNode *PIC16TargetLowering::ExpandAdd(SDNode *N, SelectionDAG &DAG) {
355   SDValue OperLeft = N->getOperand(0);
356   SDValue OperRight = N->getOperand(1);
357
358   if((OperLeft.getOpcode() == ISD::Constant) || 
359      (OperRight.getOpcode() == ISD::Constant)) { 
360     return NULL;
361   }
362
363   // These case are yet to be handled
364   return NULL;
365 }
366
367 SDNode *PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) {
368   LoadSDNode *LD = dyn_cast<LoadSDNode>(SDValue(N, 0));
369   SDValue Chain = LD->getChain();
370   SDValue Ptr = LD->getBasePtr();
371
372   SDValue Load, Offset;
373   SDVTList Tys; 
374   MVT VT, NewVT;
375   SDValue PtrLo, PtrHi;
376   unsigned LoadOffset;
377
378   // Legalize direct/indirect addresses. This will give the lo and hi parts
379   // of the address and the offset.
380   LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, LoadOffset);
381
382   // Load from the pointer (direct address or FSR) 
383   VT = N->getValueType(0);
384   unsigned NumLoads = VT.getSizeInBits() / 8; 
385   std::vector<SDValue> PICLoads;
386   unsigned iter;
387   MVT MemVT = LD->getMemoryVT();
388   if(ISD::isNON_EXTLoad(N)) {
389     for (iter=0; iter<NumLoads ; ++iter) {
390       // Add the pointer offset if any
391       Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
392       Tys = DAG.getVTList(MVT::i8, MVT::Other); 
393       Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Chain, PtrLo, PtrHi,
394                          Offset); 
395       PICLoads.push_back(Load);
396     }
397   } else {
398     // If it is extended load then use PIC16Load for Memory Bytes
399     // and for all extended bytes perform action based on type of
400     // extention - i.e. SignExtendedLoad or ZeroExtendedLoad
401
402     
403     // For extended loads this is the memory value type
404     // i.e. without any extension
405     MVT MemVT = LD->getMemoryVT();
406     unsigned MemBytes = MemVT.getSizeInBits() / 8;
407     unsigned ExtdBytes = VT.getSizeInBits() / 8;
408     Offset = DAG.getConstant(LoadOffset, MVT::i8);
409
410     Tys = DAG.getVTList(MVT::i8, MVT::Other); 
411     // For MemBytes generate PIC16Load with proper offset
412     for (iter=0; iter<MemBytes; ++iter) {
413       // Add the pointer offset if any
414       Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
415       Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Chain, PtrLo, PtrHi,
416                          Offset); 
417       PICLoads.push_back(Load);
418     }
419
420     // For SignExtendedLoad
421     if (ISD::isSEXTLoad(N)) {
422       // For all ExtdBytes use the Right Shifted(Arithmetic) Value of the 
423       // highest MemByte
424       SDValue SRA = DAG.getNode(ISD::SRA, MVT::i8, Load, 
425                                 DAG.getConstant(7, MVT::i8));
426       for (iter=MemBytes; iter<ExtdBytes; ++iter) { 
427         PICLoads.push_back(SRA);
428       }
429     } else if (ISD::isZEXTLoad(N)) {
430       // ZeroExtendedLoad -- For all ExtdBytes use constant 0
431       SDValue ConstZero = DAG.getConstant(0, MVT::i8);
432       for (iter=MemBytes; iter<ExtdBytes; ++iter) { 
433         PICLoads.push_back(ConstZero);
434       }
435     }
436   }
437   SDValue BP;
438
439   if (VT == MVT::i8) {
440     // Operand of Load is illegal -- Load itself is legal
441     return PICLoads[0].getNode();
442   }
443   else if (VT == MVT::i16) {
444     BP = DAG.getNode(ISD::BUILD_PAIR, VT, PICLoads[0], PICLoads[1]);
445     if (MemVT == MVT::i8)
446       Chain = getChain(PICLoads[0]);
447     else
448       Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]),
449                           getChain(PICLoads[1]));
450   } else if (VT == MVT::i32) {
451     SDValue BPs[2];
452     BPs[0] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[0], PICLoads[1]);
453     BPs[1] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[2], PICLoads[3]);
454     BP = DAG.getNode(ISD::BUILD_PAIR, VT, BPs[0], BPs[1]);
455     if (MemVT == MVT::i8)
456       Chain = getChain(PICLoads[0]);
457     else if (MemVT == MVT::i16)
458       Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]),
459                           getChain(PICLoads[1]));
460     else {
461       SDValue Chains[2];
462       Chains[0] = DAG.getNode(ISD::TokenFactor, MVT::Other,
463                               getChain(PICLoads[0]), getChain(PICLoads[1]));
464       Chains[1] = DAG.getNode(ISD::TokenFactor, MVT::Other,
465                               getChain(PICLoads[2]), getChain(PICLoads[3]));
466       Chain =  DAG.getNode(ISD::TokenFactor, MVT::Other, Chains[0], Chains[1]);
467     }
468   }
469   Tys = DAG.getVTList(VT, MVT::Other); 
470   SDValue MergeV = DAG.getNode(ISD::MERGE_VALUES, Tys, BP, Chain);
471   return MergeV.getNode();
472
473 }
474
475 SDNode *PIC16TargetLowering::ExpandShift(SDNode *N, SelectionDAG &DAG) {
476   SDValue Value = N->getOperand(0);
477   SDValue Amt = N->getOperand(1);
478   SDValue BCF, BCFInput;
479   SDVTList Tys; 
480   SDValue ShfCom;   // Shift Component - Lo component should be shifted
481   SDValue RotCom;   // Rotate Component- Hi component should be rotated
482   PIC16ISD::NodeType ShfNode = PIC16ISD::Dummy, RotNode = PIC16ISD::Dummy;
483   
484   // Currently handling Constant shift only
485   if (Amt.getOpcode() != ISD::Constant)
486     return NULL;
487
488   // Following code considers 16 bit left-shift only
489   if (N->getValueType(0) != MVT::i16)
490     return NULL;
491
492   if (N->getOpcode() == ISD::SHL) {
493     ShfNode = PIC16ISD::LSLF;
494     RotNode = PIC16ISD::RLF;
495   } else if (N->getOpcode() == ISD::SRL) {
496     ShfNode = PIC16ISD::LRLF;
497     RotNode = PIC16ISD::RRF;
498   }
499   unsigned ShiftAmt = dyn_cast<ConstantSDNode>(Amt)->getZExtValue();
500   SDValue StatusReg = DAG.getRegister(PIC16::STATUS, MVT::i8);
501   // 0th Bit in StatusReg is CarryBit 
502   SDValue CarryBit= DAG.getConstant(0, MVT::i8);
503
504   GetExpandedParts(Value, DAG, ShfCom, RotCom);
505   BCFInput = DAG.getNode(PIC16ISD::Dummy, MVT::Flag); 
506   Tys = DAG.getVTList(MVT::i8, MVT::Flag);
507
508   for (unsigned i=0;i<ShiftAmt;i++) {
509     BCF = DAG.getNode(PIC16ISD::BCF, MVT::Flag, StatusReg, CarryBit, BCFInput);
510
511     // Following are Two-Address Instructions
512     ShfCom = DAG.getNode(ShfNode, Tys, ShfCom, BCF);
513     RotCom = DAG.getNode(RotNode, Tys, RotCom, ShfCom.getValue(1));
514
515     BCFInput = RotCom.getValue(1); 
516   }
517
518   SDValue BP = DAG.getNode(ISD::BUILD_PAIR, N->getValueType(0), ShfCom, RotCom);
519   return BP.getNode();
520 }
521
522 SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
523   switch (Op.getOpcode()) {
524     case ISD::FORMAL_ARGUMENTS:
525       return LowerFORMAL_ARGUMENTS(Op, DAG);
526     case ISD::ADDC:
527       return LowerADDC(Op, DAG);
528     case ISD::ADDE:
529       return LowerADDE(Op, DAG);
530     case ISD::SUBE:
531       return LowerSUBE(Op, DAG);
532     case ISD::SUBC:
533       return LowerSUBC(Op, DAG);
534     case ISD::LOAD:
535       return SDValue(ExpandLoad(Op.getNode(), DAG), Op.getResNo());
536     case ISD::STORE:
537       return SDValue(ExpandStore(Op.getNode(), DAG), Op.getResNo());
538     case ISD::SHL:
539       return SDValue(ExpandShift(Op.getNode(), DAG), Op.getResNo());
540     case ISD::OR:
541     case ISD::AND:
542     case ISD::XOR:
543       return LowerBinOp(Op, DAG);
544   }
545   return SDValue();
546 }
547
548 SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op,
549                                                  SelectionDAG &DAG) {
550
551   assert (Op.getValueType() == MVT::i8 
552           && "illegal value type to store on stack.");
553
554   MachineFunction &MF = DAG.getMachineFunction();
555   const Function *Func = MF.getFunction();
556   const std::string FuncName = Func->getName();
557
558   char *tmpName = new char [strlen(FuncName.c_str()) +  6];
559
560   // Put the value on stack.
561   // Get a stack slot index and convert to es.
562   int FI = MF.getFrameInfo()->CreateStackObject(1, 1);
563   sprintf(tmpName, "%s.tmp", FuncName.c_str());
564   SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
565
566   // Store the value to ES.
567   SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, MVT::Other,
568                                DAG.getEntryNode(),
569                                Op, ES, 
570                                DAG.getConstant (1, MVT::i8), // Banksel.
571                                DAG.getConstant (FI, MVT::i8));
572
573   // Load the value from ES.
574   SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other);
575   SDValue Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Store,
576                              ES, DAG.getConstant (1, MVT::i8),
577                              DAG.getConstant (FI, MVT::i8));
578     
579   return Load.getValue(0);
580 }
581
582 SDValue PIC16TargetLowering:: LowerBinOp(SDValue Op, SelectionDAG &DAG) {
583   // We should have handled larger operands in type legalizer itself.
584   assert (Op.getValueType() == MVT::i8 && "illegal Op to lower");
585
586   // Return the original Op if the one of the operands is already a load.
587   if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load
588       || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load)
589     return Op;
590
591   // Put one value on stack.
592   SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG);
593
594   return DAG.getNode(Op.getOpcode(), MVT::i8, Op.getOperand(0), NewVal);
595 }
596
597 SDValue PIC16TargetLowering:: LowerADDC(SDValue Op, SelectionDAG &DAG) {
598   // We should have handled larger operands in type legalizer itself.
599   assert (Op.getValueType() == MVT::i8 && "illegal addc to lower");
600
601   // Nothing to do if the one of the operands is already a load.
602   if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load 
603       || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load)
604     return SDValue();
605
606   // Put one value on stack.
607   SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG);
608     
609   SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
610   return DAG.getNode(ISD::ADDC, Tys, Op.getOperand(0), NewVal);
611 }
612
613 SDValue PIC16TargetLowering:: LowerADDE(SDValue Op, SelectionDAG &DAG) {
614   // We should have handled larger operands in type legalizer itself.
615   assert (Op.getValueType() == MVT::i8 && "illegal adde to lower");
616
617   // Nothing to do if the one of the operands is already a load.
618   if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load 
619       || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load)
620     return SDValue();
621
622   // Put one value on stack.
623   SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG);
624     
625   SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
626   return DAG.getNode(ISD::ADDE, Tys, Op.getOperand(0), NewVal, 
627                      Op.getOperand(2));
628 }
629
630 SDValue PIC16TargetLowering:: LowerSUBC(SDValue Op, SelectionDAG &DAG) {
631   // We should have handled larger operands in type legalizer itself.
632   assert (Op.getValueType() == MVT::i8 && "illegal subc to lower");
633
634   // Nothing to do if the first operand is already a load.
635   if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load)
636     return SDValue();
637
638   // Put first operand on stack.
639   SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG);
640
641   SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
642   return DAG.getNode(ISD::SUBC, Tys, NewVal, Op.getOperand(1));
643 }
644
645 SDValue PIC16TargetLowering:: LowerSUBE(SDValue Op, SelectionDAG &DAG) {
646   // We should have handled larger operands in type legalizer itself.
647   assert (Op.getValueType() == MVT::i8 && "illegal sube to lower");
648
649   // Nothing to do if the first operand is already a load.
650   if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load)
651     return SDValue();
652
653   // Put first operand on stack.
654   SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG);
655
656   SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
657   return DAG.getNode(ISD::SUBE, Tys, NewVal, Op.getOperand(1),
658                      Op.getOperand(2));
659 }
660
661 // LowerFORMAL_ARGUMENTS - In Lowering FORMAL ARGUMENTS - MERGE_VALUES nodes
662 // is returned. MERGE_VALUES nodes number of operands and number of values are
663 // equal. Therefore to construct MERGE_VALUE node, UNDEF nodes equal to the
664 // number of arguments of function have been created.
665
666 SDValue PIC16TargetLowering:: LowerFORMAL_ARGUMENTS(SDValue Op, 
667                                                     SelectionDAG &DAG) {
668   SmallVector<SDValue, 8> ArgValues;
669   unsigned NumArgs = Op.getNumOperands() - 3;
670
671   // Creating UNDEF nodes to meet the requirement of MERGE_VALUES node.
672   for(unsigned i = 0 ; i<NumArgs ; i++) {
673     SDValue TempNode = DAG.getNode(ISD::UNDEF, Op.getNode()->getValueType(i));
674     ArgValues.push_back(TempNode);
675   }
676
677   ArgValues.push_back(Op.getOperand(0));
678   return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(), 
679                      &ArgValues[0],
680                      ArgValues.size()).getValue(Op.getResNo());
681 }
682
683 // Perform DAGCombine of PIC16Load 
684 SDValue PIC16TargetLowering::
685 PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const {
686   SelectionDAG &DAG = DCI.DAG;
687   SDValue Chain = N->getOperand(0); 
688   if (N->hasNUsesOfValue(0, 0)) {
689     DAG.ReplaceAllUsesOfValueWith(SDValue(N,1), Chain);
690   }
691   return SDValue();
692 }
693
694
695 SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N, 
696                                                DAGCombinerInfo &DCI) const {
697   switch (N->getOpcode()) {
698   case PIC16ISD::PIC16Load:
699     return PerformPIC16LoadCombine(N, DCI);
700   }
701   return SDValue();
702 }