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