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