2 // The LLVM Compiler Infrastructure
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
7 //===----------------------------------------------------------------------===//
9 // This file defines the interfaces that PIC16 uses to lower LLVM code into a
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "pic16-lower"
16 #include "PIC16ISelLowering.h"
17 #include "PIC16TargetMachine.h"
18 #include "llvm/DerivedTypes.h"
19 #include "llvm/GlobalValue.h"
20 #include "llvm/Function.h"
21 #include "llvm/CallingConv.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
32 // PIC16TargetLowering Constructor.
33 PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM)
34 : TargetLowering(TM) {
36 Subtarget = &TM.getSubtarget<PIC16Subtarget>();
38 addRegisterClass(MVT::i8, PIC16::GPRRegisterClass);
40 setShiftAmountType(MVT::i8);
41 setShiftAmountFlavor(Extend);
43 // SRA library call names
44 setPIC16LibCallName(PIC16ISD::SRA_I8, "__intrinsics.sra.i8");
45 setPIC16LibCallName(PIC16ISD::SRA_I16, "__intrinsics.sra.i16");
46 setPIC16LibCallName(PIC16ISD::SRA_I32, "__intrinsics.sra.i32");
48 // SLL library call names
49 setPIC16LibCallName(PIC16ISD::SLL_I8, "__intrinsics.sll.i8");
50 setPIC16LibCallName(PIC16ISD::SLL_I16, "__intrinsics.sll.i16");
51 setPIC16LibCallName(PIC16ISD::SLL_I32, "__intrinsics.sll.i32");
53 // SRL library call names
54 setPIC16LibCallName(PIC16ISD::SRL_I8, "__intrinsics.srl.i8");
55 setPIC16LibCallName(PIC16ISD::SRL_I16, "__intrinsics.srl.i16");
56 setPIC16LibCallName(PIC16ISD::SRL_I32, "__intrinsics.srl.i32");
58 setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
60 setOperationAction(ISD::LOAD, MVT::i8, Legal);
61 setOperationAction(ISD::LOAD, MVT::i16, Custom);
62 setOperationAction(ISD::LOAD, MVT::i32, Custom);
64 setOperationAction(ISD::STORE, MVT::i8, Legal);
65 setOperationAction(ISD::STORE, MVT::i16, Custom);
66 setOperationAction(ISD::STORE, MVT::i32, Custom);
68 setOperationAction(ISD::ADDE, MVT::i8, Custom);
69 setOperationAction(ISD::ADDC, MVT::i8, Custom);
70 setOperationAction(ISD::SUBE, MVT::i8, Custom);
71 setOperationAction(ISD::SUBC, MVT::i8, Custom);
72 setOperationAction(ISD::ADD, MVT::i8, Legal);
73 setOperationAction(ISD::ADD, MVT::i16, Custom);
75 setOperationAction(ISD::OR, MVT::i8, Custom);
76 setOperationAction(ISD::AND, MVT::i8, Custom);
77 setOperationAction(ISD::XOR, MVT::i8, Custom);
79 setOperationAction(ISD::FrameIndex, MVT::i16, Custom);
80 setOperationAction(ISD::CALL, MVT::i16, Custom);
81 setOperationAction(ISD::RET, MVT::Other, Custom);
83 setOperationAction(ISD::SRA, MVT::i8, Custom);
84 setOperationAction(ISD::SRA, MVT::i16, Custom);
85 setOperationAction(ISD::SRA, MVT::i32, Custom);
87 setOperationAction(ISD::SHL, MVT::i8, Custom);
88 setOperationAction(ISD::SHL, MVT::i16, Custom);
89 setOperationAction(ISD::SHL, MVT::i32, Custom);
90 setOperationAction(ISD::SRL, MVT::i8, Custom);
91 setOperationAction(ISD::SRL, MVT::i16, Custom);
92 setOperationAction(ISD::SRL, MVT::i32, Custom);
94 // PIC16 does not have a SETCC, expand it to SELECT_CC.
95 setOperationAction(ISD::SETCC, MVT::i8, Expand);
96 setOperationAction(ISD::SELECT, MVT::i8, Expand);
97 setOperationAction(ISD::BRCOND, MVT::Other, Expand);
98 setOperationAction(ISD::BRIND, MVT::Other, Expand);
100 setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);
101 setOperationAction(ISD::BR_CC, MVT::i8, Custom);
103 //setOperationAction(ISD::TRUNCATE, MVT::i16, Custom);
104 setTruncStoreAction(MVT::i16, MVT::i8, Custom);
106 // Now deduce the information based on the above mentioned
108 computeRegisterProperties();
111 static void PopulateResults(SDValue N, SmallVectorImpl<SDValue>&Results) {
112 if (N.getOpcode() == ISD::MERGE_VALUES) {
113 int NumResults = N.getNumOperands();
114 for( int i = 0; i < NumResults; i++)
115 Results.push_back(N.getOperand(i));
118 Results.push_back(N);
121 MVT PIC16TargetLowering::getSetCCResultType(MVT ValType) const {
127 PIC16TargetLowering::setPIC16LibCallName(PIC16ISD::PIC16LibCall Call,
129 PIC16LibCallNames[Call] = Name;
133 PIC16TargetLowering::getPIC16LibCallName(PIC16ISD::PIC16LibCall Call) {
134 return PIC16LibCallNames[Call];
138 PIC16TargetLowering::MakePIC16LibCall(PIC16ISD::PIC16LibCall Call,
139 MVT RetVT, const SDValue *Ops,
140 unsigned NumOps, bool isSigned,
143 TargetLowering::ArgListTy Args;
144 Args.reserve(NumOps);
146 TargetLowering::ArgListEntry Entry;
147 for (unsigned i = 0; i != NumOps; ++i) {
149 Entry.Ty = Entry.Node.getValueType().getTypeForMVT();
150 Entry.isSExt = isSigned;
151 Entry.isZExt = !isSigned;
152 Args.push_back(Entry);
154 SDValue Callee = DAG.getExternalSymbol(getPIC16LibCallName(Call), MVT::i8);
156 const Type *RetTy = RetVT.getTypeForMVT();
157 std::pair<SDValue,SDValue> CallInfo =
158 LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false,
159 false, CallingConv::C, false, Callee, Args, DAG);
161 return CallInfo.first;
165 PIC16TargetLowering::getCurrentFrame(SelectionDAG &DAG) {
166 MachineFunction &MF = DAG.getMachineFunction();
167 const Function *Func = MF.getFunction();
168 const std::string FuncName = Func->getName();
170 // this is causing memory waste
171 // because for every call new memory will be allocated
172 char *tmpName = new char [strlen(FuncName.c_str()) + 6];
173 sprintf(tmpName, "%s.tmp", FuncName.c_str());
175 // if the external symbol of the same name already exists then
176 // it will not create the new one.
177 return DAG.getTargetExternalSymbol(tmpName, MVT::i8);
181 PIC16TargetLowering::getCurrentFrameIndex(SelectionDAG &DAG, SDValue &ES,
182 unsigned SlotSize, int &FromFI) {
183 MachineFunction &MF = DAG.getMachineFunction();
184 const Function *Func = MF.getFunction();
185 const std::string FuncName = Func->getName();
187 // this is causing memory waste
188 // because for every call new memory will be allocated
189 char *tmpName = new char [strlen(FuncName.c_str()) + 6];
190 sprintf(tmpName, "%s.tmp", FuncName.c_str());
192 // if the external symbol of the same name already exists then
193 // it will not create the new one.
194 ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
196 // Alignment is always 1
197 //FromFI = MF.getFrameInfo()->CreateStackObject(SlotSize, 1);
198 FromFI = MF.getFrameInfo()->CreateStackObject(1, 1);
200 for(unsigned i=1;i<SlotSize; ++i) {
201 FI = MF.getFrameInfo()->CreateStackObject(1, 1);
205 const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode) const {
207 default: return NULL;
208 case PIC16ISD::Lo: return "PIC16ISD::Lo";
209 case PIC16ISD::Hi: return "PIC16ISD::Hi";
210 case PIC16ISD::MTLO: return "PIC16ISD::MTLO";
211 case PIC16ISD::MTHI: return "PIC16ISD::MTHI";
212 case PIC16ISD::Banksel: return "PIC16ISD::Banksel";
213 case PIC16ISD::PIC16Load: return "PIC16ISD::PIC16Load";
214 case PIC16ISD::PIC16LdWF: return "PIC16ISD::PIC16LdWF";
215 case PIC16ISD::PIC16Store: return "PIC16ISD::PIC16Store";
216 case PIC16ISD::PIC16StWF: return "PIC16ISD::PIC16StWF";
217 case PIC16ISD::BCF: return "PIC16ISD::BCF";
218 case PIC16ISD::LSLF: return "PIC16ISD::LSLF";
219 case PIC16ISD::LRLF: return "PIC16ISD::LRLF";
220 case PIC16ISD::RLF: return "PIC16ISD::RLF";
221 case PIC16ISD::RRF: return "PIC16ISD::RRF";
222 case PIC16ISD::CALL: return "PIC16ISD::CALL";
223 case PIC16ISD::SUBCC: return "PIC16ISD::SUBCC";
224 case PIC16ISD::SELECT_ICC: return "PIC16ISD::SELECT_ICC";
225 case PIC16ISD::BRCOND: return "PIC16ISD::BRCOND";
226 case PIC16ISD::Dummy: return "PIC16ISD::Dummy";
230 void PIC16TargetLowering::ReplaceNodeResults(SDNode *N,
231 SmallVectorImpl<SDValue>&Results,
234 switch (N->getOpcode()) {
235 case ISD::GlobalAddress:
236 Results.push_back(ExpandGlobalAddress(N, DAG));
238 case ISD::ExternalSymbol:
239 Results.push_back(ExpandExternalSymbol(N, DAG));
242 Results.push_back(ExpandStore(N, DAG));
245 PopulateResults(ExpandLoad(N, DAG), Results);
248 // Results.push_back(ExpandAdd(N, DAG));
254 SDValue Res = ExpandShift(N, DAG);
256 Results.push_back(Res);
259 case ISD::FrameIndex:
260 Results.push_back(ExpandFrameIndex(N, DAG));
263 assert (0 && "not implemented");
268 SDValue PIC16TargetLowering::ExpandFrameIndex(SDNode *N, SelectionDAG &DAG) {
270 // Currently handling FrameIndex of size MVT::i16 only
271 // One example of this scenario is when return value is written on
274 if (N->getValueType(0) != MVT::i16)
277 // Expand the FrameIndex into ExternalSymbol and a Constant node
278 // The constant will represent the frame index number
279 // Get the current function frame
280 MachineFunction &MF = DAG.getMachineFunction();
281 const Function *Func = MF.getFunction();
282 const std::string Name = Func->getName();
284 FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(SDValue(N,0));
285 int Index = FR->getIndex();
288 FI[0] = DAG.getTargetFrameIndex(Index, MVT::i8);
289 FI[1] = DAG.getTargetFrameIndex(Index + 1, MVT::i8);
290 return DAG.getNode(ISD::BUILD_PAIR, N->getValueType(0), FI[0], FI[1]);
294 SDValue PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) {
295 StoreSDNode *St = cast<StoreSDNode>(N);
296 SDValue Chain = St->getChain();
297 SDValue Src = St->getValue();
298 SDValue Ptr = St->getBasePtr();
299 MVT ValueType = Src.getValueType();
300 unsigned StoreOffset = 0;
302 SDValue PtrLo, PtrHi;
303 LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, StoreOffset);
305 if (ValueType == MVT::i8) {
306 return DAG.getNode (PIC16ISD::PIC16Store, MVT::Other, Chain, Src,
308 DAG.getConstant (0 + StoreOffset, MVT::i8));
310 else if (ValueType == MVT::i16) {
311 // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
312 SDValue SrcLo, SrcHi;
313 GetExpandedParts(Src, DAG, SrcLo, SrcHi);
314 SDValue ChainLo = Chain, ChainHi = Chain;
315 if (Chain.getOpcode() == ISD::TokenFactor) {
316 ChainLo = Chain.getOperand(0);
317 ChainHi = Chain.getOperand(1);
319 SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other,
322 DAG.getConstant (0 + StoreOffset, MVT::i8));
324 SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi,
326 DAG.getConstant (1 + StoreOffset, MVT::i8));
328 return DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1),
331 else if (ValueType == MVT::i32) {
332 // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
333 SDValue SrcLo, SrcHi;
334 GetExpandedParts(Src, DAG, SrcLo, SrcHi);
336 // Get the expanded parts of each of SrcLo and SrcHi.
337 SDValue SrcLo1, SrcLo2, SrcHi1, SrcHi2;
338 GetExpandedParts(SrcLo, DAG, SrcLo1, SrcLo2);
339 GetExpandedParts(SrcHi, DAG, SrcHi1, SrcHi2);
341 SDValue ChainLo = Chain, ChainHi = Chain;
342 if (Chain.getOpcode() == ISD::TokenFactor) {
343 ChainLo = Chain.getOperand(0);
344 ChainHi = Chain.getOperand(1);
346 SDValue ChainLo1 = ChainLo, ChainLo2 = ChainLo, ChainHi1 = ChainHi,
348 if (ChainLo.getOpcode() == ISD::TokenFactor) {
349 ChainLo1 = ChainLo.getOperand(0);
350 ChainLo2 = ChainLo.getOperand(1);
352 if (ChainHi.getOpcode() == ISD::TokenFactor) {
353 ChainHi1 = ChainHi.getOperand(0);
354 ChainHi2 = ChainHi.getOperand(1);
356 SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other,
358 SrcLo1, PtrLo, PtrHi,
359 DAG.getConstant (0 + StoreOffset, MVT::i8));
361 SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainLo2,
362 SrcLo2, PtrLo, PtrHi,
363 DAG.getConstant (1 + StoreOffset, MVT::i8));
365 SDValue Store3 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi1,
366 SrcHi1, PtrLo, PtrHi,
367 DAG.getConstant (2 + StoreOffset, MVT::i8));
369 SDValue Store4 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi2,
370 SrcHi2, PtrLo, PtrHi,
371 DAG.getConstant (3 + StoreOffset, MVT::i8));
373 SDValue RetLo = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1),
375 SDValue RetHi = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store3),
377 return DAG.getNode(ISD::TokenFactor, MVT::Other, RetLo, RetHi);
381 assert (0 && "value type not supported");
386 SDValue PIC16TargetLowering::ExpandExternalSymbol(SDNode *N, SelectionDAG &DAG)
388 ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(SDValue(N, 0));
390 SDValue TES = DAG.getTargetExternalSymbol(ES->getSymbol(), MVT::i8);
392 SDValue Lo = DAG.getNode(PIC16ISD::Lo, MVT::i8, TES);
393 SDValue Hi = DAG.getNode(PIC16ISD::Hi, MVT::i8, TES);
395 return DAG.getNode(ISD::BUILD_PAIR, MVT::i16, Lo, Hi);
398 // ExpandGlobalAddress -
399 SDValue PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) {
400 GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(SDValue(N, 0));
402 SDValue TGA = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i8,
405 SDValue Lo = DAG.getNode(PIC16ISD::Lo, MVT::i8, TGA);
406 SDValue Hi = DAG.getNode(PIC16ISD::Hi, MVT::i8, TGA);
408 return DAG.getNode(ISD::BUILD_PAIR, MVT::i16, Lo, Hi);
411 bool PIC16TargetLowering::isDirectAddress(const SDValue &Op) {
412 assert (Op.getNode() != NULL && "Can't operate on NULL SDNode!!");
414 if (Op.getOpcode() == ISD::BUILD_PAIR) {
415 if (Op.getOperand(0).getOpcode() == PIC16ISD::Lo)
421 // Return true if DirectAddress is in ROM_SPACE
422 bool PIC16TargetLowering::isRomAddress(const SDValue &Op) {
424 // RomAddress is a GlobalAddress in ROM_SPACE_
425 // If the Op is not a GlobalAddress return NULL without checking
427 if (!isDirectAddress(Op))
430 // Its a GlobalAddress.
431 // It is BUILD_PAIR((PIC16Lo TGA), (PIC16Hi TGA)) and Op is BUILD_PAIR
432 SDValue TGA = Op.getOperand(0).getOperand(0);
433 GlobalAddressSDNode *GSDN = dyn_cast<GlobalAddressSDNode>(TGA);
434 const Type *ValueType = GSDN->getGlobal()->getType();
436 if (!isa<PointerType>(ValueType)) {
437 assert(0 && "TGA must be of a PointerType");
440 int AddrSpace = dyn_cast<PointerType>(ValueType)->getAddressSpace();
441 if (AddrSpace == PIC16ISD::ROM_SPACE)
444 // Any other address space return it false
448 // Extract the out flag
449 SDValue PIC16TargetLowering::getOutFlag(SDValue &Op) {
450 SDValue Flag = Op.getValue(Op.getNode()->getNumValues() - 1);
452 assert (Flag.getValueType() == MVT::Flag && "Node does not have an out Flag");
457 // To extract chain value from the SDValue Nodes
458 // This function will help to maintain the chain extracting
459 // code at one place. In case of any change in future it will
460 // help maintain the code.
461 SDValue PIC16TargetLowering::getChain(SDValue &Op) {
462 SDValue Chain = Op.getValue(Op.getNode()->getNumValues() - 1);
464 // If the last value returned in Flag then the chain is
465 // second last value returned.
466 if (Chain.getValueType() == MVT::Flag)
467 Chain = Op.getValue(Op.getNode()->getNumValues() - 2);
469 // All nodes may not produce a chain. Therefore following assert
470 // verifies that the node is returning a chain only.
471 assert (Chain.getValueType() == MVT::Other && "Node does not have a chain");
476 void PIC16TargetLowering::GetExpandedParts(SDValue Op, SelectionDAG &DAG,
478 SDValue &Lo, SDValue &Hi) {
479 SDNode *N = Op.getNode();
481 std::vector<SDValue> Opers;
482 NewVT = getTypeToTransformTo(N->getValueType(0));
484 // extract the lo component
486 Opers.push_back(DAG.getConstant(0,MVT::i8));
487 Lo = DAG.getNode(ISD::EXTRACT_ELEMENT,NewVT,&Opers[0],Opers.size());
488 // extract the hi component
491 Opers.push_back(DAG.getConstant(1,MVT::i8));
492 Hi = DAG.getNode(ISD::EXTRACT_ELEMENT,NewVT,&Opers[0],Opers.size());
495 // Legalize FrameIndex into ExternalSymbol and offset.
497 PIC16TargetLowering::LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG,
498 SDValue &ES, int &Offset) {
500 MachineFunction &MF = DAG.getMachineFunction();
501 const Function *Func = MF.getFunction();
502 const std::string Name = Func->getName();
504 char *tmpName = new char [strlen(Name.c_str()) + 8];
505 sprintf(tmpName, "%s.args", Name.c_str());
506 ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
507 FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(Op);
508 Offset = FR->getIndex();
513 // This function legalizes the PIC16 Addresses. If the Pointer is
514 // -- Direct address variable residing
515 // --> then a Banksel for that variable will be created.
517 // --> then it will be treated as an indirect address.
518 // -- Indirect address
519 // --> then the address will be loaded into FSR
520 // -- ADD with constant operand
521 // --> then constant operand of ADD will be returned as Offset
522 // and non-constant operand of ADD will be treated as pointer.
523 // Returns the high and lo part of the address, and the offset(in case of ADD).
525 void PIC16TargetLowering:: LegalizeAddress(SDValue Ptr, SelectionDAG &DAG,
526 SDValue &Lo, SDValue &Hi,
529 // Offset, by default, should be 0
532 // If the pointer is ADD with constant,
533 // return the constant value as the offset
534 if (Ptr.getOpcode() == ISD::ADD) {
535 SDValue OperLeft = Ptr.getOperand(0);
536 SDValue OperRight = Ptr.getOperand(1);
537 if (OperLeft.getOpcode() == ISD::Constant) {
538 Offset = dyn_cast<ConstantSDNode>(OperLeft)->getZExtValue();
540 } else if (OperRight.getOpcode() == ISD::Constant) {
541 Offset = dyn_cast<ConstantSDNode>(OperRight)->getZExtValue();
546 // If the pointer is Type i8 and an external symbol
547 // then treat it as direct address.
548 // One example for such case is storing and loading
549 // from function frame during a call
550 if (Ptr.getValueType() == MVT::i8) {
551 switch (Ptr.getOpcode()) {
552 case ISD::TargetExternalSymbol:
554 Hi = DAG.getConstant(1, MVT::i8);
559 if (Ptr.getOpcode() == ISD::BUILD_PAIR &&
560 Ptr.getOperand(0).getOpcode() == ISD::TargetFrameIndex) {
563 LegalizeFrameIndex(Ptr.getOperand(0), DAG, Lo, FrameOffset);
564 Hi = DAG.getConstant(1, MVT::i8);
565 Offset += FrameOffset;
569 if (isDirectAddress(Ptr) && !isRomAddress(Ptr)) {
570 // Direct addressing case for RAM variables. The Hi part is constant
571 // and the Lo part is the TGA itself.
572 Lo = Ptr.getOperand(0).getOperand(0);
574 // For direct addresses Hi is a constant. Value 1 for the constant
575 // signifies that banksel needs to generated for it. Value 0 for
576 // the constant signifies that banksel does not need to be generated
577 // for it. Mark it as 1 now and optimize later.
578 Hi = DAG.getConstant(1, MVT::i8);
582 // Indirect addresses. Get the hi and lo parts of ptr.
583 GetExpandedParts(Ptr, DAG, Lo, Hi);
585 // Put the hi and lo parts into FSR.
586 Lo = DAG.getNode(PIC16ISD::MTLO, MVT::i8, Lo);
587 Hi = DAG.getNode(PIC16ISD::MTHI, MVT::i8, Hi);
592 //SDValue PIC16TargetLowering::ExpandAdd(SDNode *N, SelectionDAG &DAG) {
593 //SDValue OperLeft = N->getOperand(0);
594 //SDValue OperRight = N->getOperand(1);
596 //if((OperLeft.getOpcode() == ISD::Constant) ||
597 //(OperRight.getOpcode() == ISD::Constant)) {
601 // These case are yet to be handled
605 SDValue PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) {
606 LoadSDNode *LD = dyn_cast<LoadSDNode>(SDValue(N, 0));
607 SDValue Chain = LD->getChain();
608 SDValue Ptr = LD->getBasePtr();
610 SDValue Load, Offset;
613 SDValue PtrLo, PtrHi;
616 // Legalize direct/indirect addresses. This will give the lo and hi parts
617 // of the address and the offset.
618 LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, LoadOffset);
620 // Load from the pointer (direct address or FSR)
621 VT = N->getValueType(0);
622 unsigned NumLoads = VT.getSizeInBits() / 8;
623 std::vector<SDValue> PICLoads;
625 MVT MemVT = LD->getMemoryVT();
626 if(ISD::isNON_EXTLoad(N)) {
627 for (iter=0; iter<NumLoads ; ++iter) {
628 // Add the pointer offset if any
629 Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
630 Tys = DAG.getVTList(MVT::i8, MVT::Other);
631 Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Chain, PtrLo, PtrHi,
633 PICLoads.push_back(Load);
636 // If it is extended load then use PIC16Load for Memory Bytes
637 // and for all extended bytes perform action based on type of
638 // extention - i.e. SignExtendedLoad or ZeroExtendedLoad
641 // For extended loads this is the memory value type
642 // i.e. without any extension
643 MVT MemVT = LD->getMemoryVT();
644 unsigned MemBytes = MemVT.getSizeInBits() / 8;
645 unsigned ExtdBytes = VT.getSizeInBits() / 8;
646 Offset = DAG.getConstant(LoadOffset, MVT::i8);
648 Tys = DAG.getVTList(MVT::i8, MVT::Other);
649 // For MemBytes generate PIC16Load with proper offset
650 for (iter=0; iter<MemBytes; ++iter) {
651 // Add the pointer offset if any
652 Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
653 Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Chain, PtrLo, PtrHi,
655 PICLoads.push_back(Load);
658 // For SignExtendedLoad
659 if (ISD::isSEXTLoad(N)) {
660 // For all ExtdBytes use the Right Shifted(Arithmetic) Value of the
662 SDValue SRA = DAG.getNode(ISD::SRA, MVT::i8, Load,
663 DAG.getConstant(7, MVT::i8));
664 for (iter=MemBytes; iter<ExtdBytes; ++iter) {
665 PICLoads.push_back(SRA);
667 } else if (ISD::isZEXTLoad(N)) {
668 // ZeroExtendedLoad -- For all ExtdBytes use constant 0
669 SDValue ConstZero = DAG.getConstant(0, MVT::i8);
670 for (iter=MemBytes; iter<ExtdBytes; ++iter) {
671 PICLoads.push_back(ConstZero);
678 // Operand of Load is illegal -- Load itself is legal
681 else if (VT == MVT::i16) {
682 BP = DAG.getNode(ISD::BUILD_PAIR, VT, PICLoads[0], PICLoads[1]);
683 if (MemVT == MVT::i8)
684 Chain = getChain(PICLoads[0]);
686 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]),
687 getChain(PICLoads[1]));
688 } else if (VT == MVT::i32) {
690 BPs[0] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[0], PICLoads[1]);
691 BPs[1] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[2], PICLoads[3]);
692 BP = DAG.getNode(ISD::BUILD_PAIR, VT, BPs[0], BPs[1]);
693 if (MemVT == MVT::i8)
694 Chain = getChain(PICLoads[0]);
695 else if (MemVT == MVT::i16)
696 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]),
697 getChain(PICLoads[1]));
700 Chains[0] = DAG.getNode(ISD::TokenFactor, MVT::Other,
701 getChain(PICLoads[0]), getChain(PICLoads[1]));
702 Chains[1] = DAG.getNode(ISD::TokenFactor, MVT::Other,
703 getChain(PICLoads[2]), getChain(PICLoads[3]));
704 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Chains[0], Chains[1]);
707 Tys = DAG.getVTList(VT, MVT::Other);
708 return DAG.getNode(ISD::MERGE_VALUES, Tys, BP, Chain);
711 SDValue PIC16TargetLowering::ExpandShift(SDNode *N, SelectionDAG &DAG) {
712 SDValue Value = N->getOperand(0);
713 SDValue Amt = N->getOperand(1);
714 SDValue BCF, BCFInput;
715 SDValue ShfCom; // Shift Component - Lo component should be shifted
716 SDValue RotCom; // Rotate Component- Hi component should be rotated
718 PIC16ISD::PIC16LibCall CallCode;
720 // Shift amount should be MVT::i8 only. If it is more than that then
721 // extract MVT::i8 from that
722 if (Amt.getValueType() == MVT::i8) {
723 // Do Nothing - This is ok
724 } else if (Amt.getValueType() == MVT::i16) {
726 GetExpandedParts(Amt, DAG, Lo, Hi);
727 Amt = Lo; // Take the Lo part as amount
729 } else if (Amt.getValueType() == MVT::i32) {
731 // Get MVT::i16 Components
732 GetExpandedParts(Amt, DAG, Lo, Hi);
733 // Get MVT::i8 Components
734 GetExpandedParts(Lo, DAG, Lo, Hi);
738 assert ( 0 && "Invalid Shift amount");
741 // Shift library call will always have two operands
742 if (N->getValueType(0) == MVT::i8) {
743 switch (N->getOpcode()) {
745 CallCode = PIC16ISD::SRA_I8;
748 CallCode = PIC16ISD::SLL_I8;
751 CallCode = PIC16ISD::SRL_I8;
754 assert ( 0 && "This shift is not implemented yet.");
757 } else if (N->getValueType(0) == MVT::i16) {
758 switch (N->getOpcode()) {
760 CallCode = PIC16ISD::SRA_I16;
763 CallCode = PIC16ISD::SLL_I16;
766 CallCode = PIC16ISD::SRL_I16;
769 assert ( 0 && "This shift is not implemented yet.");
772 } else if (N->getValueType(0) == MVT::i32) {
773 switch (N->getOpcode()) {
775 CallCode = PIC16ISD::SRA_I32;
778 CallCode = PIC16ISD::SLL_I32;
781 CallCode = PIC16ISD::SRL_I32;
784 assert ( 0 && "This shift is not implemented yet.");
788 //assert ( 0 && "Shift for this value type not yet implemented.");
792 SmallVector<SDValue, 2> Ops(2);
795 SDValue Call = MakePIC16LibCall(CallCode, N->getValueType(0), &Ops[0], 2, true, DAG);
799 SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
800 switch (Op.getOpcode()) {
801 case ISD::FORMAL_ARGUMENTS:
802 return LowerFORMAL_ARGUMENTS(Op, DAG);
806 return LowerADD(Op, DAG);
810 return LowerSUB(Op, DAG);
812 return ExpandLoad(Op.getNode(), DAG);
814 return ExpandStore(Op.getNode(), DAG);
818 return ExpandShift(Op.getNode(), DAG);
822 return LowerBinOp(Op, DAG);
824 // This is called only from LegalizeDAG. No call is made to
825 // legalize CALL node from LegalizeType.
826 return LowerCALL(Op, DAG);
828 return LowerRET(Op, DAG);
830 return LowerBR_CC(Op, DAG);
832 return LowerSELECT_CC(Op, DAG);
837 SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op,
840 assert (Op.getValueType() == MVT::i8
841 && "illegal value type to store on stack.");
843 MachineFunction &MF = DAG.getMachineFunction();
844 const Function *Func = MF.getFunction();
845 const std::string FuncName = Func->getName();
847 char *tmpName = new char [strlen(FuncName.c_str()) + 6];
849 // Put the value on stack.
850 // Get a stack slot index and convert to es.
851 int FI = MF.getFrameInfo()->CreateStackObject(1, 1);
852 sprintf(tmpName, "%s.tmp", FuncName.c_str());
853 SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
855 // Store the value to ES.
856 SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, MVT::Other,
859 DAG.getConstant (1, MVT::i8), // Banksel.
860 DAG.getConstant (FI, MVT::i8));
862 // Load the value from ES.
863 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other);
864 SDValue Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Store,
865 ES, DAG.getConstant (1, MVT::i8),
866 DAG.getConstant (FI, MVT::i8));
868 return Load.getValue(0);
872 PIC16TargetLowering::LowerCallArguments(SDValue Op, SDValue Chain,
873 SDValue FrameAddress,
876 CallSDNode *TheCall = dyn_cast<CallSDNode>(Op);
877 unsigned NumOps = TheCall->getNumArgs();
879 SDValue Arg, StoreAt;
885 // FIXME: This portion of code currently assumes only
886 // primitive types being passed as arguments.
888 // Legalize the address before use
889 SDValue PtrLo, PtrHi;
890 unsigned AddressOffset;
892 LegalizeAddress(FrameAddress, DAG, PtrLo, PtrHi, AddressOffset);
895 std::vector<SDValue> Ops;
896 SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
897 for (unsigned i=ArgCount, Offset = 0; i<NumOps; i++) {
899 Arg = TheCall->getArg(i);
901 StoreOffset = (Offset + AddressOffset);
903 // Store the argument on frame
906 Ops.push_back(Chain);
907 Ops.push_back(Arg.getValue(0));
908 Ops.push_back(PtrLo);
909 Ops.push_back(PtrHi);
910 Ops.push_back(DAG.getConstant(StoreOffset, MVT::i8));
911 Ops.push_back(InFlag);
913 StoreRet = DAG.getNode (PIC16ISD::PIC16StWF, Tys, &Ops[0], Ops.size());
915 Chain = getChain(StoreRet);
916 InFlag = getOutFlag(StoreRet);
918 // Update the frame offset to be used for next argument
919 ArgVT = Arg.getValueType();
920 Size = ArgVT.getSizeInBits();
921 Size = Size/8; // Calculate size in bytes
922 Offset += Size; // Increase the frame offset
928 PIC16TargetLowering::LowerCallReturn(SDValue Op, SDValue Chain,
929 SDValue FrameAddress,
932 CallSDNode *TheCall = dyn_cast<CallSDNode>(Op);
933 // Currently handling primitive types only. They will come in
935 unsigned RetVals = TheCall->getNumRetVals();
937 std::vector<SDValue> ResultVals;
939 // Return immediately if the return type is void
943 // Call has something to return
945 // Legalize the address before use
948 LegalizeAddress(FrameAddress, DAG, LdLo, LdHi, LdOffset);
950 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other, MVT::Flag);
953 for(unsigned i=0, Offset=0;i<RetVals;i++) {
955 LoadRet = DAG.getNode(PIC16ISD::PIC16LdWF, Tys, Chain, LdLo, LdHi,
956 DAG.getConstant(LdOffset + Offset, MVT::i8),
959 InFlag = getOutFlag(LoadRet);
961 Chain = getChain(LoadRet);
963 ResultVals.push_back(LoadRet);
966 // To return use MERGE_VALUES
967 ResultVals.push_back(Chain);
968 SDValue Res = DAG.getMergeValues(&ResultVals[0], ResultVals.size());
972 SDValue PIC16TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) {
973 //int NumOps = Op.getNode()->getNumOperands();
975 // For default cases LLVM returns the value on the function frame
976 // So let LLVM do this for all the cases other than character
980 SDValue PIC16TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
981 CallSDNode *TheCall = dyn_cast<CallSDNode>(Op);
982 SDValue Chain = TheCall->getChain();
983 SDValue Callee = TheCall->getCallee();
985 if (Callee.getValueType() == MVT::i16 &&
986 Callee.getOpcode() == ISD::BUILD_PAIR) {
987 // It has come from TypeLegalizer for lowering
989 Callee = Callee.getOperand(0).getOperand(0);
991 std::vector<SDValue> Ops;
992 Ops.push_back(Chain);
993 Ops.push_back(Callee);
995 // Add the call arguments and their flags
996 unsigned NumArgs = TheCall->getNumArgs();
997 for(i=0;i<NumArgs;i++) {
998 Ops.push_back(TheCall->getArg(i));
999 Ops.push_back(TheCall->getArgFlagsVal(i));
1002 std::vector<MVT> NodeTys;
1003 unsigned NumRets = TheCall->getNumRetVals();
1004 for(i=0;i<NumRets;i++)
1005 NodeTys.push_back(TheCall->getRetValType(i));
1007 // Return a Chain as well
1008 NodeTys.push_back(MVT::Other);
1010 SDVTList VTs = DAG.getVTList(&NodeTys[0], NodeTys.size());
1012 DAG.getCall(TheCall->getCallingConv(), TheCall->isVarArg(),
1013 TheCall->isTailCall(), TheCall->isInreg(), VTs,
1014 &Ops[0], Ops.size());
1019 SDValue ZeroOperand = DAG.getConstant(0, MVT::i8);
1021 // Start the call sequence.
1022 // Carring the Constant 0 along the CALLSEQSTART
1023 // because there is nothing else to carry.
1024 SDValue SeqStart = DAG.getCALLSEQ_START(Chain, ZeroOperand);
1025 Chain = getChain(SeqStart);
1027 // For any direct call - callee will be GlobalAddressNode or
1030 // Considering the GlobalAddressNode case here.
1031 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
1032 GlobalValue *GV = G->getGlobal();
1033 Callee = DAG.getTargetGlobalAddress(GV, MVT::i8);
1036 // Considering the ExternalSymbol case here
1037 if (ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Callee)) {
1038 Callee = DAG.getTargetExternalSymbol(ES->getSymbol(), MVT::i8);
1041 SDValue OperFlag = getOutFlag(Chain); // To manage the data dependency
1045 // Considering GlobalAddress here
1046 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
1047 Name = G->getGlobal()->getName();
1049 // Considering ExternalSymbol here
1050 if (ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Callee))
1051 Name = ES->getSymbol();
1053 char *argFrame = new char [strlen(Name.c_str()) + 8];
1054 sprintf(argFrame, "%s.args", Name.c_str());
1055 SDValue ArgLabel = DAG.getTargetExternalSymbol(argFrame, MVT::i8);
1057 char *retName = new char [strlen(Name.c_str()) + 8];
1058 sprintf(retName, "%s.retval", Name.c_str());
1059 SDValue RetLabel = DAG.getTargetExternalSymbol(retName, MVT::i8);
1061 // Pass the argument to function before making the call.
1062 SDValue CallArgs = LowerCallArguments(Op, Chain, ArgLabel, OperFlag, DAG);
1063 Chain = getChain(CallArgs);
1064 OperFlag = getOutFlag(CallArgs);
1066 SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
1067 SDValue PICCall = DAG.getNode(PIC16ISD::CALL, Tys, Chain, Callee,
1069 Chain = getChain(PICCall);
1070 OperFlag = getOutFlag(PICCall);
1073 // Carrying the Constant 0 along the CALLSEQSTART
1074 // because there is nothing else to carry.
1075 SDValue SeqEnd = DAG.getCALLSEQ_END(Chain, ZeroOperand, ZeroOperand,
1077 Chain = getChain(SeqEnd);
1078 OperFlag = getOutFlag(SeqEnd);
1080 // Lower the return value reading after the call.
1081 return LowerCallReturn(Op, Chain, RetLabel, OperFlag, DAG);
1084 bool PIC16TargetLowering::isDirectLoad(const SDValue Op) {
1085 if (Op.getOpcode() == PIC16ISD::PIC16Load)
1086 if (Op.getOperand(1).getOpcode() == ISD::TargetGlobalAddress
1087 || Op.getOperand(1).getOpcode() == ISD::TargetExternalSymbol)
1092 bool PIC16TargetLowering::NeedToConvertToMemOp(SDValue Op, unsigned &MemOp) {
1093 // Return false if one of the operands is already a direct
1094 // load and that operand has only one use.
1095 if (Op.getOperand(0).getOpcode() == ISD::Constant ||
1096 Op.getOperand(1).getOpcode() == ISD::Constant)
1098 if (isDirectLoad(Op.getOperand(0))) {
1099 if (Op.getOperand(0).hasOneUse())
1104 if (isDirectLoad(Op.getOperand(1))) {
1105 if (Op.getOperand(1).hasOneUse())
1113 SDValue PIC16TargetLowering:: LowerBinOp(SDValue Op, SelectionDAG &DAG) {
1114 // We should have handled larger operands in type legalizer itself.
1115 assert (Op.getValueType() == MVT::i8 && "illegal Op to lower");
1117 if (NeedToConvertToMemOp(Op, MemOp)) {
1118 // Put one value on stack.
1119 SDValue NewVal = ConvertToMemOperand (Op.getOperand(MemOp), DAG);
1121 return DAG.getNode(Op.getOpcode(), MVT::i8, Op.getOperand(MemOp ^ 1),
1129 SDValue PIC16TargetLowering:: LowerADD(SDValue Op, SelectionDAG &DAG) {
1130 // We should have handled larger operands in type legalizer itself.
1131 assert (Op.getValueType() == MVT::i8 && "illegal add to lower");
1133 if (NeedToConvertToMemOp(Op, MemOp)) {
1134 // Put one value on stack.
1135 SDValue NewVal = ConvertToMemOperand (Op.getOperand(MemOp), DAG);
1137 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
1139 if (Op.getOpcode() == ISD::ADDE)
1140 return DAG.getNode(Op.getOpcode(), Tys, Op.getOperand(MemOp ^ 1), NewVal,
1143 return DAG.getNode(Op.getOpcode(), Tys, Op.getOperand(MemOp ^ 1), NewVal);
1150 SDValue PIC16TargetLowering::LowerSUB(SDValue Op, SelectionDAG &DAG) {
1151 // We should have handled larger operands in type legalizer itself.
1152 assert (Op.getValueType() == MVT::i8 && "illegal sub to lower");
1154 // Nothing to do if the first operand is already a direct load and it has
1156 if (isDirectLoad(Op.getOperand(0)) && Op.getOperand(0).hasOneUse())
1159 // Put first operand on stack.
1160 SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG);
1162 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
1163 if (Op.getOpcode() == ISD::SUBE)
1164 return DAG.getNode(Op.getOpcode(), Tys, NewVal, Op.getOperand(1),
1167 return DAG.getNode(Op.getOpcode(), Tys, NewVal, Op.getOperand(1));
1170 // LowerFORMAL_ARGUMENTS - In Lowering FORMAL ARGUMENTS - MERGE_VALUES nodes
1171 // is returned. MERGE_VALUES nodes number of operands and number of values are
1172 // equal. Therefore to construct MERGE_VALUE node, UNDEF nodes equal to the
1173 // number of arguments of function have been created.
1175 SDValue PIC16TargetLowering:: LowerFORMAL_ARGUMENTS(SDValue Op,
1176 SelectionDAG &DAG) {
1177 SmallVector<SDValue, 8> ArgValues;
1178 unsigned NumArgs = Op.getNumOperands() - 3;
1180 // Creating UNDEF nodes to meet the requirement of MERGE_VALUES node.
1181 for(unsigned i = 0 ; i<NumArgs ; i++) {
1182 SDValue TempNode = DAG.getNode(ISD::UNDEF, Op.getNode()->getValueType(i));
1183 ArgValues.push_back(TempNode);
1186 ArgValues.push_back(Op.getOperand(0));
1187 return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(),
1189 ArgValues.size()).getValue(Op.getResNo());
1192 // Perform DAGCombine of PIC16Load
1193 SDValue PIC16TargetLowering::
1194 PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const {
1195 SelectionDAG &DAG = DCI.DAG;
1196 SDValue Chain = N->getOperand(0);
1197 if (N->hasNUsesOfValue(0, 0)) {
1198 DAG.ReplaceAllUsesOfValueWith(SDValue(N,1), Chain);
1204 SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N,
1205 DAGCombinerInfo &DCI) const {
1206 switch (N->getOpcode()) {
1207 case PIC16ISD::PIC16Load:
1208 return PerformPIC16LoadCombine(N, DCI);
1213 static PIC16CC::CondCodes IntCCToPIC16CC(ISD::CondCode CC) {
1215 default: assert(0 && "Unknown condition code!");
1216 case ISD::SETNE: return PIC16CC::NE;
1217 case ISD::SETEQ: return PIC16CC::EQ;
1218 case ISD::SETGT: return PIC16CC::GT;
1219 case ISD::SETGE: return PIC16CC::GE;
1220 case ISD::SETLT: return PIC16CC::LT;
1221 case ISD::SETLE: return PIC16CC::LE;
1222 case ISD::SETULT: return PIC16CC::LT;
1223 case ISD::SETULE: return PIC16CC::LE;
1224 case ISD::SETUGE: return PIC16CC::GE;
1225 case ISD::SETUGT: return PIC16CC::GT;
1229 // Look at LHS/RHS/CC and see if they are a lowered setcc instruction. If so
1230 // set LHS/RHS and SPCC to the LHS/RHS of the setcc and SPCC to the condition.
1231 static void LookThroughSetCC(SDValue &LHS, SDValue &RHS,
1232 ISD::CondCode CC, unsigned &SPCC) {
1233 if (isa<ConstantSDNode>(RHS) &&
1234 cast<ConstantSDNode>(RHS)->getZExtValue() == 0 &&
1236 (LHS.getOpcode() == PIC16ISD::SELECT_ICC &&
1237 LHS.getOperand(3).getOpcode() == PIC16ISD::SUBCC) &&
1238 isa<ConstantSDNode>(LHS.getOperand(0)) &&
1239 isa<ConstantSDNode>(LHS.getOperand(1)) &&
1240 cast<ConstantSDNode>(LHS.getOperand(0))->getZExtValue() == 1 &&
1241 cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue() == 0) {
1242 SDValue CMPCC = LHS.getOperand(3);
1243 SPCC = cast<ConstantSDNode>(LHS.getOperand(2))->getZExtValue();
1244 LHS = CMPCC.getOperand(0);
1245 RHS = CMPCC.getOperand(1);
1249 // Returns appropriate CMP insn and corresponding condition code in PIC16CC
1250 SDValue PIC16TargetLowering::getPIC16Cmp(SDValue LHS, SDValue RHS,
1251 unsigned CC, SDValue &PIC16CC,
1252 SelectionDAG &DAG) {
1253 PIC16CC::CondCodes CondCode = (PIC16CC::CondCodes) CC;
1255 // PIC16 sub is literal - W. So Swap the operands and condition if needed.
1256 // i.e. a < 12 can be rewritten as 12 > a.
1257 if (RHS.getOpcode() == ISD::Constant) {
1266 CondCode = PIC16CC::GT;
1269 CondCode = PIC16CC::LT;
1272 CondCode = PIC16CC::LE;
1275 CondCode = PIC16CC::GE;
1280 PIC16CC = DAG.getConstant(CondCode, MVT::i8);
1281 SDVTList VTs = DAG.getVTList (MVT::i8, MVT::Flag);
1283 // We can use a subtract operation to set the condition codes. But
1284 // we need to put one operand in memory if required.
1285 // Nothing to do if the first operand is already a direct load and it has
1287 if (! (isDirectLoad(LHS) && LHS.hasOneUse()))
1288 // Put first operand on stack.
1289 LHS = ConvertToMemOperand (LHS, DAG);
1291 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
1292 return DAG.getNode(PIC16ISD::SUBCC, VTs, LHS, RHS);
1296 SDValue PIC16TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) {
1297 SDValue LHS = Op.getOperand(0);
1298 SDValue RHS = Op.getOperand(1);
1299 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
1300 SDValue TrueVal = Op.getOperand(2);
1301 SDValue FalseVal = Op.getOperand(3);
1302 unsigned ORIGCC = ~0;
1304 // If this is a select_cc of a "setcc", and if the setcc got lowered into
1305 // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
1307 // A setcc: lhs, rhs, cc is expanded by llvm to
1308 // select_cc: result of setcc, 0, 1, 0, setne
1309 // We can think of it as:
1310 // select_cc: lhs, rhs, 1, 0, cc
1311 LookThroughSetCC(LHS, RHS, CC, ORIGCC);
1312 if (ORIGCC == ~0U) ORIGCC = IntCCToPIC16CC (CC);
1315 SDValue Cmp = getPIC16Cmp(LHS, RHS, ORIGCC, PIC16CC, DAG);
1317 return DAG.getNode (PIC16ISD::SELECT_ICC, TrueVal.getValueType(), TrueVal,
1318 FalseVal, PIC16CC, Cmp.getValue(1));
1322 PIC16TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
1323 MachineBasicBlock *BB) {
1324 const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
1325 unsigned CC = (PIC16CC::CondCodes)MI->getOperand(3).getImm();
1327 // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
1328 // control-flow pattern. The incoming instruction knows the destination vreg
1329 // to set, the condition code register to branch on, the true/false values to
1330 // select between, and a branch opcode to use.
1331 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1332 MachineFunction::iterator It = BB;
1339 // fallthrough --> copy0MBB
1340 MachineBasicBlock *thisMBB = BB;
1341 MachineFunction *F = BB->getParent();
1342 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
1343 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
1344 BuildMI(BB, TII.get(PIC16::pic16brcond)).addMBB(sinkMBB).addImm(CC);
1345 F->insert(It, copy0MBB);
1346 F->insert(It, sinkMBB);
1348 // Update machine-CFG edges by transferring all successors of the current
1349 // block to the new block which will contain the Phi node for the select.
1350 sinkMBB->transferSuccessors(BB);
1351 // Next, add the true and fallthrough blocks as its successors.
1352 BB->addSuccessor(copy0MBB);
1353 BB->addSuccessor(sinkMBB);
1356 // %FalseValue = ...
1357 // # fallthrough to sinkMBB
1360 // Update machine-CFG edges
1361 BB->addSuccessor(sinkMBB);
1364 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1367 BuildMI(BB, TII.get(PIC16::PHI), MI->getOperand(0).getReg())
1368 .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
1369 .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
1371 F->DeleteMachineInstr(MI); // The pseudo instruction is gone now.
1376 SDValue PIC16TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) {
1377 SDValue Chain = Op.getOperand(0);
1378 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
1379 SDValue LHS = Op.getOperand(2); // LHS of the condition.
1380 SDValue RHS = Op.getOperand(3); // RHS of the condition.
1381 SDValue Dest = Op.getOperand(4); // BB to jump to
1382 unsigned ORIGCC = ~0;
1384 // If this is a br_cc of a "setcc", and if the setcc got lowered into
1385 // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
1386 LookThroughSetCC(LHS, RHS, CC, ORIGCC);
1387 if (ORIGCC == ~0U) ORIGCC = IntCCToPIC16CC (CC);
1389 // Get the Compare insn and condition code.
1391 SDValue Cmp = getPIC16Cmp(LHS, RHS, ORIGCC, PIC16CC, DAG);
1393 return DAG.getNode(PIC16ISD::BRCOND, MVT::Other, Chain, Dest, PIC16CC,