blob: ed3c64576246dbe68dea9fe7e6836b53ca61cb88 [file] [log] [blame]
Sanjiv Gupta0e687712008-05-13 09:02:57 +00001//===-- PIC16ISelLowering.cpp - PIC16 DAG Lowering Implementation ---------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the interfaces that PIC16 uses to lower LLVM code into a
11// selection DAG.
12//
13//===----------------------------------------------------------------------===//
14
15#define DEBUG_TYPE "pic16-lower"
16
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"
Sanjiv Gupta0e687712008-05-13 09:02:57 +000031using namespace llvm;
32
33const char *PIC16TargetLowering:: getTargetNodeName(unsigned Opcode) const
34{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000035 switch (Opcode) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +000036 case PIC16ISD::Hi : return "PIC16ISD::Hi";
37 case PIC16ISD::Lo : return "PIC16ISD::Lo";
38 case PIC16ISD::Package : return "PIC16ISD::Package";
39 case PIC16ISD::Wrapper : return "PIC16ISD::Wrapper";
40 case PIC16ISD::SetBank : return "PIC16ISD::SetBank";
41 case PIC16ISD::SetPage : return "PIC16ISD::SetPage";
42 case PIC16ISD::Branch : return "PIC16ISD::Branch";
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000043 case PIC16ISD::Cmp : return "PIC16ISD::Cmp";
Sanjiv Gupta0e687712008-05-13 09:02:57 +000044 case PIC16ISD::BTFSS : return "PIC16ISD::BTFSS";
45 case PIC16ISD::BTFSC : return "PIC16ISD::BTFSC";
46 case PIC16ISD::XORCC : return "PIC16ISD::XORCC";
47 case PIC16ISD::SUBCC : return "PIC16ISD::SUBCC";
48 default : return NULL;
49 }
50}
51
52PIC16TargetLowering::
53PIC16TargetLowering(PIC16TargetMachine &TM): TargetLowering(TM)
54{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000055 // Set up the register classes.
56 addRegisterClass(MVT::i8, PIC16::CPURegsRegisterClass);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000057 addRegisterClass(MVT::i16, PIC16::PTRRegsRegisterClass);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000058
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000059 // Load extented operations for i1 types must be promoted .
Evan Cheng03294662008-10-14 21:26:46 +000060 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
61 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
62 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000063
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000064 setOperationAction(ISD::ADD, MVT::i1, Promote);
65 setOperationAction(ISD::ADD, MVT::i8, Legal);
66 setOperationAction(ISD::ADD, MVT::i16, Custom);
67 setOperationAction(ISD::ADD, MVT::i32, Expand);
68 setOperationAction(ISD::ADD, MVT::i64, Expand);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000069
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000070 setOperationAction(ISD::SUB, MVT::i1, Promote);
71 setOperationAction(ISD::SUB, MVT::i8, Legal);
72 setOperationAction(ISD::SUB, MVT::i16, Custom);
73 setOperationAction(ISD::SUB, MVT::i32, Expand);
74 setOperationAction(ISD::SUB, MVT::i64, Expand);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000075
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000076 setOperationAction(ISD::ADDC, MVT::i1, Promote);
77 setOperationAction(ISD::ADDC, MVT::i8, Legal);
78 setOperationAction(ISD::ADDC, MVT::i16, Custom);
79 setOperationAction(ISD::ADDC, MVT::i32, Expand);
80 setOperationAction(ISD::ADDC, MVT::i64, Expand);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000081
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000082 setOperationAction(ISD::ADDE, MVT::i1, Promote);
83 setOperationAction(ISD::ADDE, MVT::i8, Legal);
84 setOperationAction(ISD::ADDE, MVT::i16, Custom);
85 setOperationAction(ISD::ADDE, MVT::i32, Expand);
86 setOperationAction(ISD::ADDE, MVT::i64, Expand);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000087
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000088 setOperationAction(ISD::SUBC, MVT::i1, Promote);
89 setOperationAction(ISD::SUBC, MVT::i8, Legal);
90 setOperationAction(ISD::SUBC, MVT::i16, Custom);
91 setOperationAction(ISD::SUBC, MVT::i32, Expand);
92 setOperationAction(ISD::SUBC, MVT::i64, Expand);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000093
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000094 setOperationAction(ISD::SUBE, MVT::i1, Promote);
95 setOperationAction(ISD::SUBE, MVT::i8, Legal);
96 setOperationAction(ISD::SUBE, MVT::i16, Custom);
97 setOperationAction(ISD::SUBE, MVT::i32, Expand);
98 setOperationAction(ISD::SUBE, MVT::i64, Expand);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000099
100 // PIC16 does not have these NodeTypes below.
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000101 setOperationAction(ISD::SETCC, MVT::i1, Expand);
102 setOperationAction(ISD::SETCC, MVT::i8, Expand);
103 setOperationAction(ISD::SETCC, MVT::Other, Expand);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000104 setOperationAction(ISD::SELECT_CC, MVT::i1, Custom);
105 setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);
106
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000107 setOperationAction(ISD::BRCOND, MVT::i1, Expand);
108 setOperationAction(ISD::BRCOND, MVT::i8, Expand);
109 setOperationAction(ISD::BRCOND, MVT::Other, Expand);
110
111 setOperationAction(ISD::BR_CC, MVT::i1, Custom);
112 setOperationAction(ISD::BR_CC, MVT::i8, Custom);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000113
114 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
115
116
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000117 // FIXME: Do we really need to Custom lower the GA ??
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000118 setOperationAction(ISD::GlobalAddress, MVT::i8, Custom);
119 setOperationAction(ISD::RET, MVT::Other, Custom);
120
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000121 setOperationAction(ISD::CTPOP, MVT::i32, Expand);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000122 setOperationAction(ISD::CTTZ, MVT::i32, Expand);
123 setOperationAction(ISD::CTLZ, MVT::i32, Expand);
124 setOperationAction(ISD::ROTL, MVT::i32, Expand);
125 setOperationAction(ISD::ROTR, MVT::i32, Expand);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000126 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
127
128 setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
129 setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
130 setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
131
132 // We don't have line number support yet.
Dan Gohman7f460202008-06-30 20:59:49 +0000133 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000134 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
Dan Gohman44066042008-07-01 00:05:16 +0000135 setOperationAction(ISD::DBG_LABEL, MVT::Other, Expand);
136 setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000137
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000138 // Use the default for now.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000139 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
140 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
141
142 setOperationAction(ISD::LOAD, MVT::i1, Promote);
143 setOperationAction(ISD::LOAD, MVT::i8, Legal);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000144
145 setTargetDAGCombine(ISD::LOAD);
146 setTargetDAGCombine(ISD::STORE);
147 setTargetDAGCombine(ISD::ADDE);
148 setTargetDAGCombine(ISD::ADDC);
149 setTargetDAGCombine(ISD::ADD);
150 setTargetDAGCombine(ISD::SUBE);
151 setTargetDAGCombine(ISD::SUBC);
152 setTargetDAGCombine(ISD::SUB);
153
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000154 setStackPointerRegisterToSaveRestore(PIC16::STKPTR);
155 computeRegisterProperties();
156}
157
158
Dan Gohman475871a2008-07-27 21:46:04 +0000159SDValue PIC16TargetLowering:: LowerOperation(SDValue Op, SelectionDAG &DAG)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000160{
161 SDVTList VTList16 = DAG.getVTList(MVT::i16, MVT::i16, MVT::Other);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000162 switch (Op.getOpcode()) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000163 case ISD::STORE:
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000164 DOUT << "reduce store\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000165 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000166
167 case ISD::FORMAL_ARGUMENTS:
168 DOUT << "==== lowering formal args\n";
169 return LowerFORMAL_ARGUMENTS(Op, DAG);
170
171 case ISD::GlobalAddress:
172 DOUT << "==== lowering GA\n";
173 return LowerGlobalAddress(Op, DAG);
174
175 case ISD::RET:
176 DOUT << "==== lowering ret\n";
177 return LowerRET(Op, DAG);
178
179 case ISD::FrameIndex:
180 DOUT << "==== lowering frame index\n";
181 return LowerFrameIndex(Op, DAG);
182
183 case ISD::ADDE:
184 DOUT << "==== lowering adde\n";
185 break;
186
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000187 case ISD::LOAD:
188 case ISD::ADD:
189 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000190
191 case ISD::BR_CC:
192 DOUT << "==== lowering BR_CC\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000193 return LowerBR_CC(Op, DAG);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000194 } // end switch.
Dan Gohman475871a2008-07-27 21:46:04 +0000195 return SDValue();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000196}
197
198
199//===----------------------------------------------------------------------===//
200// Lower helper functions
201//===----------------------------------------------------------------------===//
202
Dan Gohman475871a2008-07-27 21:46:04 +0000203SDValue PIC16TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000204{
Duncan Sands83ec4b62008-06-06 12:08:01 +0000205 MVT VT = Op.getValueType();
Dan Gohman475871a2008-07-27 21:46:04 +0000206 SDValue Chain = Op.getOperand(0);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000207 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
Dan Gohman475871a2008-07-27 21:46:04 +0000208 SDValue LHS = Op.getOperand(2);
209 SDValue RHS = Op.getOperand(3);
210 SDValue JumpVal = Op.getOperand(4);
211 SDValue Result;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000212 unsigned cmpOpcode;
213 unsigned branchOpcode;
Dan Gohman475871a2008-07-27 21:46:04 +0000214 SDValue branchOperand;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000215
Dan Gohman475871a2008-07-27 21:46:04 +0000216 SDValue StatusReg = DAG.getRegister(PIC16::STATUSREG, MVT::i8);
217 SDValue CPUReg = DAG.getRegister(PIC16::WREG, MVT::i8);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000218 switch(CC) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000219 default:
220 assert(0 && "This condition code is not handled yet!!");
221 abort();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000222
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000223 case ISD::SETNE:
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000224 DOUT << "setne\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000225 cmpOpcode = PIC16ISD::XORCC;
226 branchOpcode = PIC16ISD::BTFSS;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000227 branchOperand = DAG.getConstant(2, MVT::i8);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000228 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000229
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000230 case ISD::SETEQ:
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000231 DOUT << "seteq\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000232 cmpOpcode = PIC16ISD::XORCC;
233 branchOpcode = PIC16ISD::BTFSC;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000234 branchOperand = DAG.getConstant(2, MVT::i8);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000235 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000236
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000237 case ISD::SETGT:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000238 assert(0 && "Greater Than condition code is not handled yet!!");
239 abort();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000240 break;
241
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000242 case ISD::SETGE:
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000243 DOUT << "setge\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000244 cmpOpcode = PIC16ISD::SUBCC;
245 branchOpcode = PIC16ISD::BTFSS;
246 branchOperand = DAG.getConstant(1, MVT::i8);
247 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000248
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000249 case ISD::SETLT:
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000250 DOUT << "setlt\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000251 cmpOpcode = PIC16ISD::SUBCC;
252 branchOpcode = PIC16ISD::BTFSC;
253 branchOperand = DAG.getConstant(1,MVT::i8);
254 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000255
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000256 case ISD::SETLE:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000257 assert(0 && "Less Than Equal condition code is not handled yet!!");
258 abort();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000259 break;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000260 } // End of Switch
261
262 SDVTList VTList = DAG.getVTList(MVT::i8, MVT::Flag);
Dan Gohman475871a2008-07-27 21:46:04 +0000263 SDValue CmpValue = DAG.getNode(cmpOpcode, VTList, LHS, RHS).getValue(1);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000264 Result = DAG.getNode(branchOpcode, VT, Chain, JumpVal, branchOperand,
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000265 StatusReg, CmpValue);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000266 return Result;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000267}
268
269
270//===----------------------------------------------------------------------===//
271// Misc Lower Operation implementation
272//===----------------------------------------------------------------------===//
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000273
274// LowerGlobalAddress - Create a constant pool entry for global value
275// and wrap it in a wrapper node.
Dan Gohman475871a2008-07-27 21:46:04 +0000276SDValue
277PIC16TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000278{
Duncan Sands83ec4b62008-06-06 12:08:01 +0000279 MVT PtrVT = getPointerTy();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000280 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
281 GlobalValue *GV = GSDN->getGlobal();
282
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000283 // FIXME: for now only do the ram.
Dan Gohman475871a2008-07-27 21:46:04 +0000284 SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 2);
285 SDValue CPBank = DAG.getNode(PIC16ISD::SetBank, MVT::i8, CPAddr);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000286 CPAddr = DAG.getNode(PIC16ISD::Wrapper, MVT::i8, CPAddr,CPBank);
287
288 return CPAddr;
289}
290
Dan Gohman475871a2008-07-27 21:46:04 +0000291SDValue
292PIC16TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000293{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000294 switch(Op.getNumOperands()) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000295 default:
296 assert(0 && "Do not know how to return this many arguments!");
297 abort();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000298
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000299 case 1:
Dan Gohman475871a2008-07-27 21:46:04 +0000300 return SDValue(); // ret void is legal
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000301 }
302}
303
Dan Gohman475871a2008-07-27 21:46:04 +0000304SDValue
305PIC16TargetLowering::LowerFrameIndex(SDValue N, SelectionDAG &DAG)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000306{
307 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N)) {
308 return DAG.getTargetFrameIndex(FIN->getIndex(), MVT::i32);
309 }
310
311 return N;
312}
313
Dan Gohman475871a2008-07-27 21:46:04 +0000314SDValue
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000315PIC16TargetLowering::LowerLOAD(SDNode *N,
316 SelectionDAG &DAG,
317 DAGCombinerInfo &DCI) const
318{
Dan Gohman475871a2008-07-27 21:46:04 +0000319 SDValue Outs[2];
320 SDValue TF; //TokenFactor
321 SDValue OutChains[2];
322 SDValue Chain = N->getOperand(0);
323 SDValue Src = N->getOperand(1);
324 SDValue retVal;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000325 SDVTList VTList;
326
327 // If this load is directly stored, replace the load value with the stored
328 // value.
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000329 // FIXME: Handle store large -> read small portion.
330 // FIXME: Handle TRUNCSTORE/LOADEXT
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000331 LoadSDNode *LD = cast<LoadSDNode>(N);
Dan Gohman475871a2008-07-27 21:46:04 +0000332 SDValue Ptr = LD->getBasePtr();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000333 if (LD->getExtensionType() == ISD::NON_EXTLOAD) {
Gabor Greifba36cb52008-08-28 21:40:38 +0000334 if (ISD::isNON_TRUNCStore(Chain.getNode())) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000335 StoreSDNode *PrevST = cast<StoreSDNode>(Chain);
336 if (PrevST->getBasePtr() == Ptr &&
337 PrevST->getValue().getValueType() == N->getValueType(0))
338 return DCI.CombineTo(N, Chain.getOperand(1), Chain);
339 }
340 }
341
342 if (N->getValueType(0) != MVT::i16)
Dan Gohman475871a2008-07-27 21:46:04 +0000343 return SDValue();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000344
Dan Gohman475871a2008-07-27 21:46:04 +0000345 SDValue toWorklist;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000346 Outs[0] = DAG.getLoad(MVT::i8, Chain, Src, NULL, 0);
347 toWorklist = DAG.getNode(ISD::ADD, MVT::i16, Src,
348 DAG.getConstant(1, MVT::i16));
349 Outs[1] = DAG.getLoad(MVT::i8, Chain, toWorklist, NULL, 0);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000350 // FIXME: Add to worklist may not be needed.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000351 // It is meant to merge sequences of add with constant into one.
Gabor Greifba36cb52008-08-28 21:40:38 +0000352 DCI.AddToWorklist(toWorklist.getNode());
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000353
354 // Create the tokenfactors and carry it on to the build_pair node
355 OutChains[0] = Outs[0].getValue(1);
356 OutChains[1] = Outs[1].getValue(1);
357 TF = DAG.getNode(ISD::TokenFactor, MVT::Other, &OutChains[0], 2);
358
359 VTList = DAG.getVTList(MVT::i16, MVT::Flag);
360 retVal = DAG.getNode (PIC16ISD::Package, VTList, &Outs[0], 2);
361
362 DCI.CombineTo (N, retVal, TF);
363
364 return retVal;
365}
366
Dan Gohman475871a2008-07-27 21:46:04 +0000367SDValue
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000368PIC16TargetLowering::LowerADDSUB(SDNode *N, SelectionDAG &DAG,
369 DAGCombinerInfo &DCI) const
370{
371 bool changed = false;
372 int i;
Dan Gohman475871a2008-07-27 21:46:04 +0000373 SDValue LoOps[3], HiOps[3];
374 SDValue OutOps[3]; // [0]:left, [1]:right, [2]:carry
375 SDValue InOp[2];
376 SDValue retVal;
377 SDValue as1,as2;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000378 SDVTList VTList;
Evan Chengbb606742008-05-14 20:33:21 +0000379 unsigned AS = 0, ASE = 0, ASC=0;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000380
381 InOp[0] = N->getOperand(0);
382 InOp[1] = N->getOperand(1);
383
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000384 switch (N->getOpcode()) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000385 case ISD::ADD:
386 if (InOp[0].getOpcode() == ISD::Constant &&
387 InOp[1].getOpcode() == ISD::Constant) {
388 ConstantSDNode *CST0 = dyn_cast<ConstantSDNode>(InOp[0]);
389 ConstantSDNode *CST1 = dyn_cast<ConstantSDNode>(InOp[1]);
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000390 return DAG.getConstant(CST0->getZExtValue() + CST1->getZExtValue(),
391 MVT::i16);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000392 }
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000393 break;
394
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000395 case ISD::ADDE:
396 case ISD::ADDC:
397 AS = ISD::ADD;
398 ASE = ISD::ADDE;
399 ASC = ISD::ADDC;
400 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000401
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000402 case ISD::SUB:
403 if (InOp[0].getOpcode() == ISD::Constant &&
404 InOp[1].getOpcode() == ISD::Constant) {
405 ConstantSDNode *CST0 = dyn_cast<ConstantSDNode>(InOp[0]);
406 ConstantSDNode *CST1 = dyn_cast<ConstantSDNode>(InOp[1]);
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000407 return DAG.getConstant(CST0->getZExtValue() - CST1->getZExtValue(),
408 MVT::i16);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000409 }
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000410 break;
411
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000412 case ISD::SUBE:
413 case ISD::SUBC:
414 AS = ISD::SUB;
415 ASE = ISD::SUBE;
416 ASC = ISD::SUBC;
417 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000418 } // end switch.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000419
420 assert ((N->getValueType(0) == MVT::i16)
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000421 && "expecting an MVT::i16 node for lowering");
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000422 assert ((N->getOperand(0).getValueType() == MVT::i16)
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000423 && (N->getOperand(1).getValueType() == MVT::i16)
424 && "both inputs to addx/subx:i16 must be i16");
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000425
426 for (i = 0; i < 2; i++) {
427 if (InOp[i].getOpcode() == ISD::GlobalAddress) {
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000428 // We don't want to lower subs/adds with global address yet.
Dan Gohman475871a2008-07-27 21:46:04 +0000429 return SDValue();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000430 }
431 else if (InOp[i].getOpcode() == ISD::Constant) {
432 changed = true;
433 ConstantSDNode *CST = dyn_cast<ConstantSDNode>(InOp[i]);
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000434 LoOps[i] = DAG.getConstant(CST->getZExtValue() & 0xFF, MVT::i8);
435 HiOps[i] = DAG.getConstant(CST->getZExtValue() >> 8, MVT::i8);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000436 }
437 else if (InOp[i].getOpcode() == PIC16ISD::Package) {
438 LoOps[i] = InOp[i].getOperand(0);
439 HiOps[i] = InOp[i].getOperand(1);
440 }
441 else if (InOp[i].getOpcode() == ISD::LOAD) {
442 changed = true;
443 // LowerLOAD returns a Package node or it may combine and return
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000444 // anything else.
Gabor Greifba36cb52008-08-28 21:40:38 +0000445 SDValue lowered = LowerLOAD(InOp[i].getNode(), DAG, DCI);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000446
447 // So If LowerLOAD returns something other than Package,
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000448 // then just call ADD again.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000449 if (lowered.getOpcode() != PIC16ISD::Package)
450 return LowerADDSUB(N, DAG, DCI);
451
452 LoOps[i] = lowered.getOperand(0);
453 HiOps[i] = lowered.getOperand(1);
454 }
455 else if ((InOp[i].getOpcode() == ISD::ADD) ||
456 (InOp[i].getOpcode() == ISD::ADDE) ||
457 (InOp[i].getOpcode() == ISD::ADDC) ||
458 (InOp[i].getOpcode() == ISD::SUB) ||
459 (InOp[i].getOpcode() == ISD::SUBE) ||
460 (InOp[i].getOpcode() == ISD::SUBC)) {
461 changed = true;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000462 // Must call LowerADDSUB recursively here,
463 // LowerADDSUB returns a Package node.
Gabor Greifba36cb52008-08-28 21:40:38 +0000464 SDValue lowered = LowerADDSUB(InOp[i].getNode(), DAG, DCI);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000465
466 LoOps[i] = lowered.getOperand(0);
467 HiOps[i] = lowered.getOperand(1);
468 }
469 else if (InOp[i].getOpcode() == ISD::SIGN_EXTEND) {
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000470 // FIXME: I am just zero extending. for now.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000471 changed = true;
472 LoOps[i] = InOp[i].getOperand(0);
473 HiOps[i] = DAG.getConstant(0, MVT::i8);
474 }
475 else {
476 DAG.setGraphColor(N, "blue");
477 DAG.viewGraph();
478 assert (0 && "not implemented yet");
479 }
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000480 } // end for.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000481
482 assert (changed && "nothing changed while lowering SUBx/ADDx");
483
484 VTList = DAG.getVTList(MVT::i8, MVT::Flag);
485 if (N->getOpcode() == ASE) {
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000486 // We must take in the existing carry
487 // if this node is part of an existing subx/addx sequence.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000488 LoOps[2] = N->getOperand(2).getValue(1);
489 as1 = DAG.getNode (ASE, VTList, LoOps, 3);
490 }
491 else {
492 as1 = DAG.getNode (ASC, VTList, LoOps, 2);
493 }
494 HiOps[2] = as1.getValue(1);
495 as2 = DAG.getNode (ASE, VTList, HiOps, 3);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000496 // We must build a pair that also provides the carry from sube/adde.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000497 OutOps[0] = as1;
498 OutOps[1] = as2;
499 OutOps[2] = as2.getValue(1);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000500 // Breaking an original i16, so lets make the Package also an i16.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000501 if (N->getOpcode() == ASE) {
502 VTList = DAG.getVTList(MVT::i16, MVT::Flag);
503 retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 3);
504 DCI.CombineTo (N, retVal, OutOps[2]);
505 }
506 else if (N->getOpcode() == ASC) {
507 VTList = DAG.getVTList(MVT::i16, MVT::Flag);
508 retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 2);
509 DCI.CombineTo (N, retVal, OutOps[2]);
510 }
511 else if (N->getOpcode() == AS) {
512 VTList = DAG.getVTList(MVT::i16);
513 retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 2);
514 DCI.CombineTo (N, retVal);
515 }
516
517 return retVal;
518}
519
520
521//===----------------------------------------------------------------------===//
522// Calling Convention Implementation
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000523//===----------------------------------------------------------------------===//
524
525#include "PIC16GenCallingConv.inc"
526
527//===----------------------------------------------------------------------===//
528// CALL Calling Convention Implementation
529//===----------------------------------------------------------------------===//
530
531
532//===----------------------------------------------------------------------===//
533// FORMAL_ARGUMENTS Calling Convention Implementation
534//===----------------------------------------------------------------------===//
Dan Gohman475871a2008-07-27 21:46:04 +0000535SDValue PIC16TargetLowering::
536LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000537{
Dan Gohman475871a2008-07-27 21:46:04 +0000538 SmallVector<SDValue, 8> ArgValues;
539 SDValue Root = Op.getOperand(0);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000540
541 // Return the new list of results.
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000542 // FIXME: Just copy right now.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000543 ArgValues.push_back(Root);
544
Gabor Greifba36cb52008-08-28 21:40:38 +0000545 return DAG.getMergeValues(Op.getNode()->getVTList(), &ArgValues[0],
Gabor Greif99a6cb92008-08-26 22:36:50 +0000546 ArgValues.size()).getValue(Op.getResNo());
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000547}
548
549
550//===----------------------------------------------------------------------===//
551// Return Value Calling Convention Implementation
552//===----------------------------------------------------------------------===//
553
554//===----------------------------------------------------------------------===//
555// PIC16 Inline Assembly Support
556//===----------------------------------------------------------------------===//
557
558//===----------------------------------------------------------------------===//
559// Target Optimization Hooks
560//===----------------------------------------------------------------------===//
561
Dan Gohman475871a2008-07-27 21:46:04 +0000562SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N,
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000563 DAGCombinerInfo &DCI) const
564{
565 int i;
566 ConstantSDNode *CST;
567 SelectionDAG &DAG = DCI.DAG;
568
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000569 switch (N->getOpcode()) {
570 default:
571 break;
572
573 case PIC16ISD::Package:
574 DOUT << "==== combining PIC16ISD::Package\n";
Dan Gohman475871a2008-07-27 21:46:04 +0000575 return SDValue();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000576
577 case ISD::ADD:
578 case ISD::SUB:
579 if ((N->getOperand(0).getOpcode() == ISD::GlobalAddress) ||
580 (N->getOperand(0).getOpcode() == ISD::FrameIndex)) {
581 // Do not touch pointer adds.
Dan Gohman475871a2008-07-27 21:46:04 +0000582 return SDValue ();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000583 }
584 break;
585
586 case ISD::ADDE :
587 case ISD::ADDC :
588 case ISD::SUBE :
589 case ISD::SUBC :
590 if (N->getValueType(0) == MVT::i16) {
Dan Gohman475871a2008-07-27 21:46:04 +0000591 SDValue retVal = LowerADDSUB(N, DAG,DCI);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000592 // LowerADDSUB has already combined the result,
593 // so we just return nothing to avoid assertion failure from llvm
594 // if N has been deleted already.
Dan Gohman475871a2008-07-27 21:46:04 +0000595 return SDValue();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000596 }
597 else if (N->getValueType(0) == MVT::i8) {
598 // Sanity check ....
599 for (int i=0; i<2; i++) {
600 if (N->getOperand (i).getOpcode() == PIC16ISD::Package) {
601 assert (0 &&
602 "don't want to have PIC16ISD::Package as intput to add:i8");
603 }
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000604 }
605 }
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000606 break;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000607
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000608 // FIXME: split this large chunk of code.
609 case ISD::STORE :
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000610 {
Dan Gohman475871a2008-07-27 21:46:04 +0000611 SDValue Chain = N->getOperand(0);
612 SDValue Src = N->getOperand(1);
613 SDValue Dest = N->getOperand(2);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000614 unsigned int DstOff = 0;
Evan Chengbb606742008-05-14 20:33:21 +0000615 int NUM_STORES = 0;
Dan Gohman475871a2008-07-27 21:46:04 +0000616 SDValue Stores[6];
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000617
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000618 // if source operand is expected to be extended to
619 // some higher type then - remove this extension
620 // SDNode and do the extension manually
621 if ((Src.getOpcode() == ISD::ANY_EXTEND) ||
622 (Src.getOpcode() == ISD::SIGN_EXTEND) ||
623 (Src.getOpcode() == ISD::ZERO_EXTEND)) {
Gabor Greifba36cb52008-08-28 21:40:38 +0000624 Src = Src.getNode()->getOperand(0);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000625 Stores[0] = DAG.getStore(Chain, Src, Dest, NULL,0);
626 return Stores[0];
627 }
628
Duncan Sands83ec4b62008-06-06 12:08:01 +0000629 switch(Src.getValueType().getSimpleVT()) {
630 default:
631 assert(false && "Invalid value type!");
632
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000633 case MVT::i8:
634 break;
635
636 case MVT::i16:
637 NUM_STORES = 2;
638 break;
639
640 case MVT::i32:
641 NUM_STORES = 4;
642 break;
643
644 case MVT::i64:
645 NUM_STORES = 8;
646 break;
647 }
648
649 if (isa<GlobalAddressSDNode>(Dest) && isa<LoadSDNode>(Src) &&
650 (Src.getValueType() != MVT::i8)) {
651 //create direct addressing a = b
652 Chain = Src.getOperand(0);
653 for (i=0; i<NUM_STORES; i++) {
Dan Gohman475871a2008-07-27 21:46:04 +0000654 SDValue ADN = DAG.getNode(ISD::ADD, MVT::i16, Src.getOperand(1),
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000655 DAG.getConstant(DstOff, MVT::i16));
Dan Gohman475871a2008-07-27 21:46:04 +0000656 SDValue LDN = DAG.getLoad(MVT::i8, Chain, ADN, NULL, 0);
657 SDValue DSTADDR = DAG.getNode(ISD::ADD, MVT::i16, Dest,
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000658 DAG.getConstant(DstOff, MVT::i16));
659 Stores[i] = DAG.getStore(Chain, LDN, DSTADDR, NULL, 0);
660 Chain = Stores[i];
661 DstOff += 1;
662 }
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000663
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000664 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i);
665 return Chain;
666 }
667 else if (isa<GlobalAddressSDNode>(Dest) && isa<ConstantSDNode>(Src)
668 && (Src.getValueType() != MVT::i8)) {
669 //create direct addressing a = CONST
670 CST = dyn_cast<ConstantSDNode>(Src);
671 for (i = 0; i < NUM_STORES; i++) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000672 SDValue CNST = DAG.getConstant(CST->getZExtValue() >> i*8, MVT::i8);
Dan Gohman475871a2008-07-27 21:46:04 +0000673 SDValue ADN = DAG.getNode(ISD::ADD, MVT::i16, Dest,
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000674 DAG.getConstant(DstOff, MVT::i16));
675 Stores[i] = DAG.getStore(Chain, CNST, ADN, NULL, 0);
676 Chain = Stores[i];
677 DstOff += 1;
678 }
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000679
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000680 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i);
681 return Chain;
682 }
683 else if (isa<LoadSDNode>(Dest) && isa<ConstantSDNode>(Src)
684 && (Src.getValueType() != MVT::i8)) {
685 // Create indirect addressing.
686 CST = dyn_cast<ConstantSDNode>(Src);
687 Chain = Dest.getOperand(0);
Dan Gohman475871a2008-07-27 21:46:04 +0000688 SDValue Load;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000689 Load = DAG.getLoad(MVT::i16, Chain,Dest.getOperand(1), NULL, 0);
690 Chain = Load.getValue(1);
691 for (i=0; i<NUM_STORES; i++) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000692 SDValue CNST = DAG.getConstant(CST->getZExtValue() >> i*8, MVT::i8);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000693 Stores[i] = DAG.getStore(Chain, CNST, Load, NULL, 0);
694 Chain = Stores[i];
695 DstOff += 1;
696 }
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000697
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000698 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i);
699 return Chain;
700 }
701 else if (isa<LoadSDNode>(Dest) && isa<GlobalAddressSDNode>(Src)) {
702 // GlobalAddressSDNode *GAD = dyn_cast<GlobalAddressSDNode>(Src);
Dan Gohman475871a2008-07-27 21:46:04 +0000703 return SDValue();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000704 }
705 else if (Src.getOpcode() == PIC16ISD::Package) {
706 StoreSDNode *st = dyn_cast<StoreSDNode>(N);
Dan Gohman475871a2008-07-27 21:46:04 +0000707 SDValue toWorkList, retVal;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000708 Chain = N->getOperand(0);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000709
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000710 if (st->isTruncatingStore()) {
711 retVal = DAG.getStore(Chain, Src.getOperand(0), Dest, NULL, 0);
712 }
713 else {
714 toWorkList = DAG.getNode(ISD::ADD, MVT::i16, Dest,
715 DAG.getConstant(1, MVT::i16));
716 Stores[1] = DAG.getStore(Chain, Src.getOperand(0), Dest, NULL, 0);
717 Stores[0] = DAG.getStore(Chain, Src.getOperand(1), toWorkList, NULL,
718 0);
719
720 // We want to merge sequence of add with constant to one add and a
721 // constant, so add the ADD node to worklist to have llvm do that
722 // automatically.
Gabor Greifba36cb52008-08-28 21:40:38 +0000723 DCI.AddToWorklist(toWorkList.getNode());
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000724
725 // We don't need the Package so add to worklist so llvm deletes it
Gabor Greifba36cb52008-08-28 21:40:38 +0000726 DCI.AddToWorklist(Src.getNode());
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000727 retVal = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], 2);
728 }
729
730 return retVal;
731 }
732 else if (Src.getOpcode() == ISD::TRUNCATE) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000733 }
734 else {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000735 }
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000736 } // end ISD::STORE.
737 break;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000738
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000739 case ISD::LOAD :
740 {
Dan Gohman475871a2008-07-27 21:46:04 +0000741 SDValue Ptr = N->getOperand(1);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000742 if (Ptr.getOpcode() == PIC16ISD::Package) {
743 assert (0 && "not implemented yet");
744 }
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000745 }
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000746 break;
747 } // end switch.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000748
Dan Gohman475871a2008-07-27 21:46:04 +0000749 return SDValue();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000750}
751
752//===----------------------------------------------------------------------===//
753// Utility functions
754//===----------------------------------------------------------------------===//
Dan Gohman475871a2008-07-27 21:46:04 +0000755const SDValue *PIC16TargetLowering::
756findLoadi8(const SDValue &Src, SelectionDAG &DAG) const
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000757{
758 unsigned int i;
759 if ((Src.getOpcode() == ISD::LOAD) && (Src.getValueType() == MVT::i8))
760 return &Src;
761 for (i=0; i<Src.getNumOperands(); i++) {
Dan Gohman475871a2008-07-27 21:46:04 +0000762 const SDValue *retVal = findLoadi8(Src.getOperand(i),DAG);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000763 if (retVal) return retVal;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000764 }
765
766 return NULL;
767}