LLVM API Documentation

PIC16ISelLowering.cpp

Go to the documentation of this file.
00001 //===-- PIC16ISelLowering.cpp - PIC16 DAG Lowering Implementation ---------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source 
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the interfaces that PIC16 uses to lower LLVM code into a
00011 // selection DAG.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #define DEBUG_TYPE "pic16-lower"
00016 
00017 #include "PIC16ISelLowering.h"
00018 #include "PIC16TargetMachine.h"
00019 #include "llvm/DerivedTypes.h"
00020 #include "llvm/GlobalValue.h"
00021 #include "llvm/Function.h"
00022 #include "llvm/CodeGen/MachineFrameInfo.h"
00023 #include "llvm/CodeGen/MachineFunction.h"
00024 #include <cstdio>
00025 
00026 
00027 using namespace llvm;
00028 
00029 
00030 // PIC16TargetLowering Constructor.
00031 PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM)
00032   : TargetLowering(TM) {
00033   
00034   Subtarget = &TM.getSubtarget<PIC16Subtarget>();
00035 
00036   addRegisterClass(MVT::i8, PIC16::GPRRegisterClass);
00037 
00038   setShiftAmountType(MVT::i8);
00039   setShiftAmountFlavor(Extend);
00040 
00041 
00042   setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
00043 
00044   setOperationAction(ISD::LOAD,   MVT::i8,  Legal);
00045   setOperationAction(ISD::LOAD,   MVT::i16, Custom);
00046   setOperationAction(ISD::LOAD,   MVT::i32, Custom);
00047 
00048   setOperationAction(ISD::STORE,  MVT::i8,  Legal);
00049   setOperationAction(ISD::STORE,  MVT::i16, Custom);
00050   setOperationAction(ISD::STORE,  MVT::i32, Custom);
00051 
00052   setOperationAction(ISD::ADDE,    MVT::i8,  Custom);
00053   setOperationAction(ISD::ADDC,    MVT::i8,  Custom);
00054   setOperationAction(ISD::SUBE,    MVT::i8,  Custom);
00055   setOperationAction(ISD::SUBC,    MVT::i8,  Custom);
00056   setOperationAction(ISD::ADD,    MVT::i8,  Legal);
00057   setOperationAction(ISD::ADD,    MVT::i16, Custom);
00058 
00059   setOperationAction(ISD::OR,     MVT::i8,  Custom);
00060   setOperationAction(ISD::AND,    MVT::i8,  Custom);
00061   setOperationAction(ISD::XOR,    MVT::i8,  Custom);
00062 
00063   setOperationAction(ISD::SHL,    MVT::i16, Custom);
00064   setOperationAction(ISD::SHL,    MVT::i32, Custom);
00065 
00066   //setOperationAction(ISD::TRUNCATE, MVT::i16, Custom);
00067   setTruncStoreAction(MVT::i16,   MVT::i8,  Custom);
00068 
00069   // Now deduce the information based on the above mentioned 
00070   // actions
00071   computeRegisterProperties();
00072 }
00073 
00074 const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode) const {
00075   switch (Opcode) {
00076   default:                         return NULL;
00077   case PIC16ISD::Lo:               return "PIC16ISD::Lo";
00078   case PIC16ISD::Hi:               return "PIC16ISD::Hi";
00079   case PIC16ISD::MTLO:             return "PIC16ISD::MTLO";
00080   case PIC16ISD::MTHI:             return "PIC16ISD::MTHI";
00081   case PIC16ISD::Banksel:          return "PIC16ISD::Banksel";
00082   case PIC16ISD::PIC16Load:        return "PIC16ISD::PIC16Load";
00083   case PIC16ISD::PIC16Store:       return "PIC16ISD::PIC16Store";
00084   case PIC16ISD::BCF:              return "PIC16ISD::BCF";
00085   case PIC16ISD::LSLF:             return "PIC16ISD::LSLF";
00086   case PIC16ISD::LRLF:             return "PIC16ISD::LRLF";
00087   case PIC16ISD::RLF:              return "PIC16ISD::RLF";
00088   case PIC16ISD::RRF:              return "PIC16ISD::RRF";
00089   case PIC16ISD::Dummy:            return "PIC16ISD::Dummy";
00090   }
00091 }
00092 
00093 void PIC16TargetLowering::ReplaceNodeResults(SDNode *N,
00094                                              SmallVectorImpl<SDValue>&Results,
00095                                              SelectionDAG &DAG) {
00096   switch (N->getOpcode()) {
00097     case ISD::GlobalAddress:
00098       Results.push_back(ExpandGlobalAddress(N, DAG));
00099       return;
00100     case ISD::STORE:
00101       Results.push_back(ExpandStore(N, DAG));
00102       return;
00103     case ISD::LOAD:
00104       Results.push_back(ExpandLoad(N, DAG));
00105       return;
00106     case ISD::ADD:
00107 //      return ExpandAdd(N, DAG);
00108       return;
00109     case ISD::SHL: {
00110       SDValue Res = ExpandShift(N, DAG);
00111       if (Res.getNode())
00112         Results.push_back(Res);
00113       return;
00114     }
00115     default:
00116       assert (0 && "not implemented");
00117       return;
00118   }
00119 }
00120 
00121 SDValue PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) {
00122   StoreSDNode *St = cast<StoreSDNode>(N);
00123   SDValue Chain = St->getChain();
00124   SDValue Src = St->getValue();
00125   SDValue Ptr = St->getBasePtr();
00126   MVT ValueType = Src.getValueType();
00127   unsigned StoreOffset = 0;
00128 
00129   SDValue PtrLo, PtrHi;
00130   LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, StoreOffset);
00131  
00132   if (ValueType == MVT::i8) {
00133     return DAG.getNode (PIC16ISD::PIC16Store, MVT::Other, Chain, Src,
00134                         PtrLo, PtrHi, DAG.getConstant (0, MVT::i8));
00135   }
00136   else if (ValueType == MVT::i16) {
00137     // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
00138     SDValue SrcLo, SrcHi;
00139     GetExpandedParts(Src, DAG, SrcLo, SrcHi);
00140     SDValue ChainLo = Chain, ChainHi = Chain;
00141     if (Chain.getOpcode() == ISD::TokenFactor) {
00142       ChainLo = Chain.getOperand(0);
00143       ChainHi = Chain.getOperand(1);
00144     }
00145     SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other,
00146                                  ChainLo,
00147                                  SrcLo, PtrLo, PtrHi,
00148                                  DAG.getConstant (0 + StoreOffset, MVT::i8));
00149 
00150     SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi, 
00151                                  SrcHi, PtrLo, PtrHi,
00152                                  DAG.getConstant (1 + StoreOffset, MVT::i8));
00153 
00154     return DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1),
00155                        getChain(Store2));
00156   }
00157   else if (ValueType == MVT::i32) {
00158     // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
00159     SDValue SrcLo, SrcHi;
00160     GetExpandedParts(Src, DAG, SrcLo, SrcHi);
00161 
00162     // Get the expanded parts of each of SrcLo and SrcHi.
00163     SDValue SrcLo1, SrcLo2, SrcHi1, SrcHi2;
00164     GetExpandedParts(SrcLo, DAG, SrcLo1, SrcLo2);
00165     GetExpandedParts(SrcHi, DAG, SrcHi1, SrcHi2);
00166 
00167     SDValue ChainLo = Chain, ChainHi = Chain;
00168     if (Chain.getOpcode() == ISD::TokenFactor) {  
00169       ChainLo = Chain.getOperand(0);
00170       ChainHi = Chain.getOperand(1);
00171     }
00172     SDValue ChainLo1 = ChainLo, ChainLo2 = ChainLo, ChainHi1 = ChainHi,
00173             ChainHi2 = ChainHi;
00174     if (ChainLo.getOpcode() == ISD::TokenFactor) {
00175       ChainLo1 = ChainLo.getOperand(0);
00176       ChainLo2 = ChainLo.getOperand(1);
00177     }
00178     if (ChainHi.getOpcode() == ISD::TokenFactor) {
00179       ChainHi1 = ChainHi.getOperand(0);
00180       ChainHi2 = ChainHi.getOperand(1);
00181     }
00182     SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other,
00183                                  ChainLo1,
00184                                  SrcLo1, PtrLo, PtrHi,
00185                                  DAG.getConstant (0 + StoreOffset, MVT::i8));
00186 
00187     SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainLo2,
00188                                  SrcLo2, PtrLo, PtrHi,
00189                                  DAG.getConstant (1 + StoreOffset, MVT::i8));
00190 
00191     SDValue Store3 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi1,
00192                                  SrcHi1, PtrLo, PtrHi,
00193                                  DAG.getConstant (2 + StoreOffset, MVT::i8));
00194 
00195     SDValue Store4 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi2,
00196                                  SrcHi2, PtrLo, PtrHi,
00197                                  DAG.getConstant (3 + StoreOffset, MVT::i8));
00198 
00199     SDValue RetLo =  DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1),
00200                                  getChain(Store2));
00201     SDValue RetHi =  DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store3),
00202                                 getChain(Store4));
00203     return DAG.getNode(ISD::TokenFactor, MVT::Other, RetLo, RetHi);
00204   }
00205   else {
00206     assert (0 && "value type not supported");
00207     return SDValue();
00208   }
00209 }
00210 
00211 // ExpandGlobalAddress - 
00212 SDValue PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) {
00213   GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(SDValue(N, 0));
00214   
00215   SDValue TGA = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i8,
00216                                            G->getOffset());
00217 
00218   SDValue Lo = DAG.getNode(PIC16ISD::Lo, MVT::i8, TGA);
00219   SDValue Hi = DAG.getNode(PIC16ISD::Hi, MVT::i8, TGA);
00220 
00221   SDValue BP = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, Lo, Hi);
00222   return BP;
00223 }
00224 
00225 bool PIC16TargetLowering::isDirectAddress(const SDValue &Op) {
00226   assert (Op.getNode() != NULL && "Can't operate on NULL SDNode!!");
00227 
00228   if (Op.getOpcode() == ISD::BUILD_PAIR) {
00229    if (Op.getOperand(0).getOpcode() == PIC16ISD::Lo) 
00230      return true;
00231   }
00232   return false;
00233 }
00234 
00235 // Return true if DirectAddress is in ROM_SPACE
00236 bool PIC16TargetLowering::isRomAddress(const SDValue &Op) {
00237 
00238   // RomAddress is a GlobalAddress in ROM_SPACE_
00239   // If the Op is not a GlobalAddress return NULL without checking
00240   // anything further.
00241   if (!isDirectAddress(Op))
00242     return false; 
00243 
00244   // Its a GlobalAddress.
00245   // It is BUILD_PAIR((PIC16Lo TGA), (PIC16Hi TGA)) and Op is BUILD_PAIR
00246   SDValue TGA = Op.getOperand(0).getOperand(0);
00247   GlobalAddressSDNode *GSDN = dyn_cast<GlobalAddressSDNode>(TGA);
00248   const Type *ValueType = GSDN->getGlobal()->getType();
00249 
00250   if (!isa<PointerType>(ValueType)) {
00251     assert(0 && "TGA must be of a PointerType");
00252   }
00253 
00254   int AddrSpace = dyn_cast<PointerType>(ValueType)->getAddressSpace();
00255   if (AddrSpace == PIC16ISD::ROM_SPACE)
00256     return true;
00257 
00258   // Any other address space return it false
00259   return false;
00260 }
00261 
00262 // To extract chain value from the SDValue Nodes
00263 // This function will help to maintain the chain extracting
00264 // code at one place. In case of any change in future it will
00265 // help maintain the code.
00266 SDValue PIC16TargetLowering::getChain(SDValue &Op) { 
00267   SDValue Chain = Op.getValue(Op.getNode()->getNumValues() - 1);
00268 
00269   // All nodes may not produce a chain. Therefore following assert
00270   // verifies that the node is returning a chain only.
00271   assert (Chain.getValueType() == MVT::Other && "Node does not have a chain");
00272 
00273   return Chain;
00274 }
00275 
00276 void PIC16TargetLowering::GetExpandedParts(SDValue Op, SelectionDAG &DAG,
00277                                            SDValue &Lo, SDValue &Hi) {  
00278   SDNode *N = Op.getNode();
00279   unsigned NumValues = N->getNumValues();
00280   std::vector<MVT> VTs;
00281   MVT NewVT;
00282   std::vector<SDValue> Opers;
00283 
00284   // EXTRACT_ELEMENT should have same number and type of values that the 
00285   // node replacing the EXTRACT_ELEMENT should have. (i.e. extracted element)
00286   // Some nodes such as LOAD and PIC16Load have more than one values. In such 
00287   // cases EXTRACT_ELEMENT should have more than one values. Therefore creating
00288   // vector of Values for EXTRACT_ELEMENT. This list will have same number of 
00289   // values as the extracted element will have.
00290 
00291   for (unsigned i=0;i < NumValues; ++i) {
00292     NewVT = getTypeToTransformTo(N->getValueType(i));
00293     VTs.push_back(NewVT);
00294   }
00295 
00296   // extract the lo component
00297   Opers.push_back(Op);
00298   Opers.push_back(DAG.getConstant(0,MVT::i8));
00299   Lo = DAG.getNode(ISD::EXTRACT_ELEMENT,VTs,&Opers[0],Opers.size());
00300 
00301   // extract the hi component
00302   Opers.clear();
00303   Opers.push_back(Op);
00304   Opers.push_back(DAG.getConstant(1,MVT::i8));
00305   Hi = DAG.getNode(ISD::EXTRACT_ELEMENT,VTs,&Opers[0],Opers.size());
00306 }
00307 
00308 // This function legalizes the PIC16 Addresses. If the Pointer is  
00309 //  -- Direct address variable residing 
00310 //     --> then a Banksel for that variable will be created.
00311 //  -- Rom variable            
00312 //     --> then it will be treated as an indirect address.
00313 //  -- Indirect address 
00314 //     --> then the address will be loaded into FSR
00315 //  -- ADD with constant operand
00316 //     --> then constant operand of ADD will be returned as Offset
00317 //         and non-constant operand of ADD will be treated as pointer.
00318 // Returns the high and lo part of the address, and the offset(in case of ADD).
00319 
00320 void PIC16TargetLowering:: LegalizeAddress(SDValue Ptr, SelectionDAG &DAG, 
00321                                            SDValue &Lo, SDValue &Hi,
00322                                            unsigned &Offset) {
00323 
00324   // Offset, by default, should be 0
00325   Offset = 0;
00326 
00327   // If the pointer is ADD with constant,
00328   // return the constant value as the offset  
00329   if (Ptr.getOpcode() == ISD::ADD) {
00330     SDValue OperLeft = Ptr.getOperand(0);
00331     SDValue OperRight = Ptr.getOperand(1);
00332     if (OperLeft.getOpcode() == ISD::Constant) {
00333       Offset = dyn_cast<ConstantSDNode>(OperLeft)->getZExtValue();
00334       Ptr = OperRight;
00335     } else {
00336       Ptr = OperLeft;
00337       Offset = dyn_cast<ConstantSDNode>(OperRight)->getZExtValue();
00338     }
00339   }
00340 
00341   if (isDirectAddress(Ptr) && !isRomAddress(Ptr)) {
00342     // Direct addressing case for RAM variables. The Hi part is constant
00343     // and the Lo part is the TGA itself.
00344     Lo = Ptr.getOperand(0).getOperand(0);
00345 
00346     // For direct addresses Hi is a constant. Value 1 for the constant
00347     // signifies that banksel needs to generated for it. Value 0 for
00348     // the constant signifies that banksel does not need to be generated 
00349     // for it. Mark it as 1 now and optimize later. 
00350     Hi = DAG.getConstant(1, MVT::i8);
00351     return; 
00352   }
00353 
00354   // Indirect addresses. Get the hi and lo parts of ptr. 
00355   GetExpandedParts(Ptr, DAG, Lo, Hi);
00356 
00357   // Put the hi and lo parts into FSR.
00358   Lo = DAG.getNode(PIC16ISD::MTLO, MVT::i8, Lo);
00359   Hi = DAG.getNode(PIC16ISD::MTHI, MVT::i8, Hi);
00360 
00361   return;
00362 }
00363 
00364 //SDNode *PIC16TargetLowering::ExpandAdd(SDNode *N, SelectionDAG &DAG) {
00365 //  SDValue OperLeft = N->getOperand(0);
00366 //  SDValue OperRight = N->getOperand(1);
00367 //
00368 //  if((OperLeft.getOpcode() == ISD::Constant) ||
00369 //     (OperRight.getOpcode() == ISD::Constant)) {
00370 //    return NULL;
00371 //  }
00372 //
00373 //  // These case are yet to be handled
00374 //  return NULL;
00375 //}
00376 
00377 SDValue PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) {
00378   LoadSDNode *LD = dyn_cast<LoadSDNode>(SDValue(N, 0));
00379   SDValue Chain = LD->getChain();
00380   SDValue Ptr = LD->getBasePtr();
00381 
00382   SDValue Load, Offset;
00383   SDVTList Tys; 
00384   MVT VT, NewVT;
00385   SDValue PtrLo, PtrHi;
00386   unsigned LoadOffset;
00387 
00388   // Legalize direct/indirect addresses. This will give the lo and hi parts
00389   // of the address and the offset.
00390   LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, LoadOffset);
00391 
00392   // Load from the pointer (direct address or FSR) 
00393   VT = N->getValueType(0);
00394   unsigned NumLoads = VT.getSizeInBits() / 8; 
00395   std::vector<SDValue> PICLoads;
00396   unsigned iter;
00397   MVT MemVT = LD->getMemoryVT();
00398   if(ISD::isNON_EXTLoad(N)) {
00399     for (iter=0; iter<NumLoads ; ++iter) {
00400       // Add the pointer offset if any
00401       Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
00402       Tys = DAG.getVTList(MVT::i8, MVT::Other); 
00403       Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Chain, PtrLo, PtrHi,
00404                          Offset); 
00405       PICLoads.push_back(Load);
00406     }
00407   } else {
00408     // If it is extended load then use PIC16Load for Memory Bytes
00409     // and for all extended bytes perform action based on type of
00410     // extention - i.e. SignExtendedLoad or ZeroExtendedLoad
00411 
00412     
00413     // For extended loads this is the memory value type
00414     // i.e. without any extension
00415     MVT MemVT = LD->getMemoryVT();
00416     unsigned MemBytes = MemVT.getSizeInBits() / 8;
00417     unsigned ExtdBytes = VT.getSizeInBits() / 8;
00418     Offset = DAG.getConstant(LoadOffset, MVT::i8);
00419 
00420     Tys = DAG.getVTList(MVT::i8, MVT::Other); 
00421     // For MemBytes generate PIC16Load with proper offset
00422     for (iter=0; iter<MemBytes; ++iter) {
00423       // Add the pointer offset if any
00424       Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
00425       Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Chain, PtrLo, PtrHi,
00426                          Offset); 
00427       PICLoads.push_back(Load);
00428     }
00429 
00430     // For SignExtendedLoad
00431     if (ISD::isSEXTLoad(N)) {
00432       // For all ExtdBytes use the Right Shifted(Arithmetic) Value of the 
00433       // highest MemByte
00434       SDValue SRA = DAG.getNode(ISD::SRA, MVT::i8, Load, 
00435                                 DAG.getConstant(7, MVT::i8));
00436       for (iter=MemBytes; iter<ExtdBytes; ++iter) { 
00437         PICLoads.push_back(SRA);
00438       }
00439     } else if (ISD::isZEXTLoad(N)) {
00440       // ZeroExtendedLoad -- For all ExtdBytes use constant 0
00441       SDValue ConstZero = DAG.getConstant(0, MVT::i8);
00442       for (iter=MemBytes; iter<ExtdBytes; ++iter) { 
00443         PICLoads.push_back(ConstZero);
00444       }
00445     }
00446   }
00447   SDValue BP;
00448 
00449   if (VT == MVT::i8) {
00450     // Operand of Load is illegal -- Load itself is legal
00451     return PICLoads[0];
00452   }
00453   else if (VT == MVT::i16) {
00454     BP = DAG.getNode(ISD::BUILD_PAIR, VT, PICLoads[0], PICLoads[1]);
00455     if (MemVT == MVT::i8)
00456       Chain = getChain(PICLoads[0]);
00457     else
00458       Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]),
00459                           getChain(PICLoads[1]));
00460   } else if (VT == MVT::i32) {
00461     SDValue BPs[2];
00462     BPs[0] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[0], PICLoads[1]);
00463     BPs[1] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[2], PICLoads[3]);
00464     BP = DAG.getNode(ISD::BUILD_PAIR, VT, BPs[0], BPs[1]);
00465     if (MemVT == MVT::i8)
00466       Chain = getChain(PICLoads[0]);
00467     else if (MemVT == MVT::i16)
00468       Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]),
00469                           getChain(PICLoads[1]));
00470     else {
00471       SDValue Chains[2];
00472       Chains[0] = DAG.getNode(ISD::TokenFactor, MVT::Other,
00473                               getChain(PICLoads[0]), getChain(PICLoads[1]));
00474       Chains[1] = DAG.getNode(ISD::TokenFactor, MVT::Other,
00475                               getChain(PICLoads[2]), getChain(PICLoads[3]));
00476       Chain =  DAG.getNode(ISD::TokenFactor, MVT::Other, Chains[0], Chains[1]);
00477     }
00478   }
00479   Tys = DAG.getVTList(VT, MVT::Other); 
00480   return DAG.getNode(ISD::MERGE_VALUES, Tys, BP, Chain);
00481 }
00482 
00483 SDValue PIC16TargetLowering::ExpandShift(SDNode *N, SelectionDAG &DAG) {
00484   SDValue Value = N->getOperand(0);
00485   SDValue Amt = N->getOperand(1);
00486   SDValue BCF, BCFInput;
00487   SDVTList Tys; 
00488   SDValue ShfCom;   // Shift Component - Lo component should be shifted
00489   SDValue RotCom;   // Rotate Component- Hi component should be rotated
00490   PIC16ISD::NodeType ShfNode = PIC16ISD::Dummy, RotNode = PIC16ISD::Dummy;
00491   
00492   // Currently handling Constant shift only
00493   if (Amt.getOpcode() != ISD::Constant)
00494     return SDValue();
00495 
00496   // Following code considers 16 bit left-shift only
00497   if (N->getValueType(0) != MVT::i16)
00498     return SDValue();
00499 
00500   if (N->getOpcode() == ISD::SHL) {
00501     ShfNode = PIC16ISD::LSLF;
00502     RotNode = PIC16ISD::RLF;
00503   } else if (N->getOpcode() == ISD::SRL) {
00504     ShfNode = PIC16ISD::LRLF;
00505     RotNode = PIC16ISD::RRF;
00506   }
00507   unsigned ShiftAmt = dyn_cast<ConstantSDNode>(Amt)->getZExtValue();
00508   SDValue StatusReg = DAG.getRegister(PIC16::STATUS, MVT::i8);
00509   // 0th Bit in StatusReg is CarryBit 
00510   SDValue CarryBit= DAG.getConstant(0, MVT::i8);
00511 
00512   GetExpandedParts(Value, DAG, ShfCom, RotCom);
00513   BCFInput = DAG.getNode(PIC16ISD::Dummy, MVT::Flag); 
00514   Tys = DAG.getVTList(MVT::i8, MVT::Flag);
00515 
00516   for (unsigned i=0;i<ShiftAmt;i++) {
00517     BCF = DAG.getNode(PIC16ISD::BCF, MVT::Flag, StatusReg, CarryBit, BCFInput);
00518 
00519     // Following are Two-Address Instructions
00520     ShfCom = DAG.getNode(ShfNode, Tys, ShfCom, BCF);
00521     RotCom = DAG.getNode(RotNode, Tys, RotCom, ShfCom.getValue(1));
00522 
00523     BCFInput = RotCom.getValue(1); 
00524   }
00525 
00526   return DAG.getNode(ISD::BUILD_PAIR, N->getValueType(0), ShfCom, RotCom);
00527 }
00528 
00529 SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
00530   switch (Op.getOpcode()) {
00531     case ISD::FORMAL_ARGUMENTS:
00532       return LowerFORMAL_ARGUMENTS(Op, DAG);
00533     case ISD::ADDC:
00534       return LowerADDC(Op, DAG);
00535     case ISD::ADDE:
00536       return LowerADDE(Op, DAG);
00537     case ISD::SUBE:
00538       return LowerSUBE(Op, DAG);
00539     case ISD::SUBC:
00540       return LowerSUBC(Op, DAG);
00541     case ISD::LOAD:
00542       return ExpandLoad(Op.getNode(), DAG);
00543     case ISD::STORE:
00544       return ExpandStore(Op.getNode(), DAG);
00545     case ISD::SHL:
00546       return ExpandShift(Op.getNode(), DAG);
00547     case ISD::OR:
00548     case ISD::AND:
00549     case ISD::XOR:
00550       return LowerBinOp(Op, DAG);
00551   }
00552   return SDValue();
00553 }
00554 
00555 SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op,
00556                                                  SelectionDAG &DAG) {
00557 
00558   assert (Op.getValueType() == MVT::i8 
00559           && "illegal value type to store on stack.");
00560 
00561   MachineFunction &MF = DAG.getMachineFunction();
00562   const Function *Func = MF.getFunction();
00563   const std::string FuncName = Func->getName();
00564 
00565   char *tmpName = new char [strlen(FuncName.c_str()) +  6];
00566 
00567   // Put the value on stack.
00568   // Get a stack slot index and convert to es.
00569   int FI = MF.getFrameInfo()->CreateStackObject(1, 1);
00570   sprintf(tmpName, "%s.tmp", FuncName.c_str());
00571   SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
00572 
00573   // Store the value to ES.
00574   SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, MVT::Other,
00575                                DAG.getEntryNode(),
00576                                Op, ES, 
00577                                DAG.getConstant (1, MVT::i8), // Banksel.
00578                                DAG.getConstant (FI, MVT::i8));
00579 
00580   // Load the value from ES.
00581   SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other);
00582   SDValue Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Store,
00583                              ES, DAG.getConstant (1, MVT::i8),
00584                              DAG.getConstant (FI, MVT::i8));
00585     
00586   return Load.getValue(0);
00587 }
00588 
00589 SDValue PIC16TargetLowering:: LowerBinOp(SDValue Op, SelectionDAG &DAG) {
00590   // We should have handled larger operands in type legalizer itself.
00591   assert (Op.getValueType() == MVT::i8 && "illegal Op to lower");
00592 
00593   // Return the original Op if the one of the operands is already a load.
00594   if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load
00595       || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load)
00596     return Op;
00597 
00598   // Put one value on stack.
00599   SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG);
00600 
00601   return DAG.getNode(Op.getOpcode(), MVT::i8, Op.getOperand(0), NewVal);
00602 }
00603 
00604 SDValue PIC16TargetLowering:: LowerADDC(SDValue Op, SelectionDAG &DAG) {
00605   // We should have handled larger operands in type legalizer itself.
00606   assert (Op.getValueType() == MVT::i8 && "illegal addc to lower");
00607 
00608   // Nothing to do if the one of the operands is already a load.
00609   if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load 
00610       || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load)
00611     return SDValue();
00612 
00613   // Put one value on stack.
00614   SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG);
00615     
00616   SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
00617   return DAG.getNode(ISD::ADDC, Tys, Op.getOperand(0), NewVal);
00618 }
00619 
00620 SDValue PIC16TargetLowering:: LowerADDE(SDValue Op, SelectionDAG &DAG) {
00621   // We should have handled larger operands in type legalizer itself.
00622   assert (Op.getValueType() == MVT::i8 && "illegal adde to lower");
00623 
00624   // Nothing to do if the one of the operands is already a load.
00625   if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load 
00626       || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load)
00627     return SDValue();
00628 
00629   // Put one value on stack.
00630   SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG);
00631     
00632   SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
00633   return DAG.getNode(ISD::ADDE, Tys, Op.getOperand(0), NewVal, 
00634                      Op.getOperand(2));
00635 }
00636 
00637 SDValue PIC16TargetLowering:: LowerSUBC(SDValue Op, SelectionDAG &DAG) {
00638   // We should have handled larger operands in type legalizer itself.
00639   assert (Op.getValueType() == MVT::i8 && "illegal subc to lower");
00640 
00641   // Nothing to do if the first operand is already a load.
00642   if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load)
00643     return SDValue();
00644 
00645   // Put first operand on stack.
00646   SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG);
00647 
00648   SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
00649   return DAG.getNode(ISD::SUBC, Tys, NewVal, Op.getOperand(1));
00650 }
00651 
00652 SDValue PIC16TargetLowering:: LowerSUBE(SDValue Op, SelectionDAG &DAG) {
00653   // We should have handled larger operands in type legalizer itself.
00654   assert (Op.getValueType() == MVT::i8 && "illegal sube to lower");
00655 
00656   // Nothing to do if the first operand is already a load.
00657   if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load)
00658     return SDValue();
00659 
00660   // Put first operand on stack.
00661   SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG);
00662 
00663   SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
00664   return DAG.getNode(ISD::SUBE, Tys, NewVal, Op.getOperand(1),
00665                      Op.getOperand(2));
00666 }
00667 
00668 // LowerFORMAL_ARGUMENTS - In Lowering FORMAL ARGUMENTS - MERGE_VALUES nodes
00669 // is returned. MERGE_VALUES nodes number of operands and number of values are
00670 // equal. Therefore to construct MERGE_VALUE node, UNDEF nodes equal to the
00671 // number of arguments of function have been created.
00672 
00673 SDValue PIC16TargetLowering:: LowerFORMAL_ARGUMENTS(SDValue Op, 
00674                                                     SelectionDAG &DAG) {
00675   SmallVector<SDValue, 8> ArgValues;
00676   unsigned NumArgs = Op.getNumOperands() - 3;
00677 
00678   // Creating UNDEF nodes to meet the requirement of MERGE_VALUES node.
00679   for(unsigned i = 0 ; i<NumArgs ; i++) {
00680     SDValue TempNode = DAG.getNode(ISD::UNDEF, Op.getNode()->getValueType(i));
00681     ArgValues.push_back(TempNode);
00682   }
00683 
00684   ArgValues.push_back(Op.getOperand(0));
00685   return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(), 
00686                      &ArgValues[0],
00687                      ArgValues.size()).getValue(Op.getResNo());
00688 }
00689 
00690 // Perform DAGCombine of PIC16Load 
00691 SDValue PIC16TargetLowering::
00692 PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const {
00693   SelectionDAG &DAG = DCI.DAG;
00694   SDValue Chain = N->getOperand(0); 
00695   if (N->hasNUsesOfValue(0, 0)) {
00696     DAG.ReplaceAllUsesOfValueWith(SDValue(N,1), Chain);
00697   }
00698   return SDValue();
00699 }
00700 
00701 
00702 SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N, 
00703                                                DAGCombinerInfo &DCI) const {
00704   switch (N->getOpcode()) {
00705   case PIC16ISD::PIC16Load:
00706     return PerformPIC16LoadCombine(N, DCI);
00707   }
00708   return SDValue();
00709 }



This web site is hosted by the Computer Science Department at the University of Illinois at Urbana-Champaign.