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