blob: 1f1f9e477ca8eea9e464e72a2eaf8fe3df8ee41d [file] [log] [blame]
Sanjiv Gupta0e687712008-05-13 09:02:57 +00001//
2// The LLVM Compiler Infrastructure
3//
4// This file is distributed under the University of Illinois Open Source
5// License. See LICENSE.TXT for details.
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the interfaces that PIC16 uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#define DEBUG_TYPE "pic16-lower"
15
16#include "PIC16ISelLowering.h"
17#include "PIC16TargetMachine.h"
18#include "llvm/DerivedTypes.h"
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000019#include "llvm/GlobalValue.h"
Sanjiv Gupta0e687712008-05-13 09:02:57 +000020#include "llvm/Function.h"
Sanjiv Gupta1b046942009-01-13 19:18:47 +000021#include "llvm/CallingConv.h"
Sanjiv Gupta0e687712008-05-13 09:02:57 +000022#include "llvm/CodeGen/MachineFrameInfo.h"
23#include "llvm/CodeGen/MachineFunction.h"
Sanjiv Gupta1b046942009-01-13 19:18:47 +000024#include "llvm/CodeGen/MachineInstrBuilder.h"
25#include "llvm/CodeGen/MachineRegisterInfo.h"
Duncan Sandsc6dbe7f2008-11-28 10:20:03 +000026#include <cstdio>
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000027
28
Sanjiv Gupta0e687712008-05-13 09:02:57 +000029using namespace llvm;
30
Sanjiv Gupta0e687712008-05-13 09:02:57 +000031
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000032// PIC16TargetLowering Constructor.
33PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine &TM)
34 : TargetLowering(TM) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +000035
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000036 Subtarget = &TM.getSubtarget<PIC16Subtarget>();
Sanjiv Gupta0e687712008-05-13 09:02:57 +000037
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000038 addRegisterClass(MVT::i8, PIC16::GPRRegisterClass);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000039
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000040 setShiftAmountType(MVT::i8);
41 setShiftAmountFlavor(Extend);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000042
Sanjiv Gupta1b046942009-01-13 19:18:47 +000043 // SRA library call names
44 setPIC16LibCallName(PIC16ISD::SRA_I8, "__intrinsics.sra.i8");
45 setPIC16LibCallName(PIC16ISD::SRA_I16, "__intrinsics.sra.i16");
46 setPIC16LibCallName(PIC16ISD::SRA_I32, "__intrinsics.sra.i32");
47
48 // SLL library call names
49 setPIC16LibCallName(PIC16ISD::SLL_I8, "__intrinsics.sll.i8");
50 setPIC16LibCallName(PIC16ISD::SLL_I16, "__intrinsics.sll.i16");
51 setPIC16LibCallName(PIC16ISD::SLL_I32, "__intrinsics.sll.i32");
52
53 // SRL library call names
54 setPIC16LibCallName(PIC16ISD::SRL_I8, "__intrinsics.srl.i8");
55 setPIC16LibCallName(PIC16ISD::SRL_I16, "__intrinsics.srl.i16");
56 setPIC16LibCallName(PIC16ISD::SRL_I32, "__intrinsics.srl.i32");
Sanjiv Gupta0e687712008-05-13 09:02:57 +000057
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000058 setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000059
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000060 setOperationAction(ISD::LOAD, MVT::i8, Legal);
61 setOperationAction(ISD::LOAD, MVT::i16, Custom);
62 setOperationAction(ISD::LOAD, MVT::i32, Custom);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000063
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000064 setOperationAction(ISD::STORE, MVT::i8, Legal);
65 setOperationAction(ISD::STORE, MVT::i16, Custom);
66 setOperationAction(ISD::STORE, MVT::i32, Custom);
Sanjiv Gupta0e687712008-05-13 09:02:57 +000067
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000068 setOperationAction(ISD::ADDE, MVT::i8, Custom);
69 setOperationAction(ISD::ADDC, MVT::i8, Custom);
70 setOperationAction(ISD::SUBE, MVT::i8, Custom);
71 setOperationAction(ISD::SUBC, MVT::i8, Custom);
72 setOperationAction(ISD::ADD, MVT::i8, Legal);
73 setOperationAction(ISD::ADD, MVT::i16, Custom);
74
Sanjiv Gupta8f78fa82008-11-26 10:53:50 +000075 setOperationAction(ISD::OR, MVT::i8, Custom);
76 setOperationAction(ISD::AND, MVT::i8, Custom);
77 setOperationAction(ISD::XOR, MVT::i8, Custom);
78
Sanjiv Gupta1b046942009-01-13 19:18:47 +000079 setOperationAction(ISD::FrameIndex, MVT::i16, Custom);
80 setOperationAction(ISD::CALL, MVT::i16, Custom);
81 setOperationAction(ISD::RET, MVT::Other, Custom);
82
83 setOperationAction(ISD::SRA, MVT::i8, Custom);
84 setOperationAction(ISD::SRA, MVT::i16, Custom);
85 setOperationAction(ISD::SRA, MVT::i32, Custom);
86
87 setOperationAction(ISD::SHL, MVT::i8, Custom);
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +000088 setOperationAction(ISD::SHL, MVT::i16, Custom);
89 setOperationAction(ISD::SHL, MVT::i32, Custom);
Sanjiv Gupta1b046942009-01-13 19:18:47 +000090 setOperationAction(ISD::SRL, MVT::i8, Custom);
91 setOperationAction(ISD::SRL, MVT::i16, Custom);
92 setOperationAction(ISD::SRL, MVT::i32, Custom);
93
94 // PIC16 does not have a SETCC, expand it to SELECT_CC.
95 setOperationAction(ISD::SETCC, MVT::i8, Expand);
96 setOperationAction(ISD::SELECT, MVT::i8, Expand);
97 setOperationAction(ISD::BRCOND, MVT::Other, Expand);
98 setOperationAction(ISD::BRIND, MVT::Other, Expand);
99
100 setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);
101 setOperationAction(ISD::BR_CC, MVT::i8, Custom);
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000102
103 //setOperationAction(ISD::TRUNCATE, MVT::i16, Custom);
104 setTruncStoreAction(MVT::i16, MVT::i8, Custom);
105
106 // Now deduce the information based on the above mentioned
107 // actions
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000108 computeRegisterProperties();
109}
110
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000111static void PopulateResults(SDValue N, SmallVectorImpl<SDValue>&Results) {
112 if (N.getOpcode() == ISD::MERGE_VALUES) {
113 int NumResults = N.getNumOperands();
114 for( int i = 0; i < NumResults; i++)
115 Results.push_back(N.getOperand(i));
116 }
117 else
118 Results.push_back(N);
119}
120
121MVT PIC16TargetLowering::getSetCCResultType(MVT ValType) const {
122 return MVT::i8;
123}
124
125
126void
127PIC16TargetLowering::setPIC16LibCallName(PIC16ISD::PIC16LibCall Call,
128 const char *Name) {
129 PIC16LibCallNames[Call] = Name;
130}
131
132const char *
133PIC16TargetLowering::getPIC16LibCallName(PIC16ISD::PIC16LibCall Call) {
134 return PIC16LibCallNames[Call];
135}
136
137SDValue
138PIC16TargetLowering::MakePIC16LibCall(PIC16ISD::PIC16LibCall Call,
139 MVT RetVT, const SDValue *Ops,
140 unsigned NumOps, bool isSigned,
141 SelectionDAG &DAG) {
142
143 TargetLowering::ArgListTy Args;
144 Args.reserve(NumOps);
145
146 TargetLowering::ArgListEntry Entry;
147 for (unsigned i = 0; i != NumOps; ++i) {
148 Entry.Node = Ops[i];
149 Entry.Ty = Entry.Node.getValueType().getTypeForMVT();
150 Entry.isSExt = isSigned;
151 Entry.isZExt = !isSigned;
152 Args.push_back(Entry);
153 }
154 SDValue Callee = DAG.getExternalSymbol(getPIC16LibCallName(Call), MVT::i8);
155
156 const Type *RetTy = RetVT.getTypeForMVT();
157 std::pair<SDValue,SDValue> CallInfo =
158 LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false,
159 false, CallingConv::C, false, Callee, Args, DAG);
160
161 return CallInfo.first;
162}
163
164SDValue
165PIC16TargetLowering::getCurrentFrame(SelectionDAG &DAG) {
166 MachineFunction &MF = DAG.getMachineFunction();
167 const Function *Func = MF.getFunction();
168 const std::string FuncName = Func->getName();
169
170 // this is causing memory waste
171 // because for every call new memory will be allocated
172 char *tmpName = new char [strlen(FuncName.c_str()) + 6];
173 sprintf(tmpName, "%s.tmp", FuncName.c_str());
174
175 // if the external symbol of the same name already exists then
176 // it will not create the new one.
177 return DAG.getTargetExternalSymbol(tmpName, MVT::i8);
178}
179
180void
181PIC16TargetLowering::getCurrentFrameIndex(SelectionDAG &DAG, SDValue &ES,
182 unsigned SlotSize, int &FromFI) {
183 MachineFunction &MF = DAG.getMachineFunction();
184 const Function *Func = MF.getFunction();
185 const std::string FuncName = Func->getName();
186
187 // this is causing memory waste
188 // because for every call new memory will be allocated
189 char *tmpName = new char [strlen(FuncName.c_str()) + 6];
190 sprintf(tmpName, "%s.tmp", FuncName.c_str());
191
192 // if the external symbol of the same name already exists then
193 // it will not create the new one.
194 ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
195
196 // Alignment is always 1
197 //FromFI = MF.getFrameInfo()->CreateStackObject(SlotSize, 1);
198 FromFI = MF.getFrameInfo()->CreateStackObject(1, 1);
199 int FI;
200 for(unsigned i=1;i<SlotSize; ++i) {
201 FI = MF.getFrameInfo()->CreateStackObject(1, 1);
202 }
203}
204
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000205const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode) const {
206 switch (Opcode) {
207 default: return NULL;
208 case PIC16ISD::Lo: return "PIC16ISD::Lo";
209 case PIC16ISD::Hi: return "PIC16ISD::Hi";
210 case PIC16ISD::MTLO: return "PIC16ISD::MTLO";
211 case PIC16ISD::MTHI: return "PIC16ISD::MTHI";
212 case PIC16ISD::Banksel: return "PIC16ISD::Banksel";
213 case PIC16ISD::PIC16Load: return "PIC16ISD::PIC16Load";
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000214 case PIC16ISD::PIC16LdWF: return "PIC16ISD::PIC16LdWF";
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000215 case PIC16ISD::PIC16Store: return "PIC16ISD::PIC16Store";
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000216 case PIC16ISD::PIC16StWF: return "PIC16ISD::PIC16StWF";
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000217 case PIC16ISD::BCF: return "PIC16ISD::BCF";
218 case PIC16ISD::LSLF: return "PIC16ISD::LSLF";
219 case PIC16ISD::LRLF: return "PIC16ISD::LRLF";
220 case PIC16ISD::RLF: return "PIC16ISD::RLF";
221 case PIC16ISD::RRF: return "PIC16ISD::RRF";
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000222 case PIC16ISD::CALL: return "PIC16ISD::CALL";
223 case PIC16ISD::SUBCC: return "PIC16ISD::SUBCC";
224 case PIC16ISD::SELECT_ICC: return "PIC16ISD::SELECT_ICC";
225 case PIC16ISD::BRCOND: return "PIC16ISD::BRCOND";
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000226 case PIC16ISD::Dummy: return "PIC16ISD::Dummy";
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000227 }
228}
229
Duncan Sands1607f052008-12-01 11:39:25 +0000230void PIC16TargetLowering::ReplaceNodeResults(SDNode *N,
231 SmallVectorImpl<SDValue>&Results,
232 SelectionDAG &DAG) {
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000233
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000234 switch (N->getOpcode()) {
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000235 case ISD::GlobalAddress:
Duncan Sands1607f052008-12-01 11:39:25 +0000236 Results.push_back(ExpandGlobalAddress(N, DAG));
237 return;
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000238 case ISD::ExternalSymbol:
239 Results.push_back(ExpandExternalSymbol(N, DAG));
240 return;
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000241 case ISD::STORE:
Duncan Sands1607f052008-12-01 11:39:25 +0000242 Results.push_back(ExpandStore(N, DAG));
243 return;
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000244 case ISD::LOAD:
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000245 PopulateResults(ExpandLoad(N, DAG), Results);
Duncan Sands1607f052008-12-01 11:39:25 +0000246 return;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000247 case ISD::ADD:
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000248 // Results.push_back(ExpandAdd(N, DAG));
Duncan Sands1607f052008-12-01 11:39:25 +0000249 return;
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000250 case ISD::SHL:
251 case ISD::SRL:
252 case ISD::SRA:
253 {
Duncan Sands1607f052008-12-01 11:39:25 +0000254 SDValue Res = ExpandShift(N, DAG);
255 if (Res.getNode())
256 Results.push_back(Res);
257 return;
258 }
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000259 case ISD::FrameIndex:
260 Results.push_back(ExpandFrameIndex(N, DAG));
261 return;
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000262 default:
263 assert (0 && "not implemented");
Duncan Sands1607f052008-12-01 11:39:25 +0000264 return;
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000265 }
266}
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000267
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000268SDValue PIC16TargetLowering::ExpandFrameIndex(SDNode *N, SelectionDAG &DAG) {
269
270 // Currently handling FrameIndex of size MVT::i16 only
271 // One example of this scenario is when return value is written on
272 // FrameIndex#0
273
274 if (N->getValueType(0) != MVT::i16)
275 return SDValue();
276
277 // Expand the FrameIndex into ExternalSymbol and a Constant node
278 // The constant will represent the frame index number
279 // Get the current function frame
280 MachineFunction &MF = DAG.getMachineFunction();
281 const Function *Func = MF.getFunction();
282 const std::string Name = Func->getName();
283
284 FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(SDValue(N,0));
285 int Index = FR->getIndex();
286
287 SDValue FI[2];
288 FI[0] = DAG.getTargetFrameIndex(Index, MVT::i8);
289 FI[1] = DAG.getTargetFrameIndex(Index + 1, MVT::i8);
290 return DAG.getNode(ISD::BUILD_PAIR, N->getValueType(0), FI[0], FI[1]);
291}
292
293
294SDValue PIC16TargetLowering::ExpandStore(SDNode *N, SelectionDAG &DAG) {
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000295 StoreSDNode *St = cast<StoreSDNode>(N);
296 SDValue Chain = St->getChain();
297 SDValue Src = St->getValue();
298 SDValue Ptr = St->getBasePtr();
299 MVT ValueType = Src.getValueType();
300 unsigned StoreOffset = 0;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000301
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000302 SDValue PtrLo, PtrHi;
303 LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, StoreOffset);
304
305 if (ValueType == MVT::i8) {
Duncan Sands1607f052008-12-01 11:39:25 +0000306 return DAG.getNode (PIC16ISD::PIC16Store, MVT::Other, Chain, Src,
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000307 PtrLo, PtrHi,
308 DAG.getConstant (0 + StoreOffset, MVT::i8));
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000309 }
310 else if (ValueType == MVT::i16) {
311 // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
312 SDValue SrcLo, SrcHi;
313 GetExpandedParts(Src, DAG, SrcLo, SrcHi);
314 SDValue ChainLo = Chain, ChainHi = Chain;
315 if (Chain.getOpcode() == ISD::TokenFactor) {
316 ChainLo = Chain.getOperand(0);
317 ChainHi = Chain.getOperand(1);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000318 }
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000319 SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other,
320 ChainLo,
321 SrcLo, PtrLo, PtrHi,
322 DAG.getConstant (0 + StoreOffset, MVT::i8));
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000323
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000324 SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi,
325 SrcHi, PtrLo, PtrHi,
326 DAG.getConstant (1 + StoreOffset, MVT::i8));
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000327
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000328 return DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1),
Duncan Sands1607f052008-12-01 11:39:25 +0000329 getChain(Store2));
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000330 }
331 else if (ValueType == MVT::i32) {
332 // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
333 SDValue SrcLo, SrcHi;
334 GetExpandedParts(Src, DAG, SrcLo, SrcHi);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000335
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000336 // Get the expanded parts of each of SrcLo and SrcHi.
337 SDValue SrcLo1, SrcLo2, SrcHi1, SrcHi2;
338 GetExpandedParts(SrcLo, DAG, SrcLo1, SrcLo2);
339 GetExpandedParts(SrcHi, DAG, SrcHi1, SrcHi2);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000340
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000341 SDValue ChainLo = Chain, ChainHi = Chain;
342 if (Chain.getOpcode() == ISD::TokenFactor) {
343 ChainLo = Chain.getOperand(0);
344 ChainHi = Chain.getOperand(1);
345 }
346 SDValue ChainLo1 = ChainLo, ChainLo2 = ChainLo, ChainHi1 = ChainHi,
347 ChainHi2 = ChainHi;
348 if (ChainLo.getOpcode() == ISD::TokenFactor) {
349 ChainLo1 = ChainLo.getOperand(0);
350 ChainLo2 = ChainLo.getOperand(1);
351 }
352 if (ChainHi.getOpcode() == ISD::TokenFactor) {
353 ChainHi1 = ChainHi.getOperand(0);
354 ChainHi2 = ChainHi.getOperand(1);
355 }
356 SDValue Store1 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other,
357 ChainLo1,
358 SrcLo1, PtrLo, PtrHi,
359 DAG.getConstant (0 + StoreOffset, MVT::i8));
360
361 SDValue Store2 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainLo2,
362 SrcLo2, PtrLo, PtrHi,
363 DAG.getConstant (1 + StoreOffset, MVT::i8));
364
365 SDValue Store3 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi1,
366 SrcHi1, PtrLo, PtrHi,
367 DAG.getConstant (2 + StoreOffset, MVT::i8));
368
369 SDValue Store4 = DAG.getNode(PIC16ISD::PIC16Store, MVT::Other, ChainHi2,
370 SrcHi2, PtrLo, PtrHi,
371 DAG.getConstant (3 + StoreOffset, MVT::i8));
372
373 SDValue RetLo = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store1),
374 getChain(Store2));
375 SDValue RetHi = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(Store3),
376 getChain(Store4));
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000377 return DAG.getNode(ISD::TokenFactor, MVT::Other, RetLo, RetHi);
378
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000379 }
380 else {
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000381 assert (0 && "value type not supported");
Duncan Sands1607f052008-12-01 11:39:25 +0000382 return SDValue();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000383 }
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000384}
385
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000386SDValue PIC16TargetLowering::ExpandExternalSymbol(SDNode *N, SelectionDAG &DAG)
387{
388 ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(SDValue(N, 0));
389
390 SDValue TES = DAG.getTargetExternalSymbol(ES->getSymbol(), MVT::i8);
391
392 SDValue Lo = DAG.getNode(PIC16ISD::Lo, MVT::i8, TES);
393 SDValue Hi = DAG.getNode(PIC16ISD::Hi, MVT::i8, TES);
394
395 return DAG.getNode(ISD::BUILD_PAIR, MVT::i16, Lo, Hi);
396}
397
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000398// ExpandGlobalAddress -
Duncan Sands1607f052008-12-01 11:39:25 +0000399SDValue PIC16TargetLowering::ExpandGlobalAddress(SDNode *N, SelectionDAG &DAG) {
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000400 GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(SDValue(N, 0));
401
402 SDValue TGA = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i8,
403 G->getOffset());
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000404
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000405 SDValue Lo = DAG.getNode(PIC16ISD::Lo, MVT::i8, TGA);
406 SDValue Hi = DAG.getNode(PIC16ISD::Hi, MVT::i8, TGA);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000407
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000408 return DAG.getNode(ISD::BUILD_PAIR, MVT::i16, Lo, Hi);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000409}
410
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000411bool PIC16TargetLowering::isDirectAddress(const SDValue &Op) {
412 assert (Op.getNode() != NULL && "Can't operate on NULL SDNode!!");
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000413
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000414 if (Op.getOpcode() == ISD::BUILD_PAIR) {
415 if (Op.getOperand(0).getOpcode() == PIC16ISD::Lo)
416 return true;
417 }
418 return false;
419}
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000420
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000421// Return true if DirectAddress is in ROM_SPACE
422bool PIC16TargetLowering::isRomAddress(const SDValue &Op) {
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000423
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000424 // RomAddress is a GlobalAddress in ROM_SPACE_
425 // If the Op is not a GlobalAddress return NULL without checking
426 // anything further.
427 if (!isDirectAddress(Op))
428 return false;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000429
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000430 // Its a GlobalAddress.
431 // It is BUILD_PAIR((PIC16Lo TGA), (PIC16Hi TGA)) and Op is BUILD_PAIR
432 SDValue TGA = Op.getOperand(0).getOperand(0);
433 GlobalAddressSDNode *GSDN = dyn_cast<GlobalAddressSDNode>(TGA);
434 const Type *ValueType = GSDN->getGlobal()->getType();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000435
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000436 if (!isa<PointerType>(ValueType)) {
437 assert(0 && "TGA must be of a PointerType");
438 }
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000439
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000440 int AddrSpace = dyn_cast<PointerType>(ValueType)->getAddressSpace();
441 if (AddrSpace == PIC16ISD::ROM_SPACE)
442 return true;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000443
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000444 // Any other address space return it false
445 return false;
446}
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000447
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000448// Extract the out flag
449SDValue PIC16TargetLowering::getOutFlag(SDValue &Op) {
450 SDValue Flag = Op.getValue(Op.getNode()->getNumValues() - 1);
451
452 assert (Flag.getValueType() == MVT::Flag && "Node does not have an out Flag");
453
454 return Flag;
455}
456
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000457// To extract chain value from the SDValue Nodes
458// This function will help to maintain the chain extracting
459// code at one place. In case of any change in future it will
460// help maintain the code.
461SDValue PIC16TargetLowering::getChain(SDValue &Op) {
462 SDValue Chain = Op.getValue(Op.getNode()->getNumValues() - 1);
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000463
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000464 // If the last value returned in Flag then the chain is
465 // second last value returned.
466 if (Chain.getValueType() == MVT::Flag)
467 Chain = Op.getValue(Op.getNode()->getNumValues() - 2);
468
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000469 // All nodes may not produce a chain. Therefore following assert
470 // verifies that the node is returning a chain only.
471 assert (Chain.getValueType() == MVT::Other && "Node does not have a chain");
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000472
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000473 return Chain;
474}
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000475
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000476void PIC16TargetLowering::GetExpandedParts(SDValue Op, SelectionDAG &DAG,
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000477
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000478 SDValue &Lo, SDValue &Hi) {
479 SDNode *N = Op.getNode();
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000480 MVT NewVT;
481 std::vector<SDValue> Opers;
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000482 NewVT = getTypeToTransformTo(N->getValueType(0));
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000483
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000484 // extract the lo component
485 Opers.push_back(Op);
486 Opers.push_back(DAG.getConstant(0,MVT::i8));
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000487 Lo = DAG.getNode(ISD::EXTRACT_ELEMENT,NewVT,&Opers[0],Opers.size());
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000488 // extract the hi component
489 Opers.clear();
490 Opers.push_back(Op);
491 Opers.push_back(DAG.getConstant(1,MVT::i8));
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000492 Hi = DAG.getNode(ISD::EXTRACT_ELEMENT,NewVT,&Opers[0],Opers.size());
493}
494
495// Legalize FrameIndex into ExternalSymbol and offset.
496void
497PIC16TargetLowering::LegalizeFrameIndex(SDValue Op, SelectionDAG &DAG,
498 SDValue &ES, int &Offset) {
499
500 MachineFunction &MF = DAG.getMachineFunction();
501 const Function *Func = MF.getFunction();
502 const std::string Name = Func->getName();
503
504 char *tmpName = new char [strlen(Name.c_str()) + 8];
505 sprintf(tmpName, "%s.args", Name.c_str());
506 ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
507 FrameIndexSDNode *FR = dyn_cast<FrameIndexSDNode>(Op);
508 Offset = FR->getIndex();
509
510 return;
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000511}
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000512
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000513// This function legalizes the PIC16 Addresses. If the Pointer is
514// -- Direct address variable residing
515// --> then a Banksel for that variable will be created.
516// -- Rom variable
517// --> then it will be treated as an indirect address.
518// -- Indirect address
519// --> then the address will be loaded into FSR
520// -- ADD with constant operand
521// --> then constant operand of ADD will be returned as Offset
522// and non-constant operand of ADD will be treated as pointer.
523// Returns the high and lo part of the address, and the offset(in case of ADD).
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000524
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000525void PIC16TargetLowering:: LegalizeAddress(SDValue Ptr, SelectionDAG &DAG,
526 SDValue &Lo, SDValue &Hi,
527 unsigned &Offset) {
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000528
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000529 // Offset, by default, should be 0
530 Offset = 0;
Sanjiv Gupta2010b3e2008-05-14 11:31:39 +0000531
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000532 // If the pointer is ADD with constant,
533 // return the constant value as the offset
534 if (Ptr.getOpcode() == ISD::ADD) {
535 SDValue OperLeft = Ptr.getOperand(0);
536 SDValue OperRight = Ptr.getOperand(1);
537 if (OperLeft.getOpcode() == ISD::Constant) {
538 Offset = dyn_cast<ConstantSDNode>(OperLeft)->getZExtValue();
539 Ptr = OperRight;
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000540 } else if (OperRight.getOpcode() == ISD::Constant) {
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000541 Offset = dyn_cast<ConstantSDNode>(OperRight)->getZExtValue();
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000542 Ptr = OperLeft;
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000543 }
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000544 }
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000545
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000546 // If the pointer is Type i8 and an external symbol
547 // then treat it as direct address.
548 // One example for such case is storing and loading
549 // from function frame during a call
550 if (Ptr.getValueType() == MVT::i8) {
551 switch (Ptr.getOpcode()) {
552 case ISD::TargetExternalSymbol:
553 Lo = Ptr;
554 Hi = DAG.getConstant(1, MVT::i8);
555 return;
556 }
557 }
558
559 if (Ptr.getOpcode() == ISD::BUILD_PAIR &&
560 Ptr.getOperand(0).getOpcode() == ISD::TargetFrameIndex) {
561
562 int FrameOffset;
563 LegalizeFrameIndex(Ptr.getOperand(0), DAG, Lo, FrameOffset);
564 Hi = DAG.getConstant(1, MVT::i8);
565 Offset += FrameOffset;
566 return;
567 }
568
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000569 if (isDirectAddress(Ptr) && !isRomAddress(Ptr)) {
570 // Direct addressing case for RAM variables. The Hi part is constant
571 // and the Lo part is the TGA itself.
572 Lo = Ptr.getOperand(0).getOperand(0);
573
574 // For direct addresses Hi is a constant. Value 1 for the constant
575 // signifies that banksel needs to generated for it. Value 0 for
576 // the constant signifies that banksel does not need to be generated
577 // for it. Mark it as 1 now and optimize later.
578 Hi = DAG.getConstant(1, MVT::i8);
579 return;
580 }
581
582 // Indirect addresses. Get the hi and lo parts of ptr.
583 GetExpandedParts(Ptr, DAG, Lo, Hi);
584
585 // Put the hi and lo parts into FSR.
586 Lo = DAG.getNode(PIC16ISD::MTLO, MVT::i8, Lo);
587 Hi = DAG.getNode(PIC16ISD::MTHI, MVT::i8, Hi);
588
589 return;
590}
591
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000592//SDValue PIC16TargetLowering::ExpandAdd(SDNode *N, SelectionDAG &DAG) {
593 //SDValue OperLeft = N->getOperand(0);
594 //SDValue OperRight = N->getOperand(1);
595
596 //if((OperLeft.getOpcode() == ISD::Constant) ||
597 //(OperRight.getOpcode() == ISD::Constant)) {
598 //return SDValue();
599 //}
600
601 // These case are yet to be handled
602 //return SDValue();
Duncan Sands1607f052008-12-01 11:39:25 +0000603//}
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000604
Duncan Sands1607f052008-12-01 11:39:25 +0000605SDValue PIC16TargetLowering::ExpandLoad(SDNode *N, SelectionDAG &DAG) {
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000606 LoadSDNode *LD = dyn_cast<LoadSDNode>(SDValue(N, 0));
607 SDValue Chain = LD->getChain();
608 SDValue Ptr = LD->getBasePtr();
609
610 SDValue Load, Offset;
611 SDVTList Tys;
612 MVT VT, NewVT;
613 SDValue PtrLo, PtrHi;
614 unsigned LoadOffset;
615
616 // Legalize direct/indirect addresses. This will give the lo and hi parts
617 // of the address and the offset.
618 LegalizeAddress(Ptr, DAG, PtrLo, PtrHi, LoadOffset);
619
620 // Load from the pointer (direct address or FSR)
621 VT = N->getValueType(0);
622 unsigned NumLoads = VT.getSizeInBits() / 8;
623 std::vector<SDValue> PICLoads;
624 unsigned iter;
625 MVT MemVT = LD->getMemoryVT();
626 if(ISD::isNON_EXTLoad(N)) {
627 for (iter=0; iter<NumLoads ; ++iter) {
628 // Add the pointer offset if any
629 Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
630 Tys = DAG.getVTList(MVT::i8, MVT::Other);
631 Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Chain, PtrLo, PtrHi,
632 Offset);
633 PICLoads.push_back(Load);
634 }
635 } else {
636 // If it is extended load then use PIC16Load for Memory Bytes
637 // and for all extended bytes perform action based on type of
638 // extention - i.e. SignExtendedLoad or ZeroExtendedLoad
639
640
641 // For extended loads this is the memory value type
642 // i.e. without any extension
643 MVT MemVT = LD->getMemoryVT();
644 unsigned MemBytes = MemVT.getSizeInBits() / 8;
645 unsigned ExtdBytes = VT.getSizeInBits() / 8;
646 Offset = DAG.getConstant(LoadOffset, MVT::i8);
647
648 Tys = DAG.getVTList(MVT::i8, MVT::Other);
649 // For MemBytes generate PIC16Load with proper offset
650 for (iter=0; iter<MemBytes; ++iter) {
651 // Add the pointer offset if any
652 Offset = DAG.getConstant(iter + LoadOffset, MVT::i8);
653 Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Chain, PtrLo, PtrHi,
654 Offset);
655 PICLoads.push_back(Load);
656 }
657
658 // For SignExtendedLoad
659 if (ISD::isSEXTLoad(N)) {
660 // For all ExtdBytes use the Right Shifted(Arithmetic) Value of the
661 // highest MemByte
662 SDValue SRA = DAG.getNode(ISD::SRA, MVT::i8, Load,
663 DAG.getConstant(7, MVT::i8));
664 for (iter=MemBytes; iter<ExtdBytes; ++iter) {
665 PICLoads.push_back(SRA);
666 }
667 } else if (ISD::isZEXTLoad(N)) {
668 // ZeroExtendedLoad -- For all ExtdBytes use constant 0
669 SDValue ConstZero = DAG.getConstant(0, MVT::i8);
670 for (iter=MemBytes; iter<ExtdBytes; ++iter) {
671 PICLoads.push_back(ConstZero);
672 }
673 }
674 }
675 SDValue BP;
676
677 if (VT == MVT::i8) {
678 // Operand of Load is illegal -- Load itself is legal
Duncan Sands1607f052008-12-01 11:39:25 +0000679 return PICLoads[0];
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000680 }
681 else if (VT == MVT::i16) {
682 BP = DAG.getNode(ISD::BUILD_PAIR, VT, PICLoads[0], PICLoads[1]);
683 if (MemVT == MVT::i8)
684 Chain = getChain(PICLoads[0]);
685 else
686 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]),
687 getChain(PICLoads[1]));
688 } else if (VT == MVT::i32) {
689 SDValue BPs[2];
690 BPs[0] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[0], PICLoads[1]);
691 BPs[1] = DAG.getNode(ISD::BUILD_PAIR, MVT::i16, PICLoads[2], PICLoads[3]);
692 BP = DAG.getNode(ISD::BUILD_PAIR, VT, BPs[0], BPs[1]);
693 if (MemVT == MVT::i8)
694 Chain = getChain(PICLoads[0]);
695 else if (MemVT == MVT::i16)
696 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, getChain(PICLoads[0]),
697 getChain(PICLoads[1]));
698 else {
699 SDValue Chains[2];
700 Chains[0] = DAG.getNode(ISD::TokenFactor, MVT::Other,
701 getChain(PICLoads[0]), getChain(PICLoads[1]));
702 Chains[1] = DAG.getNode(ISD::TokenFactor, MVT::Other,
703 getChain(PICLoads[2]), getChain(PICLoads[3]));
704 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Chains[0], Chains[1]);
705 }
706 }
707 Tys = DAG.getVTList(VT, MVT::Other);
Duncan Sands1607f052008-12-01 11:39:25 +0000708 return DAG.getNode(ISD::MERGE_VALUES, Tys, BP, Chain);
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000709}
710
Duncan Sands1607f052008-12-01 11:39:25 +0000711SDValue PIC16TargetLowering::ExpandShift(SDNode *N, SelectionDAG &DAG) {
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000712 SDValue Value = N->getOperand(0);
713 SDValue Amt = N->getOperand(1);
714 SDValue BCF, BCFInput;
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000715 SDValue ShfCom; // Shift Component - Lo component should be shifted
716 SDValue RotCom; // Rotate Component- Hi component should be rotated
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000717
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000718 PIC16ISD::PIC16LibCall CallCode;
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000719
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000720 // Shift amount should be MVT::i8 only. If it is more than that then
721 // extract MVT::i8 from that
722 if (Amt.getValueType() == MVT::i8) {
723 // Do Nothing - This is ok
724 } else if (Amt.getValueType() == MVT::i16) {
725 SDValue Lo, Hi;
726 GetExpandedParts(Amt, DAG, Lo, Hi);
727 Amt = Lo; // Take the Lo part as amount
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000728
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000729 } else if (Amt.getValueType() == MVT::i32) {
730 SDValue Lo, Hi;
731 // Get MVT::i16 Components
732 GetExpandedParts(Amt, DAG, Lo, Hi);
733 // Get MVT::i8 Components
734 GetExpandedParts(Lo, DAG, Lo, Hi);
735 Amt = Lo;
736
737 } else {
738 assert ( 0 && "Invalid Shift amount");
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000739 }
740
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000741 // Shift library call will always have two operands
742 if (N->getValueType(0) == MVT::i8) {
743 switch (N->getOpcode()) {
744 case ISD::SRA:
745 CallCode = PIC16ISD::SRA_I8;
746 break;
747 case ISD::SHL:
748 CallCode = PIC16ISD::SLL_I8;
749 break;
750 case ISD::SRL:
751 CallCode = PIC16ISD::SRL_I8;
752 break;
753 default:
754 assert ( 0 && "This shift is not implemented yet.");
755 return SDValue();
756 }
757 } else if (N->getValueType(0) == MVT::i16) {
758 switch (N->getOpcode()) {
759 case ISD::SRA:
760 CallCode = PIC16ISD::SRA_I16;
761 break;
762 case ISD::SHL:
763 CallCode = PIC16ISD::SLL_I16;
764 break;
765 case ISD::SRL:
766 CallCode = PIC16ISD::SRL_I16;
767 break;
768 default:
769 assert ( 0 && "This shift is not implemented yet.");
770 return SDValue();
771 }
772 } else if (N->getValueType(0) == MVT::i32) {
773 switch (N->getOpcode()) {
774 case ISD::SRA:
775 CallCode = PIC16ISD::SRA_I32;
776 break;
777 case ISD::SHL:
778 CallCode = PIC16ISD::SLL_I32;
779 break;
780 case ISD::SRL:
781 CallCode = PIC16ISD::SRL_I32;
782 break;
783 default:
784 assert ( 0 && "This shift is not implemented yet.");
785 return SDValue();
786 }
787 } else {
788 //assert ( 0 && "Shift for this value type not yet implemented.");
789 return SDValue();
790 }
791
792 SmallVector<SDValue, 2> Ops(2);
793 Ops[0] = Value;
794 Ops[1] = Amt;
795 SDValue Call = MakePIC16LibCall(CallCode, N->getValueType(0), &Ops[0], 2, true, DAG);
796 return Call;
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000797}
798
799SDValue PIC16TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
800 switch (Op.getOpcode()) {
801 case ISD::FORMAL_ARGUMENTS:
802 return LowerFORMAL_ARGUMENTS(Op, DAG);
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000803 case ISD::ADD:
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000804 case ISD::ADDC:
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000805 case ISD::ADDE:
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000806 return LowerADD(Op, DAG);
807 case ISD::SUB:
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000808 case ISD::SUBC:
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000809 case ISD::SUBE:
810 return LowerSUB(Op, DAG);
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000811 case ISD::LOAD:
Duncan Sands1607f052008-12-01 11:39:25 +0000812 return ExpandLoad(Op.getNode(), DAG);
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000813 case ISD::STORE:
Duncan Sands1607f052008-12-01 11:39:25 +0000814 return ExpandStore(Op.getNode(), DAG);
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000815 case ISD::SHL:
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000816 case ISD::SRA:
817 case ISD::SRL:
Duncan Sands1607f052008-12-01 11:39:25 +0000818 return ExpandShift(Op.getNode(), DAG);
Sanjiv Gupta8f78fa82008-11-26 10:53:50 +0000819 case ISD::OR:
820 case ISD::AND:
821 case ISD::XOR:
822 return LowerBinOp(Op, DAG);
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000823 case ISD::CALL:
824 // This is called only from LegalizeDAG. No call is made to
825 // legalize CALL node from LegalizeType.
826 return LowerCALL(Op, DAG);
827 case ISD::RET:
828 return LowerRET(Op, DAG);
829 case ISD::BR_CC:
830 return LowerBR_CC(Op, DAG);
831 case ISD::SELECT_CC:
832 return LowerSELECT_CC(Op, DAG);
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000833 }
Dan Gohman475871a2008-07-27 21:46:04 +0000834 return SDValue();
Sanjiv Gupta0e687712008-05-13 09:02:57 +0000835}
836
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +0000837SDValue PIC16TargetLowering::ConvertToMemOperand(SDValue Op,
838 SelectionDAG &DAG) {
839
840 assert (Op.getValueType() == MVT::i8
841 && "illegal value type to store on stack.");
842
843 MachineFunction &MF = DAG.getMachineFunction();
844 const Function *Func = MF.getFunction();
845 const std::string FuncName = Func->getName();
846
847 char *tmpName = new char [strlen(FuncName.c_str()) + 6];
848
849 // Put the value on stack.
850 // Get a stack slot index and convert to es.
851 int FI = MF.getFrameInfo()->CreateStackObject(1, 1);
852 sprintf(tmpName, "%s.tmp", FuncName.c_str());
853 SDValue ES = DAG.getTargetExternalSymbol(tmpName, MVT::i8);
854
855 // Store the value to ES.
856 SDValue Store = DAG.getNode (PIC16ISD::PIC16Store, MVT::Other,
857 DAG.getEntryNode(),
858 Op, ES,
859 DAG.getConstant (1, MVT::i8), // Banksel.
860 DAG.getConstant (FI, MVT::i8));
861
862 // Load the value from ES.
863 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other);
864 SDValue Load = DAG.getNode(PIC16ISD::PIC16Load, Tys, Store,
865 ES, DAG.getConstant (1, MVT::i8),
866 DAG.getConstant (FI, MVT::i8));
867
868 return Load.getValue(0);
869}
Sanjiv Gupta1b046942009-01-13 19:18:47 +0000870
871SDValue
872PIC16TargetLowering::LowerCallArguments(SDValue Op, SDValue Chain,
873 SDValue FrameAddress,
874 SDValue InFlag,
875 SelectionDAG &DAG) {
876 CallSDNode *TheCall = dyn_cast<CallSDNode>(Op);
877 unsigned NumOps = TheCall->getNumArgs();
878 std::string Name;
879 SDValue Arg, StoreAt;
880 MVT ArgVT;
881 unsigned Size=0;
882 unsigned ArgCount=0;
883
884
885 // FIXME: This portion of code currently assumes only
886 // primitive types being passed as arguments.
887
888 // Legalize the address before use
889 SDValue PtrLo, PtrHi;
890 unsigned AddressOffset;
891 int StoreOffset = 0;
892 LegalizeAddress(FrameAddress, DAG, PtrLo, PtrHi, AddressOffset);
893 SDValue StoreRet;
894
895 std::vector<SDValue> Ops;
896 SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
897 for (unsigned i=ArgCount, Offset = 0; i<NumOps; i++) {
898 // Get the argument
899 Arg = TheCall->getArg(i);
900
901 StoreOffset = (Offset + AddressOffset);
902
903 // Store the argument on frame
904
905 Ops.clear();
906 Ops.push_back(Chain);
907 Ops.push_back(Arg.getValue(0));
908 Ops.push_back(PtrLo);
909 Ops.push_back(PtrHi);
910 Ops.push_back(DAG.getConstant(StoreOffset, MVT::i8));
911 Ops.push_back(InFlag);
912
913 StoreRet = DAG.getNode (PIC16ISD::PIC16StWF, Tys, &Ops[0], Ops.size());
914
915 Chain = getChain(StoreRet);
916 InFlag = getOutFlag(StoreRet);
917
918 // Update the frame offset to be used for next argument
919 ArgVT = Arg.getValueType();
920 Size = ArgVT.getSizeInBits();
921 Size = Size/8; // Calculate size in bytes
922 Offset += Size; // Increase the frame offset
923 }
924 return Chain;
925}
926
927SDValue
928PIC16TargetLowering::LowerCallReturn(SDValue Op, SDValue Chain,
929 SDValue FrameAddress,
930 SDValue InFlag,
931 SelectionDAG &DAG) {
932 CallSDNode *TheCall = dyn_cast<CallSDNode>(Op);
933 // Currently handling primitive types only. They will come in
934 // i8 parts
935 unsigned RetVals = TheCall->getNumRetVals();
936
937 std::vector<SDValue> ResultVals;
938
939 // Return immediately if the return type is void
940 if (RetVals == 0)
941 return Chain;
942
943 // Call has something to return
944
945 // Legalize the address before use
946 SDValue LdLo, LdHi;
947 unsigned LdOffset;
948 LegalizeAddress(FrameAddress, DAG, LdLo, LdHi, LdOffset);
949
950 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Other, MVT::Flag);
951 SDValue LoadRet;
952
953 for(unsigned i=0, Offset=0;i<RetVals;i++) {
954
955 LoadRet = DAG.getNode(PIC16ISD::PIC16LdWF, Tys, Chain, LdLo, LdHi,
956 DAG.getConstant(LdOffset + Offset, MVT::i8),
957 InFlag);
958
959 InFlag = getOutFlag(LoadRet);
960
961 Chain = getChain(LoadRet);
962 Offset++;
963 ResultVals.push_back(LoadRet);
964 }
965
966 // To return use MERGE_VALUES
967 ResultVals.push_back(Chain);
968 SDValue Res = DAG.getMergeValues(&ResultVals[0], ResultVals.size());
969 return Res;
970}
971
972SDValue PIC16TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) {
973 //int NumOps = Op.getNode()->getNumOperands();
974
975 // For default cases LLVM returns the value on the function frame
976 // So let LLVM do this for all the cases other than character
977 return Op;
978}
979
980SDValue PIC16TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
981 CallSDNode *TheCall = dyn_cast<CallSDNode>(Op);
982 SDValue Chain = TheCall->getChain();
983 SDValue Callee = TheCall->getCallee();
984 unsigned i =0;
985 if (Callee.getValueType() == MVT::i16 &&
986 Callee.getOpcode() == ISD::BUILD_PAIR) {
987 // It has come from TypeLegalizer for lowering
988
989 Callee = Callee.getOperand(0).getOperand(0);
990
991 std::vector<SDValue> Ops;
992 Ops.push_back(Chain);
993 Ops.push_back(Callee);
994
995 // Add the call arguments and their flags
996 unsigned NumArgs = TheCall->getNumArgs();
997 for(i=0;i<NumArgs;i++) {
998 Ops.push_back(TheCall->getArg(i));
999 Ops.push_back(TheCall->getArgFlagsVal(i));
1000 }
1001
1002 std::vector<MVT> NodeTys;
1003 unsigned NumRets = TheCall->getNumRetVals();
1004 for(i=0;i<NumRets;i++)
1005 NodeTys.push_back(TheCall->getRetValType(i));
1006
1007 // Return a Chain as well
1008 NodeTys.push_back(MVT::Other);
1009
1010 SDVTList VTs = DAG.getVTList(&NodeTys[0], NodeTys.size());
1011 SDValue NewCall =
1012 DAG.getCall(TheCall->getCallingConv(), TheCall->isVarArg(),
1013 TheCall->isTailCall(), TheCall->isInreg(), VTs,
1014 &Ops[0], Ops.size());
1015
1016 return NewCall;
1017 }
1018
1019 SDValue ZeroOperand = DAG.getConstant(0, MVT::i8);
1020
1021 // Start the call sequence.
1022 // Carring the Constant 0 along the CALLSEQSTART
1023 // because there is nothing else to carry.
1024 SDValue SeqStart = DAG.getCALLSEQ_START(Chain, ZeroOperand);
1025 Chain = getChain(SeqStart);
1026
1027 // For any direct call - callee will be GlobalAddressNode or
1028 // ExternalSymbol
1029
1030 // Considering the GlobalAddressNode case here.
1031 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
1032 GlobalValue *GV = G->getGlobal();
1033 Callee = DAG.getTargetGlobalAddress(GV, MVT::i8);
1034 }
1035
1036 // Considering the ExternalSymbol case here
1037 if (ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Callee)) {
1038 Callee = DAG.getTargetExternalSymbol(ES->getSymbol(), MVT::i8);
1039 }
1040
1041 SDValue OperFlag = getOutFlag(Chain); // To manage the data dependency
1042
1043 std::string Name;
1044
1045 // Considering GlobalAddress here
1046 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
1047 Name = G->getGlobal()->getName();
1048
1049 // Considering ExternalSymbol here
1050 if (ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Callee))
1051 Name = ES->getSymbol();
1052
1053 char *argFrame = new char [strlen(Name.c_str()) + 8];
1054 sprintf(argFrame, "%s.args", Name.c_str());
1055 SDValue ArgLabel = DAG.getTargetExternalSymbol(argFrame, MVT::i8);
1056
1057 char *retName = new char [strlen(Name.c_str()) + 8];
1058 sprintf(retName, "%s.retval", Name.c_str());
1059 SDValue RetLabel = DAG.getTargetExternalSymbol(retName, MVT::i8);
1060
1061 // Pass the argument to function before making the call.
1062 SDValue CallArgs = LowerCallArguments(Op, Chain, ArgLabel, OperFlag, DAG);
1063 Chain = getChain(CallArgs);
1064 OperFlag = getOutFlag(CallArgs);
1065
1066 SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
1067 SDValue PICCall = DAG.getNode(PIC16ISD::CALL, Tys, Chain, Callee,
1068 OperFlag);
1069 Chain = getChain(PICCall);
1070 OperFlag = getOutFlag(PICCall);
1071
1072
1073 // Carrying the Constant 0 along the CALLSEQSTART
1074 // because there is nothing else to carry.
1075 SDValue SeqEnd = DAG.getCALLSEQ_END(Chain, ZeroOperand, ZeroOperand,
1076 OperFlag);
1077 Chain = getChain(SeqEnd);
1078 OperFlag = getOutFlag(SeqEnd);
1079
1080 // Lower the return value reading after the call.
1081 return LowerCallReturn(Op, Chain, RetLabel, OperFlag, DAG);
1082}
1083
1084bool PIC16TargetLowering::isDirectLoad(const SDValue Op) {
1085 if (Op.getOpcode() == PIC16ISD::PIC16Load)
1086 if (Op.getOperand(1).getOpcode() == ISD::TargetGlobalAddress
1087 || Op.getOperand(1).getOpcode() == ISD::TargetExternalSymbol)
1088 return true;
1089 return false;
1090}
1091
1092bool PIC16TargetLowering::NeedToConvertToMemOp(SDValue Op, unsigned &MemOp) {
1093 // Return false if one of the operands is already a direct
1094 // load and that operand has only one use.
1095 if (Op.getOperand(0).getOpcode() == ISD::Constant ||
1096 Op.getOperand(1).getOpcode() == ISD::Constant)
1097 return false;
1098 if (isDirectLoad(Op.getOperand(0))) {
1099 if (Op.getOperand(0).hasOneUse())
1100 return false;
1101 else
1102 MemOp = 0;
1103 }
1104 if (isDirectLoad(Op.getOperand(1))) {
1105 if (Op.getOperand(1).hasOneUse())
1106 return false;
1107 else
1108 MemOp = 1;
1109 }
1110 return true;
1111}
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +00001112
Sanjiv Gupta8f78fa82008-11-26 10:53:50 +00001113SDValue PIC16TargetLowering:: LowerBinOp(SDValue Op, SelectionDAG &DAG) {
1114 // We should have handled larger operands in type legalizer itself.
1115 assert (Op.getValueType() == MVT::i8 && "illegal Op to lower");
Sanjiv Gupta1b046942009-01-13 19:18:47 +00001116 unsigned MemOp = 1;
1117 if (NeedToConvertToMemOp(Op, MemOp)) {
1118 // Put one value on stack.
1119 SDValue NewVal = ConvertToMemOperand (Op.getOperand(MemOp), DAG);
Sanjiv Gupta8f78fa82008-11-26 10:53:50 +00001120
Sanjiv Gupta1b046942009-01-13 19:18:47 +00001121 return DAG.getNode(Op.getOpcode(), MVT::i8, Op.getOperand(MemOp ^ 1),
1122 NewVal);
1123 }
1124 else {
Sanjiv Gupta8f78fa82008-11-26 10:53:50 +00001125 return Op;
Sanjiv Gupta1b046942009-01-13 19:18:47 +00001126 }
Sanjiv Gupta8f78fa82008-11-26 10:53:50 +00001127}
1128
Sanjiv Gupta1b046942009-01-13 19:18:47 +00001129SDValue PIC16TargetLowering:: LowerADD(SDValue Op, SelectionDAG &DAG) {
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +00001130 // We should have handled larger operands in type legalizer itself.
Sanjiv Gupta1b046942009-01-13 19:18:47 +00001131 assert (Op.getValueType() == MVT::i8 && "illegal add to lower");
1132 unsigned MemOp = 1;
1133 if (NeedToConvertToMemOp(Op, MemOp)) {
1134 // Put one value on stack.
1135 SDValue NewVal = ConvertToMemOperand (Op.getOperand(MemOp), DAG);
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +00001136
Sanjiv Gupta1b046942009-01-13 19:18:47 +00001137 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +00001138
Sanjiv Gupta1b046942009-01-13 19:18:47 +00001139 if (Op.getOpcode() == ISD::ADDE)
1140 return DAG.getNode(Op.getOpcode(), Tys, Op.getOperand(MemOp ^ 1), NewVal,
1141 Op.getOperand(2));
1142 else
1143 return DAG.getNode(Op.getOpcode(), Tys, Op.getOperand(MemOp ^ 1), NewVal);
1144 }
1145 else {
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +00001146 return SDValue();
Sanjiv Gupta1b046942009-01-13 19:18:47 +00001147 }
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +00001148}
1149
Sanjiv Gupta1b046942009-01-13 19:18:47 +00001150SDValue PIC16TargetLowering::LowerSUB(SDValue Op, SelectionDAG &DAG) {
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +00001151 // We should have handled larger operands in type legalizer itself.
Sanjiv Gupta1b046942009-01-13 19:18:47 +00001152 assert (Op.getValueType() == MVT::i8 && "illegal sub to lower");
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +00001153
Sanjiv Gupta1b046942009-01-13 19:18:47 +00001154 // Nothing to do if the first operand is already a direct load and it has
1155 // only one use.
1156 if (isDirectLoad(Op.getOperand(0)) && Op.getOperand(0).hasOneUse())
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +00001157 return SDValue();
1158
1159 // Put first operand on stack.
1160 SDValue NewVal = ConvertToMemOperand (Op.getOperand(0), DAG);
1161
1162 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
Sanjiv Gupta1b046942009-01-13 19:18:47 +00001163 if (Op.getOpcode() == ISD::SUBE)
1164 return DAG.getNode(Op.getOpcode(), Tys, NewVal, Op.getOperand(1),
1165 Op.getOperand(2));
1166 else
1167 return DAG.getNode(Op.getOpcode(), Tys, NewVal, Op.getOperand(1));
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +00001168}
1169
1170// LowerFORMAL_ARGUMENTS - In Lowering FORMAL ARGUMENTS - MERGE_VALUES nodes
1171// is returned. MERGE_VALUES nodes number of operands and number of values are
1172// equal. Therefore to construct MERGE_VALUE node, UNDEF nodes equal to the
1173// number of arguments of function have been created.
1174
1175SDValue PIC16TargetLowering:: LowerFORMAL_ARGUMENTS(SDValue Op,
1176 SelectionDAG &DAG) {
1177 SmallVector<SDValue, 8> ArgValues;
1178 unsigned NumArgs = Op.getNumOperands() - 3;
1179
1180 // Creating UNDEF nodes to meet the requirement of MERGE_VALUES node.
1181 for(unsigned i = 0 ; i<NumArgs ; i++) {
1182 SDValue TempNode = DAG.getNode(ISD::UNDEF, Op.getNode()->getValueType(i));
1183 ArgValues.push_back(TempNode);
Sanjiv Gupta0e687712008-05-13 09:02:57 +00001184 }
1185
Sanjiv Guptab1b5ffd2008-11-19 11:00:54 +00001186 ArgValues.push_back(Op.getOperand(0));
1187 return DAG.getNode(ISD::MERGE_VALUES, Op.getNode()->getVTList(),
1188 &ArgValues[0],
1189 ArgValues.size()).getValue(Op.getResNo());
1190}
1191
1192// Perform DAGCombine of PIC16Load
1193SDValue PIC16TargetLowering::
1194PerformPIC16LoadCombine(SDNode *N, DAGCombinerInfo &DCI) const {
1195 SelectionDAG &DAG = DCI.DAG;
1196 SDValue Chain = N->getOperand(0);
1197 if (N->hasNUsesOfValue(0, 0)) {
1198 DAG.ReplaceAllUsesOfValueWith(SDValue(N,1), Chain);
1199 }
1200 return SDValue();
1201}
1202
1203
1204SDValue PIC16TargetLowering::PerformDAGCombine(SDNode *N,
1205 DAGCombinerInfo &DCI) const {
1206 switch (N->getOpcode()) {
1207 case PIC16ISD::PIC16Load:
1208 return PerformPIC16LoadCombine(N, DCI);
1209 }
1210 return SDValue();
Sanjiv Gupta0e687712008-05-13 09:02:57 +00001211}
Sanjiv Gupta1b046942009-01-13 19:18:47 +00001212
1213static PIC16CC::CondCodes IntCCToPIC16CC(ISD::CondCode CC) {
1214 switch (CC) {
1215 default: assert(0 && "Unknown condition code!");
1216 case ISD::SETNE: return PIC16CC::NE;
1217 case ISD::SETEQ: return PIC16CC::EQ;
1218 case ISD::SETGT: return PIC16CC::GT;
1219 case ISD::SETGE: return PIC16CC::GE;
1220 case ISD::SETLT: return PIC16CC::LT;
1221 case ISD::SETLE: return PIC16CC::LE;
1222 case ISD::SETULT: return PIC16CC::LT;
1223 case ISD::SETULE: return PIC16CC::LE;
1224 case ISD::SETUGE: return PIC16CC::GE;
1225 case ISD::SETUGT: return PIC16CC::GT;
1226 }
1227}
1228
1229// Look at LHS/RHS/CC and see if they are a lowered setcc instruction. If so
1230// set LHS/RHS and SPCC to the LHS/RHS of the setcc and SPCC to the condition.
1231static void LookThroughSetCC(SDValue &LHS, SDValue &RHS,
1232 ISD::CondCode CC, unsigned &SPCC) {
1233 if (isa<ConstantSDNode>(RHS) &&
1234 cast<ConstantSDNode>(RHS)->getZExtValue() == 0 &&
1235 CC == ISD::SETNE &&
1236 (LHS.getOpcode() == PIC16ISD::SELECT_ICC &&
1237 LHS.getOperand(3).getOpcode() == PIC16ISD::SUBCC) &&
1238 isa<ConstantSDNode>(LHS.getOperand(0)) &&
1239 isa<ConstantSDNode>(LHS.getOperand(1)) &&
1240 cast<ConstantSDNode>(LHS.getOperand(0))->getZExtValue() == 1 &&
1241 cast<ConstantSDNode>(LHS.getOperand(1))->getZExtValue() == 0) {
1242 SDValue CMPCC = LHS.getOperand(3);
1243 SPCC = cast<ConstantSDNode>(LHS.getOperand(2))->getZExtValue();
1244 LHS = CMPCC.getOperand(0);
1245 RHS = CMPCC.getOperand(1);
1246 }
1247}
1248
1249// Returns appropriate CMP insn and corresponding condition code in PIC16CC
1250SDValue PIC16TargetLowering::getPIC16Cmp(SDValue LHS, SDValue RHS,
1251 unsigned CC, SDValue &PIC16CC,
1252 SelectionDAG &DAG) {
1253 PIC16CC::CondCodes CondCode = (PIC16CC::CondCodes) CC;
1254
1255 // PIC16 sub is literal - W. So Swap the operands and condition if needed.
1256 // i.e. a < 12 can be rewritten as 12 > a.
1257 if (RHS.getOpcode() == ISD::Constant) {
1258
1259 SDValue Tmp = LHS;
1260 LHS = RHS;
1261 RHS = Tmp;
1262
1263 switch (CondCode) {
1264 default: break;
1265 case PIC16CC::LT:
1266 CondCode = PIC16CC::GT;
1267 break;
1268 case PIC16CC::GT:
1269 CondCode = PIC16CC::LT;
1270 break;
1271 case PIC16CC::GE:
1272 CondCode = PIC16CC::LE;
1273 break;
1274 case PIC16CC::LE:
1275 CondCode = PIC16CC::GE;
1276 break;
1277 }
1278 }
1279
1280 PIC16CC = DAG.getConstant(CondCode, MVT::i8);
1281 SDVTList VTs = DAG.getVTList (MVT::i8, MVT::Flag);
1282
1283 // We can use a subtract operation to set the condition codes. But
1284 // we need to put one operand in memory if required.
1285 // Nothing to do if the first operand is already a direct load and it has
1286 // only one use.
1287 if (! (isDirectLoad(LHS) && LHS.hasOneUse()))
1288 // Put first operand on stack.
1289 LHS = ConvertToMemOperand (LHS, DAG);
1290
1291 SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
1292 return DAG.getNode(PIC16ISD::SUBCC, VTs, LHS, RHS);
1293}
1294
1295
1296SDValue PIC16TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) {
1297 SDValue LHS = Op.getOperand(0);
1298 SDValue RHS = Op.getOperand(1);
1299 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
1300 SDValue TrueVal = Op.getOperand(2);
1301 SDValue FalseVal = Op.getOperand(3);
1302 unsigned ORIGCC = ~0;
1303
1304 // If this is a select_cc of a "setcc", and if the setcc got lowered into
1305 // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
1306 // i.e.
1307 // A setcc: lhs, rhs, cc is expanded by llvm to
1308 // select_cc: result of setcc, 0, 1, 0, setne
1309 // We can think of it as:
1310 // select_cc: lhs, rhs, 1, 0, cc
1311 LookThroughSetCC(LHS, RHS, CC, ORIGCC);
1312 if (ORIGCC == ~0U) ORIGCC = IntCCToPIC16CC (CC);
1313
1314 SDValue PIC16CC;
1315 SDValue Cmp = getPIC16Cmp(LHS, RHS, ORIGCC, PIC16CC, DAG);
1316
1317 return DAG.getNode (PIC16ISD::SELECT_ICC, TrueVal.getValueType(), TrueVal,
1318 FalseVal, PIC16CC, Cmp.getValue(1));
1319}
1320
1321MachineBasicBlock *
1322PIC16TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
1323 MachineBasicBlock *BB) {
1324 const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
1325 unsigned CC = (PIC16CC::CondCodes)MI->getOperand(3).getImm();
1326
1327 // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
1328 // control-flow pattern. The incoming instruction knows the destination vreg
1329 // to set, the condition code register to branch on, the true/false values to
1330 // select between, and a branch opcode to use.
1331 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1332 MachineFunction::iterator It = BB;
1333 ++It;
1334
1335 // thisMBB:
1336 // ...
1337 // TrueVal = ...
1338 // [f]bCC copy1MBB
1339 // fallthrough --> copy0MBB
1340 MachineBasicBlock *thisMBB = BB;
1341 MachineFunction *F = BB->getParent();
1342 MachineBasicBlock *copy0MBB = F->CreateMachineBasicBlock(LLVM_BB);
1343 MachineBasicBlock *sinkMBB = F->CreateMachineBasicBlock(LLVM_BB);
1344 BuildMI(BB, TII.get(PIC16::pic16brcond)).addMBB(sinkMBB).addImm(CC);
1345 F->insert(It, copy0MBB);
1346 F->insert(It, sinkMBB);
1347
1348 // Update machine-CFG edges by transferring all successors of the current
1349 // block to the new block which will contain the Phi node for the select.
1350 sinkMBB->transferSuccessors(BB);
1351 // Next, add the true and fallthrough blocks as its successors.
1352 BB->addSuccessor(copy0MBB);
1353 BB->addSuccessor(sinkMBB);
1354
1355 // copy0MBB:
1356 // %FalseValue = ...
1357 // # fallthrough to sinkMBB
1358 BB = copy0MBB;
1359
1360 // Update machine-CFG edges
1361 BB->addSuccessor(sinkMBB);
1362
1363 // sinkMBB:
1364 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1365 // ...
1366 BB = sinkMBB;
1367 BuildMI(BB, TII.get(PIC16::PHI), MI->getOperand(0).getReg())
1368 .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB)
1369 .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB);
1370
1371 F->DeleteMachineInstr(MI); // The pseudo instruction is gone now.
1372 return BB;
1373}
1374
1375
1376SDValue PIC16TargetLowering::LowerBR_CC(SDValue Op, SelectionDAG &DAG) {
1377 SDValue Chain = Op.getOperand(0);
1378 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get();
1379 SDValue LHS = Op.getOperand(2); // LHS of the condition.
1380 SDValue RHS = Op.getOperand(3); // RHS of the condition.
1381 SDValue Dest = Op.getOperand(4); // BB to jump to
1382 unsigned ORIGCC = ~0;
1383
1384 // If this is a br_cc of a "setcc", and if the setcc got lowered into
1385 // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
1386 LookThroughSetCC(LHS, RHS, CC, ORIGCC);
1387 if (ORIGCC == ~0U) ORIGCC = IntCCToPIC16CC (CC);
1388
1389 // Get the Compare insn and condition code.
1390 SDValue PIC16CC;
1391 SDValue Cmp = getPIC16Cmp(LHS, RHS, ORIGCC, PIC16CC, DAG);
1392
1393 return DAG.getNode(PIC16ISD::BRCOND, MVT::Other, Chain, Dest, PIC16CC,
1394 Cmp.getValue(1));
1395}
1396
1397