LLVM API Documentation

PIC16ISelLowering.cpp

Go to the documentation of this file.
00001 //
00002 //                     The LLVM Compiler Infrastructure
00003 //
00004 // This file is distributed under the University of Illinois Open Source 
00005 // License. See LICENSE.TXT for details.
00006 //
00007 //===----------------------------------------------------------------------===//
00008 //
00009 // This file defines the interfaces that PIC16 uses to lower LLVM code into a
00010 // selection DAG.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #define DEBUG_TYPE "pic16-lower"
00015 
00016 #include "PIC16ISelLowering.h"
00017 #include "PIC16TargetMachine.h"
00018 #include "llvm/DerivedTypes.h"
00019 #include "llvm/GlobalValue.h"
00020 #include "llvm/Function.h"
00021 #include "llvm/CallingConv.h"
00022 #include "llvm/CodeGen/MachineFrameInfo.h"
00023 #include "llvm/CodeGen/MachineFunction.h"
00024 #include "llvm/CodeGen/MachineInstrBuilder.h"
00025 #include "llvm/CodeGen/MachineRegisterInfo.h"
00026 #include <cstdio>
00027 
00028 
00029 using namespace llvm;
00030 
00031 
00032 // PIC16TargetLowering Constructor.
00033 PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM)
00034   : TargetLowering(TM) {
00035   
00036   Subtarget = &TM.getSubtarget<PIC16Subtarget>();
00037 
00038   addRegisterClass(MVT::i8, PIC16::GPRRegisterClass);
00039 
00040   setShiftAmountType(MVT::i8);
00041   setShiftAmountFlavor(Extend);
00042 
00043   // SRA library call names
00044   setPIC16LibcallName(PIC16ISD::SRA_I8, "__intrinsics.sra.i8");
00045   setLibcallName(RTLIB::SRA_I16, "__intrinsics.sra.i16");
00046   setLibcallName(RTLIB::SRA_I32, "__intrinsics.sra.i32");
00047 
00048   // SHL library call names
00049   setPIC16LibcallName(PIC16ISD::SLL_I8, "__intrinsics.sll.i8");
00050   setLibcallName(RTLIB::SHL_I16, "__intrinsics.sll.i16");
00051   setLibcallName(RTLIB::SHL_I32, "__intrinsics.sll.i32");
00052 
00053   // SRL library call names
00054   setPIC16LibcallName(PIC16ISD::SRL_I8, "__intrinsics.srl.i8");
00055   setLibcallName(RTLIB::SRL_I16, "__intrinsics.srl.i16");
00056   setLibcallName(RTLIB::SRL_I32, "__intrinsics.srl.i32");
00057 
00058   // MUL Library call names
00059   setPIC16LibcallName(PIC16ISD::MUL_I8, "__intrinsics.mul.i8");
00060   setLibcallName(RTLIB::MUL_I16, "__intrinsics.mul.i16");
00061   setLibcallName(RTLIB::MUL_I32, "__intrinsics.mul.i32");
00062 
00063   setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
00064   setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom);
00065 
00066   setOperationAction(ISD::LOAD,   MVT::i8,  Legal);
00067   setOperationAction(ISD::LOAD,   MVT::i16, Custom);
00068   setOperationAction(ISD::LOAD,   MVT::i32, Custom);
00069 
00070   setOperationAction(ISD::STORE,  MVT::i8,  Legal);
00071   setOperationAction(ISD::STORE,  MVT::i16, Custom);
00072   setOperationAction(ISD::STORE,  MVT::i32, Custom);
00073 
00074   setOperationAction(ISD::ADDE,    MVT::i8,  Custom);
00075   setOperationAction(ISD::ADDC,    MVT::i8,  Custom);
00076   setOperationAction(ISD::SUBE,    MVT::i8,  Custom);
00077   setOperationAction(ISD::SUBC,    MVT::i8,  Custom);
00078   setOperationAction(ISD::ADD,    MVT::i8,  Custom);
00079   setOperationAction(ISD::ADD,    MVT::i16, Custom);
00080 
00081   setOperationAction(ISD::OR,     MVT::i8,  Custom);
00082   setOperationAction(ISD::AND,    MVT::i8,  Custom);
00083   setOperationAction(ISD::XOR,    MVT::i8,  Custom);
00084 
00085   setOperationAction(ISD::FrameIndex, MVT::i16, Custom);
00086   setOperationAction(ISD::CALL,   MVT::i16, Custom);
00087   setOperationAction(ISD::RET,    MVT::Other, Custom);
00088 
00089   setOperationAction(ISD::MUL,    MVT::i8,  Custom); 
00090   setOperationAction(ISD::MUL,    MVT::i16, Expand);
00091   setOperationAction(ISD::MUL,    MVT::i32, Expand);
00092 
00093   setOperationAction(ISD::SMUL_LOHI,    MVT::i8,  Expand);
00094   setOperationAction(ISD::SMUL_LOHI,    MVT::i16, Expand);
00095   setOperationAction(ISD::SMUL_LOHI,    MVT::i32, Expand);
00096   setOperationAction(ISD::UMUL_LOHI,    MVT::i8,  Expand);
00097   setOperationAction(ISD::UMUL_LOHI,    MVT::i16, Expand);
00098   setOperationAction(ISD::UMUL_LOHI,    MVT::i32, Expand);
00099   setOperationAction(ISD::MULHU,        MVT::i8, Expand);
00100   setOperationAction(ISD::MULHU,        MVT::i16, Expand);
00101   setOperationAction(ISD::MULHU,        MVT::i32, Expand);
00102   setOperationAction(ISD::MULHS,        MVT::i8, Expand);
00103   setOperationAction(ISD::MULHS,        MVT::i16, Expand);
00104   setOperationAction(ISD::MULHS,        MVT::i32, Expand);
00105 
00106   setOperationAction(ISD::SRA,    MVT::i8,  Custom);
00107   setOperationAction(ISD::SRA,    MVT::i16, Expand);
00108   setOperationAction(ISD::SRA,    MVT::i32, Expand);
00109   setOperationAction(ISD::SHL,    MVT::i8,  Custom);
00110   setOperationAction(ISD::SHL,    MVT::i16, Expand);
00111   setOperationAction(ISD::SHL,    MVT::i32, Expand);
00112   setOperationAction(ISD::SRL,    MVT::i8,  Custom);
00113   setOperationAction(ISD::SRL,    MVT::i16, Expand);
00114   setOperationAction(ISD::SRL,    MVT::i32, Expand);
00115 
00116   // PIC16 does not support shift parts
00117   setOperationAction(ISD::SRA_PARTS,    MVT::i8,  Expand);
00118   setOperationAction(ISD::SRA_PARTS,    MVT::i16, Expand);
00119   setOperationAction(ISD::SRA_PARTS,    MVT::i32, Expand);
00120   setOperationAction(ISD::SHL_PARTS,    MVT::i8, Expand);
00121   setOperationAction(ISD::SHL_PARTS,    MVT::i16, Expand);
00122   setOperationAction(ISD::SHL_PARTS,    MVT::i32, Expand);
00123   setOperationAction(ISD::SRL_PARTS,    MVT::i8, Expand);
00124   setOperationAction(ISD::SRL_PARTS,    MVT::i16, Expand);
00125   setOperationAction(ISD::SRL_PARTS,    MVT::i32, Expand);
00126 
00127 
00128   // PIC16 does not have a SETCC, expand it to SELECT_CC.
00129   setOperationAction(ISD::SETCC,  MVT::i8, Expand);
00130   setOperationAction(ISD::SELECT,  MVT::i8, Expand);
00131   setOperationAction(ISD::BRCOND, MVT::Other, Expand);
00132   setOperationAction(ISD::BRIND, MVT::Other, Expand);
00133 
00134   setOperationAction(ISD::SELECT_CC,  MVT::i8, Custom);
00135   setOperationAction(ISD::BR_CC,  MVT::i8, Custom);
00136 
00137   //setOperationAction(ISD::TRUNCATE, MVT::i16, Custom);
00138   setTruncStoreAction(MVT::i16,   MVT::i8,  Custom);
00139 
00140   // Now deduce the information based on the above mentioned 
00141   // actions
00142   computeRegisterProperties();
00143 }
00144 
00145 static void PopulateResults(SDValue N, SmallVectorImpl<SDValue>&Results) {
00146   if (N.getOpcode() == ISD::MERGE_VALUES) {
00147     int NumResults = N.getNumOperands();
00148     for( int i = 0; i < NumResults; i++)
00149       Results.push_back(N.getOperand(i));
00150   }
00151   else
00152     Results.push_back(N);
00153 }
00154 
00155 MVT PIC16TargetLowering::getSetCCResultType(MVT ValType) const {
00156   return MVT::i8;
00157 }
00158 
00159 
00160 void 
00161 PIC16TargetLowering::setPIC16LibcallName(PIC16ISD::PIC16Libcall Call,
00162                                          const char *Name) {
00163  PIC16LibcallNames[Call] = Name; 
00164 }
00165 
00166 const char *
00167 PIC16TargetLowering::getPIC16LibcallName(PIC16ISD::PIC16Libcall Call) {
00168  return PIC16LibcallNames[Call];
00169 }
00170 
00171 SDValue
00172 PIC16TargetLowering::MakePIC16Libcall(PIC16ISD::PIC16Libcall Call,
00173                                       MVT RetVT, const SDValue *Ops,
00174                                       unsigned NumOps, bool isSigned,
00175                                       SelectionDAG &DAG, DebugLoc dl) {
00176 
00177  TargetLowering::ArgListTy Args;
00178  Args.reserve(NumOps);
00179 
00180  TargetLowering::ArgListEntry Entry;
00181  for (unsigned i = 0; i != NumOps; ++i) {
00182    Entry.Node = Ops[i];
00183    Entry.Ty = Entry.Node.getValueType().getTypeForMVT();
00184    Entry.isSExt = isSigned;
00185    Entry.isZExt = !isSigned;
00186    Args.push_back(Entry);
00187  }
00188  SDValue Callee = DAG.getExternalSymbol(getPIC16LibcallName(Call), MVT::i8);
00189 
00190   const Type *RetTy = RetVT.getTypeForMVT();
00191   std::pair<SDValue,SDValue> CallInfo = 
00192      LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false,
00193                      false, CallingConv::C, false, Callee, Args, DAG, dl);
00194 
00195   return CallInfo.first;
00196 }
00197 
00198 SDValue
00199 PIC16TargetLowering::getCurrentFrame(SelectionDAG &DAG) {
00200   MachineFunction &MF = DAG.getMachineFunction();
00201   const Function *Func = MF.getFunction();
00202   const std::string FuncName = Func->getName();
00203 
00204   // this is causing memory waste
00205   // because for every call new memory will be allocated
00206   char *tmpName = new char [strlen(FuncName.c_str()) +  6];
00207   sprintf(tmpName, "%s.tmp", FuncName.c_str());
00208 
00209   // if the external symbol of the same name already exists then
00210   // it will not create the new one.
00211   return DAG.getTargetExternalSymbol(tmpName, MVT::i8);
00212 }
00213 
00214 void 
00215 PIC16TargetLowering::getCurrentFrameIndex(SelectionDAG &DAG, SDValue &ES, 
00216                                         unsigned SlotSize, int &FromFI) {
00217   MachineFunction &MF = DAG.getMachineFunction();
00218   const Function *Func = MF.getFunction();
00219   const std::string FuncName = Func->getName();
00220 
00221   // this is causing memory waste
00222   // because for every call new memory will be allocated
00223   char *tmpName = new char [strlen(FuncName.c_str()) +  6];
00224   sprintf(tmpName, "%s.tmp", FuncName.c_str());
00225 
00226   // if the external symbol of the same name already exists then
00227   // it will not create the new one.
00228   ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
00229 
00230   // Alignment is always 1
00231   //FromFI = MF.getFrameInfo()->CreateStackObject(SlotSize, 1);
00232   FromFI = MF.getFrameInfo()->CreateStackObject(1, 1);
00233   int FI;
00234   for(unsigned i=1;i<SlotSize; ++i) {
00235     FI = MF.getFrameInfo()->CreateStackObject(1, 1);
00236   }
00237 }
00238 
00239 const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode) const {
00240   switch (Opcode) {
00241   default:                         return NULL;
00242   case PIC16ISD::Lo:               return "PIC16ISD::Lo";
00243   case PIC16ISD::Hi:               return "PIC16ISD::Hi";
00244   case PIC16ISD::MTLO:             return "PIC16ISD::MTLO";
00245   case PIC16ISD::MTHI:             return "PIC16ISD::MTHI";
00246   case PIC16ISD::Banksel:          return "PIC16ISD::Banksel";
00247   case PIC16ISD::PIC16Load:        return "PIC16ISD::PIC16Load";
00248   case PIC16ISD::PIC16LdWF:        return "PIC16ISD::PIC16LdWF";
00249   case PIC16ISD::PIC16Store:       return "PIC16ISD::PIC16Store";
00250   case PIC16ISD::PIC16StWF:        return "PIC16ISD::PIC16StWF";
00251   case PIC16ISD::BCF:              return "PIC16ISD::BCF";
00252   case PIC16ISD::LSLF:             return "PIC16ISD::LSLF";
00253   case PIC16ISD::LRLF:             return "PIC16ISD::LRLF";
00254   case PIC16ISD::RLF:              return "PIC16ISD::RLF";
00255   case PIC16ISD::RRF:              return "PIC16ISD::RRF";
00256   case PIC16ISD::CALL:             return "PIC16ISD::CALL";
00257   case PIC16ISD::SUBCC:            return "PIC16ISD::SUBCC";
00258   case PIC16ISD::SELECT_ICC:       return "PIC16ISD::SELECT_ICC";
00259   case PIC16ISD::BRCOND:           return "PIC16ISD::BRCOND";
00260   case PIC16ISD::Dummy:            return "PIC16ISD::Dummy";
00261   }
00262 }
00263 
00264 void PIC16TargetLowering::ReplaceNodeResults(SDNode *N,
00265                                              SmallVectorImpl<SDValue>&Results,
00266                                              SelectionDAG &DAG) {
00267 
00268   switch (N->getOpcode()) {
00269     case ISD::GlobalAddress:
00270       Results.push_back(ExpandGlobalAddress(N, DAG));
00271       return;
00272     case ISD::ExternalSymbol:
00273       Results.push_back(ExpandExternalSymbol(N, DAG));
00274       return;
00275     case ISD::STORE:
00276       Results.push_back(ExpandStore(N, DAG));
00277       return;
00278     case ISD::LOAD:
00279       PopulateResults(ExpandLoad(N, DAG), Results);
00280       return;
00281     case ISD::ADD:
00282       // Results.push_back(ExpandAdd(N, DAG));
00283       return;
00284     case ISD::FrameIndex:
00285       Results.push_back(ExpandFrameIndex(N, DAG));
00286       return;
00287     default:
00288       assert (0 && "not implemented");
00289       return;
00290   }
00291 }
00292 
00293 SDValue PIC16TargetLowering::ExpandFrameIndex(SDNode *N, SelectionDAG &DAG) {
00294 
00295   // Currently handling FrameIndex of size MVT::i16 only
00296   // One example of this scenario is when return value is written on
00297   // FrameIndex#0
00298 
00299   if (N->getValueType(0) != MVT::i16)
00300     return SDValue();
00301 
00302   // Expand the FrameIndex into ExternalSymbol and a Constant node
00303   // The constant will represent the frame index number
00304   // Get the current function frame
00305   MachineFunction &MF = DAG.getMachineFunction();
00306   const Function *Func = MF.getFunction();
00307   const std::string Name = Func->getName();
00308 
00309   FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(SDValue(N,0));
00310   int Index = FR->getIndex();
00311 
00312   SDValue FI[2];
00313   FI[0] = DAG.getTargetFrameIndex(Index, MVT::i8);
00314   FI[1] = DAG.getTargetFrameIndex(Index + 1, MVT::i8);
00315   return DAG.getNode(ISD::BUILD_PAIR, N->getValueType(0), FI[0], FI[1]);
00316 }
00317 
00318 
00319 SDValue PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) { 
00320   StoreSDNode *St = cast<StoreSDNode>(N);
00321   SDValue Chain = St->getChain();
00322   SDValue Src = St->getValue();
00323   SDValue Ptr = St->getBasePtr();
00324   MVT ValueType = Src.getValueType();
00325   unsigned StoreOffset = 0;
00326 
00327   SDValue PtrLo, PtrHi;
00328   LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, StoreOffset);
00329  
00330   if (ValueType == MVT::i8) {
00331     return DAG.getNode (PIC16ISD::PIC16Store, MVT::Other, Chain, Src,
00332                         PtrLo, PtrHi, 
00333                         DAG.getConstant (0 + StoreOffset, MVT::i8));
00334   }
00335   else if (ValueType == MVT::i16) {
00336     // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
00337     SDValue SrcLo, SrcHi;
00338     GetExpandedParts(Src, DAG, SrcLo, SrcHi);
00339     SDValue ChainLo = Chain, ChainHi = Chain;
00340     if (Chain.getOpcode() == ISD::TokenFactor) {
00341       ChainLo = Chain.getOperand(0);
00342       ChainHi = Chain.getOperand(1);
00343     }
00344     SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other,
00345                                  ChainLo,
00346                                  SrcLo, PtrLo, PtrHi,
00347                                  DAG.getConstant (0 + StoreOffset, MVT::i8));
00348 
00349     SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi, 
00350                                  SrcHi, PtrLo, PtrHi,
00351                                  DAG.getConstant (1 + StoreOffset, MVT::i8));
00352 
00353     return DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1),
00354                        getChain(Store2));
00355   }
00356   else if (ValueType == MVT::i32) {
00357     // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
00358     SDValue SrcLo, SrcHi;
00359     GetExpandedParts(Src, DAG, SrcLo, SrcHi);
00360 
00361     // Get the expanded parts of each of SrcLo and SrcHi.
00362     SDValue SrcLo1, SrcLo2, SrcHi1, SrcHi2;
00363     GetExpandedParts(SrcLo, DAG, SrcLo1, SrcLo2);
00364     GetExpandedParts(SrcHi, DAG, SrcHi1, SrcHi2);
00365 
00366     SDValue ChainLo = Chain, ChainHi = Chain;
00367     if (Chain.getOpcode() == ISD::TokenFactor) {  
00368       ChainLo = Chain.getOperand(0);
00369       ChainHi = Chain.getOperand(1);
00370     }
00371     SDValue ChainLo1 = ChainLo, ChainLo2 = ChainLo, ChainHi1 = ChainHi,
00372             ChainHi2 = ChainHi;
00373     if (ChainLo.getOpcode() == ISD::TokenFactor) {
00374       ChainLo1 = ChainLo.getOperand(0);
00375       ChainLo2 = ChainLo.getOperand(1);
00376     }
00377     if (ChainHi.getOpcode() == ISD::TokenFactor) {
00378       ChainHi1 = ChainHi.getOperand(0);
00379       ChainHi2 = ChainHi.getOperand(1);
00380     }
00381     SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other,
00382                                  ChainLo1,
00383                                  SrcLo1, PtrLo, PtrHi,
00384                                  DAG.getConstant (0 + StoreOffset, MVT::i8));
00385 
00386     SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainLo2,
00387                                  SrcLo2, PtrLo, PtrHi,
00388                                  DAG.getConstant (1 + StoreOffset, MVT::i8));
00389 
00390     SDValue Store3 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi1,
00391                                  SrcHi1, PtrLo, PtrHi,
00392                                  DAG.getConstant (2 + StoreOffset, MVT::i8));
00393 
00394     SDValue Store4 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi2,
00395                                  SrcHi2, PtrLo, PtrHi,
00396                                  DAG.getConstant (3 + StoreOffset, MVT::i8));
00397 
00398     SDValue RetLo =  DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1),
00399                                  getChain(Store2));
00400     SDValue RetHi =  DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store3),
00401                                 getChain(Store4));
00402     return  DAG.getNode(ISD::TokenFactor, MVT::Other, RetLo, RetHi);
00403 
00404   }
00405   else {
00406     assert (0 && "value type not supported");
00407     return SDValue();
00408   }
00409 }
00410 
00411 SDValue PIC16TargetLowering::ExpandExternalSymbol(SDNode *N, SelectionDAG &DAG)
00412 {
00413   ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(SDValue(N, 0));
00414 
00415   SDValue TES = DAG.getTargetExternalSymbol(ES->getSymbol(), MVT::i8);
00416 
00417   SDValue Lo = DAG.getNode(PIC16ISD::Lo, MVT::i8, TES);
00418   SDValue Hi = DAG.getNode(PIC16ISD::Hi, MVT::i8, TES);
00419 
00420   return DAG.getNode(ISD::BUILD_PAIR, MVT::i16, Lo, Hi);
00421 }
00422 
00423 // ExpandGlobalAddress - 
00424 SDValue PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) {
00425   GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(SDValue(N, 0));
00426   
00427   SDValue TGA = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i8,
00428                                            G->getOffset());
00429 
00430   SDValue Lo = DAG.getNode(PIC16ISD::Lo, MVT::i8, TGA);
00431   SDValue Hi = DAG.getNode(PIC16ISD::Hi, MVT::i8, TGA);
00432 
00433   return DAG.getNode(ISD::BUILD_PAIR, MVT::i16, Lo, Hi);
00434 }
00435 
00436 bool PIC16TargetLowering::isDirectAddress(const SDValue &Op) {
00437   assert (Op.getNode() != NULL && "Can't operate on NULL SDNode!!");
00438 
00439   if (Op.getOpcode() == ISD::BUILD_PAIR) {
00440    if (Op.getOperand(0).getOpcode() == PIC16ISD::Lo) 
00441      return true;
00442   }
00443   return false;
00444 }
00445 
00446 // Return true if DirectAddress is in ROM_SPACE
00447 bool PIC16TargetLowering::isRomAddress(const SDValue &Op) {
00448 
00449   // RomAddress is a GlobalAddress in ROM_SPACE_
00450   // If the Op is not a GlobalAddress return NULL without checking
00451   // anything further.
00452   if (!isDirectAddress(Op))
00453     return false; 
00454 
00455   // Its a GlobalAddress.
00456   // It is BUILD_PAIR((PIC16Lo TGA), (PIC16Hi TGA)) and Op is BUILD_PAIR
00457   SDValue TGA = Op.getOperand(0).getOperand(0);
00458   GlobalAddressSDNode *GSDN = dyn_cast<GlobalAddressSDNode>(TGA);
00459   const Type *ValueType = GSDN->getGlobal()->getType();
00460 
00461   if (!isa<PointerType>(ValueType)) {
00462     assert(0 && "TGA must be of a PointerType");
00463   }
00464 
00465   int AddrSpace = dyn_cast<PointerType>(ValueType)->getAddressSpace();
00466   if (AddrSpace == PIC16ISD::ROM_SPACE)
00467     return true;
00468 
00469   // Any other address space return it false
00470   return false;
00471 }
00472 
00473 // Extract the out flag 
00474 SDValue PIC16TargetLowering::getOutFlag(SDValue &Op) {
00475   SDValue Flag = Op.getValue(Op.getNode()->getNumValues() - 1);
00476 
00477   assert (Flag.getValueType() == MVT::Flag && "Node does not have an out Flag");
00478 
00479   return Flag;
00480 }
00481 
00482 // To extract chain value from the SDValue Nodes
00483 // This function will help to maintain the chain extracting
00484 // code at one place. In case of any change in future it will
00485 // help maintain the code.
00486 SDValue PIC16TargetLowering::getChain(SDValue &Op) { 
00487   SDValue Chain = Op.getValue(Op.getNode()->getNumValues() - 1);
00488 
00489   // If the last value returned in Flag then the chain is
00490   // second last value returned.
00491   if (Chain.getValueType() == MVT::Flag)
00492     Chain = Op.getValue(Op.getNode()->getNumValues() - 2);
00493   
00494   // All nodes may not produce a chain. Therefore following assert
00495   // verifies that the node is returning a chain only.
00496   assert (Chain.getValueType() == MVT::Other && "Node does not have a chain");
00497 
00498   return Chain;
00499 }
00500 
00501 void PIC16TargetLowering::GetExpandedParts(SDValue Op, SelectionDAG &DAG,
00502 
00503                                            SDValue &Lo, SDValue &Hi) {  
00504   SDNode *N = Op.getNode();
00505   MVT NewVT;
00506   std::vector<SDValue> Opers;
00507   NewVT = getTypeToTransformTo(N->getValueType(0));
00508 
00509   // extract the lo component
00510   Opers.push_back(Op);
00511   Opers.push_back(DAG.getConstant(0,MVT::i8));
00512   Lo = DAG.getNode(ISD::EXTRACT_ELEMENT,NewVT,&Opers[0],Opers.size());
00513   // extract the hi component
00514   Opers.clear();
00515   Opers.push_back(Op);
00516   Opers.push_back(DAG.getConstant(1,MVT::i8));
00517   Hi = DAG.getNode(ISD::EXTRACT_ELEMENT,NewVT,&Opers[0],Opers.size());
00518 }
00519 
00520 // Legalize FrameIndex into ExternalSymbol and offset.
00521 void 
00522 PIC16TargetLowering::LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG,
00523                                         SDValue &ES, int &Offset) {
00524 
00525   MachineFunction &MF = DAG.getMachineFunction();
00526   const Function *Func = MF.getFunction();
00527   const std::string Name = Func->getName();
00528 
00529   char *tmpName = new char [strlen(Name.c_str()) +  8];
00530   sprintf(tmpName, "%s.args", Name.c_str());
00531   ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
00532   FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(Op);
00533   Offset = FR->getIndex();
00534 
00535   return;
00536 }
00537 
00538 // This function legalizes the PIC16 Addresses. If the Pointer is  
00539 //  -- Direct address variable residing 
00540 //     --> then a Banksel for that variable will be created.
00541 //  -- Rom variable            
00542 //     --> then it will be treated as an indirect address.
00543 //  -- Indirect address 
00544 //     --> then the address will be loaded into FSR
00545 //  -- ADD with constant operand
00546 //     --> then constant operand of ADD will be returned as Offset
00547 //         and non-constant operand of ADD will be treated as pointer.
00548 // Returns the high and lo part of the address, and the offset(in case of ADD).
00549 
00550 void PIC16TargetLowering:: LegalizeAddress(SDValue Ptr, SelectionDAG &DAG, 
00551                                            SDValue &Lo, SDValue &Hi,
00552                                            unsigned &Offset) {
00553 
00554   // Offset, by default, should be 0
00555   Offset = 0;
00556 
00557   // If the pointer is ADD with constant,
00558   // return the constant value as the offset  
00559   if (Ptr.getOpcode() == ISD::ADD) {
00560     SDValue OperLeft = Ptr.getOperand(0);
00561     SDValue OperRight = Ptr.getOperand(1);
00562     if (OperLeft.getOpcode() == ISD::Constant) {
00563       Offset = dyn_cast<ConstantSDNode>(OperLeft)->getZExtValue();
00564       Ptr = OperRight;
00565     } else if (OperRight.getOpcode() == ISD::Constant) {
00566       Offset = dyn_cast<ConstantSDNode>(OperRight)->getZExtValue();
00567       Ptr = OperLeft;
00568     }
00569   }
00570 
00571   // If the pointer is Type i8 and an external symbol
00572   // then treat it as direct address.
00573   // One example for such case is storing and loading
00574   // from function frame during a call
00575   if (Ptr.getValueType() == MVT::i8) {
00576     switch (Ptr.getOpcode()) {
00577     case ISD::TargetExternalSymbol:
00578       Lo = Ptr;
00579       Hi = DAG.getConstant(1, MVT::i8);
00580       return;
00581     }
00582   }
00583 
00584   if (Ptr.getOpcode() == ISD::BUILD_PAIR && 
00585       Ptr.getOperand(0).getOpcode() == ISD::TargetFrameIndex) {
00586 
00587     int FrameOffset;
00588     LegalizeFrameIndex(Ptr.getOperand(0), DAG, Lo, FrameOffset);
00589     Hi = DAG.getConstant(1, MVT::i8);
00590     Offset += FrameOffset; 
00591     return;
00592   }
00593 
00594   if (isDirectAddress(Ptr) && !isRomAddress(Ptr)) {
00595     // Direct addressing case for RAM variables. The Hi part is constant
00596     // and the Lo part is the TGA itself.
00597     Lo = Ptr.getOperand(0).getOperand(0);
00598 
00599     // For direct addresses Hi is a constant. Value 1 for the constant
00600     // signifies that banksel needs to generated for it. Value 0 for
00601     // the constant signifies that banksel does not need to be generated 
00602     // for it. Mark it as 1 now and optimize later. 
00603     Hi = DAG.getConstant(1, MVT::i8);
00604     return; 
00605   }
00606 
00607   // Indirect addresses. Get the hi and lo parts of ptr. 
00608   GetExpandedParts(Ptr, DAG, Lo, Hi);
00609 
00610   // Put the hi and lo parts into FSR.
00611   Lo = DAG.getNode(PIC16ISD::MTLO, MVT::i8, Lo);
00612   Hi = DAG.getNode(PIC16ISD::MTHI, MVT::i8, Hi);
00613 
00614   return;
00615 }
00616 
00617 //SDValue PIC16TargetLowering::ExpandAdd(SDNode *N, SelectionDAG &DAG) {
00618   //SDValue OperLeft = N->getOperand(0);
00619   //SDValue OperRight = N->getOperand(1);
00620 
00621   //if((OperLeft.getOpcode() == ISD::Constant) ||
00622      //(OperRight.getOpcode() == ISD::Constant)) {
00623     //return SDValue();
00624   //}
00625 
00626   // These case are yet to be handled
00627   //return SDValue();
00628 //}
00629 
00630 SDValue PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) {
00631   LoadSDNode *LD = dyn_cast<LoadSDNode>(SDValue(N, 0));
00632   SDValue Chain = LD->getChain();
00633   SDValue Ptr = LD->getBasePtr();
00634 
00635   SDValue Load, Offset;
00636   SDVTList Tys; 
00637   MVT VT, NewVT;
00638   SDValue PtrLo, PtrHi;
00639   unsigned LoadOffset;
00640 
00641   // Legalize direct/indirect addresses. This will give the lo and hi parts
00642   // of the address and the offset.
00643   LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, LoadOffset);
00644 
00645   // Load from the pointer (direct address or FSR) 
00646   VT = N->getValueType(0);
00647   unsigned NumLoads = VT.getSizeInBits() / 8; 
00648   std::vector<SDValue> PICLoads;
00649   unsigned iter;
00650   MVT MemVT = LD->getMemoryVT();
00651   if(ISD::isNON_EXTLoad(N)) {
00652     for (iter=0; iter<NumLoads ; ++iter) {
00653       // Add the pointer offset if any
00654       Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
00655       Tys = DAG.getVTList(MVT::i8, MVT::Other); 
00656       Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Chain, PtrLo, PtrHi,
00657                          Offset); 
00658       PICLoads.push_back(Load);
00659     }
00660   } else {
00661     // If it is extended load then use PIC16Load for Memory Bytes
00662     // and for all extended bytes perform action based on type of
00663     // extention - i.e. SignExtendedLoad or ZeroExtendedLoad
00664 
00665     
00666     // For extended loads this is the memory value type
00667     // i.e. without any extension
00668     MVT MemVT = LD->getMemoryVT();
00669     unsigned MemBytes = MemVT.getSizeInBits() / 8;
00670     unsigned ExtdBytes = VT.getSizeInBits() / 8;
00671     Offset = DAG.getConstant(LoadOffset, MVT::i8);
00672 
00673     Tys = DAG.getVTList(MVT::i8, MVT::Other); 
00674     // For MemBytes generate PIC16Load with proper offset
00675     for (iter=0; iter<MemBytes; ++iter) {
00676       // Add the pointer offset if any
00677       Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
00678       Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Chain, PtrLo, PtrHi,
00679                          Offset); 
00680       PICLoads.push_back(Load);
00681     }
00682 
00683     // For SignExtendedLoad
00684     if (ISD::isSEXTLoad(N)) {
00685       // For all ExtdBytes use the Right Shifted(Arithmetic) Value of the 
00686       // highest MemByte
00687       SDValue SRA = DAG.getNode(ISD::SRA, MVT::i8, Load, 
00688                                 DAG.getConstant(7, MVT::i8));
00689       for (iter=MemBytes; iter<ExtdBytes; ++iter) { 
00690         PICLoads.push_back(SRA);
00691       }
00692     } else if (ISD::isZEXTLoad(N)) {
00693       // ZeroExtendedLoad -- For all ExtdBytes use constant 0
00694       SDValue ConstZero = DAG.getConstant(0, MVT::i8);
00695       for (iter=MemBytes; iter<ExtdBytes; ++iter) { 
00696         PICLoads.push_back(ConstZero);
00697       }
00698     }
00699   }
00700   SDValue BP;
00701 
00702   if (VT == MVT::i8) {
00703     // Operand of Load is illegal -- Load itself is legal
00704     return PICLoads[0];
00705   }
00706   else if (VT == MVT::i16) {
00707     BP = DAG.getNode(ISD::BUILD_PAIR, VT, PICLoads[0], PICLoads[1]);
00708     if (MemVT == MVT::i8)
00709       Chain = getChain(PICLoads[0]);
00710     else
00711       Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]),
00712                           getChain(PICLoads[1]));
00713   } else if (VT == MVT::i32) {
00714     SDValue BPs[2];
00715     BPs[0] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[0], PICLoads[1]);
00716     BPs[1] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[2], PICLoads[3]);
00717     BP = DAG.getNode(ISD::BUILD_PAIR, VT, BPs[0], BPs[1]);
00718     if (MemVT == MVT::i8)
00719       Chain = getChain(PICLoads[0]);
00720     else if (MemVT == MVT::i16)
00721       Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]),
00722                           getChain(PICLoads[1]));
00723     else {
00724       SDValue Chains[2];
00725       Chains[0] = DAG.getNode(ISD::TokenFactor, MVT::Other,
00726                               getChain(PICLoads[0]), getChain(PICLoads[1]));
00727       Chains[1] = DAG.getNode(ISD::TokenFactor, MVT::Other,
00728                               getChain(PICLoads[2]), getChain(PICLoads[3]));
00729       Chain =  DAG.getNode(ISD::TokenFactor, MVT::Other, Chains[0], Chains[1]);
00730     }
00731   }
00732   Tys = DAG.getVTList(VT, MVT::Other); 
00733   return DAG.getNode(ISD::MERGE_VALUES, Tys, BP, Chain);
00734 }
00735 
00736 SDValue PIC16TargetLowering::LowerShift(SDValue Op, SelectionDAG &DAG) {
00737   // We should have handled larger operands in type legalizer itself.
00738   assert (Op.getValueType() == MVT::i8 && "illegal shift to lower");
00739  
00740   SDNode *N = Op.getNode();
00741   SDValue Value = N->getOperand(0);
00742   SDValue Amt = N->getOperand(1);
00743   PIC16ISD::PIC16Libcall CallCode;
00744   switch (N->getOpcode()) {
00745   case ISD::SRA:
00746     CallCode = PIC16ISD::SRA_I8;
00747     break;
00748   case ISD::SHL:
00749     CallCode = PIC16ISD::SLL_I8;
00750     break;
00751   case ISD::SRL:
00752     CallCode = PIC16ISD::SRL_I8;
00753     break;
00754   default:
00755     assert ( 0 && "This shift is not implemented yet.");
00756     return SDValue();
00757   }
00758   SmallVector<SDValue, 2> Ops(2);
00759   Ops[0] = Value;
00760   Ops[1] = Amt;
00761   SDValue Call = MakePIC16Libcall(CallCode, N->getValueType(0), &Ops[0], 2, 
00762                                   true, DAG, N->getDebugLoc());
00763   return Call;
00764 }
00765 
00766 void
00767 PIC16TargetLowering::LowerOperationWrapper(SDNode *N,
00768                                            SmallVectorImpl<SDValue>&Results,
00769                                            SelectionDAG &DAG) {
00770   SDValue Op = SDValue(N, 0);
00771   SDValue Res;
00772   unsigned i;
00773   switch (Op.getOpcode()) {
00774     case ISD::FORMAL_ARGUMENTS:
00775       Res = LowerFORMAL_ARGUMENTS(Op, DAG); break;
00776     case ISD::LOAD:
00777       Res = ExpandLoad(Op.getNode(), DAG); break;
00778     case ISD::CALL:
00779       Res = LowerCALL(Op, DAG); break;
00780     default: {
00781       // All other operations are handled in LowerOperation.
00782       Res = LowerOperation(Op, DAG);
00783       if (Res.getNode())
00784         Results.push_back(Res);
00785         
00786       return; 
00787     }
00788   }
00789 
00790   N = Res.getNode();
00791   unsigned NumValues = N->getNumValues(); 
00792   for (i = 0; i < NumValues ; i++) {
00793     Results.push_back(SDValue(N, i)); 
00794   }
00795 }
00796 
00797 SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
00798   switch (Op.getOpcode()) {
00799     case ISD::FORMAL_ARGUMENTS:
00800       return LowerFORMAL_ARGUMENTS(Op, DAG);
00801     case ISD::ADD:
00802     case ISD::ADDC:
00803     case ISD::ADDE:
00804       return LowerADD(Op, DAG);
00805     case ISD::SUB:
00806     case ISD::SUBC:
00807     case ISD::SUBE:
00808       return LowerSUB(Op, DAG);
00809     case ISD::LOAD:
00810       return ExpandLoad(Op.getNode(), DAG);
00811     case ISD::STORE:
00812       return ExpandStore(Op.getNode(), DAG);
00813     case ISD::SHL:
00814     case ISD::SRA:
00815     case ISD::SRL:
00816       return LowerShift(Op, DAG);
00817     case ISD::OR:
00818     case ISD::AND:
00819     case ISD::XOR:
00820       return LowerBinOp(Op, DAG);
00821     case ISD::CALL:
00822       return LowerCALL(Op, DAG);
00823     case ISD::RET:
00824       return LowerRET(Op, DAG);
00825     case ISD::BR_CC:
00826       return LowerBR_CC(Op, DAG);
00827     case ISD::SELECT_CC:
00828       return LowerSELECT_CC(Op, DAG);
00829   }
00830   return SDValue();
00831 }
00832 
00833 SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op,
00834                                                  SelectionDAG &DAG) {
00835 
00836   assert (Op.getValueType() == MVT::i8 
00837           && "illegal value type to store on stack.");
00838 
00839   MachineFunction &MF = DAG.getMachineFunction();
00840   const Function *Func = MF.getFunction();
00841   const std::string FuncName = Func->getName();
00842 
00843   char *tmpName = new char [strlen(FuncName.c_str()) +  6];
00844 
00845   // Put the value on stack.
00846   // Get a stack slot index and convert to es.
00847   int FI = MF.getFrameInfo()->CreateStackObject(1, 1);
00848   sprintf(tmpName, "%s.tmp", FuncName.c_str());
00849   SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
00850 
00851   // Store the value to ES.
00852   SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, MVT::Other,
00853                                DAG.getEntryNode(),
00854                                Op, ES, 
00855                                DAG.getConstant (1, MVT::i8), // Banksel.
00856                                DAG.getConstant (FI, MVT::i8));
00857 
00858   // Load the value from ES.
00859   SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other);
00860   SDValue Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Store,
00861                              ES, DAG.getConstant (1, MVT::i8),
00862                              DAG.getConstant (FI, MVT::i8));
00863     
00864   return Load.getValue(0);
00865 }
00866           
00867 SDValue
00868 PIC16TargetLowering::LowerCallArguments(SDValue Op, SDValue Chain,
00869                                         SDValue FrameAddress, 
00870                                         SDValue InFlag,
00871                                         SelectionDAG &DAG) {
00872   CallSDNode *TheCall = dyn_cast<CallSDNode>(Op);
00873   unsigned NumOps = TheCall->getNumArgs();
00874   std::string Name;
00875   SDValue Arg, StoreAt;
00876   MVT ArgVT;
00877   unsigned Size=0;
00878   unsigned ArgCount=0;
00879 
00880 
00881   // FIXME: This portion of code currently assumes only
00882   // primitive types being passed as arguments.
00883 
00884   // Legalize the address before use
00885   SDValue PtrLo, PtrHi;
00886   unsigned AddressOffset;
00887   int StoreOffset = 0;
00888   LegalizeAddress(FrameAddress, DAG, PtrLo, PtrHi, AddressOffset);
00889   SDValue StoreRet;
00890 
00891   std::vector<SDValue> Ops;
00892   SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
00893   for (unsigned i=ArgCount, Offset = 0; i<NumOps; i++) {
00894     // Get the argument
00895     Arg = TheCall->getArg(i);
00896 
00897     StoreOffset = (Offset + AddressOffset);
00898    
00899     // Store the argument on frame
00900 
00901     Ops.clear();
00902     Ops.push_back(Chain);
00903     Ops.push_back(Arg.getValue(0));
00904     Ops.push_back(PtrLo);
00905     Ops.push_back(PtrHi);
00906     Ops.push_back(DAG.getConstant(StoreOffset, MVT::i8));
00907     Ops.push_back(InFlag);
00908 
00909     StoreRet = DAG.getNode (PIC16ISD::PIC16StWF, Tys, &Ops[0], Ops.size());
00910 
00911     Chain = getChain(StoreRet);
00912     InFlag = getOutFlag(StoreRet);
00913 
00914     // Update the frame offset to be used for next argument
00915     ArgVT = Arg.getValueType();
00916     Size = ArgVT.getSizeInBits();
00917     Size = Size/8;    // Calculate size in bytes
00918     Offset += Size;   // Increase the frame offset
00919   }
00920   return Chain;
00921 }
00922 
00923 SDValue
00924 PIC16TargetLowering::LowerCallReturn(SDValue Op, SDValue Chain,
00925                                      SDValue FrameAddress,
00926                                      SDValue InFlag,
00927                                      SelectionDAG &DAG) {
00928   CallSDNode *TheCall = dyn_cast<CallSDNode>(Op);
00929   // Currently handling primitive types only. They will come in
00930   // i8 parts
00931   unsigned RetVals = TheCall->getNumRetVals();
00932   
00933   std::vector<SDValue> ResultVals;
00934 
00935   // Return immediately if the return type is void
00936   if (RetVals == 0)
00937     return Chain;
00938 
00939   // Call has something to return
00940   
00941   // Legalize the address before use
00942   SDValue LdLo, LdHi;
00943   unsigned LdOffset;
00944   LegalizeAddress(FrameAddress, DAG, LdLo, LdHi, LdOffset);
00945 
00946   SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other, MVT::Flag);
00947   SDValue LoadRet;
00948  
00949   for(unsigned i=0, Offset=0;i<RetVals;i++) {
00950 
00951     LoadRet = DAG.getNode(PIC16ISD::PIC16LdWF, Tys, Chain, LdLo, LdHi,
00952                           DAG.getConstant(LdOffset + Offset, MVT::i8),
00953                           InFlag);
00954 
00955     InFlag = getOutFlag(LoadRet);
00956 
00957     Chain = getChain(LoadRet);
00958     Offset++;
00959     ResultVals.push_back(LoadRet);
00960   }
00961 
00962   // To return use MERGE_VALUES
00963   ResultVals.push_back(Chain);
00964   SDValue Res = DAG.getMergeValues(&ResultVals[0], ResultVals.size());
00965   return Res;
00966 }
00967 
00968 SDValue PIC16TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) {
00969  //int NumOps = Op.getNode()->getNumOperands();
00970 
00971  // For default cases LLVM returns the value on the function frame 
00972  // So let LLVM do this for all the cases other than character
00973  return Op; 
00974 }
00975 
00976 SDValue PIC16TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
00977     CallSDNode *TheCall = dyn_cast<CallSDNode>(Op);
00978     SDValue Chain = TheCall->getChain();
00979     SDValue Callee = TheCall->getCallee();
00980     unsigned i =0;
00981     if (Callee.getValueType() == MVT::i16 &&
00982       Callee.getOpcode() == ISD::BUILD_PAIR) {
00983       // It has come from TypeLegalizer for lowering
00984 
00985       Callee = Callee.getOperand(0).getOperand(0);
00986 
00987       std::vector<SDValue> Ops;
00988       Ops.push_back(Chain);
00989       Ops.push_back(Callee);
00990 
00991       // Add the call arguments and their flags
00992       unsigned NumArgs = TheCall->getNumArgs();
00993       for(i=0;i<NumArgs;i++) { 
00994         Ops.push_back(TheCall->getArg(i));
00995         Ops.push_back(TheCall->getArgFlagsVal(i));
00996       }
00997 
00998       std::vector<MVT> NodeTys;
00999       unsigned NumRets = TheCall->getNumRetVals();
01000       for(i=0;i<NumRets;i++)
01001         NodeTys.push_back(TheCall->getRetValType(i));
01002 
01003       // Return a Chain as well
01004       NodeTys.push_back(MVT::Other);
01005 
01006       SDVTList VTs = DAG.getVTList(&NodeTys[0], NodeTys.size());
01007       SDValue NewCall = 
01008               DAG.getCall(TheCall->getCallingConv(), TheCall->isVarArg(), 
01009                           TheCall->isTailCall(), TheCall->isInreg(), VTs, 
01010                           &Ops[0], Ops.size());
01011 
01012       return NewCall;
01013     }
01014     
01015     SDValue ZeroOperand = DAG.getConstant(0, MVT::i8);
01016 
01017     // Start the call sequence.
01018     // Carring the Constant 0 along the CALLSEQSTART
01019     // because there is nothing else to carry.
01020     SDValue SeqStart  = DAG.getCALLSEQ_START(Chain, ZeroOperand);
01021     Chain = getChain(SeqStart);
01022 
01023     // For any direct call - callee will be GlobalAddressNode or
01024     // ExternalSymbol
01025 
01026     // Considering the GlobalAddressNode case here.
01027     if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
01028       GlobalValue *GV = G->getGlobal();
01029       Callee = DAG.getTargetGlobalAddress(GV, MVT::i8);
01030     }
01031 
01032     // Considering the ExternalSymbol case here
01033     if (ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Callee)) {
01034       Callee = DAG.getTargetExternalSymbol(ES->getSymbol(), MVT::i8); 
01035     }
01036 
01037     SDValue OperFlag = getOutFlag(Chain); // To manage the data dependency
01038 
01039     std::string Name;
01040 
01041     // Considering GlobalAddress here
01042     if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
01043        Name = G->getGlobal()->getName();
01044 
01045     // Considering ExternalSymbol here
01046     if (ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Callee))
01047        Name = ES->getSymbol();
01048 
01049     char *argFrame = new char [strlen(Name.c_str()) +  8];
01050     sprintf(argFrame, "%s.args", Name.c_str());
01051     SDValue ArgLabel = DAG.getTargetExternalSymbol(argFrame, MVT::i8);
01052 
01053     char *retName = new char [strlen(Name.c_str()) +  8];
01054     sprintf(retName, "%s.retval", Name.c_str());
01055     SDValue RetLabel = DAG.getTargetExternalSymbol(retName, MVT::i8);
01056 
01057     // Pass the argument to function before making the call.
01058     SDValue CallArgs = LowerCallArguments(Op, Chain, ArgLabel, OperFlag, DAG);
01059     Chain = getChain(CallArgs);
01060     OperFlag = getOutFlag(CallArgs);
01061 
01062     SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
01063     SDValue PICCall = DAG.getNode(PIC16ISD::CALL, Tys, Chain, Callee,
01064                                   OperFlag);
01065     Chain = getChain(PICCall);
01066     OperFlag = getOutFlag(PICCall);
01067 
01068 
01069     // Carrying the Constant 0 along the CALLSEQSTART
01070     // because there is nothing else to carry.
01071     SDValue SeqEnd = DAG.getCALLSEQ_END(Chain, ZeroOperand, ZeroOperand,
01072                                         OperFlag);
01073     Chain = getChain(SeqEnd);
01074     OperFlag = getOutFlag(SeqEnd);
01075 
01076     // Lower the return value reading after the call.
01077     return LowerCallReturn(Op, Chain, RetLabel, OperFlag, DAG);
01078 }
01079 
01080 bool PIC16TargetLowering::isDirectLoad(const SDValue Op) {
01081   if (Op.getOpcode() == PIC16ISD::PIC16Load)
01082     if (Op.getOperand(1).getOpcode() == ISD::TargetGlobalAddress
01083      || Op.getOperand(1).getOpcode() == ISD::TargetExternalSymbol)
01084       return true;
01085   return false;
01086 }
01087 
01088 bool PIC16TargetLowering::NeedToConvertToMemOp(SDValue Op, unsigned &MemOp) {
01089   // Return false if one of the operands is already a direct
01090   // load and that operand has only one use.
01091   if (Op.getOperand(0).getOpcode() == ISD::Constant ||
01092       Op.getOperand(1).getOpcode() == ISD::Constant)
01093     return false;    
01094   if (isDirectLoad(Op.getOperand(0))) {
01095     if (Op.getOperand(0).hasOneUse())
01096       return false;
01097     else 
01098       MemOp = 0;
01099   }
01100   if (isDirectLoad(Op.getOperand(1))) {
01101     if (Op.getOperand(1).hasOneUse())
01102       return false;
01103     else 
01104       MemOp = 1; 
01105   }
01106   return true;
01107 }  
01108 
01109 SDValue PIC16TargetLowering:: LowerBinOp(SDValue Op, SelectionDAG &DAG) {
01110   // We should have handled larger operands in type legalizer itself.
01111   assert (Op.getValueType() == MVT::i8 && "illegal Op to lower");
01112   unsigned MemOp = 1;
01113   if (NeedToConvertToMemOp(Op, MemOp)) {
01114     // Put one value on stack.
01115     SDValue NewVal = ConvertToMemOperand (Op.getOperand(MemOp), DAG);
01116 
01117     return DAG.getNode(Op.getOpcode(), MVT::i8, Op.getOperand(MemOp ^ 1),
01118     NewVal);
01119   }
01120   else {
01121     return Op;
01122   }
01123 }
01124 
01125 SDValue PIC16TargetLowering:: LowerADD(SDValue Op, SelectionDAG &DAG) {
01126   // We should have handled larger operands in type legalizer itself.
01127   assert (Op.getValueType() == MVT::i8 && "illegal add to lower");
01128   unsigned MemOp = 1;
01129   if (NeedToConvertToMemOp(Op, MemOp)) {
01130     // Put one value on stack.
01131     SDValue NewVal = ConvertToMemOperand (Op.getOperand(MemOp), DAG);
01132     
01133     SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
01134 
01135     if (Op.getOpcode() == ISD::ADDE)
01136       return DAG.getNode(Op.getOpcode(), Tys, Op.getOperand(MemOp ^ 1), NewVal, 
01137                          Op.getOperand(2));
01138     else
01139       return DAG.getNode(Op.getOpcode(), Tys, Op.getOperand(MemOp ^ 1), NewVal);
01140   }
01141   else if (Op.getOpcode() == ISD::ADD) {
01142     return Op;
01143   }
01144   else {
01145     return SDValue();
01146   }
01147 }
01148 
01149 SDValue PIC16TargetLowering::LowerSUB(SDValue Op, SelectionDAG &DAG) {
01150   // We should have handled larger operands in type legalizer itself.
01151   assert (Op.getValueType() == MVT::i8 && "illegal sub to lower");
01152 
01153   // Nothing to do if the first operand is already a direct load and it has
01154   // only one use.
01155   if (isDirectLoad(Op.getOperand(0)) && Op.getOperand(0).hasOneUse())
01156     return SDValue();
01157 
01158   // Put first operand on stack.
01159   SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG);
01160 
01161   SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
01162   if (Op.getOpcode() == ISD::SUBE)
01163     return DAG.getNode(Op.getOpcode(), Tys, NewVal, Op.getOperand(1),
01164                        Op.getOperand(2));
01165   else
01166     return DAG.getNode(Op.getOpcode(), Tys, NewVal, Op.getOperand(1));
01167 }
01168 
01169 // LowerFORMAL_ARGUMENTS - In Lowering FORMAL ARGUMENTS - MERGE_VALUES nodes
01170 // is returned. MERGE_VALUES nodes number of operands and number of values are
01171 // equal. Therefore to construct MERGE_VALUE node, UNDEF nodes equal to the
01172 // number of arguments of function have been created.
01173 
01174 SDValue PIC16TargetLowering:: LowerFORMAL_ARGUMENTS(SDValue Op, 
01175                                                     SelectionDAG &DAG) {
01176   SmallVector<SDValue, 8> ArgValues;
01177   unsigned NumArgs = Op.getNumOperands() - 3;
01178 
01179   // Creating UNDEF nodes to meet the requirement of MERGE_VALUES node.
01180   for(unsigned i = 0 ; i<NumArgs ; i++) {
01181     SDValue TempNode = DAG.getNode(ISD::UNDEF, Op.getNode()->getValueType(i));
01182     ArgValues.push_back(TempNode);
01183   }
01184 
01185   ArgValues.push_back(Op.getOperand(0));
01186   return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(), 
01187                      &ArgValues[0],
01188                      ArgValues.size()).getValue(Op.getResNo());
01189 }
01190 
01191 // Perform DAGCombine of PIC16Load 
01192 SDValue PIC16TargetLowering::
01193 PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const {
01194   SelectionDAG &DAG = DCI.DAG;
01195   SDValue Chain = N->getOperand(0); 
01196   if (N->hasNUsesOfValue(0, 0)) {
01197     DAG.ReplaceAllUsesOfValueWith(SDValue(N,1), Chain);
01198   }
01199   return SDValue();
01200 }
01201 
01202 
01203 SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N, 
01204                                                DAGCombinerInfo &DCI) const {
01205   switch (N->getOpcode()) {
01206   case PIC16ISD::PIC16Load:
01207     return PerformPIC16LoadCombine(N, DCI);
01208   }
01209   return SDValue();
01210 }
01211 
01212 static PIC16CC::CondCodes IntCCToPIC16CC(ISD::CondCode CC) {
01213   switch (CC) {
01214   default: assert(0 && "Unknown condition code!");
01215   case ISD::SETNE:  return PIC16CC::NE;
01216   case ISD::SETEQ:  return PIC16CC::EQ;
01217   case ISD::SETGT:  return PIC16CC::GT;
01218   case ISD::SETGE:  return PIC16CC::GE;
01219   case ISD::SETLT:  return PIC16CC::LT;
01220   case ISD::SETLE:  return PIC16CC::LE;
01221   case ISD::SETULT: return PIC16CC::ULT;
01222   case ISD::SETULE: return PIC16CC::LE;
01223   case ISD::SETUGE: return PIC16CC::GE;
01224   case ISD::SETUGT: return PIC16CC::UGT;
01225   }
01226 }
01227 
01228 // Look at LHS/RHS/CC and see if they are a lowered setcc instruction.  If so
01229 // set LHS/RHS and SPCC to the LHS/RHS of the setcc and SPCC to the condition.
01230 static void LookThroughSetCC(SDValue &LHS, SDValue &RHS,
01231                              ISD::CondCode CC, unsigned &SPCC) {
01232   if (isa<ConstantSDNode>(RHS) &&
01233       cast<ConstantSDNode>(RHS)->getZExtValue() == 0 &&
01234       CC == ISD::SETNE &&
01235       (LHS.getOpcode() == PIC16ISD::SELECT_ICC &&
01236         LHS.getOperand(3).getOpcode() == PIC16ISD::SUBCC) &&
01237       isa<ConstantSDNode>(LHS.getOperand(0)) &&
01238       isa<ConstantSDNode>(LHS.getOperand(1)) &&
01239       cast<ConstantSDNode>(LHS.getOperand(0))->getZExtValue() == 1 &&
01240       cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue() == 0) {
01241     SDValue CMPCC = LHS.getOperand(3);
01242     SPCC = cast<ConstantSDNode>(LHS.getOperand(2))->getZExtValue();
01243     LHS = CMPCC.getOperand(0);
01244     RHS = CMPCC.getOperand(1);
01245   }
01246 }
01247 
01248 // Returns appropriate CMP insn and corresponding condition code in PIC16CC
01249 SDValue PIC16TargetLowering::getPIC16Cmp(SDValue LHS, SDValue RHS, 
01250                                          unsigned CC, SDValue &PIC16CC, 
01251                                          SelectionDAG &DAG) {
01252   PIC16CC::CondCodes CondCode = (PIC16CC::CondCodes) CC;
01253 
01254   // PIC16 sub is literal - W. So Swap the operands and condition if needed.
01255   // i.e. a < 12 can be rewritten as 12 > a.
01256   if (RHS.getOpcode() == ISD::Constant) {
01257 
01258     SDValue Tmp = LHS;
01259     LHS = RHS;
01260     RHS = Tmp;
01261 
01262     switch (CondCode) {
01263     default: break;
01264     case PIC16CC::LT:
01265       CondCode = PIC16CC::GT; 
01266       break;
01267     case PIC16CC::GT:
01268       CondCode = PIC16CC::LT; 
01269       break;
01270     case PIC16CC::ULT:
01271       CondCode = PIC16CC::UGT; 
01272       break;
01273     case PIC16CC::UGT:
01274       CondCode = PIC16CC::ULT; 
01275       break;
01276     case PIC16CC::GE:
01277       CondCode = PIC16CC::LE; 
01278       break;
01279     case PIC16CC::LE:
01280       CondCode = PIC16CC::GE;
01281       break;
01282     case PIC16CC::ULE:
01283       CondCode = PIC16CC::UGE;
01284       break;
01285     case PIC16CC::UGE:
01286       CondCode = PIC16CC::ULE;
01287       break;
01288     }
01289   }
01290 
01291   PIC16CC = DAG.getConstant(CondCode, MVT::i8);
01292 
01293   // These are signed comparisons. 
01294   SDValue Mask = DAG.getConstant(128, MVT::i8);
01295   if (isSignedComparison(CondCode)) {
01296     LHS = DAG.getNode (ISD::XOR, MVT::i8, LHS, Mask);
01297     RHS = DAG.getNode (ISD::XOR, MVT::i8, RHS, Mask); 
01298   }
01299 
01300   SDVTList VTs = DAG.getVTList (MVT::i8, MVT::Flag);
01301   // We can use a subtract operation to set the condition codes. But
01302   // we need to put one operand in memory if required.
01303   // Nothing to do if the first operand is already a valid type (direct load 
01304   // for subwf and literal for sublw) and it is used by this operation only. 
01305   if ((LHS.getOpcode() == ISD::Constant || isDirectLoad(LHS)) 
01306       && LHS.hasOneUse())
01307     return DAG.getNode(PIC16ISD::SUBCC, VTs, LHS, RHS);
01308 
01309   // else convert the first operand to mem.
01310   LHS = ConvertToMemOperand (LHS, DAG);
01311   return DAG.getNode(PIC16ISD::SUBCC, VTs, LHS, RHS);
01312 }
01313 
01314 
01315 SDValue PIC16TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) {
01316   SDValue LHS = Op.getOperand(0);
01317   SDValue RHS = Op.getOperand(1);
01318   ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
01319   SDValue TrueVal = Op.getOperand(2);
01320   SDValue FalseVal = Op.getOperand(3);
01321   unsigned ORIGCC = ~0;
01322 
01323   // If this is a select_cc of a "setcc", and if the setcc got lowered into
01324   // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
01325   // i.e.
01326   // A setcc: lhs, rhs, cc is expanded by llvm to 
01327   // select_cc: result of setcc, 0, 1, 0, setne
01328   // We can think of it as:
01329   // select_cc: lhs, rhs, 1, 0, cc
01330   LookThroughSetCC(LHS, RHS, CC, ORIGCC);
01331   if (ORIGCC == ~0U) ORIGCC = IntCCToPIC16CC (CC);
01332 
01333   SDValue PIC16CC;
01334   SDValue Cmp = getPIC16Cmp(LHS, RHS, ORIGCC, PIC16CC, DAG);
01335 
01336   return DAG.getNode (PIC16ISD::SELECT_ICC, TrueVal.getValueType(), TrueVal,
01337                       FalseVal, PIC16CC, Cmp.getValue(1)); 
01338 }
01339 
01340 MachineBasicBlock *
01341 PIC16TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
01342                                                  MachineBasicBlock *BB) {
01343   const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
01344   unsigned CC = (PIC16CC::CondCodes)MI->getOperand(3).getImm();
01345 
01346   // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
01347   // control-flow pattern.  The incoming instruction knows the destination vreg
01348   // to set, the condition code register to branch on, the true/false values to
01349   // select between, and a branch opcode to use.
01350   const BasicBlock *LLVM_BB = BB->getBasicBlock();
01351   MachineFunction::iterator It = BB;
01352   ++It;
01353 
01354   //  thisMBB:
01355   //  ...
01356   //   TrueVal = ...
01357   //   [f]bCC copy1MBB
01358   //   fallthrough --> copy0MBB
01359   MachineBasicBlock *thisMBB = BB;
01360   MachineFunction *F = BB->getParent();
01361   MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
01362   MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
01363   BuildMI(BB, TII.get(PIC16::pic16brcond)).addMBB(sinkMBB).addImm(CC);
01364   F->insert(It, copy0MBB);
01365   F->insert(It, sinkMBB);
01366 
01367   // Update machine-CFG edges by transferring all successors of the current
01368   // block to the new block which will contain the Phi node for the select.
01369   sinkMBB->transferSuccessors(BB);
01370   // Next, add the true and fallthrough blocks as its successors.
01371   BB->addSuccessor(copy0MBB);
01372   BB->addSuccessor(sinkMBB);
01373 
01374   //  copy0MBB:
01375   //   %FalseValue = ...
01376   //   # fallthrough to sinkMBB
01377   BB = copy0MBB;
01378 
01379   // Update machine-CFG edges
01380   BB->addSuccessor(sinkMBB);
01381 
01382   //  sinkMBB:
01383   //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
01384   //  ...
01385   BB = sinkMBB;
01386   BuildMI(BB, TII.get(PIC16::PHI), MI->getOperand(0).getReg())
01387     .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
01388     .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
01389 
01390   F->DeleteMachineInstr(MI);   // The pseudo instruction is gone now.
01391   return BB;
01392 }
01393 
01394 
01395 SDValue PIC16TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) {
01396   SDValue Chain = Op.getOperand(0);
01397   ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
01398   SDValue LHS = Op.getOperand(2);   // LHS of the condition.
01399   SDValue RHS = Op.getOperand(3);   // RHS of the condition.
01400   SDValue Dest = Op.getOperand(4);  // BB to jump to
01401   unsigned ORIGCC = ~0;
01402 
01403   // If this is a br_cc of a "setcc", and if the setcc got lowered into
01404   // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
01405   LookThroughSetCC(LHS, RHS, CC, ORIGCC);
01406   if (ORIGCC == ~0U) ORIGCC = IntCCToPIC16CC (CC);
01407 
01408   // Get the Compare insn and condition code.
01409   SDValue PIC16CC;
01410   SDValue Cmp = getPIC16Cmp(LHS, RHS, ORIGCC, PIC16CC, DAG);
01411 
01412   return DAG.getNode(PIC16ISD::BRCOND, MVT::Other, Chain, Dest, PIC16CC, 
01413                      Cmp.getValue(1));
01414 }
01415 
01416