2 // The LLVM Compiler Infrastructure
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
7 //===----------------------------------------------------------------------===//
9 // This file defines the interfaces that PIC16 uses to lower LLVM code into a
12 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "pic16-lower"
16 #include "PIC16ISelLowering.h"
17 #include "PIC16TargetMachine.h"
18 #include "llvm/DerivedTypes.h"
19 #include "llvm/GlobalValue.h"
20 #include "llvm/Function.h"
21 #include "llvm/CallingConv.h"
22 #include "llvm/CodeGen/MachineFrameInfo.h"
23 #include "llvm/CodeGen/MachineFunction.h"
24 #include "llvm/CodeGen/MachineInstrBuilder.h"
25 #include "llvm/CodeGen/MachineRegisterInfo.h"
30 static const char *getIntrinsicName(unsigned opcode
) {
33 default: assert (0 && "do not know intrinsic name");
34 case PIC16ISD::SRA_I8
: Basename
= "sra.i8"; break;
35 case RTLIB::SRA_I16
: Basename
= "sra.i16"; break;
36 case RTLIB::SRA_I32
: Basename
= "sra.i32"; break;
38 case PIC16ISD::SLL_I8
: Basename
= "sll.i8"; break;
39 case RTLIB::SHL_I16
: Basename
= "sll.i16"; break;
40 case RTLIB::SHL_I32
: Basename
= "sll.i32"; break;
42 case PIC16ISD::SRL_I8
: Basename
= "srl.i8"; break;
43 case RTLIB::SRL_I16
: Basename
= "srl.i16"; break;
44 case RTLIB::SRL_I32
: Basename
= "srl.i32"; break;
46 case PIC16ISD::MUL_I8
: Basename
= "mul.i8"; break;
47 case RTLIB::MUL_I16
: Basename
= "mul.i16"; break;
48 case RTLIB::MUL_I32
: Basename
= "mul.i32"; break;
51 std::string prefix
= PAN::getTagName(PAN::PREFIX_SYMBOL
);
52 std::string tagname
= PAN::getTagName(PAN::LIBCALL
);
53 std::string Fullname
= prefix
+ tagname
+ Basename
;
55 // The name has to live through program life.
56 char *tmp
= new char[Fullname
.size() + 1];
57 strcpy (tmp
, Fullname
.c_str());
62 // PIC16TargetLowering Constructor.
63 PIC16TargetLowering::PIC16TargetLowering(PIC16TargetMachine
&TM
)
64 : TargetLowering(TM
), TmpSize(0) {
66 Subtarget
= &TM
.getSubtarget
<PIC16Subtarget
>();
68 addRegisterClass(MVT::i8
, PIC16::GPRRegisterClass
);
70 setShiftAmountType(MVT::i8
);
71 setShiftAmountFlavor(Extend
);
73 // SRA library call names
74 setPIC16LibcallName(PIC16ISD::SRA_I8
, getIntrinsicName(PIC16ISD::SRA_I8
));
75 setLibcallName(RTLIB::SRA_I16
, getIntrinsicName(RTLIB::SRA_I16
));
76 setLibcallName(RTLIB::SRA_I32
, getIntrinsicName(RTLIB::SRA_I32
));
78 // SHL library call names
79 setPIC16LibcallName(PIC16ISD::SLL_I8
, getIntrinsicName(PIC16ISD::SLL_I8
));
80 setLibcallName(RTLIB::SHL_I16
, getIntrinsicName(RTLIB::SHL_I16
));
81 setLibcallName(RTLIB::SHL_I32
, getIntrinsicName(RTLIB::SHL_I32
));
83 // SRL library call names
84 setPIC16LibcallName(PIC16ISD::SRL_I8
, getIntrinsicName(PIC16ISD::SRL_I8
));
85 setLibcallName(RTLIB::SRL_I16
, getIntrinsicName(RTLIB::SRL_I16
));
86 setLibcallName(RTLIB::SRL_I32
, getIntrinsicName(RTLIB::SRL_I32
));
88 // MUL Library call names
89 setPIC16LibcallName(PIC16ISD::MUL_I8
, getIntrinsicName(PIC16ISD::MUL_I8
));
90 setLibcallName(RTLIB::MUL_I16
, getIntrinsicName(RTLIB::MUL_I16
));
91 setLibcallName(RTLIB::MUL_I32
, getIntrinsicName(RTLIB::MUL_I32
));
93 setOperationAction(ISD::GlobalAddress
, MVT::i16
, Custom
);
94 setOperationAction(ISD::ExternalSymbol
, MVT::i16
, Custom
);
96 setOperationAction(ISD::LOAD
, MVT::i8
, Legal
);
97 setOperationAction(ISD::LOAD
, MVT::i16
, Custom
);
98 setOperationAction(ISD::LOAD
, MVT::i32
, Custom
);
100 setOperationAction(ISD::STORE
, MVT::i8
, Legal
);
101 setOperationAction(ISD::STORE
, MVT::i16
, Custom
);
102 setOperationAction(ISD::STORE
, MVT::i32
, Custom
);
104 setOperationAction(ISD::ADDE
, MVT::i8
, Custom
);
105 setOperationAction(ISD::ADDC
, MVT::i8
, Custom
);
106 setOperationAction(ISD::SUBE
, MVT::i8
, Custom
);
107 setOperationAction(ISD::SUBC
, MVT::i8
, Custom
);
108 setOperationAction(ISD::ADD
, MVT::i8
, Custom
);
109 setOperationAction(ISD::ADD
, MVT::i16
, Custom
);
111 setOperationAction(ISD::OR
, MVT::i8
, Custom
);
112 setOperationAction(ISD::AND
, MVT::i8
, Custom
);
113 setOperationAction(ISD::XOR
, MVT::i8
, Custom
);
115 setOperationAction(ISD::FrameIndex
, MVT::i16
, Custom
);
116 setOperationAction(ISD::CALL
, MVT::i16
, Custom
);
117 setOperationAction(ISD::RET
, MVT::Other
, Custom
);
119 setOperationAction(ISD::MUL
, MVT::i8
, Custom
);
120 setOperationAction(ISD::MUL
, MVT::i16
, Expand
);
121 setOperationAction(ISD::MUL
, MVT::i32
, Expand
);
123 setOperationAction(ISD::SMUL_LOHI
, MVT::i8
, Expand
);
124 setOperationAction(ISD::SMUL_LOHI
, MVT::i16
, Expand
);
125 setOperationAction(ISD::SMUL_LOHI
, MVT::i32
, Expand
);
126 setOperationAction(ISD::UMUL_LOHI
, MVT::i8
, Expand
);
127 setOperationAction(ISD::UMUL_LOHI
, MVT::i16
, Expand
);
128 setOperationAction(ISD::UMUL_LOHI
, MVT::i32
, Expand
);
129 setOperationAction(ISD::MULHU
, MVT::i8
, Expand
);
130 setOperationAction(ISD::MULHU
, MVT::i16
, Expand
);
131 setOperationAction(ISD::MULHU
, MVT::i32
, Expand
);
132 setOperationAction(ISD::MULHS
, MVT::i8
, Expand
);
133 setOperationAction(ISD::MULHS
, MVT::i16
, Expand
);
134 setOperationAction(ISD::MULHS
, MVT::i32
, Expand
);
136 setOperationAction(ISD::SRA
, MVT::i8
, Custom
);
137 setOperationAction(ISD::SRA
, MVT::i16
, Expand
);
138 setOperationAction(ISD::SRA
, MVT::i32
, Expand
);
139 setOperationAction(ISD::SHL
, MVT::i8
, Custom
);
140 setOperationAction(ISD::SHL
, MVT::i16
, Expand
);
141 setOperationAction(ISD::SHL
, MVT::i32
, Expand
);
142 setOperationAction(ISD::SRL
, MVT::i8
, Custom
);
143 setOperationAction(ISD::SRL
, MVT::i16
, Expand
);
144 setOperationAction(ISD::SRL
, MVT::i32
, Expand
);
146 // PIC16 does not support shift parts
147 setOperationAction(ISD::SRA_PARTS
, MVT::i8
, Expand
);
148 setOperationAction(ISD::SRA_PARTS
, MVT::i16
, Expand
);
149 setOperationAction(ISD::SRA_PARTS
, MVT::i32
, Expand
);
150 setOperationAction(ISD::SHL_PARTS
, MVT::i8
, Expand
);
151 setOperationAction(ISD::SHL_PARTS
, MVT::i16
, Expand
);
152 setOperationAction(ISD::SHL_PARTS
, MVT::i32
, Expand
);
153 setOperationAction(ISD::SRL_PARTS
, MVT::i8
, Expand
);
154 setOperationAction(ISD::SRL_PARTS
, MVT::i16
, Expand
);
155 setOperationAction(ISD::SRL_PARTS
, MVT::i32
, Expand
);
158 // PIC16 does not have a SETCC, expand it to SELECT_CC.
159 setOperationAction(ISD::SETCC
, MVT::i8
, Expand
);
160 setOperationAction(ISD::SELECT
, MVT::i8
, Expand
);
161 setOperationAction(ISD::BRCOND
, MVT::Other
, Expand
);
162 setOperationAction(ISD::BRIND
, MVT::Other
, Expand
);
164 setOperationAction(ISD::SELECT_CC
, MVT::i8
, Custom
);
165 setOperationAction(ISD::BR_CC
, MVT::i8
, Custom
);
167 //setOperationAction(ISD::TRUNCATE, MVT::i16, Custom);
168 setTruncStoreAction(MVT::i16
, MVT::i8
, Custom
);
170 // Now deduce the information based on the above mentioned
172 computeRegisterProperties();
175 // getOutFlag - Extract the flag result if the Op has it.
176 static SDValue
getOutFlag(SDValue
&Op
) {
177 // Flag is the last value of the node.
178 SDValue Flag
= Op
.getValue(Op
.getNode()->getNumValues() - 1);
180 assert (Flag
.getValueType() == MVT::Flag
181 && "Node does not have an out Flag");
185 // Get the TmpOffset for FrameIndex
186 unsigned PIC16TargetLowering::GetTmpOffsetForFI(unsigned FI
, unsigned size
) {
187 std::map
<unsigned, unsigned>::iterator
188 MapIt
= FiTmpOffsetMap
.find(FI
);
189 if (MapIt
!= FiTmpOffsetMap
.end())
190 return MapIt
->second
;
192 // This FI (FrameIndex) is not yet mapped, so map it
193 FiTmpOffsetMap
[FI
] = TmpSize
;
195 return FiTmpOffsetMap
[FI
];
198 // To extract chain value from the SDValue Nodes
199 // This function will help to maintain the chain extracting
200 // code at one place. In case of any change in future it will
201 // help maintain the code.
202 static SDValue
getChain(SDValue
&Op
) {
203 SDValue Chain
= Op
.getValue(Op
.getNode()->getNumValues() - 1);
205 // If the last value returned in Flag then the chain is
206 // second last value returned.
207 if (Chain
.getValueType() == MVT::Flag
)
208 Chain
= Op
.getValue(Op
.getNode()->getNumValues() - 2);
210 // All nodes may not produce a chain. Therefore following assert
211 // verifies that the node is returning a chain only.
212 assert (Chain
.getValueType() == MVT::Other
213 && "Node does not have a chain");
218 /// PopulateResults - Helper function to LowerOperation.
219 /// If a node wants to return multiple results after lowering,
220 /// it stuffs them into an array of SDValue called Results.
222 static void PopulateResults(SDValue N
, SmallVectorImpl
<SDValue
>&Results
) {
223 if (N
.getOpcode() == ISD::MERGE_VALUES
) {
224 int NumResults
= N
.getNumOperands();
225 for( int i
= 0; i
< NumResults
; i
++)
226 Results
.push_back(N
.getOperand(i
));
229 Results
.push_back(N
);
232 MVT
PIC16TargetLowering::getSetCCResultType(MVT ValType
) const {
236 /// The type legalizer framework of generating legalizer can generate libcalls
237 /// only when the operand/result types are illegal.
238 /// PIC16 needs to generate libcalls even for the legal types (i8) for some ops.
239 /// For example an arithmetic right shift. These functions are used to lower
240 /// such operations that generate libcall for legal types.
243 PIC16TargetLowering::setPIC16LibcallName(PIC16ISD::PIC16Libcall Call
,
245 PIC16LibcallNames
[Call
] = Name
;
249 PIC16TargetLowering::getPIC16LibcallName(PIC16ISD::PIC16Libcall Call
) {
250 return PIC16LibcallNames
[Call
];
254 PIC16TargetLowering::MakePIC16Libcall(PIC16ISD::PIC16Libcall Call
,
255 MVT RetVT
, const SDValue
*Ops
,
256 unsigned NumOps
, bool isSigned
,
257 SelectionDAG
&DAG
, DebugLoc dl
) {
259 TargetLowering::ArgListTy Args
;
260 Args
.reserve(NumOps
);
262 TargetLowering::ArgListEntry Entry
;
263 for (unsigned i
= 0; i
!= NumOps
; ++i
) {
265 Entry
.Ty
= Entry
.Node
.getValueType().getTypeForMVT();
266 Entry
.isSExt
= isSigned
;
267 Entry
.isZExt
= !isSigned
;
268 Args
.push_back(Entry
);
270 SDValue Callee
= DAG
.getExternalSymbol(getPIC16LibcallName(Call
), MVT::i8
);
272 const Type
*RetTy
= RetVT
.getTypeForMVT();
273 std::pair
<SDValue
,SDValue
> CallInfo
=
274 LowerCallTo(DAG
.getEntryNode(), RetTy
, isSigned
, !isSigned
, false,
275 false, CallingConv::C
, false, Callee
, Args
, DAG
, dl
);
277 return CallInfo
.first
;
280 const char *PIC16TargetLowering::getTargetNodeName(unsigned Opcode
) const {
282 default: return NULL
;
283 case PIC16ISD::Lo
: return "PIC16ISD::Lo";
284 case PIC16ISD::Hi
: return "PIC16ISD::Hi";
285 case PIC16ISD::MTLO
: return "PIC16ISD::MTLO";
286 case PIC16ISD::MTHI
: return "PIC16ISD::MTHI";
287 case PIC16ISD::MTPCLATH
: return "PIC16ISD::MTPCLATH";
288 case PIC16ISD::PIC16Connect
: return "PIC16ISD::PIC16Connect";
289 case PIC16ISD::Banksel
: return "PIC16ISD::Banksel";
290 case PIC16ISD::PIC16Load
: return "PIC16ISD::PIC16Load";
291 case PIC16ISD::PIC16LdArg
: return "PIC16ISD::PIC16LdArg";
292 case PIC16ISD::PIC16LdWF
: return "PIC16ISD::PIC16LdWF";
293 case PIC16ISD::PIC16Store
: return "PIC16ISD::PIC16Store";
294 case PIC16ISD::PIC16StWF
: return "PIC16ISD::PIC16StWF";
295 case PIC16ISD::BCF
: return "PIC16ISD::BCF";
296 case PIC16ISD::LSLF
: return "PIC16ISD::LSLF";
297 case PIC16ISD::LRLF
: return "PIC16ISD::LRLF";
298 case PIC16ISD::RLF
: return "PIC16ISD::RLF";
299 case PIC16ISD::RRF
: return "PIC16ISD::RRF";
300 case PIC16ISD::CALL
: return "PIC16ISD::CALL";
301 case PIC16ISD::CALLW
: return "PIC16ISD::CALLW";
302 case PIC16ISD::SUBCC
: return "PIC16ISD::SUBCC";
303 case PIC16ISD::SELECT_ICC
: return "PIC16ISD::SELECT_ICC";
304 case PIC16ISD::BRCOND
: return "PIC16ISD::BRCOND";
305 case PIC16ISD::Dummy
: return "PIC16ISD::Dummy";
309 void PIC16TargetLowering::ReplaceNodeResults(SDNode
*N
,
310 SmallVectorImpl
<SDValue
>&Results
,
313 switch (N
->getOpcode()) {
314 case ISD::GlobalAddress
:
315 Results
.push_back(ExpandGlobalAddress(N
, DAG
));
317 case ISD::ExternalSymbol
:
318 Results
.push_back(ExpandExternalSymbol(N
, DAG
));
321 Results
.push_back(ExpandStore(N
, DAG
));
324 PopulateResults(ExpandLoad(N
, DAG
), Results
);
327 // Results.push_back(ExpandAdd(N, DAG));
329 case ISD::FrameIndex
:
330 Results
.push_back(ExpandFrameIndex(N
, DAG
));
333 assert (0 && "not implemented");
338 SDValue
PIC16TargetLowering::ExpandFrameIndex(SDNode
*N
, SelectionDAG
&DAG
) {
340 // Currently handling FrameIndex of size MVT::i16 only
341 // One example of this scenario is when return value is written on
344 if (N
->getValueType(0) != MVT::i16
)
347 // Expand the FrameIndex into ExternalSymbol and a Constant node
348 // The constant will represent the frame index number
349 // Get the current function frame
350 MachineFunction
&MF
= DAG
.getMachineFunction();
351 const Function
*Func
= MF
.getFunction();
352 const std::string Name
= Func
->getName();
354 FrameIndexSDNode
*FR
= dyn_cast
<FrameIndexSDNode
>(SDValue(N
,0));
355 // FIXME there isn't really debug info here
356 DebugLoc dl
= FR
->getDebugLoc();
357 int Index
= FR
->getIndex();
359 // Expand FrameIndex like GlobalAddress and ExternalSymbol
360 // Also use Offset field for lo and hi parts. The default
362 SDValue Offset
= DAG
.getConstant(0, MVT::i8
);
363 SDValue FI
= DAG
.getTargetFrameIndex(Index
, MVT::i8
);
364 SDValue Lo
= DAG
.getNode(PIC16ISD::Lo
, dl
, MVT::i8
, FI
, Offset
);
365 SDValue Hi
= DAG
.getNode(PIC16ISD::Hi
, dl
, MVT::i8
, FI
, Offset
);
366 return DAG
.getNode(ISD::BUILD_PAIR
, dl
, N
->getValueType(0), Lo
, Hi
);
370 SDValue
PIC16TargetLowering::ExpandStore(SDNode
*N
, SelectionDAG
&DAG
) {
371 StoreSDNode
*St
= cast
<StoreSDNode
>(N
);
372 SDValue Chain
= St
->getChain();
373 SDValue Src
= St
->getValue();
374 SDValue Ptr
= St
->getBasePtr();
375 MVT ValueType
= Src
.getValueType();
376 unsigned StoreOffset
= 0;
377 DebugLoc dl
= N
->getDebugLoc();
379 SDValue PtrLo
, PtrHi
;
380 LegalizeAddress(Ptr
, DAG
, PtrLo
, PtrHi
, StoreOffset
, dl
);
382 if (ValueType
== MVT::i8
) {
383 return DAG
.getNode (PIC16ISD::PIC16Store
, dl
, MVT::Other
, Chain
, Src
,
385 DAG
.getConstant (0 + StoreOffset
, MVT::i8
));
387 else if (ValueType
== MVT::i16
) {
388 // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
389 SDValue SrcLo
, SrcHi
;
390 GetExpandedParts(Src
, DAG
, SrcLo
, SrcHi
);
391 SDValue ChainLo
= Chain
, ChainHi
= Chain
;
392 if (Chain
.getOpcode() == ISD::TokenFactor
) {
393 ChainLo
= Chain
.getOperand(0);
394 ChainHi
= Chain
.getOperand(1);
396 SDValue Store1
= DAG
.getNode(PIC16ISD::PIC16Store
, dl
, MVT::Other
,
399 DAG
.getConstant (0 + StoreOffset
, MVT::i8
));
401 SDValue Store2
= DAG
.getNode(PIC16ISD::PIC16Store
, dl
, MVT::Other
, ChainHi
,
403 DAG
.getConstant (1 + StoreOffset
, MVT::i8
));
405 return DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, getChain(Store1
),
408 else if (ValueType
== MVT::i32
) {
409 // Get the Lo and Hi parts from MERGE_VALUE or BUILD_PAIR.
410 SDValue SrcLo
, SrcHi
;
411 GetExpandedParts(Src
, DAG
, SrcLo
, SrcHi
);
413 // Get the expanded parts of each of SrcLo and SrcHi.
414 SDValue SrcLo1
, SrcLo2
, SrcHi1
, SrcHi2
;
415 GetExpandedParts(SrcLo
, DAG
, SrcLo1
, SrcLo2
);
416 GetExpandedParts(SrcHi
, DAG
, SrcHi1
, SrcHi2
);
418 SDValue ChainLo
= Chain
, ChainHi
= Chain
;
419 if (Chain
.getOpcode() == ISD::TokenFactor
) {
420 ChainLo
= Chain
.getOperand(0);
421 ChainHi
= Chain
.getOperand(1);
423 SDValue ChainLo1
= ChainLo
, ChainLo2
= ChainLo
, ChainHi1
= ChainHi
,
425 if (ChainLo
.getOpcode() == ISD::TokenFactor
) {
426 ChainLo1
= ChainLo
.getOperand(0);
427 ChainLo2
= ChainLo
.getOperand(1);
429 if (ChainHi
.getOpcode() == ISD::TokenFactor
) {
430 ChainHi1
= ChainHi
.getOperand(0);
431 ChainHi2
= ChainHi
.getOperand(1);
433 SDValue Store1
= DAG
.getNode(PIC16ISD::PIC16Store
, dl
, MVT::Other
,
435 SrcLo1
, PtrLo
, PtrHi
,
436 DAG
.getConstant (0 + StoreOffset
, MVT::i8
));
438 SDValue Store2
= DAG
.getNode(PIC16ISD::PIC16Store
, dl
, MVT::Other
, ChainLo2
,
439 SrcLo2
, PtrLo
, PtrHi
,
440 DAG
.getConstant (1 + StoreOffset
, MVT::i8
));
442 SDValue Store3
= DAG
.getNode(PIC16ISD::PIC16Store
, dl
, MVT::Other
, ChainHi1
,
443 SrcHi1
, PtrLo
, PtrHi
,
444 DAG
.getConstant (2 + StoreOffset
, MVT::i8
));
446 SDValue Store4
= DAG
.getNode(PIC16ISD::PIC16Store
, dl
, MVT::Other
, ChainHi2
,
447 SrcHi2
, PtrLo
, PtrHi
,
448 DAG
.getConstant (3 + StoreOffset
, MVT::i8
));
450 SDValue RetLo
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
,
451 getChain(Store1
), getChain(Store2
));
452 SDValue RetHi
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
,
453 getChain(Store3
), getChain(Store4
));
454 return DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
, RetLo
, RetHi
);
458 assert (0 && "value type not supported");
463 SDValue
PIC16TargetLowering::ExpandExternalSymbol(SDNode
*N
, SelectionDAG
&DAG
)
465 ExternalSymbolSDNode
*ES
= dyn_cast
<ExternalSymbolSDNode
>(SDValue(N
, 0));
466 // FIXME there isn't really debug info here
467 DebugLoc dl
= ES
->getDebugLoc();
469 SDValue TES
= DAG
.getTargetExternalSymbol(ES
->getSymbol(), MVT::i8
);
470 SDValue Offset
= DAG
.getConstant(0, MVT::i8
);
471 SDValue Lo
= DAG
.getNode(PIC16ISD::Lo
, dl
, MVT::i8
, TES
, Offset
);
472 SDValue Hi
= DAG
.getNode(PIC16ISD::Hi
, dl
, MVT::i8
, TES
, Offset
);
474 return DAG
.getNode(ISD::BUILD_PAIR
, dl
, MVT::i16
, Lo
, Hi
);
477 // ExpandGlobalAddress -
478 SDValue
PIC16TargetLowering::ExpandGlobalAddress(SDNode
*N
, SelectionDAG
&DAG
) {
479 GlobalAddressSDNode
*G
= dyn_cast
<GlobalAddressSDNode
>(SDValue(N
, 0));
480 // FIXME there isn't really debug info here
481 DebugLoc dl
= G
->getDebugLoc();
483 SDValue TGA
= DAG
.getTargetGlobalAddress(G
->getGlobal(), MVT::i8
,
486 SDValue Offset
= DAG
.getConstant(0, MVT::i8
);
487 SDValue Lo
= DAG
.getNode(PIC16ISD::Lo
, dl
, MVT::i8
, TGA
, Offset
);
488 SDValue Hi
= DAG
.getNode(PIC16ISD::Hi
, dl
, MVT::i8
, TGA
, Offset
);
490 return DAG
.getNode(ISD::BUILD_PAIR
, dl
, MVT::i16
, Lo
, Hi
);
493 bool PIC16TargetLowering::isDirectAddress(const SDValue
&Op
) {
494 assert (Op
.getNode() != NULL
&& "Can't operate on NULL SDNode!!");
496 if (Op
.getOpcode() == ISD::BUILD_PAIR
) {
497 if (Op
.getOperand(0).getOpcode() == PIC16ISD::Lo
)
503 // Return true if DirectAddress is in ROM_SPACE
504 bool PIC16TargetLowering::isRomAddress(const SDValue
&Op
) {
506 // RomAddress is a GlobalAddress in ROM_SPACE_
507 // If the Op is not a GlobalAddress return NULL without checking
509 if (!isDirectAddress(Op
))
512 // Its a GlobalAddress.
513 // It is BUILD_PAIR((PIC16Lo TGA), (PIC16Hi TGA)) and Op is BUILD_PAIR
514 SDValue TGA
= Op
.getOperand(0).getOperand(0);
515 GlobalAddressSDNode
*GSDN
= dyn_cast
<GlobalAddressSDNode
>(TGA
);
517 if (GSDN
->getAddressSpace() == PIC16ISD::ROM_SPACE
)
520 // Any other address space return it false
525 // GetExpandedParts - This function is on the similiar lines as
526 // the GetExpandedInteger in type legalizer is. This returns expanded
527 // parts of Op in Lo and Hi.
529 void PIC16TargetLowering::GetExpandedParts(SDValue Op
, SelectionDAG
&DAG
,
530 SDValue
&Lo
, SDValue
&Hi
) {
531 SDNode
*N
= Op
.getNode();
532 DebugLoc dl
= N
->getDebugLoc();
533 MVT NewVT
= getTypeToTransformTo(N
->getValueType(0));
535 // Extract the lo component.
536 Lo
= DAG
.getNode(ISD::EXTRACT_ELEMENT
, dl
, NewVT
, Op
,
537 DAG
.getConstant(0, MVT::i8
));
539 // extract the hi component
540 Hi
= DAG
.getNode(ISD::EXTRACT_ELEMENT
, dl
, NewVT
, Op
,
541 DAG
.getConstant(1, MVT::i8
));
544 // Legalize FrameIndex into ExternalSymbol and offset.
546 PIC16TargetLowering::LegalizeFrameIndex(SDValue Op
, SelectionDAG
&DAG
,
547 SDValue
&ES
, int &Offset
) {
549 MachineFunction
&MF
= DAG
.getMachineFunction();
550 const Function
*Func
= MF
.getFunction();
551 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
552 const std::string Name
= Func
->getName();
554 FrameIndexSDNode
*FR
= dyn_cast
<FrameIndexSDNode
>(Op
);
556 // FrameIndices are not stack offsets. But they represent the request
557 // for space on stack. That space requested may be more than one byte.
558 // Therefore, to calculate the stack offset that a FrameIndex aligns
559 // with, we need to traverse all the FrameIndices available earlier in
560 // the list and add their requested size.
561 unsigned FIndex
= FR
->getIndex();
563 if (FIndex
< ReservedFrameCount
) {
564 tmpName
= createESName(PAN::getFrameLabel(Name
));
565 ES
= DAG
.getTargetExternalSymbol(tmpName
, MVT::i8
);
567 for (unsigned i
=0; i
<FIndex
; ++i
) {
568 Offset
+= MFI
->getObjectSize(i
);
571 // FrameIndex has been made for some temporary storage
572 tmpName
= createESName(PAN::getTempdataLabel(Name
));
573 ES
= DAG
.getTargetExternalSymbol(tmpName
, MVT::i8
);
574 Offset
= GetTmpOffsetForFI(FIndex
, MFI
->getObjectSize(FIndex
));
580 // This function legalizes the PIC16 Addresses. If the Pointer is
581 // -- Direct address variable residing
582 // --> then a Banksel for that variable will be created.
584 // --> then it will be treated as an indirect address.
585 // -- Indirect address
586 // --> then the address will be loaded into FSR
587 // -- ADD with constant operand
588 // --> then constant operand of ADD will be returned as Offset
589 // and non-constant operand of ADD will be treated as pointer.
590 // Returns the high and lo part of the address, and the offset(in case of ADD).
592 void PIC16TargetLowering::LegalizeAddress(SDValue Ptr
, SelectionDAG
&DAG
,
593 SDValue
&Lo
, SDValue
&Hi
,
594 unsigned &Offset
, DebugLoc dl
) {
596 // Offset, by default, should be 0
599 // If the pointer is ADD with constant,
600 // return the constant value as the offset
601 if (Ptr
.getOpcode() == ISD::ADD
) {
602 SDValue OperLeft
= Ptr
.getOperand(0);
603 SDValue OperRight
= Ptr
.getOperand(1);
604 if (OperLeft
.getOpcode() == ISD::Constant
) {
605 Offset
= dyn_cast
<ConstantSDNode
>(OperLeft
)->getZExtValue();
607 } else if (OperRight
.getOpcode() == ISD::Constant
) {
608 Offset
= dyn_cast
<ConstantSDNode
>(OperRight
)->getZExtValue();
613 // If the pointer is Type i8 and an external symbol
614 // then treat it as direct address.
615 // One example for such case is storing and loading
616 // from function frame during a call
617 if (Ptr
.getValueType() == MVT::i8
) {
618 switch (Ptr
.getOpcode()) {
619 case ISD::TargetExternalSymbol
:
621 Hi
= DAG
.getConstant(1, MVT::i8
);
626 // Expansion of FrameIndex has Lo/Hi parts
627 if (isDirectAddress(Ptr
)) {
628 SDValue TFI
= Ptr
.getOperand(0).getOperand(0);
629 if (TFI
.getOpcode() == ISD::TargetFrameIndex
) {
631 LegalizeFrameIndex(TFI
, DAG
, Lo
, FrameOffset
);
632 Hi
= DAG
.getConstant(1, MVT::i8
);
633 Offset
+= FrameOffset
;
638 if (isDirectAddress(Ptr
) && !isRomAddress(Ptr
)) {
639 // Direct addressing case for RAM variables. The Hi part is constant
640 // and the Lo part is the TGA itself.
641 Lo
= Ptr
.getOperand(0).getOperand(0);
643 // For direct addresses Hi is a constant. Value 1 for the constant
644 // signifies that banksel needs to generated for it. Value 0 for
645 // the constant signifies that banksel does not need to be generated
646 // for it. Mark it as 1 now and optimize later.
647 Hi
= DAG
.getConstant(1, MVT::i8
);
651 // Indirect addresses. Get the hi and lo parts of ptr.
652 GetExpandedParts(Ptr
, DAG
, Lo
, Hi
);
654 // Put the hi and lo parts into FSR.
655 Lo
= DAG
.getNode(PIC16ISD::MTLO
, dl
, MVT::i8
, Lo
);
656 Hi
= DAG
.getNode(PIC16ISD::MTHI
, dl
, MVT::i8
, Hi
);
661 SDValue
PIC16TargetLowering::ExpandLoad(SDNode
*N
, SelectionDAG
&DAG
) {
662 LoadSDNode
*LD
= dyn_cast
<LoadSDNode
>(SDValue(N
, 0));
663 SDValue Chain
= LD
->getChain();
664 SDValue Ptr
= LD
->getBasePtr();
665 DebugLoc dl
= LD
->getDebugLoc();
667 SDValue Load
, Offset
;
670 SDValue PtrLo
, PtrHi
;
673 // Legalize direct/indirect addresses. This will give the lo and hi parts
674 // of the address and the offset.
675 LegalizeAddress(Ptr
, DAG
, PtrLo
, PtrHi
, LoadOffset
, dl
);
677 // Load from the pointer (direct address or FSR)
678 VT
= N
->getValueType(0);
679 unsigned NumLoads
= VT
.getSizeInBits() / 8;
680 std::vector
<SDValue
> PICLoads
;
682 MVT MemVT
= LD
->getMemoryVT();
683 if(ISD::isNON_EXTLoad(N
)) {
684 for (iter
=0; iter
<NumLoads
; ++iter
) {
685 // Add the pointer offset if any
686 Offset
= DAG
.getConstant(iter
+ LoadOffset
, MVT::i8
);
687 Tys
= DAG
.getVTList(MVT::i8
, MVT::Other
);
688 Load
= DAG
.getNode(PIC16ISD::PIC16Load
, dl
, Tys
, Chain
, PtrLo
, PtrHi
,
690 PICLoads
.push_back(Load
);
693 // If it is extended load then use PIC16Load for Memory Bytes
694 // and for all extended bytes perform action based on type of
695 // extention - i.e. SignExtendedLoad or ZeroExtendedLoad
698 // For extended loads this is the memory value type
699 // i.e. without any extension
700 MVT MemVT
= LD
->getMemoryVT();
701 unsigned MemBytes
= MemVT
.getSizeInBits() / 8;
702 unsigned ExtdBytes
= VT
.getSizeInBits() / 8;
703 Offset
= DAG
.getConstant(LoadOffset
, MVT::i8
);
705 Tys
= DAG
.getVTList(MVT::i8
, MVT::Other
);
706 // For MemBytes generate PIC16Load with proper offset
707 for (iter
=0; iter
<MemBytes
; ++iter
) {
708 // Add the pointer offset if any
709 Offset
= DAG
.getConstant(iter
+ LoadOffset
, MVT::i8
);
710 Load
= DAG
.getNode(PIC16ISD::PIC16Load
, dl
, Tys
, Chain
, PtrLo
, PtrHi
,
712 PICLoads
.push_back(Load
);
715 // For SignExtendedLoad
716 if (ISD::isSEXTLoad(N
)) {
717 // For all ExtdBytes use the Right Shifted(Arithmetic) Value of the
719 SDValue SRA
= DAG
.getNode(ISD::SRA
, dl
, MVT::i8
, Load
,
720 DAG
.getConstant(7, MVT::i8
));
721 for (iter
=MemBytes
; iter
<ExtdBytes
; ++iter
) {
722 PICLoads
.push_back(SRA
);
724 } else if (ISD::isZEXTLoad(N
)) {
725 // ZeroExtendedLoad -- For all ExtdBytes use constant 0
726 SDValue ConstZero
= DAG
.getConstant(0, MVT::i8
);
727 for (iter
=MemBytes
; iter
<ExtdBytes
; ++iter
) {
728 PICLoads
.push_back(ConstZero
);
735 // Operand of Load is illegal -- Load itself is legal
738 else if (VT
== MVT::i16
) {
739 BP
= DAG
.getNode(ISD::BUILD_PAIR
, dl
, VT
, PICLoads
[0], PICLoads
[1]);
740 if (MemVT
== MVT::i8
)
741 Chain
= getChain(PICLoads
[0]);
743 Chain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
,
744 getChain(PICLoads
[0]), getChain(PICLoads
[1]));
745 } else if (VT
== MVT::i32
) {
747 BPs
[0] = DAG
.getNode(ISD::BUILD_PAIR
, dl
, MVT::i16
,
748 PICLoads
[0], PICLoads
[1]);
749 BPs
[1] = DAG
.getNode(ISD::BUILD_PAIR
, dl
, MVT::i16
,
750 PICLoads
[2], PICLoads
[3]);
751 BP
= DAG
.getNode(ISD::BUILD_PAIR
, dl
, VT
, BPs
[0], BPs
[1]);
752 if (MemVT
== MVT::i8
)
753 Chain
= getChain(PICLoads
[0]);
754 else if (MemVT
== MVT::i16
)
755 Chain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
,
756 getChain(PICLoads
[0]), getChain(PICLoads
[1]));
759 Chains
[0] = DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
,
760 getChain(PICLoads
[0]), getChain(PICLoads
[1]));
761 Chains
[1] = DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
,
762 getChain(PICLoads
[2]), getChain(PICLoads
[3]));
763 Chain
= DAG
.getNode(ISD::TokenFactor
, dl
, MVT::Other
,
764 Chains
[0], Chains
[1]);
767 Tys
= DAG
.getVTList(VT
, MVT::Other
);
768 return DAG
.getNode(ISD::MERGE_VALUES
, dl
, Tys
, BP
, Chain
);
771 SDValue
PIC16TargetLowering::LowerShift(SDValue Op
, SelectionDAG
&DAG
) {
772 // We should have handled larger operands in type legalizer itself.
773 assert (Op
.getValueType() == MVT::i8
&& "illegal shift to lower");
775 SDNode
*N
= Op
.getNode();
776 SDValue Value
= N
->getOperand(0);
777 SDValue Amt
= N
->getOperand(1);
778 PIC16ISD::PIC16Libcall CallCode
;
779 switch (N
->getOpcode()) {
781 CallCode
= PIC16ISD::SRA_I8
;
784 CallCode
= PIC16ISD::SLL_I8
;
787 CallCode
= PIC16ISD::SRL_I8
;
790 assert ( 0 && "This shift is not implemented yet.");
793 SmallVector
<SDValue
, 2> Ops(2);
796 SDValue Call
= MakePIC16Libcall(CallCode
, N
->getValueType(0), &Ops
[0], 2,
797 true, DAG
, N
->getDebugLoc());
802 PIC16TargetLowering::LowerOperationWrapper(SDNode
*N
,
803 SmallVectorImpl
<SDValue
>&Results
,
805 SDValue Op
= SDValue(N
, 0);
808 switch (Op
.getOpcode()) {
809 case ISD::FORMAL_ARGUMENTS
:
810 Res
= LowerFORMAL_ARGUMENTS(Op
, DAG
); break;
812 Res
= ExpandLoad(Op
.getNode(), DAG
); break;
814 Res
= LowerCALL(Op
, DAG
); break;
816 // All other operations are handled in LowerOperation.
817 Res
= LowerOperation(Op
, DAG
);
819 Results
.push_back(Res
);
826 unsigned NumValues
= N
->getNumValues();
827 for (i
= 0; i
< NumValues
; i
++) {
828 Results
.push_back(SDValue(N
, i
));
832 SDValue
PIC16TargetLowering::LowerOperation(SDValue Op
, SelectionDAG
&DAG
) {
833 switch (Op
.getOpcode()) {
834 case ISD::FORMAL_ARGUMENTS
:
835 return LowerFORMAL_ARGUMENTS(Op
, DAG
);
839 return LowerADD(Op
, DAG
);
843 return LowerSUB(Op
, DAG
);
845 return ExpandLoad(Op
.getNode(), DAG
);
847 return ExpandStore(Op
.getNode(), DAG
);
851 return LowerShift(Op
, DAG
);
855 return LowerBinOp(Op
, DAG
);
857 return LowerCALL(Op
, DAG
);
859 return LowerRET(Op
, DAG
);
861 return LowerBR_CC(Op
, DAG
);
863 return LowerSELECT_CC(Op
, DAG
);
868 SDValue
PIC16TargetLowering::ConvertToMemOperand(SDValue Op
,
871 assert (Op
.getValueType() == MVT::i8
872 && "illegal value type to store on stack.");
874 MachineFunction
&MF
= DAG
.getMachineFunction();
875 const Function
*Func
= MF
.getFunction();
876 const std::string FuncName
= Func
->getName();
879 // Put the value on stack.
880 // Get a stack slot index and convert to es.
881 int FI
= MF
.getFrameInfo()->CreateStackObject(1, 1);
882 const char *tmpName
= createESName(PAN::getTempdataLabel(FuncName
));
883 SDValue ES
= DAG
.getTargetExternalSymbol(tmpName
, MVT::i8
);
885 // Store the value to ES.
886 SDValue Store
= DAG
.getNode (PIC16ISD::PIC16Store
, dl
, MVT::Other
,
889 DAG
.getConstant (1, MVT::i8
), // Banksel.
890 DAG
.getConstant (GetTmpOffsetForFI(FI
, 1),
893 // Load the value from ES.
894 SDVTList Tys
= DAG
.getVTList(MVT::i8
, MVT::Other
);
895 SDValue Load
= DAG
.getNode(PIC16ISD::PIC16Load
, dl
, Tys
, Store
,
896 ES
, DAG
.getConstant (1, MVT::i8
),
897 DAG
.getConstant (GetTmpOffsetForFI(FI
, 1),
900 return Load
.getValue(0);
903 SDValue
PIC16TargetLowering::
904 LowerIndirectCallArguments(SDValue Op
, SDValue Chain
, SDValue InFlag
,
905 SDValue DataAddr_Lo
, SDValue DataAddr_Hi
,
907 CallSDNode
*TheCall
= dyn_cast
<CallSDNode
>(Op
);
908 unsigned NumOps
= TheCall
->getNumArgs();
909 DebugLoc dl
= TheCall
->getDebugLoc();
911 // If call has no arguments then do nothing and return.
915 std::vector
<SDValue
> Ops
;
916 SDVTList Tys
= DAG
.getVTList(MVT::Other
, MVT::Flag
);
917 SDValue Arg
, StoreRet
;
919 // For PIC16 ABI the arguments come after the return value.
920 unsigned RetVals
= TheCall
->getNumRetVals();
921 for (unsigned i
= 0, ArgOffset
= RetVals
; i
< NumOps
; i
++) {
923 Arg
= TheCall
->getArg(i
);
926 Ops
.push_back(Chain
);
928 Ops
.push_back(DataAddr_Lo
);
929 Ops
.push_back(DataAddr_Hi
);
930 Ops
.push_back(DAG
.getConstant(ArgOffset
, MVT::i8
));
931 Ops
.push_back(InFlag
);
933 StoreRet
= DAG
.getNode (PIC16ISD::PIC16StWF
, dl
, Tys
, &Ops
[0], Ops
.size());
935 Chain
= getChain(StoreRet
);
936 InFlag
= getOutFlag(StoreRet
);
942 SDValue
PIC16TargetLowering::
943 LowerDirectCallArguments(SDValue Op
, SDValue Chain
, SDValue ArgLabel
,
944 SDValue InFlag
, SelectionDAG
&DAG
) {
945 CallSDNode
*TheCall
= dyn_cast
<CallSDNode
>(Op
);
946 unsigned NumOps
= TheCall
->getNumArgs();
947 DebugLoc dl
= TheCall
->getDebugLoc();
949 SDValue Arg
, StoreAt
;
954 // If call has no arguments then do nothing and return.
958 // FIXME: This portion of code currently assumes only
959 // primitive types being passed as arguments.
961 // Legalize the address before use
962 SDValue PtrLo
, PtrHi
;
963 unsigned AddressOffset
;
965 LegalizeAddress(ArgLabel
, DAG
, PtrLo
, PtrHi
, AddressOffset
, dl
);
968 std::vector
<SDValue
> Ops
;
969 SDVTList Tys
= DAG
.getVTList(MVT::Other
, MVT::Flag
);
970 for (unsigned i
=ArgCount
, Offset
= 0; i
<NumOps
; i
++) {
972 Arg
= TheCall
->getArg(i
);
973 StoreOffset
= (Offset
+ AddressOffset
);
975 // Store the argument on frame
978 Ops
.push_back(Chain
);
980 Ops
.push_back(PtrLo
);
981 Ops
.push_back(PtrHi
);
982 Ops
.push_back(DAG
.getConstant(StoreOffset
, MVT::i8
));
983 Ops
.push_back(InFlag
);
985 StoreRet
= DAG
.getNode (PIC16ISD::PIC16StWF
, dl
, Tys
, &Ops
[0], Ops
.size());
987 Chain
= getChain(StoreRet
);
988 InFlag
= getOutFlag(StoreRet
);
990 // Update the frame offset to be used for next argument
991 ArgVT
= Arg
.getValueType();
992 Size
= ArgVT
.getSizeInBits();
993 Size
= Size
/8; // Calculate size in bytes
994 Offset
+= Size
; // Increase the frame offset
999 SDValue
PIC16TargetLowering::
1000 LowerIndirectCallReturn (SDValue Op
, SDValue Chain
, SDValue InFlag
,
1001 SDValue DataAddr_Lo
, SDValue DataAddr_Hi
,
1002 SelectionDAG
&DAG
) {
1003 CallSDNode
*TheCall
= dyn_cast
<CallSDNode
>(Op
);
1004 DebugLoc dl
= TheCall
->getDebugLoc();
1005 unsigned RetVals
= TheCall
->getNumRetVals();
1007 // If call does not have anything to return
1008 // then do nothing and go back.
1012 // Call has something to return
1013 std::vector
<SDValue
> ResultVals
;
1016 SDVTList Tys
= DAG
.getVTList(MVT::i8
, MVT::Other
, MVT::Flag
);
1017 for(unsigned i
=0;i
<RetVals
;i
++) {
1018 LoadRet
= DAG
.getNode(PIC16ISD::PIC16LdWF
, dl
, Tys
, Chain
, DataAddr_Lo
,
1019 DataAddr_Hi
, DAG
.getConstant(i
, MVT::i8
),
1021 InFlag
= getOutFlag(LoadRet
);
1022 Chain
= getChain(LoadRet
);
1023 ResultVals
.push_back(LoadRet
);
1025 ResultVals
.push_back(Chain
);
1026 SDValue Res
= DAG
.getMergeValues(&ResultVals
[0], ResultVals
.size(), dl
);
1030 SDValue
PIC16TargetLowering::
1031 LowerDirectCallReturn(SDValue Op
, SDValue Chain
, SDValue RetLabel
,
1032 SDValue InFlag
, SelectionDAG
&DAG
) {
1033 CallSDNode
*TheCall
= dyn_cast
<CallSDNode
>(Op
);
1034 DebugLoc dl
= TheCall
->getDebugLoc();
1035 // Currently handling primitive types only. They will come in
1037 unsigned RetVals
= TheCall
->getNumRetVals();
1039 std::vector
<SDValue
> ResultVals
;
1041 // Return immediately if the return type is void
1045 // Call has something to return
1047 // Legalize the address before use
1050 LegalizeAddress(RetLabel
, DAG
, LdLo
, LdHi
, LdOffset
, dl
);
1052 SDVTList Tys
= DAG
.getVTList(MVT::i8
, MVT::Other
, MVT::Flag
);
1055 for(unsigned i
=0, Offset
=0;i
<RetVals
;i
++) {
1057 LoadRet
= DAG
.getNode(PIC16ISD::PIC16LdWF
, dl
, Tys
, Chain
, LdLo
, LdHi
,
1058 DAG
.getConstant(LdOffset
+ Offset
, MVT::i8
),
1061 InFlag
= getOutFlag(LoadRet
);
1063 Chain
= getChain(LoadRet
);
1065 ResultVals
.push_back(LoadRet
);
1068 // To return use MERGE_VALUES
1069 ResultVals
.push_back(Chain
);
1070 SDValue Res
= DAG
.getMergeValues(&ResultVals
[0], ResultVals
.size(), dl
);
1074 SDValue
PIC16TargetLowering::LowerRET(SDValue Op
, SelectionDAG
&DAG
) {
1075 SDValue Chain
= Op
.getOperand(0);
1076 DebugLoc dl
= Op
.getDebugLoc();
1078 if (Op
.getNumOperands() == 1) // return void
1081 // return should have odd number of operands
1082 if ((Op
.getNumOperands() % 2) == 0 ) {
1083 assert(0 && "Do not know how to return this many arguments!");
1087 // Number of values to return
1088 unsigned NumRet
= (Op
.getNumOperands() / 2);
1090 // Function returns value always on stack with the offset starting
1092 MachineFunction
&MF
= DAG
.getMachineFunction();
1093 const Function
*F
= MF
.getFunction();
1094 std::string FuncName
= F
->getName();
1096 const char *tmpName
= createESName(PAN::getFrameLabel(FuncName
));
1097 SDVTList VTs
= DAG
.getVTList (MVT::i8
, MVT::Other
);
1098 SDValue ES
= DAG
.getTargetExternalSymbol(tmpName
, MVT::i8
);
1099 SDValue BS
= DAG
.getConstant(1, MVT::i8
);
1101 for(unsigned i
=0;i
<NumRet
; ++i
) {
1102 RetVal
= Op
.getNode()->getOperand(2*i
+ 1);
1103 Chain
= DAG
.getNode (PIC16ISD::PIC16Store
, dl
, MVT::Other
, Chain
, RetVal
,
1105 DAG
.getConstant (i
, MVT::i8
));
1108 return DAG
.getNode(ISD::RET
, dl
, MVT::Other
, Chain
);
1111 // CALL node may have some operands non-legal to PIC16. Generate new CALL
1112 // node with all the operands legal.
1113 // Currently only Callee operand of the CALL node is non-legal. This function
1114 // legalizes the Callee operand and uses all other operands as are to generate
1117 SDValue
PIC16TargetLowering::LegalizeCALL(SDValue Op
, SelectionDAG
&DAG
) {
1118 CallSDNode
*TheCall
= dyn_cast
<CallSDNode
>(Op
);
1119 SDValue Chain
= TheCall
->getChain();
1120 SDValue Callee
= TheCall
->getCallee();
1121 DebugLoc dl
= TheCall
->getDebugLoc();
1124 assert(Callee
.getValueType() == MVT::i16
&&
1125 "Don't know how to legalize this call node!!!");
1126 assert(Callee
.getOpcode() == ISD::BUILD_PAIR
&&
1127 "Don't know how to legalize this call node!!!");
1129 if (isDirectAddress(Callee
)) {
1130 // Come here for direct calls
1131 Callee
= Callee
.getOperand(0).getOperand(0);
1133 // Come here for indirect calls
1135 // Indirect addresses. Get the hi and lo parts of ptr.
1136 GetExpandedParts(Callee
, DAG
, Lo
, Hi
);
1137 // Connect Lo and Hi parts of the callee with the PIC16Connect
1138 Callee
= DAG
.getNode(PIC16ISD::PIC16Connect
, dl
, MVT::i8
, Lo
, Hi
);
1140 std::vector
<SDValue
> Ops
;
1141 Ops
.push_back(Chain
);
1142 Ops
.push_back(Callee
);
1144 // Add the call arguments and their flags
1145 unsigned NumArgs
= TheCall
->getNumArgs();
1146 for(i
=0;i
<NumArgs
;i
++) {
1147 Ops
.push_back(TheCall
->getArg(i
));
1148 Ops
.push_back(TheCall
->getArgFlagsVal(i
));
1150 std::vector
<MVT
> NodeTys
;
1151 unsigned NumRets
= TheCall
->getNumRetVals();
1152 for(i
=0;i
<NumRets
;i
++)
1153 NodeTys
.push_back(TheCall
->getRetValType(i
));
1155 // Return a Chain as well
1156 NodeTys
.push_back(MVT::Other
);
1158 SDVTList VTs
= DAG
.getVTList(&NodeTys
[0], NodeTys
.size());
1159 // Generate new call with all the operands legal
1160 return DAG
.getCall(TheCall
->getCallingConv(), dl
,
1161 TheCall
->isVarArg(), TheCall
->isTailCall(),
1162 TheCall
->isInreg(), VTs
, &Ops
[0], Ops
.size());
1165 void PIC16TargetLowering::
1166 GetDataAddress(DebugLoc dl
, SDValue Callee
, SDValue
&Chain
,
1167 SDValue
&DataAddr_Lo
, SDValue
&DataAddr_Hi
,
1168 SelectionDAG
&DAG
) {
1169 assert (Callee
.getOpcode() == PIC16ISD::PIC16Connect
1170 && "Don't know what to do of such callee!!");
1171 SDValue ZeroOperand
= DAG
.getConstant(0, MVT::i8
);
1172 SDValue SeqStart
= DAG
.getCALLSEQ_START(Chain
, ZeroOperand
);
1173 Chain
= getChain(SeqStart
);
1174 SDValue OperFlag
= getOutFlag(SeqStart
); // To manage the data dependency
1176 // Get the Lo and Hi part of code address
1177 SDValue Lo
= Callee
.getOperand(0);
1178 SDValue Hi
= Callee
.getOperand(1);
1180 SDValue Data_Lo
, Data_Hi
;
1181 SDVTList Tys
= DAG
.getVTList(MVT::i8
, MVT::Other
, MVT::Flag
);
1182 // Subtract 2 from Address to get the Lower part of DataAddress.
1183 SDVTList VTList
= DAG
.getVTList(MVT::i8
, MVT::Flag
);
1184 Data_Lo
= DAG
.getNode(ISD::SUBC
, dl
, VTList
, Lo
,
1185 DAG
.getConstant(2, MVT::i8
));
1186 SDValue Ops
[3] = { Hi
, DAG
.getConstant(0, MVT::i8
), Data_Lo
.getValue(1)};
1187 Data_Hi
= DAG
.getNode(ISD::SUBE
, dl
, VTList
, Ops
, 3);
1188 SDValue PCLATH
= DAG
.getNode(PIC16ISD::MTPCLATH
, dl
, MVT::i8
, Data_Hi
);
1189 Callee
= DAG
.getNode(PIC16ISD::PIC16Connect
, dl
, MVT::i8
, Data_Lo
, PCLATH
);
1190 SDValue Call
= DAG
.getNode(PIC16ISD::CALLW
, dl
, Tys
, Chain
, Callee
,
1192 Chain
= getChain(Call
);
1193 OperFlag
= getOutFlag(Call
);
1194 SDValue SeqEnd
= DAG
.getCALLSEQ_END(Chain
, ZeroOperand
, ZeroOperand
,
1196 Chain
= getChain(SeqEnd
);
1197 OperFlag
= getOutFlag(SeqEnd
);
1199 // Low part of Data Address
1200 DataAddr_Lo
= DAG
.getNode(PIC16ISD::MTLO
, dl
, MVT::i8
, Call
, OperFlag
);
1202 // Make the second call.
1203 SeqStart
= DAG
.getCALLSEQ_START(Chain
, ZeroOperand
);
1204 Chain
= getChain(SeqStart
);
1205 OperFlag
= getOutFlag(SeqStart
); // To manage the data dependency
1207 // Subtract 1 from Address to get high part of data address.
1208 Data_Lo
= DAG
.getNode(ISD::SUBC
, dl
, VTList
, Lo
,
1209 DAG
.getConstant(1, MVT::i8
));
1210 SDValue HiOps
[3] = { Hi
, DAG
.getConstant(0, MVT::i8
), Data_Lo
.getValue(1)};
1211 Data_Hi
= DAG
.getNode(ISD::SUBE
, dl
, VTList
, HiOps
, 3);
1212 PCLATH
= DAG
.getNode(PIC16ISD::MTPCLATH
, dl
, MVT::i8
, Data_Hi
);
1214 // Use new Lo to make another CALLW
1215 Callee
= DAG
.getNode(PIC16ISD::PIC16Connect
, dl
, MVT::i8
, Data_Lo
, PCLATH
);
1216 Call
= DAG
.getNode(PIC16ISD::CALLW
, dl
, Tys
, Chain
, Callee
, OperFlag
);
1217 Chain
= getChain(Call
);
1218 OperFlag
= getOutFlag(Call
);
1219 SeqEnd
= DAG
.getCALLSEQ_END(Chain
, ZeroOperand
, ZeroOperand
,
1221 Chain
= getChain(SeqEnd
);
1222 OperFlag
= getOutFlag(SeqEnd
);
1223 // Hi part of Data Address
1224 DataAddr_Hi
= DAG
.getNode(PIC16ISD::MTHI
, dl
, MVT::i8
, Call
, OperFlag
);
1228 SDValue
PIC16TargetLowering::LowerCALL(SDValue Op
, SelectionDAG
&DAG
) {
1229 CallSDNode
*TheCall
= dyn_cast
<CallSDNode
>(Op
);
1230 SDValue Chain
= TheCall
->getChain();
1231 SDValue Callee
= TheCall
->getCallee();
1232 DebugLoc dl
= TheCall
->getDebugLoc();
1233 if (Callee
.getValueType() == MVT::i16
&&
1234 Callee
.getOpcode() == ISD::BUILD_PAIR
) {
1235 // Control should come here only from TypeLegalizer for lowering
1237 // Legalize the non-legal arguments of call and return the
1238 // new call with legal arguments.
1239 return LegalizeCALL(Op
, DAG
);
1241 // Control should come here from Legalize DAG.
1242 // Here all the operands of CALL node should be legal.
1244 // If this is an indirect call then to pass the arguments
1245 // and read the return value back, we need the data address
1246 // of the function being called.
1247 // To get the data address two more calls need to be made.
1249 // The flag to track if this is a direct or indirect call.
1250 bool IsDirectCall
= true;
1251 unsigned RetVals
= TheCall
->getNumRetVals();
1252 unsigned NumArgs
= TheCall
->getNumArgs();
1254 SDValue DataAddr_Lo
, DataAddr_Hi
;
1255 if (Callee
.getOpcode() == PIC16ISD::PIC16Connect
) {
1256 IsDirectCall
= false; // This is indirect call
1257 // Read DataAddress only if we have to pass arguments or
1258 // read return value.
1259 if ((RetVals
> 0) || (NumArgs
> 0))
1260 GetDataAddress(dl
, Callee
, Chain
, DataAddr_Lo
, DataAddr_Hi
, DAG
);
1263 SDValue ZeroOperand
= DAG
.getConstant(0, MVT::i8
);
1265 // Start the call sequence.
1266 // Carring the Constant 0 along the CALLSEQSTART
1267 // because there is nothing else to carry.
1268 SDValue SeqStart
= DAG
.getCALLSEQ_START(Chain
, ZeroOperand
);
1269 Chain
= getChain(SeqStart
);
1270 SDValue OperFlag
= getOutFlag(SeqStart
); // To manage the data dependency
1273 // For any direct call - callee will be GlobalAddressNode or
1275 SDValue ArgLabel
, RetLabel
;
1277 // Considering the GlobalAddressNode case here.
1278 if (GlobalAddressSDNode
*G
= dyn_cast
<GlobalAddressSDNode
>(Callee
)) {
1279 GlobalValue
*GV
= G
->getGlobal();
1280 Callee
= DAG
.getTargetGlobalAddress(GV
, MVT::i8
);
1281 Name
= G
->getGlobal()->getName();
1282 } else {// Considering the ExternalSymbol case here
1283 ExternalSymbolSDNode
*ES
= dyn_cast
<ExternalSymbolSDNode
>(Callee
);
1284 Callee
= DAG
.getTargetExternalSymbol(ES
->getSymbol(), MVT::i8
);
1285 Name
= ES
->getSymbol();
1288 // Label for argument passing
1289 const char *argFrame
= createESName(PAN::getArgsLabel(Name
));
1290 ArgLabel
= DAG
.getTargetExternalSymbol(argFrame
, MVT::i8
);
1292 // Label for reading return value
1293 const char *retName
= createESName(PAN::getRetvalLabel(Name
));
1294 RetLabel
= DAG
.getTargetExternalSymbol(retName
, MVT::i8
);
1297 SDValue CodeAddr_Lo
= Callee
.getOperand(0);
1298 SDValue CodeAddr_Hi
= Callee
.getOperand(1);
1300 /*CodeAddr_Lo = DAG.getNode(ISD::ADD, dl, MVT::i8, CodeAddr_Lo,
1301 DAG.getConstant(2, MVT::i8));*/
1303 // move Hi part in PCLATH
1304 CodeAddr_Hi
= DAG
.getNode(PIC16ISD::MTPCLATH
, dl
, MVT::i8
, CodeAddr_Hi
);
1305 Callee
= DAG
.getNode(PIC16ISD::PIC16Connect
, dl
, MVT::i8
, CodeAddr_Lo
,
1309 // Pass the argument to function before making the call.
1312 CallArgs
= LowerDirectCallArguments(Op
, Chain
, ArgLabel
, OperFlag
, DAG
);
1313 Chain
= getChain(CallArgs
);
1314 OperFlag
= getOutFlag(CallArgs
);
1316 CallArgs
= LowerIndirectCallArguments(Op
, Chain
, OperFlag
, DataAddr_Lo
,
1318 Chain
= getChain(CallArgs
);
1319 OperFlag
= getOutFlag(CallArgs
);
1322 SDVTList Tys
= DAG
.getVTList(MVT::Other
, MVT::Flag
);
1323 SDValue PICCall
= DAG
.getNode(PIC16ISD::CALL
, dl
, Tys
, Chain
, Callee
,
1325 Chain
= getChain(PICCall
);
1326 OperFlag
= getOutFlag(PICCall
);
1329 // Carrying the Constant 0 along the CALLSEQSTART
1330 // because there is nothing else to carry.
1331 SDValue SeqEnd
= DAG
.getCALLSEQ_END(Chain
, ZeroOperand
, ZeroOperand
,
1333 Chain
= getChain(SeqEnd
);
1334 OperFlag
= getOutFlag(SeqEnd
);
1336 // Lower the return value reading after the call.
1338 return LowerDirectCallReturn(Op
, Chain
, RetLabel
, OperFlag
, DAG
);
1340 return LowerIndirectCallReturn(Op
, Chain
, OperFlag
, DataAddr_Lo
,
1344 bool PIC16TargetLowering::isDirectLoad(const SDValue Op
) {
1345 if (Op
.getOpcode() == PIC16ISD::PIC16Load
)
1346 if (Op
.getOperand(1).getOpcode() == ISD::TargetGlobalAddress
1347 || Op
.getOperand(1).getOpcode() == ISD::TargetExternalSymbol
)
1352 // NeedToConvertToMemOp - Returns true if one of the operands of the
1353 // operation 'Op' needs to be put into memory. Also returns the
1354 // operand no. of the operand to be converted in 'MemOp'. Remember, PIC16 has
1355 // no instruction that can operation on two registers. Most insns take
1356 // one register and one memory operand (addwf) / Constant (addlw).
1357 bool PIC16TargetLowering::NeedToConvertToMemOp(SDValue Op
, unsigned &MemOp
) {
1358 // If one of the operand is a constant, return false.
1359 if (Op
.getOperand(0).getOpcode() == ISD::Constant
||
1360 Op
.getOperand(1).getOpcode() == ISD::Constant
)
1363 // Return false if one of the operands is already a direct
1364 // load and that operand has only one use.
1365 if (isDirectLoad(Op
.getOperand(0))) {
1366 if (Op
.getOperand(0).hasOneUse())
1371 if (isDirectLoad(Op
.getOperand(1))) {
1372 if (Op
.getOperand(1).hasOneUse())
1380 // LowerBinOp - Lower a commutative binary operation that does not
1381 // affect status flag carry.
1382 SDValue
PIC16TargetLowering::LowerBinOp(SDValue Op
, SelectionDAG
&DAG
) {
1383 DebugLoc dl
= Op
.getDebugLoc();
1385 // We should have handled larger operands in type legalizer itself.
1386 assert (Op
.getValueType() == MVT::i8
&& "illegal Op to lower");
1389 if (NeedToConvertToMemOp(Op
, MemOp
)) {
1390 // Put one value on stack.
1391 SDValue NewVal
= ConvertToMemOperand (Op
.getOperand(MemOp
), DAG
, dl
);
1393 return DAG
.getNode(Op
.getOpcode(), dl
, MVT::i8
, Op
.getOperand(MemOp
^ 1),
1401 // LowerADD - Lower all types of ADD operations including the ones
1402 // that affects carry.
1403 SDValue
PIC16TargetLowering::LowerADD(SDValue Op
, SelectionDAG
&DAG
) {
1404 // We should have handled larger operands in type legalizer itself.
1405 assert (Op
.getValueType() == MVT::i8
&& "illegal add to lower");
1406 DebugLoc dl
= Op
.getDebugLoc();
1408 if (NeedToConvertToMemOp(Op
, MemOp
)) {
1409 // Put one value on stack.
1410 SDValue NewVal
= ConvertToMemOperand (Op
.getOperand(MemOp
), DAG
, dl
);
1412 // ADDC and ADDE produces two results.
1413 SDVTList Tys
= DAG
.getVTList(MVT::i8
, MVT::Flag
);
1415 // ADDE has three operands, the last one is a flag.
1416 if (Op
.getOpcode() == ISD::ADDE
)
1417 return DAG
.getNode(Op
.getOpcode(), dl
, Tys
, Op
.getOperand(MemOp
^ 1),
1418 NewVal
, Op
.getOperand(2));
1419 // ADDC has two operands.
1420 else if (Op
.getOpcode() == ISD::ADDC
)
1421 return DAG
.getNode(Op
.getOpcode(), dl
, Tys
, Op
.getOperand(MemOp
^ 1),
1423 // ADD it is. It produces only one result.
1425 return DAG
.getNode(Op
.getOpcode(), dl
, MVT::i8
, Op
.getOperand(MemOp
^ 1),
1428 else if (Op
.getOpcode() == ISD::ADD
)
1434 SDValue
PIC16TargetLowering::LowerSUB(SDValue Op
, SelectionDAG
&DAG
) {
1435 DebugLoc dl
= Op
.getDebugLoc();
1436 // We should have handled larger operands in type legalizer itself.
1437 assert (Op
.getValueType() == MVT::i8
&& "illegal sub to lower");
1439 // Nothing to do if the first operand is already a direct load and it has
1441 if (isDirectLoad(Op
.getOperand(0)) && Op
.getOperand(0).hasOneUse())
1444 // Put first operand on stack.
1445 SDValue NewVal
= ConvertToMemOperand (Op
.getOperand(0), DAG
, dl
);
1447 SDVTList Tys
= DAG
.getVTList(MVT::i8
, MVT::Flag
);
1448 if (Op
.getOpcode() == ISD::SUBE
)
1449 return DAG
.getNode(Op
.getOpcode(), dl
, Tys
, NewVal
, Op
.getOperand(1),
1452 return DAG
.getNode(Op
.getOpcode(), dl
, Tys
, NewVal
, Op
.getOperand(1));
1455 void PIC16TargetLowering::InitReservedFrameCount(const Function
*F
) {
1456 unsigned NumArgs
= F
->arg_size();
1458 bool isVoidFunc
= (F
->getReturnType()->getTypeID() == Type::VoidTyID
);
1461 ReservedFrameCount
= NumArgs
;
1463 ReservedFrameCount
= NumArgs
+ 1;
1466 // LowerFORMAL_ARGUMENTS - Argument values are loaded from the
1467 // <fname>.args + offset. All arguments are already broken to leaglized
1468 // types, so the offset just runs from 0 to NumArgVals - 1.
1470 SDValue
PIC16TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op
,
1471 SelectionDAG
&DAG
) {
1472 SmallVector
<SDValue
, 8> ArgValues
;
1473 unsigned NumArgVals
= Op
.getNode()->getNumValues() - 1;
1474 DebugLoc dl
= Op
.getDebugLoc();
1475 SDValue Chain
= Op
.getOperand(0); // Formal arguments' chain
1478 // Get the callee's name to create the <fname>.args label to pass args.
1479 MachineFunction
&MF
= DAG
.getMachineFunction();
1480 const Function
*F
= MF
.getFunction();
1481 std::string FuncName
= F
->getName();
1483 // Reset the map of FI and TmpOffset
1484 ResetTmpOffsetMap();
1485 // Initialize the ReserveFrameCount
1486 InitReservedFrameCount(F
);
1488 // Create the <fname>.args external symbol.
1489 const char *tmpName
= createESName(PAN::getArgsLabel(FuncName
));
1490 SDValue ES
= DAG
.getTargetExternalSymbol(tmpName
, MVT::i8
);
1492 // Load arg values from the label + offset.
1493 SDVTList VTs
= DAG
.getVTList (MVT::i8
, MVT::Other
);
1494 SDValue BS
= DAG
.getConstant(1, MVT::i8
);
1495 for (unsigned i
= 0; i
< NumArgVals
; ++i
) {
1496 SDValue Offset
= DAG
.getConstant(i
, MVT::i8
);
1497 SDValue PICLoad
= DAG
.getNode(PIC16ISD::PIC16LdArg
, dl
, VTs
, Chain
, ES
, BS
,
1499 Chain
= getChain(PICLoad
);
1500 ArgValues
.push_back(PICLoad
);
1503 // Return a MERGE_VALUE node.
1504 ArgValues
.push_back(Op
.getOperand(0));
1505 return DAG
.getNode(ISD::MERGE_VALUES
, dl
, Op
.getNode()->getVTList(),
1506 &ArgValues
[0], ArgValues
.size()).getValue(Op
.getResNo());
1509 // Perform DAGCombine of PIC16Load.
1510 // FIXME - Need a more elaborate comment here.
1511 SDValue
PIC16TargetLowering::
1512 PerformPIC16LoadCombine(SDNode
*N
, DAGCombinerInfo
&DCI
) const {
1513 SelectionDAG
&DAG
= DCI
.DAG
;
1514 SDValue Chain
= N
->getOperand(0);
1515 if (N
->hasNUsesOfValue(0, 0)) {
1516 DAG
.ReplaceAllUsesOfValueWith(SDValue(N
,1), Chain
);
1521 // For all the functions with arguments some STORE nodes are generated
1522 // that store the argument on the frameindex. However in PIC16 the arguments
1523 // are passed on stack only. Therefore these STORE nodes are redundant.
1524 // To remove these STORE nodes will be removed in PerformStoreCombine
1526 // Currently this function is doint nothing and will be updated for removing
1527 // unwanted store operations
1528 SDValue
PIC16TargetLowering::
1529 PerformStoreCombine(SDNode
*N
, DAGCombinerInfo
&DCI
) const {
1530 return SDValue(N
, 0);
1532 // Storing an undef value is of no use, so remove it
1533 if (isStoringUndef(N, Chain, DAG)) {
1534 return Chain; // remove the store and return the chain
1536 //else everything is ok.
1537 return SDValue(N, 0);
1541 SDValue
PIC16TargetLowering::PerformDAGCombine(SDNode
*N
,
1542 DAGCombinerInfo
&DCI
) const {
1543 switch (N
->getOpcode()) {
1545 return PerformStoreCombine(N
, DCI
);
1546 case PIC16ISD::PIC16Load
:
1547 return PerformPIC16LoadCombine(N
, DCI
);
1552 static PIC16CC::CondCodes
IntCCToPIC16CC(ISD::CondCode CC
) {
1554 default: assert(0 && "Unknown condition code!");
1555 case ISD::SETNE
: return PIC16CC::NE
;
1556 case ISD::SETEQ
: return PIC16CC::EQ
;
1557 case ISD::SETGT
: return PIC16CC::GT
;
1558 case ISD::SETGE
: return PIC16CC::GE
;
1559 case ISD::SETLT
: return PIC16CC::LT
;
1560 case ISD::SETLE
: return PIC16CC::LE
;
1561 case ISD::SETULT
: return PIC16CC::ULT
;
1562 case ISD::SETULE
: return PIC16CC::LE
;
1563 case ISD::SETUGE
: return PIC16CC::GE
;
1564 case ISD::SETUGT
: return PIC16CC::UGT
;
1568 // Look at LHS/RHS/CC and see if they are a lowered setcc instruction. If so
1569 // set LHS/RHS and SPCC to the LHS/RHS of the setcc and SPCC to the condition.
1570 static void LookThroughSetCC(SDValue
&LHS
, SDValue
&RHS
,
1571 ISD::CondCode CC
, unsigned &SPCC
) {
1572 if (isa
<ConstantSDNode
>(RHS
) &&
1573 cast
<ConstantSDNode
>(RHS
)->getZExtValue() == 0 &&
1575 (LHS
.getOpcode() == PIC16ISD::SELECT_ICC
&&
1576 LHS
.getOperand(3).getOpcode() == PIC16ISD::SUBCC
) &&
1577 isa
<ConstantSDNode
>(LHS
.getOperand(0)) &&
1578 isa
<ConstantSDNode
>(LHS
.getOperand(1)) &&
1579 cast
<ConstantSDNode
>(LHS
.getOperand(0))->getZExtValue() == 1 &&
1580 cast
<ConstantSDNode
>(LHS
.getOperand(1))->getZExtValue() == 0) {
1581 SDValue CMPCC
= LHS
.getOperand(3);
1582 SPCC
= cast
<ConstantSDNode
>(LHS
.getOperand(2))->getZExtValue();
1583 LHS
= CMPCC
.getOperand(0);
1584 RHS
= CMPCC
.getOperand(1);
1588 // Returns appropriate CMP insn and corresponding condition code in PIC16CC
1589 SDValue
PIC16TargetLowering::getPIC16Cmp(SDValue LHS
, SDValue RHS
,
1590 unsigned CC
, SDValue
&PIC16CC
,
1591 SelectionDAG
&DAG
, DebugLoc dl
) {
1592 PIC16CC::CondCodes CondCode
= (PIC16CC::CondCodes
) CC
;
1594 // PIC16 sub is literal - W. So Swap the operands and condition if needed.
1595 // i.e. a < 12 can be rewritten as 12 > a.
1596 if (RHS
.getOpcode() == ISD::Constant
) {
1605 CondCode
= PIC16CC::GT
;
1608 CondCode
= PIC16CC::LT
;
1611 CondCode
= PIC16CC::UGT
;
1614 CondCode
= PIC16CC::ULT
;
1617 CondCode
= PIC16CC::LE
;
1620 CondCode
= PIC16CC::GE
;
1623 CondCode
= PIC16CC::UGE
;
1626 CondCode
= PIC16CC::ULE
;
1631 PIC16CC
= DAG
.getConstant(CondCode
, MVT::i8
);
1633 // These are signed comparisons.
1634 SDValue Mask
= DAG
.getConstant(128, MVT::i8
);
1635 if (isSignedComparison(CondCode
)) {
1636 LHS
= DAG
.getNode (ISD::XOR
, dl
, MVT::i8
, LHS
, Mask
);
1637 RHS
= DAG
.getNode (ISD::XOR
, dl
, MVT::i8
, RHS
, Mask
);
1640 SDVTList VTs
= DAG
.getVTList (MVT::i8
, MVT::Flag
);
1641 // We can use a subtract operation to set the condition codes. But
1642 // we need to put one operand in memory if required.
1643 // Nothing to do if the first operand is already a valid type (direct load
1644 // for subwf and literal for sublw) and it is used by this operation only.
1645 if ((LHS
.getOpcode() == ISD::Constant
|| isDirectLoad(LHS
))
1647 return DAG
.getNode(PIC16ISD::SUBCC
, dl
, VTs
, LHS
, RHS
);
1649 // else convert the first operand to mem.
1650 LHS
= ConvertToMemOperand (LHS
, DAG
, dl
);
1651 return DAG
.getNode(PIC16ISD::SUBCC
, dl
, VTs
, LHS
, RHS
);
1655 SDValue
PIC16TargetLowering::LowerSELECT_CC(SDValue Op
, SelectionDAG
&DAG
) {
1656 SDValue LHS
= Op
.getOperand(0);
1657 SDValue RHS
= Op
.getOperand(1);
1658 ISD::CondCode CC
= cast
<CondCodeSDNode
>(Op
.getOperand(4))->get();
1659 SDValue TrueVal
= Op
.getOperand(2);
1660 SDValue FalseVal
= Op
.getOperand(3);
1661 unsigned ORIGCC
= ~0;
1662 DebugLoc dl
= Op
.getDebugLoc();
1664 // If this is a select_cc of a "setcc", and if the setcc got lowered into
1665 // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
1667 // A setcc: lhs, rhs, cc is expanded by llvm to
1668 // select_cc: result of setcc, 0, 1, 0, setne
1669 // We can think of it as:
1670 // select_cc: lhs, rhs, 1, 0, cc
1671 LookThroughSetCC(LHS
, RHS
, CC
, ORIGCC
);
1672 if (ORIGCC
== ~0U) ORIGCC
= IntCCToPIC16CC (CC
);
1675 SDValue Cmp
= getPIC16Cmp(LHS
, RHS
, ORIGCC
, PIC16CC
, DAG
, dl
);
1677 return DAG
.getNode (PIC16ISD::SELECT_ICC
, dl
, TrueVal
.getValueType(), TrueVal
,
1678 FalseVal
, PIC16CC
, Cmp
.getValue(1));
1682 PIC16TargetLowering::EmitInstrWithCustomInserter(MachineInstr
*MI
,
1683 MachineBasicBlock
*BB
) const {
1684 const TargetInstrInfo
&TII
= *getTargetMachine().getInstrInfo();
1685 unsigned CC
= (PIC16CC::CondCodes
)MI
->getOperand(3).getImm();
1686 DebugLoc dl
= MI
->getDebugLoc();
1688 // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
1689 // control-flow pattern. The incoming instruction knows the destination vreg
1690 // to set, the condition code register to branch on, the true/false values to
1691 // select between, and a branch opcode to use.
1692 const BasicBlock
*LLVM_BB
= BB
->getBasicBlock();
1693 MachineFunction::iterator It
= BB
;
1700 // fallthrough --> copy0MBB
1701 MachineBasicBlock
*thisMBB
= BB
;
1702 MachineFunction
*F
= BB
->getParent();
1703 MachineBasicBlock
*copy0MBB
= F
->CreateMachineBasicBlock(LLVM_BB
);
1704 MachineBasicBlock
*sinkMBB
= F
->CreateMachineBasicBlock(LLVM_BB
);
1705 BuildMI(BB
, dl
, TII
.get(PIC16::pic16brcond
)).addMBB(sinkMBB
).addImm(CC
);
1706 F
->insert(It
, copy0MBB
);
1707 F
->insert(It
, sinkMBB
);
1709 // Update machine-CFG edges by transferring all successors of the current
1710 // block to the new block which will contain the Phi node for the select.
1711 sinkMBB
->transferSuccessors(BB
);
1712 // Next, add the true and fallthrough blocks as its successors.
1713 BB
->addSuccessor(copy0MBB
);
1714 BB
->addSuccessor(sinkMBB
);
1717 // %FalseValue = ...
1718 // # fallthrough to sinkMBB
1721 // Update machine-CFG edges
1722 BB
->addSuccessor(sinkMBB
);
1725 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
1728 BuildMI(BB
, dl
, TII
.get(PIC16::PHI
), MI
->getOperand(0).getReg())
1729 .addReg(MI
->getOperand(2).getReg()).addMBB(copy0MBB
)
1730 .addReg(MI
->getOperand(1).getReg()).addMBB(thisMBB
);
1732 F
->DeleteMachineInstr(MI
); // The pseudo instruction is gone now.
1737 SDValue
PIC16TargetLowering::LowerBR_CC(SDValue Op
, SelectionDAG
&DAG
) {
1738 SDValue Chain
= Op
.getOperand(0);
1739 ISD::CondCode CC
= cast
<CondCodeSDNode
>(Op
.getOperand(1))->get();
1740 SDValue LHS
= Op
.getOperand(2); // LHS of the condition.
1741 SDValue RHS
= Op
.getOperand(3); // RHS of the condition.
1742 SDValue Dest
= Op
.getOperand(4); // BB to jump to
1743 unsigned ORIGCC
= ~0;
1744 DebugLoc dl
= Op
.getDebugLoc();
1746 // If this is a br_cc of a "setcc", and if the setcc got lowered into
1747 // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values.
1748 LookThroughSetCC(LHS
, RHS
, CC
, ORIGCC
);
1749 if (ORIGCC
== ~0U) ORIGCC
= IntCCToPIC16CC (CC
);
1751 // Get the Compare insn and condition code.
1753 SDValue Cmp
= getPIC16Cmp(LHS
, RHS
, ORIGCC
, PIC16CC
, DAG
, dl
);
1755 return DAG
.getNode(PIC16ISD::BRCOND
, dl
, MVT::Other
, Chain
, Dest
, PIC16CC
,