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/Function.h"
21 #include "llvm/Intrinsics.h"
22 #include "llvm/CallingConv.h"
23 #include "llvm/CodeGen/CallingConvLower.h"
24 #include "llvm/CodeGen/MachineFrameInfo.h"
25 #include "llvm/CodeGen/MachineFunction.h"
26 #include "llvm/CodeGen/MachineInstrBuilder.h"
27 #include "llvm/CodeGen/MachineRegisterInfo.h"
28 #include "llvm/CodeGen/SelectionDAGISel.h"
29 #include "llvm/CodeGen/ValueTypes.h"
30 #include "llvm/Support/Debug.h"
36 const char *PIC16TargetLowering:: getTargetNodeName(unsigned Opcode) const
39 case PIC16ISD::Hi : return "PIC16ISD::Hi";
40 case PIC16ISD::Lo : return "PIC16ISD::Lo";
41 case PIC16ISD::Package : return "PIC16ISD::Package";
42 case PIC16ISD::Wrapper : return "PIC16ISD::Wrapper";
43 case PIC16ISD::SetBank : return "PIC16ISD::SetBank";
44 case PIC16ISD::SetPage : return "PIC16ISD::SetPage";
45 case PIC16ISD::Branch : return "PIC16ISD::Branch";
46 case PIC16ISD::Cmp : return "PIC16ISD::Cmp";
47 case PIC16ISD::BTFSS : return "PIC16ISD::BTFSS";
48 case PIC16ISD::BTFSC : return "PIC16ISD::BTFSC";
49 case PIC16ISD::XORCC : return "PIC16ISD::XORCC";
50 case PIC16ISD::SUBCC : return "PIC16ISD::SUBCC";
51 default : return NULL;
56 PIC16TargetLowering(PIC16TargetMachine &TM): TargetLowering(TM)
58 // Set up the register classes.
59 addRegisterClass(MVT::i8, PIC16::CPURegsRegisterClass);
60 addRegisterClass(MVT::i16, PIC16::PTRRegsRegisterClass);
62 // Load extented operations for i1 types must be promoted .
63 setLoadXAction(ISD::EXTLOAD, MVT::i1, Promote);
64 setLoadXAction(ISD::ZEXTLOAD, MVT::i1, Promote);
65 setLoadXAction(ISD::SEXTLOAD, MVT::i1, Promote);
67 setOperationAction(ISD::ADD, MVT::i1, Promote);
68 setOperationAction(ISD::ADD, MVT::i8, Legal);
69 setOperationAction(ISD::ADD, MVT::i16, Custom);
70 setOperationAction(ISD::ADD, MVT::i32, Expand);
71 setOperationAction(ISD::ADD, MVT::i64, Expand);
73 setOperationAction(ISD::SUB, MVT::i1, Promote);
74 setOperationAction(ISD::SUB, MVT::i8, Legal);
75 setOperationAction(ISD::SUB, MVT::i16, Custom);
76 setOperationAction(ISD::SUB, MVT::i32, Expand);
77 setOperationAction(ISD::SUB, MVT::i64, Expand);
79 setOperationAction(ISD::ADDC, MVT::i1, Promote);
80 setOperationAction(ISD::ADDC, MVT::i8, Legal);
81 setOperationAction(ISD::ADDC, MVT::i16, Custom);
82 setOperationAction(ISD::ADDC, MVT::i32, Expand);
83 setOperationAction(ISD::ADDC, MVT::i64, Expand);
85 setOperationAction(ISD::ADDE, MVT::i1, Promote);
86 setOperationAction(ISD::ADDE, MVT::i8, Legal);
87 setOperationAction(ISD::ADDE, MVT::i16, Custom);
88 setOperationAction(ISD::ADDE, MVT::i32, Expand);
89 setOperationAction(ISD::ADDE, MVT::i64, Expand);
91 setOperationAction(ISD::SUBC, MVT::i1, Promote);
92 setOperationAction(ISD::SUBC, MVT::i8, Legal);
93 setOperationAction(ISD::SUBC, MVT::i16, Custom);
94 setOperationAction(ISD::SUBC, MVT::i32, Expand);
95 setOperationAction(ISD::SUBC, MVT::i64, Expand);
97 setOperationAction(ISD::SUBE, MVT::i1, Promote);
98 setOperationAction(ISD::SUBE, MVT::i8, Legal);
99 setOperationAction(ISD::SUBE, MVT::i16, Custom);
100 setOperationAction(ISD::SUBE, MVT::i32, Expand);
101 setOperationAction(ISD::SUBE, MVT::i64, Expand);
103 // PIC16 does not have these NodeTypes below.
104 setOperationAction(ISD::SETCC, MVT::i1, Expand);
105 setOperationAction(ISD::SETCC, MVT::i8, Expand);
106 setOperationAction(ISD::SETCC, MVT::Other, Expand);
107 setOperationAction(ISD::SELECT_CC, MVT::i1, Custom);
108 setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);
110 setOperationAction(ISD::BRCOND, MVT::i1, Expand);
111 setOperationAction(ISD::BRCOND, MVT::i8, Expand);
112 setOperationAction(ISD::BRCOND, MVT::Other, Expand);
114 setOperationAction(ISD::BR_CC, MVT::i1, Custom);
115 setOperationAction(ISD::BR_CC, MVT::i8, Custom);
117 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
120 // FIXME: Do we really need to Custom lower the GA ??
121 setOperationAction(ISD::GlobalAddress, MVT::i8, Custom);
122 setOperationAction(ISD::RET, MVT::Other, Custom);
124 setOperationAction(ISD::CTPOP, MVT::i32, Expand);
125 setOperationAction(ISD::CTTZ, MVT::i32, Expand);
126 setOperationAction(ISD::CTLZ, MVT::i32, Expand);
127 setOperationAction(ISD::ROTL, MVT::i32, Expand);
128 setOperationAction(ISD::ROTR, MVT::i32, Expand);
129 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
131 setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
132 setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
133 setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
135 // We don't have line number support yet.
136 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
137 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
138 setOperationAction(ISD::DBG_LABEL, MVT::Other, Expand);
139 setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
141 // Use the default for now.
142 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
143 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
145 setOperationAction(ISD::LOAD, MVT::i1, Promote);
146 setOperationAction(ISD::LOAD, MVT::i8, Legal);
148 setTargetDAGCombine(ISD::LOAD);
149 setTargetDAGCombine(ISD::STORE);
150 setTargetDAGCombine(ISD::ADDE);
151 setTargetDAGCombine(ISD::ADDC);
152 setTargetDAGCombine(ISD::ADD);
153 setTargetDAGCombine(ISD::SUBE);
154 setTargetDAGCombine(ISD::SUBC);
155 setTargetDAGCombine(ISD::SUB);
157 setStackPointerRegisterToSaveRestore(PIC16::STKPTR);
158 computeRegisterProperties();
162 SDValue PIC16TargetLowering:: LowerOperation(SDValue Op, SelectionDAG &DAG)
164 SDVTList VTList16 = DAG.getVTList(MVT::i16, MVT::i16, MVT::Other);
165 switch (Op.getOpcode()) {
167 DOUT << "reduce store\n";
170 case ISD::FORMAL_ARGUMENTS:
171 DOUT << "==== lowering formal args\n";
172 return LowerFORMAL_ARGUMENTS(Op, DAG);
174 case ISD::GlobalAddress:
175 DOUT << "==== lowering GA\n";
176 return LowerGlobalAddress(Op, DAG);
179 DOUT << "==== lowering ret\n";
180 return LowerRET(Op, DAG);
182 case ISD::FrameIndex:
183 DOUT << "==== lowering frame index\n";
184 return LowerFrameIndex(Op, DAG);
187 DOUT << "==== lowering adde\n";
195 DOUT << "==== lowering BR_CC\n";
196 return LowerBR_CC(Op, DAG);
202 //===----------------------------------------------------------------------===//
203 // Lower helper functions
204 //===----------------------------------------------------------------------===//
206 SDValue PIC16TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG)
208 MVT VT = Op.getValueType();
209 SDValue Chain = Op.getOperand(0);
210 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
211 SDValue LHS = Op.getOperand(2);
212 SDValue RHS = Op.getOperand(3);
213 SDValue JumpVal = Op.getOperand(4);
216 unsigned branchOpcode;
217 SDValue branchOperand;
219 SDValue StatusReg = DAG.getRegister(PIC16::STATUSREG, MVT::i8);
220 SDValue CPUReg = DAG.getRegister(PIC16::WREG, MVT::i8);
223 assert(0 && "This condition code is not handled yet!!");
228 cmpOpcode = PIC16ISD::XORCC;
229 branchOpcode = PIC16ISD::BTFSS;
230 branchOperand = DAG.getConstant(2, MVT::i8);
235 cmpOpcode = PIC16ISD::XORCC;
236 branchOpcode = PIC16ISD::BTFSC;
237 branchOperand = DAG.getConstant(2, MVT::i8);
241 assert(0 && "Greater Than condition code is not handled yet!!");
247 cmpOpcode = PIC16ISD::SUBCC;
248 branchOpcode = PIC16ISD::BTFSS;
249 branchOperand = DAG.getConstant(1, MVT::i8);
254 cmpOpcode = PIC16ISD::SUBCC;
255 branchOpcode = PIC16ISD::BTFSC;
256 branchOperand = DAG.getConstant(1,MVT::i8);
260 assert(0 && "Less Than Equal condition code is not handled yet!!");
265 SDVTList VTList = DAG.getVTList(MVT::i8, MVT::Flag);
266 SDValue CmpValue = DAG.getNode(cmpOpcode, VTList, LHS, RHS).getValue(1);
267 Result = DAG.getNode(branchOpcode, VT, Chain, JumpVal, branchOperand,
268 StatusReg, CmpValue);
273 //===----------------------------------------------------------------------===//
274 // Misc Lower Operation implementation
275 //===----------------------------------------------------------------------===//
277 // LowerGlobalAddress - Create a constant pool entry for global value
278 // and wrap it in a wrapper node.
280 PIC16TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG)
282 MVT PtrVT = getPointerTy();
283 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
284 GlobalValue *GV = GSDN->getGlobal();
286 // FIXME: for now only do the ram.
287 SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 2);
288 SDValue CPBank = DAG.getNode(PIC16ISD::SetBank, MVT::i8, CPAddr);
289 CPAddr = DAG.getNode(PIC16ISD::Wrapper, MVT::i8, CPAddr,CPBank);
295 PIC16TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG)
297 switch(Op.getNumOperands()) {
299 assert(0 && "Do not know how to return this many arguments!");
303 return SDValue(); // ret void is legal
308 PIC16TargetLowering::LowerFrameIndex(SDValue N, SelectionDAG &DAG)
310 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N)) {
311 return DAG.getTargetFrameIndex(FIN->getIndex(), MVT::i32);
318 PIC16TargetLowering::LowerLOAD(SDNode *N,
320 DAGCombinerInfo &DCI) const
323 SDValue TF; //TokenFactor
324 SDValue OutChains[2];
325 SDValue Chain = N->getOperand(0);
326 SDValue Src = N->getOperand(1);
330 // If this load is directly stored, replace the load value with the stored
332 // FIXME: Handle store large -> read small portion.
333 // FIXME: Handle TRUNCSTORE/LOADEXT
334 LoadSDNode *LD = cast<LoadSDNode>(N);
335 SDValue Ptr = LD->getBasePtr();
336 if (LD->getExtensionType() == ISD::NON_EXTLOAD) {
337 if (ISD::isNON_TRUNCStore(Chain.getNode())) {
338 StoreSDNode *PrevST = cast<StoreSDNode>(Chain);
339 if (PrevST->getBasePtr() == Ptr &&
340 PrevST->getValue().getValueType() == N->getValueType(0))
341 return DCI.CombineTo(N, Chain.getOperand(1), Chain);
345 if (N->getValueType(0) != MVT::i16)
349 Outs[0] = DAG.getLoad(MVT::i8, Chain, Src, NULL, 0);
350 toWorklist = DAG.getNode(ISD::ADD, MVT::i16, Src,
351 DAG.getConstant(1, MVT::i16));
352 Outs[1] = DAG.getLoad(MVT::i8, Chain, toWorklist, NULL, 0);
353 // FIXME: Add to worklist may not be needed.
354 // It is meant to merge sequences of add with constant into one.
355 DCI.AddToWorklist(toWorklist.getNode());
357 // Create the tokenfactors and carry it on to the build_pair node
358 OutChains[0] = Outs[0].getValue(1);
359 OutChains[1] = Outs[1].getValue(1);
360 TF = DAG.getNode(ISD::TokenFactor, MVT::Other, &OutChains[0], 2);
362 VTList = DAG.getVTList(MVT::i16, MVT::Flag);
363 retVal = DAG.getNode (PIC16ISD::Package, VTList, &Outs[0], 2);
365 DCI.CombineTo (N, retVal, TF);
371 PIC16TargetLowering::LowerADDSUB(SDNode *N, SelectionDAG &DAG,
372 DAGCombinerInfo &DCI) const
374 bool changed = false;
376 SDValue LoOps[3], HiOps[3];
377 SDValue OutOps[3]; // [0]:left, [1]:right, [2]:carry
382 unsigned AS = 0, ASE = 0, ASC=0;
384 InOp[0] = N->getOperand(0);
385 InOp[1] = N->getOperand(1);
387 switch (N->getOpcode()) {
389 if (InOp[0].getOpcode() == ISD::Constant &&
390 InOp[1].getOpcode() == ISD::Constant) {
391 ConstantSDNode *CST0 = dyn_cast<ConstantSDNode>(InOp[0]);
392 ConstantSDNode *CST1 = dyn_cast<ConstantSDNode>(InOp[1]);
393 return DAG.getConstant(CST0->getValue() + CST1->getValue(), MVT::i16);
405 if (InOp[0].getOpcode() == ISD::Constant &&
406 InOp[1].getOpcode() == ISD::Constant) {
407 ConstantSDNode *CST0 = dyn_cast<ConstantSDNode>(InOp[0]);
408 ConstantSDNode *CST1 = dyn_cast<ConstantSDNode>(InOp[1]);
409 return DAG.getConstant(CST0->getValue() - CST1->getValue(), MVT::i16);
421 assert ((N->getValueType(0) == MVT::i16)
422 && "expecting an MVT::i16 node for lowering");
423 assert ((N->getOperand(0).getValueType() == MVT::i16)
424 && (N->getOperand(1).getValueType() == MVT::i16)
425 && "both inputs to addx/subx:i16 must be i16");
427 for (i = 0; i < 2; i++) {
428 if (InOp[i].getOpcode() == ISD::GlobalAddress) {
429 // We don't want to lower subs/adds with global address yet.
432 else if (InOp[i].getOpcode() == ISD::Constant) {
434 ConstantSDNode *CST = dyn_cast<ConstantSDNode>(InOp[i]);
435 LoOps[i] = DAG.getConstant(CST->getValue() & 0xFF, MVT::i8);
436 HiOps[i] = DAG.getConstant(CST->getValue() >> 8, MVT::i8);
438 else if (InOp[i].getOpcode() == PIC16ISD::Package) {
439 LoOps[i] = InOp[i].getOperand(0);
440 HiOps[i] = InOp[i].getOperand(1);
442 else if (InOp[i].getOpcode() == ISD::LOAD) {
444 // LowerLOAD returns a Package node or it may combine and return
446 SDValue lowered = LowerLOAD(InOp[i].getNode(), DAG, DCI);
448 // So If LowerLOAD returns something other than Package,
449 // then just call ADD again.
450 if (lowered.getOpcode() != PIC16ISD::Package)
451 return LowerADDSUB(N, DAG, DCI);
453 LoOps[i] = lowered.getOperand(0);
454 HiOps[i] = lowered.getOperand(1);
456 else if ((InOp[i].getOpcode() == ISD::ADD) ||
457 (InOp[i].getOpcode() == ISD::ADDE) ||
458 (InOp[i].getOpcode() == ISD::ADDC) ||
459 (InOp[i].getOpcode() == ISD::SUB) ||
460 (InOp[i].getOpcode() == ISD::SUBE) ||
461 (InOp[i].getOpcode() == ISD::SUBC)) {
463 // Must call LowerADDSUB recursively here,
464 // LowerADDSUB returns a Package node.
465 SDValue lowered = LowerADDSUB(InOp[i].getNode(), DAG, DCI);
467 LoOps[i] = lowered.getOperand(0);
468 HiOps[i] = lowered.getOperand(1);
470 else if (InOp[i].getOpcode() == ISD::SIGN_EXTEND) {
471 // FIXME: I am just zero extending. for now.
473 LoOps[i] = InOp[i].getOperand(0);
474 HiOps[i] = DAG.getConstant(0, MVT::i8);
477 DAG.setGraphColor(N, "blue");
479 assert (0 && "not implemented yet");
483 assert (changed && "nothing changed while lowering SUBx/ADDx");
485 VTList = DAG.getVTList(MVT::i8, MVT::Flag);
486 if (N->getOpcode() == ASE) {
487 // We must take in the existing carry
488 // if this node is part of an existing subx/addx sequence.
489 LoOps[2] = N->getOperand(2).getValue(1);
490 as1 = DAG.getNode (ASE, VTList, LoOps, 3);
493 as1 = DAG.getNode (ASC, VTList, LoOps, 2);
495 HiOps[2] = as1.getValue(1);
496 as2 = DAG.getNode (ASE, VTList, HiOps, 3);
497 // We must build a pair that also provides the carry from sube/adde.
500 OutOps[2] = as2.getValue(1);
501 // Breaking an original i16, so lets make the Package also an i16.
502 if (N->getOpcode() == ASE) {
503 VTList = DAG.getVTList(MVT::i16, MVT::Flag);
504 retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 3);
505 DCI.CombineTo (N, retVal, OutOps[2]);
507 else if (N->getOpcode() == ASC) {
508 VTList = DAG.getVTList(MVT::i16, MVT::Flag);
509 retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 2);
510 DCI.CombineTo (N, retVal, OutOps[2]);
512 else if (N->getOpcode() == AS) {
513 VTList = DAG.getVTList(MVT::i16);
514 retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 2);
515 DCI.CombineTo (N, retVal);
522 //===----------------------------------------------------------------------===//
523 // Calling Convention Implementation
524 //===----------------------------------------------------------------------===//
526 #include "PIC16GenCallingConv.inc"
528 //===----------------------------------------------------------------------===//
529 // CALL Calling Convention Implementation
530 //===----------------------------------------------------------------------===//
533 //===----------------------------------------------------------------------===//
534 // FORMAL_ARGUMENTS Calling Convention Implementation
535 //===----------------------------------------------------------------------===//
536 SDValue PIC16TargetLowering::
537 LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG)
539 SmallVector<SDValue, 8> ArgValues;
540 SDValue Root = Op.getOperand(0);
542 // Return the new list of results.
543 // FIXME: Just copy right now.
544 ArgValues.push_back(Root);
546 return DAG.getMergeValues(Op.getNode()->getVTList(), &ArgValues[0],
547 ArgValues.size()).getValue(Op.getResNo());
551 //===----------------------------------------------------------------------===//
552 // Return Value Calling Convention Implementation
553 //===----------------------------------------------------------------------===//
555 //===----------------------------------------------------------------------===//
556 // PIC16 Inline Assembly Support
557 //===----------------------------------------------------------------------===//
559 //===----------------------------------------------------------------------===//
560 // Target Optimization Hooks
561 //===----------------------------------------------------------------------===//
563 SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N,
564 DAGCombinerInfo &DCI) const
568 SelectionDAG &DAG = DCI.DAG;
570 switch (N->getOpcode()) {
574 case PIC16ISD::Package:
575 DOUT << "==== combining PIC16ISD::Package\n";
580 if ((N->getOperand(0).getOpcode() == ISD::GlobalAddress) ||
581 (N->getOperand(0).getOpcode() == ISD::FrameIndex)) {
582 // Do not touch pointer adds.
591 if (N->getValueType(0) == MVT::i16) {
592 SDValue retVal = LowerADDSUB(N, DAG,DCI);
593 // LowerADDSUB has already combined the result,
594 // so we just return nothing to avoid assertion failure from llvm
595 // if N has been deleted already.
598 else if (N->getValueType(0) == MVT::i8) {
600 for (int i=0; i<2; i++) {
601 if (N->getOperand (i).getOpcode() == PIC16ISD::Package) {
603 "don't want to have PIC16ISD::Package as intput to add:i8");
609 // FIXME: split this large chunk of code.
612 SDValue Chain = N->getOperand(0);
613 SDValue Src = N->getOperand(1);
614 SDValue Dest = N->getOperand(2);
615 unsigned int DstOff = 0;
619 // if source operand is expected to be extended to
620 // some higher type then - remove this extension
621 // SDNode and do the extension manually
622 if ((Src.getOpcode() == ISD::ANY_EXTEND) ||
623 (Src.getOpcode() == ISD::SIGN_EXTEND) ||
624 (Src.getOpcode() == ISD::ZERO_EXTEND)) {
625 Src = Src.getNode()->getOperand(0);
626 Stores[0] = DAG.getStore(Chain, Src, Dest, NULL,0);
630 switch(Src.getValueType().getSimpleVT()) {
632 assert(false && "Invalid value type!");
650 if (isa<GlobalAddressSDNode>(Dest) && isa<LoadSDNode>(Src) &&
651 (Src.getValueType() != MVT::i8)) {
652 //create direct addressing a = b
653 Chain = Src.getOperand(0);
654 for (i=0; i<NUM_STORES; i++) {
655 SDValue ADN = DAG.getNode(ISD::ADD, MVT::i16, Src.getOperand(1),
656 DAG.getConstant(DstOff, MVT::i16));
657 SDValue LDN = DAG.getLoad(MVT::i8, Chain, ADN, NULL, 0);
658 SDValue DSTADDR = DAG.getNode(ISD::ADD, MVT::i16, Dest,
659 DAG.getConstant(DstOff, MVT::i16));
660 Stores[i] = DAG.getStore(Chain, LDN, DSTADDR, NULL, 0);
665 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i);
668 else if (isa<GlobalAddressSDNode>(Dest) && isa<ConstantSDNode>(Src)
669 && (Src.getValueType() != MVT::i8)) {
670 //create direct addressing a = CONST
671 CST = dyn_cast<ConstantSDNode>(Src);
672 for (i = 0; i < NUM_STORES; i++) {
673 SDValue CNST = DAG.getConstant(CST->getValue() >> i*8, MVT::i8);
674 SDValue ADN = DAG.getNode(ISD::ADD, MVT::i16, Dest,
675 DAG.getConstant(DstOff, MVT::i16));
676 Stores[i] = DAG.getStore(Chain, CNST, ADN, NULL, 0);
681 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i);
684 else if (isa<LoadSDNode>(Dest) && isa<ConstantSDNode>(Src)
685 && (Src.getValueType() != MVT::i8)) {
686 // Create indirect addressing.
687 CST = dyn_cast<ConstantSDNode>(Src);
688 Chain = Dest.getOperand(0);
690 Load = DAG.getLoad(MVT::i16, Chain,Dest.getOperand(1), NULL, 0);
691 Chain = Load.getValue(1);
692 for (i=0; i<NUM_STORES; i++) {
693 SDValue CNST = DAG.getConstant(CST->getValue() >> i*8, MVT::i8);
694 Stores[i] = DAG.getStore(Chain, CNST, Load, NULL, 0);
699 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i);
702 else if (isa<LoadSDNode>(Dest) && isa<GlobalAddressSDNode>(Src)) {
703 // GlobalAddressSDNode *GAD = dyn_cast<GlobalAddressSDNode>(Src);
706 else if (Src.getOpcode() == PIC16ISD::Package) {
707 StoreSDNode *st = dyn_cast<StoreSDNode>(N);
708 SDValue toWorkList, retVal;
709 Chain = N->getOperand(0);
711 if (st->isTruncatingStore()) {
712 retVal = DAG.getStore(Chain, Src.getOperand(0), Dest, NULL, 0);
715 toWorkList = DAG.getNode(ISD::ADD, MVT::i16, Dest,
716 DAG.getConstant(1, MVT::i16));
717 Stores[1] = DAG.getStore(Chain, Src.getOperand(0), Dest, NULL, 0);
718 Stores[0] = DAG.getStore(Chain, Src.getOperand(1), toWorkList, NULL,
721 // We want to merge sequence of add with constant to one add and a
722 // constant, so add the ADD node to worklist to have llvm do that
724 DCI.AddToWorklist(toWorkList.getNode());
726 // We don't need the Package so add to worklist so llvm deletes it
727 DCI.AddToWorklist(Src.getNode());
728 retVal = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], 2);
733 else if (Src.getOpcode() == ISD::TRUNCATE) {
742 SDValue Ptr = N->getOperand(1);
743 if (Ptr.getOpcode() == PIC16ISD::Package) {
744 assert (0 && "not implemented yet");
753 //===----------------------------------------------------------------------===//
755 //===----------------------------------------------------------------------===//
756 const SDValue *PIC16TargetLowering::
757 findLoadi8(const SDValue &Src, SelectionDAG &DAG) const
760 if ((Src.getOpcode() == ISD::LOAD) && (Src.getValueType() == MVT::i8))
762 for (i=0; i<Src.getNumOperands(); i++) {
763 const SDValue *retVal = findLoadi8(Src.getOperand(i),DAG);
764 if (retVal) return retVal;