blob: 8a5fdb23e869c3b02bea31b2d471e05c4399eef6 [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"
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000020#include "llvm/GlobalValue.h"
Sanjiv Gupta0e687712008-05-13 09:02:57 +000021#include "llvm/Function.h"
Sanjiv Gupta0e687712008-05-13 09:02:57 +000022#include "llvm/CodeGen/MachineFrameInfo.h"
23#include "llvm/CodeGen/MachineFunction.h"
Duncan Sandsc6dbe7f2008-11-28 10:20:03 +000024#include <cstdio>
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000025
26
Sanjiv Gupta0e687712008-05-13 09:02:57 +000027using namespace llvm;
28
Sanjiv Gupta0e687712008-05-13 09:02:57 +000029
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000030// PIC16TargetLowering Constructor.
31PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM)
32 : TargetLowering(TM) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +000033
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000034 Subtarget = &TM.getSubtarget<PIC16Subtarget>();
Sanjiv Gupta0e687712008-05-13 09:02:57 +000035
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000036 addRegisterClass(MVT::i8, PIC16::GPRRegisterClass);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000037
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000038 setShiftAmountType(MVT::i8);
39 setShiftAmountFlavor(Extend);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000040
Sanjiv Gupta0e687712008-05-13 09:02:57 +000041
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000042 setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000043
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000044 setOperationAction(ISD::LOAD, MVT::i8, Legal);
45 setOperationAction(ISD::LOAD, MVT::i16, Custom);
46 setOperationAction(ISD::LOAD, MVT::i32, Custom);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000047
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000048 setOperationAction(ISD::STORE, MVT::i8, Legal);
49 setOperationAction(ISD::STORE, MVT::i16, Custom);
50 setOperationAction(ISD::STORE, MVT::i32, Custom);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000051
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000052 setOperationAction(ISD::ADDE, MVT::i8, Custom);
53 setOperationAction(ISD::ADDC, MVT::i8, Custom);
54 setOperationAction(ISD::SUBE, MVT::i8, Custom);
55 setOperationAction(ISD::SUBC, MVT::i8, Custom);
56 setOperationAction(ISD::ADD, MVT::i8, Legal);
57 setOperationAction(ISD::ADD, MVT::i16, Custom);
58
Sanjiv Gupta8f78fa82008-11-26 10:53:50 +000059 setOperationAction(ISD::OR, MVT::i8, Custom);
60 setOperationAction(ISD::AND, MVT::i8, Custom);
61 setOperationAction(ISD::XOR, MVT::i8, Custom);
62
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000063 setOperationAction(ISD::SHL, MVT::i16, Custom);
64 setOperationAction(ISD::SHL, MVT::i32, Custom);
65
66 //setOperationAction(ISD::TRUNCATE, MVT::i16, Custom);
67 setTruncStoreAction(MVT::i16, MVT::i8, Custom);
68
69 // Now deduce the information based on the above mentioned
70 // actions
Sanjiv Gupta0e687712008-05-13 09:02:57 +000071 computeRegisterProperties();
72}
73
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000074const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode) const {
75 switch (Opcode) {
76 default: return NULL;
77 case PIC16ISD::Lo: return "PIC16ISD::Lo";
78 case PIC16ISD::Hi: return "PIC16ISD::Hi";
79 case PIC16ISD::MTLO: return "PIC16ISD::MTLO";
80 case PIC16ISD::MTHI: return "PIC16ISD::MTHI";
81 case PIC16ISD::Banksel: return "PIC16ISD::Banksel";
82 case PIC16ISD::PIC16Load: return "PIC16ISD::PIC16Load";
83 case PIC16ISD::PIC16Store: return "PIC16ISD::PIC16Store";
84 case PIC16ISD::BCF: return "PIC16ISD::BCF";
85 case PIC16ISD::LSLF: return "PIC16ISD::LSLF";
86 case PIC16ISD::LRLF: return "PIC16ISD::LRLF";
87 case PIC16ISD::RLF: return "PIC16ISD::RLF";
88 case PIC16ISD::RRF: return "PIC16ISD::RRF";
89 case PIC16ISD::Dummy: return "PIC16ISD::Dummy";
Sanjiv Gupta0e687712008-05-13 09:02:57 +000090 }
91}
92
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000093SDNode *PIC16TargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) {
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +000094 switch (N->getOpcode()) {
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000095 case ISD::GlobalAddress:
96 return ExpandGlobalAddress(N, DAG);
97 case ISD::STORE:
98 return ExpandStore(N, DAG);
99 case ISD::LOAD:
100 return ExpandLoad(N, DAG);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000101 case ISD::ADD:
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000102 return ExpandAdd(N, DAG);
103 case ISD::SHL:
104 return ExpandShift(N, DAG);
105 default:
106 assert (0 && "not implemented");
107 }
108}
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000109
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000110SDNode *PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) {
111 StoreSDNode *St = cast<StoreSDNode>(N);
112 SDValue Chain = St->getChain();
113 SDValue Src = St->getValue();
114 SDValue Ptr = St->getBasePtr();
115 MVT ValueType = Src.getValueType();
116 unsigned StoreOffset = 0;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000117
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000118 SDValue PtrLo, PtrHi;
119 LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, StoreOffset);
120
121 if (ValueType == MVT::i8) {
122 SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, MVT::Other, Chain, Src,
123 PtrLo, PtrHi, DAG.getConstant (0, MVT::i8));
124 return Store.getNode();
125 }
126 else if (ValueType == MVT::i16) {
127 // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
128 SDValue SrcLo, SrcHi;
129 GetExpandedParts(Src, DAG, SrcLo, SrcHi);
130 SDValue ChainLo = Chain, ChainHi = Chain;
131 if (Chain.getOpcode() == ISD::TokenFactor) {
132 ChainLo = Chain.getOperand(0);
133 ChainHi = Chain.getOperand(1);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000134 }
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000135 SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other,
136 ChainLo,
137 SrcLo, PtrLo, PtrHi,
138 DAG.getConstant (0 + StoreOffset, MVT::i8));
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000139
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000140 SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi,
141 SrcHi, PtrLo, PtrHi,
142 DAG.getConstant (1 + StoreOffset, MVT::i8));
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000143
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000144 return DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1),
145 getChain(Store2)).getNode();
146 }
147 else if (ValueType == MVT::i32) {
148 // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
149 SDValue SrcLo, SrcHi;
150 GetExpandedParts(Src, DAG, SrcLo, SrcHi);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000151
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000152 // Get the expanded parts of each of SrcLo and SrcHi.
153 SDValue SrcLo1, SrcLo2, SrcHi1, SrcHi2;
154 GetExpandedParts(SrcLo, DAG, SrcLo1, SrcLo2);
155 GetExpandedParts(SrcHi, DAG, SrcHi1, SrcHi2);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000156
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000157 SDValue ChainLo = Chain, ChainHi = Chain;
158 if (Chain.getOpcode() == ISD::TokenFactor) {
159 ChainLo = Chain.getOperand(0);
160 ChainHi = Chain.getOperand(1);
161 }
162 SDValue ChainLo1 = ChainLo, ChainLo2 = ChainLo, ChainHi1 = ChainHi,
163 ChainHi2 = ChainHi;
164 if (ChainLo.getOpcode() == ISD::TokenFactor) {
165 ChainLo1 = ChainLo.getOperand(0);
166 ChainLo2 = ChainLo.getOperand(1);
167 }
168 if (ChainHi.getOpcode() == ISD::TokenFactor) {
169 ChainHi1 = ChainHi.getOperand(0);
170 ChainHi2 = ChainHi.getOperand(1);
171 }
172 SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other,
173 ChainLo1,
174 SrcLo1, PtrLo, PtrHi,
175 DAG.getConstant (0 + StoreOffset, MVT::i8));
176
177 SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainLo2,
178 SrcLo2, PtrLo, PtrHi,
179 DAG.getConstant (1 + StoreOffset, MVT::i8));
180
181 SDValue Store3 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi1,
182 SrcHi1, PtrLo, PtrHi,
183 DAG.getConstant (2 + StoreOffset, MVT::i8));
184
185 SDValue Store4 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi2,
186 SrcHi2, PtrLo, PtrHi,
187 DAG.getConstant (3 + StoreOffset, MVT::i8));
188
189 SDValue RetLo = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1),
190 getChain(Store2));
191 SDValue RetHi = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store3),
192 getChain(Store4));
193 return DAG.getNode(ISD::TokenFactor, MVT::Other, RetLo, RetHi).getNode();
194
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000195 }
196 else {
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000197 assert (0 && "value type not supported");
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000198 }
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000199}
200
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000201// ExpandGlobalAddress -
202SDNode *PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) {
203 GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(SDValue(N, 0));
204
205 SDValue TGA = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i8,
206 G->getOffset());
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000207
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000208 SDValue Lo = DAG.getNode(PIC16ISD::Lo, MVT::i8, TGA);
209 SDValue Hi = DAG.getNode(PIC16ISD::Hi, MVT::i8, TGA);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000210
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000211 SDValue BP = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, Lo, Hi);
212 return BP.getNode();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000213}
214
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000215bool PIC16TargetLowering::isDirectAddress(const SDValue &Op) {
216 assert (Op.getNode() != NULL && "Can't operate on NULL SDNode!!");
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000217
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000218 if (Op.getOpcode() == ISD::BUILD_PAIR) {
219 if (Op.getOperand(0).getOpcode() == PIC16ISD::Lo)
220 return true;
221 }
222 return false;
223}
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000224
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000225// Return true if DirectAddress is in ROM_SPACE
226bool PIC16TargetLowering::isRomAddress(const SDValue &Op) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000227
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000228 // RomAddress is a GlobalAddress in ROM_SPACE_
229 // If the Op is not a GlobalAddress return NULL without checking
230 // anything further.
231 if (!isDirectAddress(Op))
232 return false;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000233
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000234 // Its a GlobalAddress.
235 // It is BUILD_PAIR((PIC16Lo TGA), (PIC16Hi TGA)) and Op is BUILD_PAIR
236 SDValue TGA = Op.getOperand(0).getOperand(0);
237 GlobalAddressSDNode *GSDN = dyn_cast<GlobalAddressSDNode>(TGA);
238 const Type *ValueType = GSDN->getGlobal()->getType();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000239
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000240 if (!isa<PointerType>(ValueType)) {
241 assert(0 && "TGA must be of a PointerType");
242 }
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000243
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000244 int AddrSpace = dyn_cast<PointerType>(ValueType)->getAddressSpace();
245 if (AddrSpace == PIC16ISD::ROM_SPACE)
246 return true;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000247
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000248 // Any other address space return it false
249 return false;
250}
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000251
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000252// To extract chain value from the SDValue Nodes
253// This function will help to maintain the chain extracting
254// code at one place. In case of any change in future it will
255// help maintain the code.
256SDValue PIC16TargetLowering::getChain(SDValue &Op) {
257 SDValue Chain = Op.getValue(Op.getNode()->getNumValues() - 1);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000258
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000259 // All nodes may not produce a chain. Therefore following assert
260 // verifies that the node is returning a chain only.
261 assert (Chain.getValueType() == MVT::Other && "Node does not have a chain");
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000262
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000263 return Chain;
264}
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000265
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000266void PIC16TargetLowering::GetExpandedParts(SDValue Op, SelectionDAG &DAG,
267 SDValue &Lo, SDValue &Hi) {
268 SDNode *N = Op.getNode();
269 unsigned NumValues = N->getNumValues();
270 std::vector<MVT> VTs;
271 MVT NewVT;
272 std::vector<SDValue> Opers;
Duncan Sands83ec4b62008-06-06 12:08:01 +0000273
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000274 // EXTRACT_ELEMENT should have same number and type of values that the
275 // node replacing the EXTRACT_ELEMENT should have. (i.e. extracted element)
276 // Some nodes such as LOAD and PIC16Load have more than one values. In such
277 // cases EXTRACT_ELEMENT should have more than one values. Therefore creating
278 // vector of Values for EXTRACT_ELEMENT. This list will have same number of
279 // values as the extracted element will have.
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000280
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000281 for (unsigned i=0;i < NumValues; ++i) {
282 NewVT = getTypeToTransformTo(N->getValueType(i));
283 VTs.push_back(NewVT);
284 }
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000285
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000286 // extract the lo component
287 Opers.push_back(Op);
288 Opers.push_back(DAG.getConstant(0,MVT::i8));
289 Lo = DAG.getNode(ISD::EXTRACT_ELEMENT,VTs,&Opers[0],Opers.size());
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000290
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000291 // extract the hi component
292 Opers.clear();
293 Opers.push_back(Op);
294 Opers.push_back(DAG.getConstant(1,MVT::i8));
295 Hi = DAG.getNode(ISD::EXTRACT_ELEMENT,VTs,&Opers[0],Opers.size());
296}
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000297
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000298// This function legalizes the PIC16 Addresses. If the Pointer is
299// -- Direct address variable residing
300// --> then a Banksel for that variable will be created.
301// -- Rom variable
302// --> then it will be treated as an indirect address.
303// -- Indirect address
304// --> then the address will be loaded into FSR
305// -- ADD with constant operand
306// --> then constant operand of ADD will be returned as Offset
307// and non-constant operand of ADD will be treated as pointer.
308// Returns the high and lo part of the address, and the offset(in case of ADD).
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000309
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000310void PIC16TargetLowering:: LegalizeAddress(SDValue Ptr, SelectionDAG &DAG,
311 SDValue &Lo, SDValue &Hi,
312 unsigned &Offset) {
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000313
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000314 // Offset, by default, should be 0
315 Offset = 0;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000316
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000317 // If the pointer is ADD with constant,
318 // return the constant value as the offset
319 if (Ptr.getOpcode() == ISD::ADD) {
320 SDValue OperLeft = Ptr.getOperand(0);
321 SDValue OperRight = Ptr.getOperand(1);
322 if (OperLeft.getOpcode() == ISD::Constant) {
323 Offset = dyn_cast<ConstantSDNode>(OperLeft)->getZExtValue();
324 Ptr = OperRight;
325 } else {
326 Ptr = OperLeft;
327 Offset = dyn_cast<ConstantSDNode>(OperRight)->getZExtValue();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000328 }
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000329 }
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000330
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000331 if (isDirectAddress(Ptr) && !isRomAddress(Ptr)) {
332 // Direct addressing case for RAM variables. The Hi part is constant
333 // and the Lo part is the TGA itself.
334 Lo = Ptr.getOperand(0).getOperand(0);
335
336 // For direct addresses Hi is a constant. Value 1 for the constant
337 // signifies that banksel needs to generated for it. Value 0 for
338 // the constant signifies that banksel does not need to be generated
339 // for it. Mark it as 1 now and optimize later.
340 Hi = DAG.getConstant(1, MVT::i8);
341 return;
342 }
343
344 // Indirect addresses. Get the hi and lo parts of ptr.
345 GetExpandedParts(Ptr, DAG, Lo, Hi);
346
347 // Put the hi and lo parts into FSR.
348 Lo = DAG.getNode(PIC16ISD::MTLO, MVT::i8, Lo);
349 Hi = DAG.getNode(PIC16ISD::MTHI, MVT::i8, Hi);
350
351 return;
352}
353
354SDNode *PIC16TargetLowering::ExpandAdd(SDNode *N, SelectionDAG &DAG) {
355 SDValue OperLeft = N->getOperand(0);
356 SDValue OperRight = N->getOperand(1);
357
358 if((OperLeft.getOpcode() == ISD::Constant) ||
359 (OperRight.getOpcode() == ISD::Constant)) {
360 return NULL;
361 }
362
363 // These case are yet to be handled
364 return NULL;
365}
366
367SDNode *PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) {
368 LoadSDNode *LD = dyn_cast<LoadSDNode>(SDValue(N, 0));
369 SDValue Chain = LD->getChain();
370 SDValue Ptr = LD->getBasePtr();
371
372 SDValue Load, Offset;
373 SDVTList Tys;
374 MVT VT, NewVT;
375 SDValue PtrLo, PtrHi;
376 unsigned LoadOffset;
377
378 // Legalize direct/indirect addresses. This will give the lo and hi parts
379 // of the address and the offset.
380 LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, LoadOffset);
381
382 // Load from the pointer (direct address or FSR)
383 VT = N->getValueType(0);
384 unsigned NumLoads = VT.getSizeInBits() / 8;
385 std::vector<SDValue> PICLoads;
386 unsigned iter;
387 MVT MemVT = LD->getMemoryVT();
388 if(ISD::isNON_EXTLoad(N)) {
389 for (iter=0; iter<NumLoads ; ++iter) {
390 // Add the pointer offset if any
391 Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
392 Tys = DAG.getVTList(MVT::i8, MVT::Other);
393 Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Chain, PtrLo, PtrHi,
394 Offset);
395 PICLoads.push_back(Load);
396 }
397 } else {
398 // If it is extended load then use PIC16Load for Memory Bytes
399 // and for all extended bytes perform action based on type of
400 // extention - i.e. SignExtendedLoad or ZeroExtendedLoad
401
402
403 // For extended loads this is the memory value type
404 // i.e. without any extension
405 MVT MemVT = LD->getMemoryVT();
406 unsigned MemBytes = MemVT.getSizeInBits() / 8;
407 unsigned ExtdBytes = VT.getSizeInBits() / 8;
408 Offset = DAG.getConstant(LoadOffset, MVT::i8);
409
410 Tys = DAG.getVTList(MVT::i8, MVT::Other);
411 // For MemBytes generate PIC16Load with proper offset
412 for (iter=0; iter<MemBytes; ++iter) {
413 // Add the pointer offset if any
414 Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
415 Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Chain, PtrLo, PtrHi,
416 Offset);
417 PICLoads.push_back(Load);
418 }
419
420 // For SignExtendedLoad
421 if (ISD::isSEXTLoad(N)) {
422 // For all ExtdBytes use the Right Shifted(Arithmetic) Value of the
423 // highest MemByte
424 SDValue SRA = DAG.getNode(ISD::SRA, MVT::i8, Load,
425 DAG.getConstant(7, MVT::i8));
426 for (iter=MemBytes; iter<ExtdBytes; ++iter) {
427 PICLoads.push_back(SRA);
428 }
429 } else if (ISD::isZEXTLoad(N)) {
430 // ZeroExtendedLoad -- For all ExtdBytes use constant 0
431 SDValue ConstZero = DAG.getConstant(0, MVT::i8);
432 for (iter=MemBytes; iter<ExtdBytes; ++iter) {
433 PICLoads.push_back(ConstZero);
434 }
435 }
436 }
437 SDValue BP;
438
439 if (VT == MVT::i8) {
440 // Operand of Load is illegal -- Load itself is legal
441 return PICLoads[0].getNode();
442 }
443 else if (VT == MVT::i16) {
444 BP = DAG.getNode(ISD::BUILD_PAIR, VT, PICLoads[0], PICLoads[1]);
445 if (MemVT == MVT::i8)
446 Chain = getChain(PICLoads[0]);
447 else
448 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]),
449 getChain(PICLoads[1]));
450 } else if (VT == MVT::i32) {
451 SDValue BPs[2];
452 BPs[0] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[0], PICLoads[1]);
453 BPs[1] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[2], PICLoads[3]);
454 BP = DAG.getNode(ISD::BUILD_PAIR, VT, BPs[0], BPs[1]);
455 if (MemVT == MVT::i8)
456 Chain = getChain(PICLoads[0]);
457 else if (MemVT == MVT::i16)
458 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]),
459 getChain(PICLoads[1]));
460 else {
461 SDValue Chains[2];
462 Chains[0] = DAG.getNode(ISD::TokenFactor, MVT::Other,
463 getChain(PICLoads[0]), getChain(PICLoads[1]));
464 Chains[1] = DAG.getNode(ISD::TokenFactor, MVT::Other,
465 getChain(PICLoads[2]), getChain(PICLoads[3]));
466 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Chains[0], Chains[1]);
467 }
468 }
469 Tys = DAG.getVTList(VT, MVT::Other);
470 SDValue MergeV = DAG.getNode(ISD::MERGE_VALUES, Tys, BP, Chain);
471 return MergeV.getNode();
472
473}
474
475SDNode *PIC16TargetLowering::ExpandShift(SDNode *N, SelectionDAG &DAG) {
476 SDValue Value = N->getOperand(0);
477 SDValue Amt = N->getOperand(1);
478 SDValue BCF, BCFInput;
479 SDVTList Tys;
480 SDValue ShfCom; // Shift Component - Lo component should be shifted
481 SDValue RotCom; // Rotate Component- Hi component should be rotated
Evan Chengdc52cf42008-11-27 02:29:25 +0000482 PIC16ISD::NodeType ShfNode = PIC16ISD::Dummy, RotNode = PIC16ISD::Dummy;
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000483
484 // Currently handling Constant shift only
485 if (Amt.getOpcode() != ISD::Constant)
486 return NULL;
487
488 // Following code considers 16 bit left-shift only
489 if (N->getValueType(0) != MVT::i16)
490 return NULL;
491
492 if (N->getOpcode() == ISD::SHL) {
493 ShfNode = PIC16ISD::LSLF;
494 RotNode = PIC16ISD::RLF;
495 } else if (N->getOpcode() == ISD::SRL) {
496 ShfNode = PIC16ISD::LRLF;
497 RotNode = PIC16ISD::RRF;
498 }
499 unsigned ShiftAmt = dyn_cast<ConstantSDNode>(Amt)->getZExtValue();
500 SDValue StatusReg = DAG.getRegister(PIC16::STATUS, MVT::i8);
501 // 0th Bit in StatusReg is CarryBit
502 SDValue CarryBit= DAG.getConstant(0, MVT::i8);
503
504 GetExpandedParts(Value, DAG, ShfCom, RotCom);
505 BCFInput = DAG.getNode(PIC16ISD::Dummy, MVT::Flag);
506 Tys = DAG.getVTList(MVT::i8, MVT::Flag);
507
508 for (unsigned i=0;i<ShiftAmt;i++) {
509 BCF = DAG.getNode(PIC16ISD::BCF, MVT::Flag, StatusReg, CarryBit, BCFInput);
510
511 // Following are Two-Address Instructions
512 ShfCom = DAG.getNode(ShfNode, Tys, ShfCom, BCF);
513 RotCom = DAG.getNode(RotNode, Tys, RotCom, ShfCom.getValue(1));
514
515 BCFInput = RotCom.getValue(1);
516 }
517
518 SDValue BP = DAG.getNode(ISD::BUILD_PAIR, N->getValueType(0), ShfCom, RotCom);
519 return BP.getNode();
520}
521
522SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
523 switch (Op.getOpcode()) {
524 case ISD::FORMAL_ARGUMENTS:
525 return LowerFORMAL_ARGUMENTS(Op, DAG);
526 case ISD::ADDC:
527 return LowerADDC(Op, DAG);
528 case ISD::ADDE:
529 return LowerADDE(Op, DAG);
530 case ISD::SUBE:
531 return LowerSUBE(Op, DAG);
532 case ISD::SUBC:
533 return LowerSUBC(Op, DAG);
534 case ISD::LOAD:
535 return SDValue(ExpandLoad(Op.getNode(), DAG), Op.getResNo());
536 case ISD::STORE:
537 return SDValue(ExpandStore(Op.getNode(), DAG), Op.getResNo());
538 case ISD::SHL:
539 return SDValue(ExpandShift(Op.getNode(), DAG), Op.getResNo());
Sanjiv Gupta8f78fa82008-11-26 10:53:50 +0000540 case ISD::OR:
541 case ISD::AND:
542 case ISD::XOR:
543 return LowerBinOp(Op, DAG);
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000544 }
Dan Gohman475871a2008-07-27 21:46:04 +0000545 return SDValue();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000546}
547
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000548SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op,
549 SelectionDAG &DAG) {
550
551 assert (Op.getValueType() == MVT::i8
552 && "illegal value type to store on stack.");
553
554 MachineFunction &MF = DAG.getMachineFunction();
555 const Function *Func = MF.getFunction();
556 const std::string FuncName = Func->getName();
557
558 char *tmpName = new char [strlen(FuncName.c_str()) + 6];
559
560 // Put the value on stack.
561 // Get a stack slot index and convert to es.
562 int FI = MF.getFrameInfo()->CreateStackObject(1, 1);
563 sprintf(tmpName, "%s.tmp", FuncName.c_str());
564 SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
565
566 // Store the value to ES.
567 SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, MVT::Other,
568 DAG.getEntryNode(),
569 Op, ES,
570 DAG.getConstant (1, MVT::i8), // Banksel.
571 DAG.getConstant (FI, MVT::i8));
572
573 // Load the value from ES.
574 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other);
575 SDValue Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Store,
576 ES, DAG.getConstant (1, MVT::i8),
577 DAG.getConstant (FI, MVT::i8));
578
579 return Load.getValue(0);
580}
581
Sanjiv Gupta8f78fa82008-11-26 10:53:50 +0000582SDValue PIC16TargetLowering:: LowerBinOp(SDValue Op, SelectionDAG &DAG) {
583 // We should have handled larger operands in type legalizer itself.
584 assert (Op.getValueType() == MVT::i8 && "illegal Op to lower");
585
586 // Return the original Op if the one of the operands is already a load.
587 if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load
588 || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load)
589 return Op;
590
591 // Put one value on stack.
592 SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG);
593
594 return DAG.getNode(Op.getOpcode(), MVT::i8, Op.getOperand(0), NewVal);
595}
596
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000597SDValue PIC16TargetLowering:: LowerADDC(SDValue Op, SelectionDAG &DAG) {
598 // We should have handled larger operands in type legalizer itself.
599 assert (Op.getValueType() == MVT::i8 && "illegal addc to lower");
600
601 // Nothing to do if the one of the operands is already a load.
602 if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load
603 || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load)
604 return SDValue();
605
606 // Put one value on stack.
607 SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG);
608
609 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
610 return DAG.getNode(ISD::ADDC, Tys, Op.getOperand(0), NewVal);
611}
612
613SDValue PIC16TargetLowering:: LowerADDE(SDValue Op, SelectionDAG &DAG) {
614 // We should have handled larger operands in type legalizer itself.
615 assert (Op.getValueType() == MVT::i8 && "illegal adde to lower");
616
617 // Nothing to do if the one of the operands is already a load.
618 if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load
619 || Op.getOperand(1).getOpcode() == PIC16ISD::PIC16Load)
620 return SDValue();
621
622 // Put one value on stack.
623 SDValue NewVal = ConvertToMemOperand (Op.getOperand(1), DAG);
624
625 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
626 return DAG.getNode(ISD::ADDE, Tys, Op.getOperand(0), NewVal,
627 Op.getOperand(2));
628}
629
630SDValue PIC16TargetLowering:: LowerSUBC(SDValue Op, SelectionDAG &DAG) {
631 // We should have handled larger operands in type legalizer itself.
632 assert (Op.getValueType() == MVT::i8 && "illegal subc to lower");
633
634 // Nothing to do if the first operand is already a load.
635 if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load)
636 return SDValue();
637
638 // Put first operand on stack.
639 SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG);
640
641 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
642 return DAG.getNode(ISD::SUBC, Tys, NewVal, Op.getOperand(1));
643}
644
645SDValue PIC16TargetLowering:: LowerSUBE(SDValue Op, SelectionDAG &DAG) {
646 // We should have handled larger operands in type legalizer itself.
647 assert (Op.getValueType() == MVT::i8 && "illegal sube to lower");
648
649 // Nothing to do if the first operand is already a load.
650 if (Op.getOperand(0).getOpcode() == PIC16ISD::PIC16Load)
651 return SDValue();
652
653 // Put first operand on stack.
654 SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG);
655
656 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
657 return DAG.getNode(ISD::SUBE, Tys, NewVal, Op.getOperand(1),
658 Op.getOperand(2));
659}
660
661// LowerFORMAL_ARGUMENTS - In Lowering FORMAL ARGUMENTS - MERGE_VALUES nodes
662// is returned. MERGE_VALUES nodes number of operands and number of values are
663// equal. Therefore to construct MERGE_VALUE node, UNDEF nodes equal to the
664// number of arguments of function have been created.
665
666SDValue PIC16TargetLowering:: LowerFORMAL_ARGUMENTS(SDValue Op,
667 SelectionDAG &DAG) {
668 SmallVector<SDValue, 8> ArgValues;
669 unsigned NumArgs = Op.getNumOperands() - 3;
670
671 // Creating UNDEF nodes to meet the requirement of MERGE_VALUES node.
672 for(unsigned i = 0 ; i<NumArgs ; i++) {
673 SDValue TempNode = DAG.getNode(ISD::UNDEF, Op.getNode()->getValueType(i));
674 ArgValues.push_back(TempNode);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000675 }
676
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000677 ArgValues.push_back(Op.getOperand(0));
678 return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(),
679 &ArgValues[0],
680 ArgValues.size()).getValue(Op.getResNo());
681}
682
683// Perform DAGCombine of PIC16Load
684SDValue PIC16TargetLowering::
685PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const {
686 SelectionDAG &DAG = DCI.DAG;
687 SDValue Chain = N->getOperand(0);
688 if (N->hasNUsesOfValue(0, 0)) {
689 DAG.ReplaceAllUsesOfValueWith(SDValue(N,1), Chain);
690 }
691 return SDValue();
692}
693
694
695SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N,
696 DAGCombinerInfo &DCI) const {
697 switch (N->getOpcode()) {
698 case PIC16ISD::PIC16Load:
699 return PerformPIC16LoadCombine(N, DCI);
700 }
701 return SDValue();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000702}