LLVM API Documentation
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.