1 //===-- PIC16ISelLowering.cpp - PIC16 DAG Lowering Implementation ---------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the interfaces that PIC16 uses to lower LLVM code into a
13 //===----------------------------------------------------------------------===//
15 #define DEBUG_TYPE "pic16-lower"
17 #include "PIC16ISelLowering.h"
18 #include "PIC16TargetMachine.h"
19 #include "llvm/DerivedTypes.h"
20 #include "llvm/GlobalValue.h"
21 #include "llvm/Function.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineFunction.h"
30 // PIC16TargetLowering Constructor.
31 PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM)
32 : TargetLowering(TM) {
34 Subtarget = &TM.getSubtarget<PIC16Subtarget>();
36 addRegisterClass(MVT::i8, PIC16::GPRRegisterClass);
38 setShiftAmountType(MVT::i8);
39 setShiftAmountFlavor(Extend);
42 setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
44 setOperationAction(ISD::LOAD, MVT::i8, Legal);
45 setOperationAction(ISD::LOAD, MVT::i16, Custom);
46 setOperationAction(ISD::LOAD, MVT::i32, Custom);
48 setOperationAction(ISD::STORE, MVT::i8, Legal);
49 setOperationAction(ISD::STORE, MVT::i16, Custom);
50 setOperationAction(ISD::STORE, MVT::i32, Custom);
52 setOperationAction(ISD::ADDE, MVT::i8, Custom);
53 setOperationAction(ISD::ADDC, MVT::i8, Custom);
54 setOperationAction(ISD::SUBE, MVT::i8, Custom);
55 setOperationAction(ISD::SUBC, MVT::i8, Custom);
56 setOperationAction(ISD::ADD, MVT::i8, Legal);
57 setOperationAction(ISD::ADD, MVT::i16, Custom);
59 setOperationAction(ISD::OR, MVT::i8, Custom);
60 setOperationAction(ISD::AND, MVT::i8, Custom);
61 setOperationAction(ISD::XOR, MVT::i8, Custom);
63 setOperationAction(ISD::SHL, MVT::i16, Custom);
64 setOperationAction(ISD::SHL, MVT::i32, Custom);
66 //setOperationAction(ISD::TRUNCATE, MVT::i16, Custom);
67 setTruncStoreAction(MVT::i16, MVT::i8, Custom);
69 // Now deduce the information based on the above mentioned
71 computeRegisterProperties();
74 const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode) const {
77 case PIC16ISD::Lo: return "PIC16ISD::Lo";
78 case PIC16ISD::Hi: return "PIC16ISD::Hi";
79 case PIC16ISD::MTLO: return "PIC16ISD::MTLO";
80 case PIC16ISD::MTHI: return "PIC16ISD::MTHI";
81 case PIC16ISD::Banksel: return "PIC16ISD::Banksel";
82 case PIC16ISD::PIC16Load: return "PIC16ISD::PIC16Load";
83 case PIC16ISD::PIC16Store: return "PIC16ISD::PIC16Store";
84 case PIC16ISD::BCF: return "PIC16ISD::BCF";
85 case PIC16ISD::LSLF: return "PIC16ISD::LSLF";
86 case PIC16ISD::LRLF: return "PIC16ISD::LRLF";
87 case PIC16ISD::RLF: return "PIC16ISD::RLF";
88 case PIC16ISD::RRF: return "PIC16ISD::RRF";
89 case PIC16ISD::Dummy: return "PIC16ISD::Dummy";
93 SDNode *PIC16TargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) {
94 switch (N->getOpcode()) {
95 case ISD::GlobalAddress:
96 return ExpandGlobalAddress(N, DAG);
98 return ExpandStore(N, DAG);
100 return ExpandLoad(N, DAG);
102 return ExpandAdd(N, DAG);
104 return ExpandShift(N, DAG);
106 assert (0 && "not implemented");
110 SDNode *PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) {
111 StoreSDNode *St = cast<StoreSDNode>(N);
112 SDValue Chain = St->getChain();
113 SDValue Src = St->getValue();
114 SDValue Ptr = St->getBasePtr();
115 MVT ValueType = Src.getValueType();
116 unsigned StoreOffset = 0;
118 SDValue PtrLo, PtrHi;
119 LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, StoreOffset);
121 if (ValueType == MVT::i8) {
122 SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, MVT::Other, Chain, Src,
123 PtrLo, PtrHi, DAG.getConstant (0, MVT::i8));
124 return Store.getNode();
126 else if (ValueType == MVT::i16) {
127 // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
128 SDValue SrcLo, SrcHi;
129 GetExpandedParts(Src, DAG, SrcLo, SrcHi);
130 SDValue ChainLo = Chain, ChainHi = Chain;
131 if (Chain.getOpcode() == ISD::TokenFactor) {
132 ChainLo = Chain.getOperand(0);
133 ChainHi = Chain.getOperand(1);
135 SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other,
138 DAG.getConstant (0 + StoreOffset, MVT::i8));
140 SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi,
142 DAG.getConstant (1 + StoreOffset, MVT::i8));
144 return DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1),
145 getChain(Store2)).getNode();
147 else if (ValueType == MVT::i32) {
148 // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
149 SDValue SrcLo, SrcHi;
150 GetExpandedParts(Src, DAG, SrcLo, SrcHi);
152 // Get the expanded parts of each of SrcLo and SrcHi.
153 SDValue SrcLo1, SrcLo2, SrcHi1, SrcHi2;
154 GetExpandedParts(SrcLo, DAG, SrcLo1, SrcLo2);
155 GetExpandedParts(SrcHi, DAG, SrcHi1, SrcHi2);
157 SDValue ChainLo = Chain, ChainHi = Chain;
158 if (Chain.getOpcode() == ISD::TokenFactor) {
159 ChainLo = Chain.getOperand(0);
160 ChainHi = Chain.getOperand(1);
162 SDValue ChainLo1 = ChainLo, ChainLo2 = ChainLo, ChainHi1 = ChainHi,
164 if (ChainLo.getOpcode() == ISD::TokenFactor) {
165 ChainLo1 = ChainLo.getOperand(0);
166 ChainLo2 = ChainLo.getOperand(1);
168 if (ChainHi.getOpcode() == ISD::TokenFactor) {
169 ChainHi1 = ChainHi.getOperand(0);
170 ChainHi2 = ChainHi.getOperand(1);
172 SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other,
174 SrcLo1, PtrLo, PtrHi,
175 DAG.getConstant (0 + StoreOffset, MVT::i8));
177 SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainLo2,
178 SrcLo2, PtrLo, PtrHi,
179 DAG.getConstant (1 + StoreOffset, MVT::i8));
181 SDValue Store3 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi1,
182 SrcHi1, PtrLo, PtrHi,
183 DAG.getConstant (2 + StoreOffset, MVT::i8));
185 SDValue Store4 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi2,
186 SrcHi2, PtrLo, PtrHi,
187 DAG.getConstant (3 + StoreOffset, MVT::i8));
189 SDValue RetLo = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1),
191 SDValue RetHi = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store3),
193 return DAG.getNode(ISD::TokenFactor, MVT::Other, RetLo, RetHi).getNode();
197 assert (0 && "value type not supported");
201 // ExpandGlobalAddress -
202 SDNode *PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) {
203 GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(SDValue(N, 0));
205 SDValue TGA = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i8,
208 SDValue Lo = DAG.getNode(PIC16ISD::Lo, MVT::i8, TGA);
209 SDValue Hi = DAG.getNode(PIC16ISD::Hi, MVT::i8, TGA);
211 SDValue BP = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, Lo, Hi);
215 bool PIC16TargetLowering::isDirectAddress(const SDValue &Op) {
216 assert (Op.getNode() != NULL && "Can't operate on NULL SDNode!!");
218 if (Op.getOpcode() == ISD::BUILD_PAIR) {
219 if (Op.getOperand(0).getOpcode() == PIC16ISD::Lo)
225 // Return true if DirectAddress is in ROM_SPACE
226 bool PIC16TargetLowering::isRomAddress(const SDValue &Op) {
228 // RomAddress is a GlobalAddress in ROM_SPACE_
229 // If the Op is not a GlobalAddress return NULL without checking
231 if (!isDirectAddress(Op))
234 // Its a GlobalAddress.
235 // It is BUILD_PAIR((PIC16Lo TGA), (PIC16Hi TGA)) and Op is BUILD_PAIR
236 SDValue TGA = Op.getOperand(0).getOperand(0);
237 GlobalAddressSDNode *GSDN = dyn_cast<GlobalAddressSDNode>(TGA);
238 const Type *ValueType = GSDN->getGlobal()->getType();
240 if (!isa<PointerType>(ValueType)) {
241 assert(0 && "TGA must be of a PointerType");
244 int AddrSpace = dyn_cast<PointerType>(ValueType)->getAddressSpace();
245 if (AddrSpace == PIC16ISD::ROM_SPACE)
248 // Any other address space return it false
252 // To extract chain value from the SDValue Nodes
253 // This function will help to maintain the chain extracting
254 // code at one place. In case of any change in future it will
255 // help maintain the code.
256 SDValue PIC16TargetLowering::getChain(SDValue &Op) {
257 SDValue Chain = Op.getValue(Op.getNode()->getNumValues() - 1);
259 // All nodes may not produce a chain. Therefore following assert
260 // verifies that the node is returning a chain only.
261 assert (Chain.getValueType() == MVT::Other && "Node does not have a chain");
266 void PIC16TargetLowering::GetExpandedParts(SDValue Op, SelectionDAG &DAG,
267 SDValue &Lo, SDValue &Hi) {
268 SDNode *N = Op.getNode();
269 unsigned NumValues = N->getNumValues();
270 std::vector<MVT> VTs;
272 std::vector<SDValue> Opers;
274 // EXTRACT_ELEMENT should have same number and type of values that the
275 // node replacing the EXTRACT_ELEMENT should have. (i.e. extracted element)
276 // Some nodes such as LOAD and PIC16Load have more than one values. In such
277 // cases EXTRACT_ELEMENT should have more than one values. Therefore creating
278 // vector of Values for EXTRACT_ELEMENT. This list will have same number of
279 // values as the extracted element will have.
281 for (unsigned i=0;i < NumValues; ++i) {
282 NewVT = getTypeToTransformTo(N->getValueType(i));
283 VTs.push_back(NewVT);
286 // extract the lo component
288 Opers.push_back(DAG.getConstant(0,MVT::i8));
289 Lo = DAG.getNode(ISD::EXTRACT_ELEMENT,VTs,&Opers[0],Opers.size());
291 // extract the hi component
294 Opers.push_back(DAG.getConstant(1,MVT::i8));
295 Hi = DAG.getNode(ISD::EXTRACT_ELEMENT,VTs,&Opers[0],Opers.size());
298 // This function legalizes the PIC16 Addresses. If the Pointer is
299 // -- Direct address variable residing
300 // --> then a Banksel for that variable will be created.
302 // --> then it will be treated as an indirect address.
303 // -- Indirect address
304 // --> then the address will be loaded into FSR
305 // -- ADD with constant operand
306 // --> then constant operand of ADD will be returned as Offset
307 // and non-constant operand of ADD will be treated as pointer.
308 // Returns the high and lo part of the address, and the offset(in case of ADD).
310 void PIC16TargetLowering:: LegalizeAddress(SDValue Ptr, SelectionDAG &DAG,
311 SDValue &Lo, SDValue &Hi,
314 // Offset, by default, should be 0
317 // If the pointer is ADD with constant,
318 // return the constant value as the offset
319 if (Ptr.getOpcode() == ISD::ADD) {
320 SDValue OperLeft = Ptr.getOperand(0);
321 SDValue OperRight = Ptr.getOperand(1);
322 if (OperLeft.getOpcode() == ISD::Constant) {
323 Offset = dyn_cast<ConstantSDNode>(OperLeft)->getZExtValue();
327 Offset = dyn_cast<ConstantSDNode>(OperRight)->getZExtValue();
331 if (isDirectAddress(Ptr) && !isRomAddress(Ptr)) {
332 // Direct addressing case for RAM variables. The Hi part is constant
333 // and the Lo part is the TGA itself.
334 Lo = Ptr.getOperand(0).getOperand(0);
336 // For direct addresses Hi is a constant. Value 1 for the constant
337 // signifies that banksel needs to generated for it. Value 0 for
338 // the constant signifies that banksel does not need to be generated
339 // for it. Mark it as 1 now and optimize later.
340 Hi = DAG.getConstant(1, MVT::i8);
344 // Indirect addresses. Get the hi and lo parts of ptr.
345 GetExpandedParts(Ptr, DAG, Lo, Hi);
347 // Put the hi and lo parts into FSR.
348 Lo = DAG.getNode(PIC16ISD::MTLO, MVT::i8, Lo);
349 Hi = DAG.getNode(PIC16ISD::MTHI, MVT::i8, Hi);
354 SDNode *PIC16TargetLowering::ExpandAdd(SDNode *N, SelectionDAG &DAG) {
355 SDValue OperLeft = N->getOperand(0);
356 SDValue OperRight = N->getOperand(1);
358 if((OperLeft.getOpcode() == ISD::Constant) ||
359 (OperRight.getOpcode() == ISD::Constant)) {
363 // These case are yet to be handled
367 SDNode *PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) {
368 LoadSDNode *LD = dyn_cast<LoadSDNode>(SDValue(N, 0));
369 SDValue Chain = LD->getChain();
370 SDValue Ptr = LD->getBasePtr();
372 SDValue Load, Offset;
375 SDValue PtrLo, PtrHi;
378 // Legalize direct/indirect addresses. This will give the lo and hi parts
379 // of the address and the offset.
380 LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, LoadOffset);
382 // Load from the pointer (direct address or FSR)
383 VT = N->getValueType(0);
384 unsigned NumLoads = VT.getSizeInBits() / 8;
385 std::vector<SDValue> PICLoads;
387 MVT MemVT = LD->getMemoryVT();
388 if(ISD::isNON_EXTLoad(N)) {
389 for (iter=0; iter<NumLoads ; ++iter) {
390 // Add the pointer offset if any
391 Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
392 Tys = DAG.getVTList(MVT::i8, MVT::Other);
393 Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Chain, PtrLo, PtrHi,
395 PICLoads.push_back(Load);
398 // If it is extended load then use PIC16Load for Memory Bytes
399 // and for all extended bytes perform action based on type of
400 // extention - i.e. SignExtendedLoad or ZeroExtendedLoad
403 // For extended loads this is the memory value type
404 // i.e. without any extension
405 MVT MemVT = LD->getMemoryVT();
406 unsigned MemBytes = MemVT.getSizeInBits() / 8;
407 unsigned ExtdBytes = VT.getSizeInBits() / 8;
408 Offset = DAG.getConstant(LoadOffset, MVT::i8);
410 Tys = DAG.getVTList(MVT::i8, MVT::Other);
411 // For MemBytes generate PIC16Load with proper offset
412 for (iter=0; iter<MemBytes; ++iter) {
413 // Add the pointer offset if any
414 Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
415 Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Chain, PtrLo, PtrHi,
417 PICLoads.push_back(Load);
420 // For SignExtendedLoad
421 if (ISD::isSEXTLoad(N)) {
422 // For all ExtdBytes use the Right Shifted(Arithmetic) Value of the
424 SDValue SRA = DAG.getNode(ISD::SRA, MVT::i8, Load,
425 DAG.getConstant(7, MVT::i8));
426 for (iter=MemBytes; iter<ExtdBytes; ++iter) {
427 PICLoads.push_back(SRA);
429 } else if (ISD::isZEXTLoad(N)) {
430 // ZeroExtendedLoad -- For all ExtdBytes use constant 0
431 SDValue ConstZero = DAG.getConstant(0, MVT::i8);
432 for (iter=MemBytes; iter<ExtdBytes; ++iter) {
433 PICLoads.push_back(ConstZero);
440 // Operand of Load is illegal -- Load itself is legal
441 return PICLoads[0].getNode();
443 else if (VT == MVT::i16) {
444 BP = DAG.getNode(ISD::BUILD_PAIR, VT, PICLoads[0], PICLoads[1]);
445 if (MemVT == MVT::i8)
446 Chain = getChain(PICLoads[0]);
448 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]),
449 getChain(PICLoads[1]));
450 } else if (VT == MVT::i32) {
452 BPs[0] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[0], PICLoads[1]);
453 BPs[1] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[2], PICLoads[3]);
454 BP = DAG.getNode(ISD::BUILD_PAIR, VT, BPs[0], BPs[1]);
455 if (MemVT == MVT::i8)
456 Chain = getChain(PICLoads[0]);
457 else if (MemVT == MVT::i16)
458 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]),
459 getChain(PICLoads[1]));
462 Chains[0] = DAG.getNode(ISD::TokenFactor, MVT::Other,
463 getChain(PICLoads[0]), getChain(PICLoads[1]));
464 Chains[1] = DAG.getNode(ISD::TokenFactor, MVT::Other,
465 getChain(PICLoads[2]), getChain(PICLoads[3]));
466 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Chains[0], Chains[1]);
469 Tys = DAG.getVTList(VT, MVT::Other);
470 SDValue MergeV = DAG.getNode(ISD::MERGE_VALUES, Tys, BP, Chain);
471 return MergeV.getNode();
475 SDNode *PIC16TargetLowering::ExpandShift(SDNode *N, SelectionDAG &DAG) {
476 SDValue Value = N->getOperand(0);
477 SDValue Amt = N->getOperand(1);
478 SDValue BCF, BCFInput;
480 SDValue ShfCom; // Shift Component - Lo component should be shifted
481 SDValue RotCom; // Rotate Component- Hi component should be rotated
482 PIC16ISD::NodeType ShfNode = PIC16ISD::Dummy, RotNode = PIC16ISD::Dummy;
484 // Currently handling Constant shift only
485 if (Amt.getOpcode() != ISD::Constant)
488 // Following code considers 16 bit left-shift only
489 if (N->getValueType(0) != MVT::i16)
492 if (N->getOpcode() == ISD::SHL) {
493 ShfNode = PIC16ISD::LSLF;
494 RotNode = PIC16ISD::RLF;
495 } else if (N->getOpcode() == ISD::SRL) {
496 ShfNode = PIC16ISD::LRLF;
497 RotNode = PIC16ISD::RRF;
499 unsigned ShiftAmt = dyn_cast<ConstantSDNode>(Amt)->getZExtValue();
500 SDValue StatusReg = DAG.getRegister(PIC16::STATUS, MVT::i8);
501 // 0th Bit in StatusReg is CarryBit
502 SDValue CarryBit= DAG.getConstant(0, MVT::i8);
504 GetExpandedParts(Value, DAG, ShfCom, RotCom);
505 BCFInput = DAG.getNode(PIC16ISD::Dummy, MVT::Flag);
506 Tys = DAG.getVTList(MVT::i8, MVT::Flag);
508 for (unsigned i=0;i<ShiftAmt;i++) {
509 BCF = DAG.getNode(PIC16ISD::BCF, MVT::Flag, StatusReg, CarryBit, BCFInput);
511 // Following are Two-Address Instructions
512 ShfCom = DAG.getNode(ShfNode, Tys, ShfCom, BCF);
513 RotCom = DAG.getNode(RotNode, Tys, RotCom, ShfCom.getValue(1));
515 BCFInput = RotCom.getValue(1);
518 SDValue BP = DAG.getNode(ISD::BUILD_PAIR, N->getValueType(0), ShfCom, RotCom);
522 SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
523 switch (Op.getOpcode()) {
524 case ISD::FORMAL_ARGUMENTS:
525 return LowerFORMAL_ARGUMENTS(Op, DAG);
527 return LowerADDC(Op, DAG);
529 return LowerADDE(Op, DAG);
531 return LowerSUBE(Op, DAG);
533 return LowerSUBC(Op, DAG);
535 return SDValue(ExpandLoad(Op.getNode(), DAG), Op.getResNo());
537 return SDValue(ExpandStore(Op.getNode(), DAG), Op.getResNo());
539 return SDValue(ExpandShift(Op.getNode(), DAG), Op.getResNo());
543 return LowerBinOp(Op, DAG);
548 SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op,
551 assert (Op.getValueType() == MVT::i8
552 && "illegal value type to store on stack.");
554 MachineFunction &MF = DAG.getMachineFunction();
555 const Function *Func = MF.getFunction();
556 const std::string FuncName = Func->getName();
558 char *tmpName = new char [strlen(FuncName.c_str()) + 6];
560 // Put the value on stack.
561 // Get a stack slot index and convert to es.
562 int FI = MF.getFrameInfo()->CreateStackObject(1, 1);
563 sprintf(tmpName, "%s.tmp", FuncName.c_str());
564 SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
566 // Store the value to ES.
567 SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, MVT::Other,
570 DAG.getConstant (1, MVT::i8), // Banksel.
571 DAG.getConstant (FI, MVT::i8));
573 // Load the value from ES.
574 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other);
575 SDValue Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Store,
576 ES, DAG.getConstant (1, MVT::i8),
577 DAG.getConstant (FI, MVT::i8));
579 return Load.getValue(0);
582 SDValue PIC16TargetLowering:: LowerBinOp(SDValue Op, SelectionDAG &DAG) {
583 // We should have handled larger operands in type legalizer itself.
584 assert (Op.getValueType() == MVT::i8 && "illegal Op to lower");
586 // Return the original Op if the one of the operands is already a load.
587 if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load
588 || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load)
591 // Put one value on stack.
592 SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG);
594 return DAG.getNode(Op.getOpcode(), MVT::i8, Op.getOperand(0), NewVal);
597 SDValue PIC16TargetLowering:: LowerADDC(SDValue Op, SelectionDAG &DAG) {
598 // We should have handled larger operands in type legalizer itself.
599 assert (Op.getValueType() == MVT::i8 && "illegal addc to lower");
601 // Nothing to do if the one of the operands is already a load.
602 if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load
603 || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load)
606 // Put one value on stack.
607 SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG);
609 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
610 return DAG.getNode(ISD::ADDC, Tys, Op.getOperand(0), NewVal);
613 SDValue PIC16TargetLowering:: LowerADDE(SDValue Op, SelectionDAG &DAG) {
614 // We should have handled larger operands in type legalizer itself.
615 assert (Op.getValueType() == MVT::i8 && "illegal adde to lower");
617 // Nothing to do if the one of the operands is already a load.
618 if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load
619 || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load)
622 // Put one value on stack.
623 SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG);
625 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
626 return DAG.getNode(ISD::ADDE, Tys, Op.getOperand(0), NewVal,
630 SDValue PIC16TargetLowering:: LowerSUBC(SDValue Op, SelectionDAG &DAG) {
631 // We should have handled larger operands in type legalizer itself.
632 assert (Op.getValueType() == MVT::i8 && "illegal subc to lower");
634 // Nothing to do if the first operand is already a load.
635 if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load)
638 // Put first operand on stack.
639 SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG);
641 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
642 return DAG.getNode(ISD::SUBC, Tys, NewVal, Op.getOperand(1));
645 SDValue PIC16TargetLowering:: LowerSUBE(SDValue Op, SelectionDAG &DAG) {
646 // We should have handled larger operands in type legalizer itself.
647 assert (Op.getValueType() == MVT::i8 && "illegal sube to lower");
649 // Nothing to do if the first operand is already a load.
650 if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load)
653 // Put first operand on stack.
654 SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG);
656 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
657 return DAG.getNode(ISD::SUBE, Tys, NewVal, Op.getOperand(1),
661 // LowerFORMAL_ARGUMENTS - In Lowering FORMAL ARGUMENTS - MERGE_VALUES nodes
662 // is returned. MERGE_VALUES nodes number of operands and number of values are
663 // equal. Therefore to construct MERGE_VALUE node, UNDEF nodes equal to the
664 // number of arguments of function have been created.
666 SDValue PIC16TargetLowering:: LowerFORMAL_ARGUMENTS(SDValue Op,
668 SmallVector<SDValue, 8> ArgValues;
669 unsigned NumArgs = Op.getNumOperands() - 3;
671 // Creating UNDEF nodes to meet the requirement of MERGE_VALUES node.
672 for(unsigned i = 0 ; i<NumArgs ; i++) {
673 SDValue TempNode = DAG.getNode(ISD::UNDEF, Op.getNode()->getValueType(i));
674 ArgValues.push_back(TempNode);
677 ArgValues.push_back(Op.getOperand(0));
678 return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(),
680 ArgValues.size()).getValue(Op.getResNo());
683 // Perform DAGCombine of PIC16Load
684 SDValue PIC16TargetLowering::
685 PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const {
686 SelectionDAG &DAG = DCI.DAG;
687 SDValue Chain = N->getOperand(0);
688 if (N->hasNUsesOfValue(0, 0)) {
689 DAG.ReplaceAllUsesOfValueWith(SDValue(N,1), Chain);
695 SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N,
696 DAGCombinerInfo &DCI) const {
697 switch (N->getOpcode()) {
698 case PIC16ISD::PIC16Load:
699 return PerformPIC16LoadCombine(N, DCI);