blob: ace3170dfa533b3329da09d1cb350fa2ef764aeb [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"
31#include <queue>
32#include <set>
33
34using namespace llvm;
35
36const char *PIC16TargetLowering:: getTargetNodeName(unsigned Opcode) const
37{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000038 switch (Opcode) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +000039 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";
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000046 case PIC16ISD::Cmp : return "PIC16ISD::Cmp";
Sanjiv Gupta0e687712008-05-13 09:02:57 +000047 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;
52 }
53}
54
55PIC16TargetLowering::
56PIC16TargetLowering(PIC16TargetMachine &TM): TargetLowering(TM)
57{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000058 // Set up the register classes.
59 addRegisterClass(MVT::i8, PIC16::CPURegsRegisterClass);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000060 addRegisterClass(MVT::i16, PIC16::PTRRegsRegisterClass);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000061
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000062 // Load extented operations for i1 types must be promoted .
Evan Cheng03294662008-10-14 21:26:46 +000063 setLoadExtAction(ISD::EXTLOAD, MVT::i1, Promote);
64 setLoadExtAction(ISD::ZEXTLOAD, MVT::i1, Promote);
65 setLoadExtAction(ISD::SEXTLOAD, MVT::i1, Promote);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000066
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000067 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);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000072
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000073 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);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000078
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000079 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);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000084
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000085 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);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000090
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000091 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);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000096
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000097 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);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000102
103 // PIC16 does not have these NodeTypes below.
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000104 setOperationAction(ISD::SETCC, MVT::i1, Expand);
105 setOperationAction(ISD::SETCC, MVT::i8, Expand);
106 setOperationAction(ISD::SETCC, MVT::Other, Expand);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000107 setOperationAction(ISD::SELECT_CC, MVT::i1, Custom);
108 setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);
109
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000110 setOperationAction(ISD::BRCOND, MVT::i1, Expand);
111 setOperationAction(ISD::BRCOND, MVT::i8, Expand);
112 setOperationAction(ISD::BRCOND, MVT::Other, Expand);
113
114 setOperationAction(ISD::BR_CC, MVT::i1, Custom);
115 setOperationAction(ISD::BR_CC, MVT::i8, Custom);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000116
117 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
118
119
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000120 // FIXME: Do we really need to Custom lower the GA ??
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000121 setOperationAction(ISD::GlobalAddress, MVT::i8, Custom);
122 setOperationAction(ISD::RET, MVT::Other, Custom);
123
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000124 setOperationAction(ISD::CTPOP, MVT::i32, Expand);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000125 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);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000129 setOperationAction(ISD::BSWAP, MVT::i32, Expand);
130
131 setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand);
132 setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand);
133 setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand);
134
135 // We don't have line number support yet.
Dan Gohman7f460202008-06-30 20:59:49 +0000136 setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000137 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
Dan Gohman44066042008-07-01 00:05:16 +0000138 setOperationAction(ISD::DBG_LABEL, MVT::Other, Expand);
139 setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000140
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000141 // Use the default for now.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000142 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand);
143 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
144
145 setOperationAction(ISD::LOAD, MVT::i1, Promote);
146 setOperationAction(ISD::LOAD, MVT::i8, Legal);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000147
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);
156
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000157 setStackPointerRegisterToSaveRestore(PIC16::STKPTR);
158 computeRegisterProperties();
159}
160
161
Dan Gohman475871a2008-07-27 21:46:04 +0000162SDValue PIC16TargetLowering:: LowerOperation(SDValue Op, SelectionDAG &DAG)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000163{
164 SDVTList VTList16 = DAG.getVTList(MVT::i16, MVT::i16, MVT::Other);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000165 switch (Op.getOpcode()) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000166 case ISD::STORE:
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000167 DOUT << "reduce store\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000168 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000169
170 case ISD::FORMAL_ARGUMENTS:
171 DOUT << "==== lowering formal args\n";
172 return LowerFORMAL_ARGUMENTS(Op, DAG);
173
174 case ISD::GlobalAddress:
175 DOUT << "==== lowering GA\n";
176 return LowerGlobalAddress(Op, DAG);
177
178 case ISD::RET:
179 DOUT << "==== lowering ret\n";
180 return LowerRET(Op, DAG);
181
182 case ISD::FrameIndex:
183 DOUT << "==== lowering frame index\n";
184 return LowerFrameIndex(Op, DAG);
185
186 case ISD::ADDE:
187 DOUT << "==== lowering adde\n";
188 break;
189
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000190 case ISD::LOAD:
191 case ISD::ADD:
192 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000193
194 case ISD::BR_CC:
195 DOUT << "==== lowering BR_CC\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000196 return LowerBR_CC(Op, DAG);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000197 } // end switch.
Dan Gohman475871a2008-07-27 21:46:04 +0000198 return SDValue();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000199}
200
201
202//===----------------------------------------------------------------------===//
203// Lower helper functions
204//===----------------------------------------------------------------------===//
205
Dan Gohman475871a2008-07-27 21:46:04 +0000206SDValue PIC16TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000207{
Duncan Sands83ec4b62008-06-06 12:08:01 +0000208 MVT VT = Op.getValueType();
Dan Gohman475871a2008-07-27 21:46:04 +0000209 SDValue Chain = Op.getOperand(0);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000210 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
Dan Gohman475871a2008-07-27 21:46:04 +0000211 SDValue LHS = Op.getOperand(2);
212 SDValue RHS = Op.getOperand(3);
213 SDValue JumpVal = Op.getOperand(4);
214 SDValue Result;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000215 unsigned cmpOpcode;
216 unsigned branchOpcode;
Dan Gohman475871a2008-07-27 21:46:04 +0000217 SDValue branchOperand;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000218
Dan Gohman475871a2008-07-27 21:46:04 +0000219 SDValue StatusReg = DAG.getRegister(PIC16::STATUSREG, MVT::i8);
220 SDValue CPUReg = DAG.getRegister(PIC16::WREG, MVT::i8);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000221 switch(CC) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000222 default:
223 assert(0 && "This condition code is not handled yet!!");
224 abort();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000225
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000226 case ISD::SETNE:
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000227 DOUT << "setne\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000228 cmpOpcode = PIC16ISD::XORCC;
229 branchOpcode = PIC16ISD::BTFSS;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000230 branchOperand = DAG.getConstant(2, MVT::i8);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000231 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000232
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000233 case ISD::SETEQ:
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000234 DOUT << "seteq\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000235 cmpOpcode = PIC16ISD::XORCC;
236 branchOpcode = PIC16ISD::BTFSC;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000237 branchOperand = DAG.getConstant(2, MVT::i8);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000238 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000239
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000240 case ISD::SETGT:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000241 assert(0 && "Greater Than condition code is not handled yet!!");
242 abort();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000243 break;
244
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000245 case ISD::SETGE:
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000246 DOUT << "setge\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000247 cmpOpcode = PIC16ISD::SUBCC;
248 branchOpcode = PIC16ISD::BTFSS;
249 branchOperand = DAG.getConstant(1, MVT::i8);
250 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000251
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000252 case ISD::SETLT:
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000253 DOUT << "setlt\n";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000254 cmpOpcode = PIC16ISD::SUBCC;
255 branchOpcode = PIC16ISD::BTFSC;
256 branchOperand = DAG.getConstant(1,MVT::i8);
257 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000258
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000259 case ISD::SETLE:
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000260 assert(0 && "Less Than Equal condition code is not handled yet!!");
261 abort();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000262 break;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000263 } // End of Switch
264
265 SDVTList VTList = DAG.getVTList(MVT::i8, MVT::Flag);
Dan Gohman475871a2008-07-27 21:46:04 +0000266 SDValue CmpValue = DAG.getNode(cmpOpcode, VTList, LHS, RHS).getValue(1);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000267 Result = DAG.getNode(branchOpcode, VT, Chain, JumpVal, branchOperand,
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000268 StatusReg, CmpValue);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000269 return Result;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000270}
271
272
273//===----------------------------------------------------------------------===//
274// Misc Lower Operation implementation
275//===----------------------------------------------------------------------===//
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000276
277// LowerGlobalAddress - Create a constant pool entry for global value
278// and wrap it in a wrapper node.
Dan Gohman475871a2008-07-27 21:46:04 +0000279SDValue
280PIC16TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000281{
Duncan Sands83ec4b62008-06-06 12:08:01 +0000282 MVT PtrVT = getPointerTy();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000283 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op);
284 GlobalValue *GV = GSDN->getGlobal();
285
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000286 // FIXME: for now only do the ram.
Dan Gohman475871a2008-07-27 21:46:04 +0000287 SDValue CPAddr = DAG.getTargetConstantPool(GV, PtrVT, 2);
288 SDValue CPBank = DAG.getNode(PIC16ISD::SetBank, MVT::i8, CPAddr);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000289 CPAddr = DAG.getNode(PIC16ISD::Wrapper, MVT::i8, CPAddr,CPBank);
290
291 return CPAddr;
292}
293
Dan Gohman475871a2008-07-27 21:46:04 +0000294SDValue
295PIC16TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000296{
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000297 switch(Op.getNumOperands()) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000298 default:
299 assert(0 && "Do not know how to return this many arguments!");
300 abort();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000301
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000302 case 1:
Dan Gohman475871a2008-07-27 21:46:04 +0000303 return SDValue(); // ret void is legal
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000304 }
305}
306
Dan Gohman475871a2008-07-27 21:46:04 +0000307SDValue
308PIC16TargetLowering::LowerFrameIndex(SDValue N, SelectionDAG &DAG)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000309{
310 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N)) {
311 return DAG.getTargetFrameIndex(FIN->getIndex(), MVT::i32);
312 }
313
314 return N;
315}
316
Dan Gohman475871a2008-07-27 21:46:04 +0000317SDValue
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000318PIC16TargetLowering::LowerLOAD(SDNode *N,
319 SelectionDAG &DAG,
320 DAGCombinerInfo &DCI) const
321{
Dan Gohman475871a2008-07-27 21:46:04 +0000322 SDValue Outs[2];
323 SDValue TF; //TokenFactor
324 SDValue OutChains[2];
325 SDValue Chain = N->getOperand(0);
326 SDValue Src = N->getOperand(1);
327 SDValue retVal;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000328 SDVTList VTList;
329
330 // If this load is directly stored, replace the load value with the stored
331 // value.
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000332 // FIXME: Handle store large -> read small portion.
333 // FIXME: Handle TRUNCSTORE/LOADEXT
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000334 LoadSDNode *LD = cast<LoadSDNode>(N);
Dan Gohman475871a2008-07-27 21:46:04 +0000335 SDValue Ptr = LD->getBasePtr();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000336 if (LD->getExtensionType() == ISD::NON_EXTLOAD) {
Gabor Greifba36cb52008-08-28 21:40:38 +0000337 if (ISD::isNON_TRUNCStore(Chain.getNode())) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000338 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);
342 }
343 }
344
345 if (N->getValueType(0) != MVT::i16)
Dan Gohman475871a2008-07-27 21:46:04 +0000346 return SDValue();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000347
Dan Gohman475871a2008-07-27 21:46:04 +0000348 SDValue toWorklist;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000349 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);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000353 // FIXME: Add to worklist may not be needed.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000354 // It is meant to merge sequences of add with constant into one.
Gabor Greifba36cb52008-08-28 21:40:38 +0000355 DCI.AddToWorklist(toWorklist.getNode());
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000356
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);
361
362 VTList = DAG.getVTList(MVT::i16, MVT::Flag);
363 retVal = DAG.getNode (PIC16ISD::Package, VTList, &Outs[0], 2);
364
365 DCI.CombineTo (N, retVal, TF);
366
367 return retVal;
368}
369
Dan Gohman475871a2008-07-27 21:46:04 +0000370SDValue
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000371PIC16TargetLowering::LowerADDSUB(SDNode *N, SelectionDAG &DAG,
372 DAGCombinerInfo &DCI) const
373{
374 bool changed = false;
375 int i;
Dan Gohman475871a2008-07-27 21:46:04 +0000376 SDValue LoOps[3], HiOps[3];
377 SDValue OutOps[3]; // [0]:left, [1]:right, [2]:carry
378 SDValue InOp[2];
379 SDValue retVal;
380 SDValue as1,as2;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000381 SDVTList VTList;
Evan Chengbb606742008-05-14 20:33:21 +0000382 unsigned AS = 0, ASE = 0, ASC=0;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000383
384 InOp[0] = N->getOperand(0);
385 InOp[1] = N->getOperand(1);
386
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000387 switch (N->getOpcode()) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000388 case ISD::ADD:
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]);
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000393 return DAG.getConstant(CST0->getZExtValue() + CST1->getZExtValue(),
394 MVT::i16);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000395 }
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000396 break;
397
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000398 case ISD::ADDE:
399 case ISD::ADDC:
400 AS = ISD::ADD;
401 ASE = ISD::ADDE;
402 ASC = ISD::ADDC;
403 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000404
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000405 case ISD::SUB:
406 if (InOp[0].getOpcode() == ISD::Constant &&
407 InOp[1].getOpcode() == ISD::Constant) {
408 ConstantSDNode *CST0 = dyn_cast<ConstantSDNode>(InOp[0]);
409 ConstantSDNode *CST1 = dyn_cast<ConstantSDNode>(InOp[1]);
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000410 return DAG.getConstant(CST0->getZExtValue() - CST1->getZExtValue(),
411 MVT::i16);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000412 }
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000413 break;
414
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000415 case ISD::SUBE:
416 case ISD::SUBC:
417 AS = ISD::SUB;
418 ASE = ISD::SUBE;
419 ASC = ISD::SUBC;
420 break;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000421 } // end switch.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000422
423 assert ((N->getValueType(0) == MVT::i16)
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000424 && "expecting an MVT::i16 node for lowering");
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000425 assert ((N->getOperand(0).getValueType() == MVT::i16)
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000426 && (N->getOperand(1).getValueType() == MVT::i16)
427 && "both inputs to addx/subx:i16 must be i16");
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000428
429 for (i = 0; i < 2; i++) {
430 if (InOp[i].getOpcode() == ISD::GlobalAddress) {
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000431 // We don't want to lower subs/adds with global address yet.
Dan Gohman475871a2008-07-27 21:46:04 +0000432 return SDValue();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000433 }
434 else if (InOp[i].getOpcode() == ISD::Constant) {
435 changed = true;
436 ConstantSDNode *CST = dyn_cast<ConstantSDNode>(InOp[i]);
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000437 LoOps[i] = DAG.getConstant(CST->getZExtValue() & 0xFF, MVT::i8);
438 HiOps[i] = DAG.getConstant(CST->getZExtValue() >> 8, MVT::i8);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000439 }
440 else if (InOp[i].getOpcode() == PIC16ISD::Package) {
441 LoOps[i] = InOp[i].getOperand(0);
442 HiOps[i] = InOp[i].getOperand(1);
443 }
444 else if (InOp[i].getOpcode() == ISD::LOAD) {
445 changed = true;
446 // LowerLOAD returns a Package node or it may combine and return
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000447 // anything else.
Gabor Greifba36cb52008-08-28 21:40:38 +0000448 SDValue lowered = LowerLOAD(InOp[i].getNode(), DAG, DCI);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000449
450 // So If LowerLOAD returns something other than Package,
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000451 // then just call ADD again.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000452 if (lowered.getOpcode() != PIC16ISD::Package)
453 return LowerADDSUB(N, DAG, DCI);
454
455 LoOps[i] = lowered.getOperand(0);
456 HiOps[i] = lowered.getOperand(1);
457 }
458 else if ((InOp[i].getOpcode() == ISD::ADD) ||
459 (InOp[i].getOpcode() == ISD::ADDE) ||
460 (InOp[i].getOpcode() == ISD::ADDC) ||
461 (InOp[i].getOpcode() == ISD::SUB) ||
462 (InOp[i].getOpcode() == ISD::SUBE) ||
463 (InOp[i].getOpcode() == ISD::SUBC)) {
464 changed = true;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000465 // Must call LowerADDSUB recursively here,
466 // LowerADDSUB returns a Package node.
Gabor Greifba36cb52008-08-28 21:40:38 +0000467 SDValue lowered = LowerADDSUB(InOp[i].getNode(), DAG, DCI);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000468
469 LoOps[i] = lowered.getOperand(0);
470 HiOps[i] = lowered.getOperand(1);
471 }
472 else if (InOp[i].getOpcode() == ISD::SIGN_EXTEND) {
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000473 // FIXME: I am just zero extending. for now.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000474 changed = true;
475 LoOps[i] = InOp[i].getOperand(0);
476 HiOps[i] = DAG.getConstant(0, MVT::i8);
477 }
478 else {
479 DAG.setGraphColor(N, "blue");
480 DAG.viewGraph();
481 assert (0 && "not implemented yet");
482 }
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000483 } // end for.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000484
485 assert (changed && "nothing changed while lowering SUBx/ADDx");
486
487 VTList = DAG.getVTList(MVT::i8, MVT::Flag);
488 if (N->getOpcode() == ASE) {
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000489 // We must take in the existing carry
490 // if this node is part of an existing subx/addx sequence.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000491 LoOps[2] = N->getOperand(2).getValue(1);
492 as1 = DAG.getNode (ASE, VTList, LoOps, 3);
493 }
494 else {
495 as1 = DAG.getNode (ASC, VTList, LoOps, 2);
496 }
497 HiOps[2] = as1.getValue(1);
498 as2 = DAG.getNode (ASE, VTList, HiOps, 3);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000499 // We must build a pair that also provides the carry from sube/adde.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000500 OutOps[0] = as1;
501 OutOps[1] = as2;
502 OutOps[2] = as2.getValue(1);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000503 // Breaking an original i16, so lets make the Package also an i16.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000504 if (N->getOpcode() == ASE) {
505 VTList = DAG.getVTList(MVT::i16, MVT::Flag);
506 retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 3);
507 DCI.CombineTo (N, retVal, OutOps[2]);
508 }
509 else if (N->getOpcode() == ASC) {
510 VTList = DAG.getVTList(MVT::i16, MVT::Flag);
511 retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 2);
512 DCI.CombineTo (N, retVal, OutOps[2]);
513 }
514 else if (N->getOpcode() == AS) {
515 VTList = DAG.getVTList(MVT::i16);
516 retVal = DAG.getNode (PIC16ISD::Package, VTList, OutOps, 2);
517 DCI.CombineTo (N, retVal);
518 }
519
520 return retVal;
521}
522
523
524//===----------------------------------------------------------------------===//
525// Calling Convention Implementation
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000526//===----------------------------------------------------------------------===//
527
528#include "PIC16GenCallingConv.inc"
529
530//===----------------------------------------------------------------------===//
531// CALL Calling Convention Implementation
532//===----------------------------------------------------------------------===//
533
534
535//===----------------------------------------------------------------------===//
536// FORMAL_ARGUMENTS Calling Convention Implementation
537//===----------------------------------------------------------------------===//
Dan Gohman475871a2008-07-27 21:46:04 +0000538SDValue PIC16TargetLowering::
539LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG)
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000540{
Dan Gohman475871a2008-07-27 21:46:04 +0000541 SmallVector<SDValue, 8> ArgValues;
542 SDValue Root = Op.getOperand(0);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000543
544 // Return the new list of results.
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000545 // FIXME: Just copy right now.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000546 ArgValues.push_back(Root);
547
Gabor Greifba36cb52008-08-28 21:40:38 +0000548 return DAG.getMergeValues(Op.getNode()->getVTList(), &ArgValues[0],
Gabor Greif99a6cb92008-08-26 22:36:50 +0000549 ArgValues.size()).getValue(Op.getResNo());
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000550}
551
552
553//===----------------------------------------------------------------------===//
554// Return Value Calling Convention Implementation
555//===----------------------------------------------------------------------===//
556
557//===----------------------------------------------------------------------===//
558// PIC16 Inline Assembly Support
559//===----------------------------------------------------------------------===//
560
561//===----------------------------------------------------------------------===//
562// Target Optimization Hooks
563//===----------------------------------------------------------------------===//
564
Dan Gohman475871a2008-07-27 21:46:04 +0000565SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N,
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000566 DAGCombinerInfo &DCI) const
567{
568 int i;
569 ConstantSDNode *CST;
570 SelectionDAG &DAG = DCI.DAG;
571
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000572 switch (N->getOpcode()) {
573 default:
574 break;
575
576 case PIC16ISD::Package:
577 DOUT << "==== combining PIC16ISD::Package\n";
Dan Gohman475871a2008-07-27 21:46:04 +0000578 return SDValue();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000579
580 case ISD::ADD:
581 case ISD::SUB:
582 if ((N->getOperand(0).getOpcode() == ISD::GlobalAddress) ||
583 (N->getOperand(0).getOpcode() == ISD::FrameIndex)) {
584 // Do not touch pointer adds.
Dan Gohman475871a2008-07-27 21:46:04 +0000585 return SDValue ();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000586 }
587 break;
588
589 case ISD::ADDE :
590 case ISD::ADDC :
591 case ISD::SUBE :
592 case ISD::SUBC :
593 if (N->getValueType(0) == MVT::i16) {
Dan Gohman475871a2008-07-27 21:46:04 +0000594 SDValue retVal = LowerADDSUB(N, DAG,DCI);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000595 // LowerADDSUB has already combined the result,
596 // so we just return nothing to avoid assertion failure from llvm
597 // if N has been deleted already.
Dan Gohman475871a2008-07-27 21:46:04 +0000598 return SDValue();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000599 }
600 else if (N->getValueType(0) == MVT::i8) {
601 // Sanity check ....
602 for (int i=0; i<2; i++) {
603 if (N->getOperand (i).getOpcode() == PIC16ISD::Package) {
604 assert (0 &&
605 "don't want to have PIC16ISD::Package as intput to add:i8");
606 }
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000607 }
608 }
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000609 break;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000610
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000611 // FIXME: split this large chunk of code.
612 case ISD::STORE :
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000613 {
Dan Gohman475871a2008-07-27 21:46:04 +0000614 SDValue Chain = N->getOperand(0);
615 SDValue Src = N->getOperand(1);
616 SDValue Dest = N->getOperand(2);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000617 unsigned int DstOff = 0;
Evan Chengbb606742008-05-14 20:33:21 +0000618 int NUM_STORES = 0;
Dan Gohman475871a2008-07-27 21:46:04 +0000619 SDValue Stores[6];
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000620
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000621 // if source operand is expected to be extended to
622 // some higher type then - remove this extension
623 // SDNode and do the extension manually
624 if ((Src.getOpcode() == ISD::ANY_EXTEND) ||
625 (Src.getOpcode() == ISD::SIGN_EXTEND) ||
626 (Src.getOpcode() == ISD::ZERO_EXTEND)) {
Gabor Greifba36cb52008-08-28 21:40:38 +0000627 Src = Src.getNode()->getOperand(0);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000628 Stores[0] = DAG.getStore(Chain, Src, Dest, NULL,0);
629 return Stores[0];
630 }
631
Duncan Sands83ec4b62008-06-06 12:08:01 +0000632 switch(Src.getValueType().getSimpleVT()) {
633 default:
634 assert(false && "Invalid value type!");
635
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000636 case MVT::i8:
637 break;
638
639 case MVT::i16:
640 NUM_STORES = 2;
641 break;
642
643 case MVT::i32:
644 NUM_STORES = 4;
645 break;
646
647 case MVT::i64:
648 NUM_STORES = 8;
649 break;
650 }
651
652 if (isa<GlobalAddressSDNode>(Dest) && isa<LoadSDNode>(Src) &&
653 (Src.getValueType() != MVT::i8)) {
654 //create direct addressing a = b
655 Chain = Src.getOperand(0);
656 for (i=0; i<NUM_STORES; i++) {
Dan Gohman475871a2008-07-27 21:46:04 +0000657 SDValue ADN = DAG.getNode(ISD::ADD, MVT::i16, Src.getOperand(1),
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000658 DAG.getConstant(DstOff, MVT::i16));
Dan Gohman475871a2008-07-27 21:46:04 +0000659 SDValue LDN = DAG.getLoad(MVT::i8, Chain, ADN, NULL, 0);
660 SDValue DSTADDR = DAG.getNode(ISD::ADD, MVT::i16, Dest,
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000661 DAG.getConstant(DstOff, MVT::i16));
662 Stores[i] = DAG.getStore(Chain, LDN, DSTADDR, NULL, 0);
663 Chain = Stores[i];
664 DstOff += 1;
665 }
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000666
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000667 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i);
668 return Chain;
669 }
670 else if (isa<GlobalAddressSDNode>(Dest) && isa<ConstantSDNode>(Src)
671 && (Src.getValueType() != MVT::i8)) {
672 //create direct addressing a = CONST
673 CST = dyn_cast<ConstantSDNode>(Src);
674 for (i = 0; i < NUM_STORES; i++) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000675 SDValue CNST = DAG.getConstant(CST->getZExtValue() >> i*8, MVT::i8);
Dan Gohman475871a2008-07-27 21:46:04 +0000676 SDValue ADN = DAG.getNode(ISD::ADD, MVT::i16, Dest,
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000677 DAG.getConstant(DstOff, MVT::i16));
678 Stores[i] = DAG.getStore(Chain, CNST, ADN, NULL, 0);
679 Chain = Stores[i];
680 DstOff += 1;
681 }
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000682
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000683 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i);
684 return Chain;
685 }
686 else if (isa<LoadSDNode>(Dest) && isa<ConstantSDNode>(Src)
687 && (Src.getValueType() != MVT::i8)) {
688 // Create indirect addressing.
689 CST = dyn_cast<ConstantSDNode>(Src);
690 Chain = Dest.getOperand(0);
Dan Gohman475871a2008-07-27 21:46:04 +0000691 SDValue Load;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000692 Load = DAG.getLoad(MVT::i16, Chain,Dest.getOperand(1), NULL, 0);
693 Chain = Load.getValue(1);
694 for (i=0; i<NUM_STORES; i++) {
Dan Gohmanf5aeb1a2008-09-12 16:56:44 +0000695 SDValue CNST = DAG.getConstant(CST->getZExtValue() >> i*8, MVT::i8);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000696 Stores[i] = DAG.getStore(Chain, CNST, Load, NULL, 0);
697 Chain = Stores[i];
698 DstOff += 1;
699 }
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000700
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000701 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], i);
702 return Chain;
703 }
704 else if (isa<LoadSDNode>(Dest) && isa<GlobalAddressSDNode>(Src)) {
705 // GlobalAddressSDNode *GAD = dyn_cast<GlobalAddressSDNode>(Src);
Dan Gohman475871a2008-07-27 21:46:04 +0000706 return SDValue();
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000707 }
708 else if (Src.getOpcode() == PIC16ISD::Package) {
709 StoreSDNode *st = dyn_cast<StoreSDNode>(N);
Dan Gohman475871a2008-07-27 21:46:04 +0000710 SDValue toWorkList, retVal;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000711 Chain = N->getOperand(0);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000712
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000713 if (st->isTruncatingStore()) {
714 retVal = DAG.getStore(Chain, Src.getOperand(0), Dest, NULL, 0);
715 }
716 else {
717 toWorkList = DAG.getNode(ISD::ADD, MVT::i16, Dest,
718 DAG.getConstant(1, MVT::i16));
719 Stores[1] = DAG.getStore(Chain, Src.getOperand(0), Dest, NULL, 0);
720 Stores[0] = DAG.getStore(Chain, Src.getOperand(1), toWorkList, NULL,
721 0);
722
723 // We want to merge sequence of add with constant to one add and a
724 // constant, so add the ADD node to worklist to have llvm do that
725 // automatically.
Gabor Greifba36cb52008-08-28 21:40:38 +0000726 DCI.AddToWorklist(toWorkList.getNode());
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000727
728 // We don't need the Package so add to worklist so llvm deletes it
Gabor Greifba36cb52008-08-28 21:40:38 +0000729 DCI.AddToWorklist(Src.getNode());
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000730 retVal = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], 2);
731 }
732
733 return retVal;
734 }
735 else if (Src.getOpcode() == ISD::TRUNCATE) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000736 }
737 else {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000738 }
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000739 } // end ISD::STORE.
740 break;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000741
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000742 case ISD::LOAD :
743 {
Dan Gohman475871a2008-07-27 21:46:04 +0000744 SDValue Ptr = N->getOperand(1);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000745 if (Ptr.getOpcode() == PIC16ISD::Package) {
746 assert (0 && "not implemented yet");
747 }
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000748 }
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000749 break;
750 } // end switch.
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000751
Dan Gohman475871a2008-07-27 21:46:04 +0000752 return SDValue();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000753}
754
755//===----------------------------------------------------------------------===//
756// Utility functions
757//===----------------------------------------------------------------------===//
Dan Gohman475871a2008-07-27 21:46:04 +0000758const SDValue *PIC16TargetLowering::
759findLoadi8(const SDValue &Src, SelectionDAG &DAG) const
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000760{
761 unsigned int i;
762 if ((Src.getOpcode() == ISD::LOAD) && (Src.getValueType() == MVT::i8))
763 return &Src;
764 for (i=0; i<Src.getNumOperands(); i++) {
Dan Gohman475871a2008-07-27 21:46:04 +0000765 const SDValue *retVal = findLoadi8(Src.getOperand(i),DAG);
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000766 if (retVal) return retVal;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000767 }
768
769 return NULL;
770}