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