Deleted Added
full compact
MSP430ISelLowering.cpp (199989) MSP430ISelLowering.cpp (200581)
1//===-- MSP430ISelLowering.cpp - MSP430 DAG Lowering Implementation ------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the MSP430TargetLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#define DEBUG_TYPE "msp430-lower"
15
16#include "MSP430ISelLowering.h"
17#include "MSP430.h"
1//===-- MSP430ISelLowering.cpp - MSP430 DAG Lowering Implementation ------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the MSP430TargetLowering class.
11//
12//===----------------------------------------------------------------------===//
13
14#define DEBUG_TYPE "msp430-lower"
15
16#include "MSP430ISelLowering.h"
17#include "MSP430.h"
18#include "MSP430MachineFunctionInfo.h"
18#include "MSP430TargetMachine.h"
19#include "MSP430Subtarget.h"
20#include "llvm/DerivedTypes.h"
21#include "llvm/Function.h"
22#include "llvm/Intrinsics.h"
23#include "llvm/CallingConv.h"
24#include "llvm/GlobalVariable.h"
25#include "llvm/GlobalAlias.h"
26#include "llvm/CodeGen/CallingConvLower.h"
27#include "llvm/CodeGen/MachineFrameInfo.h"
28#include "llvm/CodeGen/MachineFunction.h"
29#include "llvm/CodeGen/MachineInstrBuilder.h"
30#include "llvm/CodeGen/MachineRegisterInfo.h"
31#include "llvm/CodeGen/PseudoSourceValue.h"
32#include "llvm/CodeGen/SelectionDAGISel.h"
33#include "llvm/CodeGen/ValueTypes.h"
34#include "llvm/Target/TargetLoweringObjectFile.h"
19#include "MSP430TargetMachine.h"
20#include "MSP430Subtarget.h"
21#include "llvm/DerivedTypes.h"
22#include "llvm/Function.h"
23#include "llvm/Intrinsics.h"
24#include "llvm/CallingConv.h"
25#include "llvm/GlobalVariable.h"
26#include "llvm/GlobalAlias.h"
27#include "llvm/CodeGen/CallingConvLower.h"
28#include "llvm/CodeGen/MachineFrameInfo.h"
29#include "llvm/CodeGen/MachineFunction.h"
30#include "llvm/CodeGen/MachineInstrBuilder.h"
31#include "llvm/CodeGen/MachineRegisterInfo.h"
32#include "llvm/CodeGen/PseudoSourceValue.h"
33#include "llvm/CodeGen/SelectionDAGISel.h"
34#include "llvm/CodeGen/ValueTypes.h"
35#include "llvm/Target/TargetLoweringObjectFile.h"
36#include "llvm/Support/CommandLine.h"
35#include "llvm/Support/Debug.h"
36#include "llvm/Support/ErrorHandling.h"
37#include "llvm/Support/raw_ostream.h"
38#include "llvm/ADT/VectorExtras.h"
39using namespace llvm;
40
37#include "llvm/Support/Debug.h"
38#include "llvm/Support/ErrorHandling.h"
39#include "llvm/Support/raw_ostream.h"
40#include "llvm/ADT/VectorExtras.h"
41using namespace llvm;
42
43typedef enum {
44 NoHWMult,
45 HWMultIntr,
46 HWMultNoIntr
47} HWMultUseMode;
48
49static cl::opt<HWMultUseMode>
50HWMultMode("msp430-hwmult-mode",
51 cl::desc("Hardware multiplier use mode"),
52 cl::init(HWMultNoIntr),
53 cl::values(
54 clEnumValN(NoHWMult, "no",
55 "Do not use hardware multiplier"),
56 clEnumValN(HWMultIntr, "interrupts",
57 "Assume hardware multiplier can be used inside interrupts"),
58 clEnumValN(HWMultNoIntr, "use",
59 "Assume hardware multiplier cannot be used inside interrupts"),
60 clEnumValEnd));
61
41MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
42 TargetLowering(tm, new TargetLoweringObjectFileELF()),
43 Subtarget(*tm.getSubtargetImpl()), TM(tm) {
44
62MSP430TargetLowering::MSP430TargetLowering(MSP430TargetMachine &tm) :
63 TargetLowering(tm, new TargetLoweringObjectFileELF()),
64 Subtarget(*tm.getSubtargetImpl()), TM(tm) {
65
66 TD = getTargetData();
67
45 // Set up the register classes.
46 addRegisterClass(MVT::i8, MSP430::GR8RegisterClass);
47 addRegisterClass(MVT::i16, MSP430::GR16RegisterClass);
48
49 // Compute derived properties from the register classes
50 computeRegisterProperties();
51
52 // Provide all sorts of operation actions

--- 34 unchanged lines hidden (view full) ---

87 setOperationAction(ISD::ROTR, MVT::i16, Expand);
88 setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
89 setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom);
90 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
91 setOperationAction(ISD::BRIND, MVT::Other, Expand);
92 setOperationAction(ISD::BR_CC, MVT::i8, Custom);
93 setOperationAction(ISD::BR_CC, MVT::i16, Custom);
94 setOperationAction(ISD::BRCOND, MVT::Other, Expand);
68 // Set up the register classes.
69 addRegisterClass(MVT::i8, MSP430::GR8RegisterClass);
70 addRegisterClass(MVT::i16, MSP430::GR16RegisterClass);
71
72 // Compute derived properties from the register classes
73 computeRegisterProperties();
74
75 // Provide all sorts of operation actions

--- 34 unchanged lines hidden (view full) ---

110 setOperationAction(ISD::ROTR, MVT::i16, Expand);
111 setOperationAction(ISD::GlobalAddress, MVT::i16, Custom);
112 setOperationAction(ISD::ExternalSymbol, MVT::i16, Custom);
113 setOperationAction(ISD::BR_JT, MVT::Other, Expand);
114 setOperationAction(ISD::BRIND, MVT::Other, Expand);
115 setOperationAction(ISD::BR_CC, MVT::i8, Custom);
116 setOperationAction(ISD::BR_CC, MVT::i16, Custom);
117 setOperationAction(ISD::BRCOND, MVT::Other, Expand);
95 setOperationAction(ISD::SETCC, MVT::i8, Expand);
96 setOperationAction(ISD::SETCC, MVT::i16, Expand);
118 setOperationAction(ISD::SETCC, MVT::i8, Custom);
119 setOperationAction(ISD::SETCC, MVT::i16, Custom);
97 setOperationAction(ISD::SELECT, MVT::i8, Expand);
98 setOperationAction(ISD::SELECT, MVT::i16, Expand);
99 setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);
100 setOperationAction(ISD::SELECT_CC, MVT::i16, Custom);
101 setOperationAction(ISD::SIGN_EXTEND, MVT::i16, Custom);
102 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand);
103 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand);
104

--- 32 unchanged lines hidden (view full) ---

137 setOperationAction(ISD::SDIVREM, MVT::i8, Expand);
138 setOperationAction(ISD::SREM, MVT::i8, Expand);
139 setOperationAction(ISD::UDIV, MVT::i16, Expand);
140 setOperationAction(ISD::UDIVREM, MVT::i16, Expand);
141 setOperationAction(ISD::UREM, MVT::i16, Expand);
142 setOperationAction(ISD::SDIV, MVT::i16, Expand);
143 setOperationAction(ISD::SDIVREM, MVT::i16, Expand);
144 setOperationAction(ISD::SREM, MVT::i16, Expand);
120 setOperationAction(ISD::SELECT, MVT::i8, Expand);
121 setOperationAction(ISD::SELECT, MVT::i16, Expand);
122 setOperationAction(ISD::SELECT_CC, MVT::i8, Custom);
123 setOperationAction(ISD::SELECT_CC, MVT::i16, Custom);
124 setOperationAction(ISD::SIGN_EXTEND, MVT::i16, Custom);
125 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i8, Expand);
126 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i16, Expand);
127

--- 32 unchanged lines hidden (view full) ---

160 setOperationAction(ISD::SDIVREM, MVT::i8, Expand);
161 setOperationAction(ISD::SREM, MVT::i8, Expand);
162 setOperationAction(ISD::UDIV, MVT::i16, Expand);
163 setOperationAction(ISD::UDIVREM, MVT::i16, Expand);
164 setOperationAction(ISD::UREM, MVT::i16, Expand);
165 setOperationAction(ISD::SDIV, MVT::i16, Expand);
166 setOperationAction(ISD::SDIVREM, MVT::i16, Expand);
167 setOperationAction(ISD::SREM, MVT::i16, Expand);
168
169 // Libcalls names.
170 if (HWMultMode == HWMultIntr) {
171 setLibcallName(RTLIB::MUL_I8, "__mulqi3hw");
172 setLibcallName(RTLIB::MUL_I16, "__mulhi3hw");
173 } else if (HWMultMode == HWMultNoIntr) {
174 setLibcallName(RTLIB::MUL_I8, "__mulqi3hw_noint");
175 setLibcallName(RTLIB::MUL_I16, "__mulhi3hw_noint");
176 }
145}
146
147SDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
148 switch (Op.getOpcode()) {
149 case ISD::SHL: // FALLTHROUGH
150 case ISD::SRL:
151 case ISD::SRA: return LowerShifts(Op, DAG);
152 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
153 case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG);
177}
178
179SDValue MSP430TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
180 switch (Op.getOpcode()) {
181 case ISD::SHL: // FALLTHROUGH
182 case ISD::SRL:
183 case ISD::SRA: return LowerShifts(Op, DAG);
184 case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
185 case ISD::ExternalSymbol: return LowerExternalSymbol(Op, DAG);
186 case ISD::SETCC: return LowerSETCC(Op, DAG);
154 case ISD::BR_CC: return LowerBR_CC(Op, DAG);
155 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
156 case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG);
187 case ISD::BR_CC: return LowerBR_CC(Op, DAG);
188 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG);
189 case ISD::SIGN_EXTEND: return LowerSIGN_EXTEND(Op, DAG);
190 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG);
191 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG);
157 default:
158 llvm_unreachable("unimplemented operand");
159 return SDValue();
160 }
161}
162
163/// getFunctionAlignment - Return the Log2 alignment of this function.
164unsigned MSP430TargetLowering::getFunctionAlignment(const Function *F) const {

--- 55 unchanged lines hidden (view full) ---

220 SmallVectorImpl<SDValue> &InVals) {
221
222 switch (CallConv) {
223 default:
224 llvm_unreachable("Unsupported calling convention");
225 case CallingConv::C:
226 case CallingConv::Fast:
227 return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
192 default:
193 llvm_unreachable("unimplemented operand");
194 return SDValue();
195 }
196}
197
198/// getFunctionAlignment - Return the Log2 alignment of this function.
199unsigned MSP430TargetLowering::getFunctionAlignment(const Function *F) const {

--- 55 unchanged lines hidden (view full) ---

255 SmallVectorImpl<SDValue> &InVals) {
256
257 switch (CallConv) {
258 default:
259 llvm_unreachable("Unsupported calling convention");
260 case CallingConv::C:
261 case CallingConv::Fast:
262 return LowerCCCArguments(Chain, CallConv, isVarArg, Ins, dl, DAG, InVals);
263 case CallingConv::MSP430_INTR:
264 if (Ins.empty())
265 return Chain;
266 else {
267 llvm_report_error("ISRs cannot have arguments");
268 return SDValue();
269 }
228 }
229}
230
231SDValue
232MSP430TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
233 CallingConv::ID CallConv, bool isVarArg,
234 bool isTailCall,
235 const SmallVectorImpl<ISD::OutputArg> &Outs,
236 const SmallVectorImpl<ISD::InputArg> &Ins,
237 DebugLoc dl, SelectionDAG &DAG,
238 SmallVectorImpl<SDValue> &InVals) {
239
240 switch (CallConv) {
241 default:
242 llvm_unreachable("Unsupported calling convention");
243 case CallingConv::Fast:
244 case CallingConv::C:
245 return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
246 Outs, Ins, dl, DAG, InVals);
270 }
271}
272
273SDValue
274MSP430TargetLowering::LowerCall(SDValue Chain, SDValue Callee,
275 CallingConv::ID CallConv, bool isVarArg,
276 bool isTailCall,
277 const SmallVectorImpl<ISD::OutputArg> &Outs,
278 const SmallVectorImpl<ISD::InputArg> &Ins,
279 DebugLoc dl, SelectionDAG &DAG,
280 SmallVectorImpl<SDValue> &InVals) {
281
282 switch (CallConv) {
283 default:
284 llvm_unreachable("Unsupported calling convention");
285 case CallingConv::Fast:
286 case CallingConv::C:
287 return LowerCCCCallTo(Chain, Callee, CallConv, isVarArg, isTailCall,
288 Outs, Ins, dl, DAG, InVals);
289 case CallingConv::MSP430_INTR:
290 llvm_report_error("ISRs cannot be called directly");
291 return SDValue();
247 }
248}
249
250/// LowerCCCArguments - transform physical registers into virtual registers and
251/// generate load operations for arguments places on the stack.
252// FIXME: struct return stuff
253// FIXME: varargs
254SDValue

--- 80 unchanged lines hidden (view full) ---

335MSP430TargetLowering::LowerReturn(SDValue Chain,
336 CallingConv::ID CallConv, bool isVarArg,
337 const SmallVectorImpl<ISD::OutputArg> &Outs,
338 DebugLoc dl, SelectionDAG &DAG) {
339
340 // CCValAssign - represent the assignment of the return value to a location
341 SmallVector<CCValAssign, 16> RVLocs;
342
292 }
293}
294
295/// LowerCCCArguments - transform physical registers into virtual registers and
296/// generate load operations for arguments places on the stack.
297// FIXME: struct return stuff
298// FIXME: varargs
299SDValue

--- 80 unchanged lines hidden (view full) ---

380MSP430TargetLowering::LowerReturn(SDValue Chain,
381 CallingConv::ID CallConv, bool isVarArg,
382 const SmallVectorImpl<ISD::OutputArg> &Outs,
383 DebugLoc dl, SelectionDAG &DAG) {
384
385 // CCValAssign - represent the assignment of the return value to a location
386 SmallVector<CCValAssign, 16> RVLocs;
387
388 // ISRs cannot return any value.
389 if (CallConv == CallingConv::MSP430_INTR && !Outs.empty()) {
390 llvm_report_error("ISRs cannot return any value");
391 return SDValue();
392 }
393
343 // CCState - Info about the registers and stack slot.
344 CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
345 RVLocs, *DAG.getContext());
346
347 // Analize return values.
348 CCInfo.AnalyzeReturn(Outs, RetCC_MSP430);
349
350 // If this is the first return lowered for this function, add the regs to the

--- 14 unchanged lines hidden (view full) ---

365 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
366 Outs[i].Val, Flag);
367
368 // Guarantee that all emitted copies are stuck together,
369 // avoiding something bad.
370 Flag = Chain.getValue(1);
371 }
372
394 // CCState - Info about the registers and stack slot.
395 CCState CCInfo(CallConv, isVarArg, getTargetMachine(),
396 RVLocs, *DAG.getContext());
397
398 // Analize return values.
399 CCInfo.AnalyzeReturn(Outs, RetCC_MSP430);
400
401 // If this is the first return lowered for this function, add the regs to the

--- 14 unchanged lines hidden (view full) ---

416 Chain = DAG.getCopyToReg(Chain, dl, VA.getLocReg(),
417 Outs[i].Val, Flag);
418
419 // Guarantee that all emitted copies are stuck together,
420 // avoiding something bad.
421 Flag = Chain.getValue(1);
422 }
423
424 unsigned Opc = (CallConv == CallingConv::MSP430_INTR ?
425 MSP430ISD::RETI_FLAG : MSP430ISD::RET_FLAG);
426
373 if (Flag.getNode())
427 if (Flag.getNode())
374 return DAG.getNode(MSP430ISD::RET_FLAG, dl, MVT::Other, Chain, Flag);
428 return DAG.getNode(Opc, dl, MVT::Other, Chain, Flag);
375
376 // Return Void
429
430 // Return Void
377 return DAG.getNode(MSP430ISD::RET_FLAG, dl, MVT::Other, Chain);
431 return DAG.getNode(Opc, dl, MVT::Other, Chain);
378}
379
380/// LowerCCCCallTo - functions arguments are copied from virtual regs to
381/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
382/// TODO: sret.
383SDValue
384MSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
385 CallingConv::ID CallConv, bool isVarArg,

--- 147 unchanged lines hidden (view full) ---

533
534SDValue MSP430TargetLowering::LowerShifts(SDValue Op,
535 SelectionDAG &DAG) {
536 unsigned Opc = Op.getOpcode();
537 SDNode* N = Op.getNode();
538 EVT VT = Op.getValueType();
539 DebugLoc dl = N->getDebugLoc();
540
432}
433
434/// LowerCCCCallTo - functions arguments are copied from virtual regs to
435/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted.
436/// TODO: sret.
437SDValue
438MSP430TargetLowering::LowerCCCCallTo(SDValue Chain, SDValue Callee,
439 CallingConv::ID CallConv, bool isVarArg,

--- 147 unchanged lines hidden (view full) ---

587
588SDValue MSP430TargetLowering::LowerShifts(SDValue Op,
589 SelectionDAG &DAG) {
590 unsigned Opc = Op.getOpcode();
591 SDNode* N = Op.getNode();
592 EVT VT = Op.getValueType();
593 DebugLoc dl = N->getDebugLoc();
594
541 // We currently only lower shifts of constant argument.
595 // Expand non-constant shifts to loops:
542 if (!isa<ConstantSDNode>(N->getOperand(1)))
596 if (!isa<ConstantSDNode>(N->getOperand(1)))
543 return SDValue();
597 switch (Opc) {
598 default:
599 assert(0 && "Invalid shift opcode!");
600 case ISD::SHL:
601 return DAG.getNode(MSP430ISD::SHL, dl,
602 VT, N->getOperand(0), N->getOperand(1));
603 case ISD::SRA:
604 return DAG.getNode(MSP430ISD::SRA, dl,
605 VT, N->getOperand(0), N->getOperand(1));
606 case ISD::SRL:
607 return DAG.getNode(MSP430ISD::SRL, dl,
608 VT, N->getOperand(0), N->getOperand(1));
609 }
544
545 uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
546
547 // Expand the stuff into sequence of shifts.
548 // FIXME: for some shift amounts this might be done better!
549 // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N
550 SDValue Victim = N->getOperand(0);
551

--- 91 unchanged lines hidden (view full) ---

643
644 SDValue TargetCC;
645 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
646
647 return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(),
648 Chain, Dest, TargetCC, Flag);
649}
650
610
611 uint64_t ShiftAmount = cast<ConstantSDNode>(N->getOperand(1))->getZExtValue();
612
613 // Expand the stuff into sequence of shifts.
614 // FIXME: for some shift amounts this might be done better!
615 // E.g.: foo >> (8 + N) => sxt(swpb(foo)) >> N
616 SDValue Victim = N->getOperand(0);
617

--- 91 unchanged lines hidden (view full) ---

709
710 SDValue TargetCC;
711 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
712
713 return DAG.getNode(MSP430ISD::BR_CC, dl, Op.getValueType(),
714 Chain, Dest, TargetCC, Flag);
715}
716
717
718SDValue MSP430TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
719 SDValue LHS = Op.getOperand(0);
720 SDValue RHS = Op.getOperand(1);
721 DebugLoc dl = Op.getDebugLoc();
722
723 // If we are doing an AND and testing against zero, then the CMP
724 // will not be generated. The AND (or BIT) will generate the condition codes,
725 // but they are different from CMP.
726 bool andCC = false;
727 if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(RHS)) {
728 if (RHSC->isNullValue() && LHS.hasOneUse() &&
729 (LHS.getOpcode() == ISD::AND ||
730 (LHS.getOpcode() == ISD::TRUNCATE &&
731 LHS.getOperand(0).getOpcode() == ISD::AND))) {
732 andCC = true;
733 }
734 }
735 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(2))->get();
736 SDValue TargetCC;
737 SDValue Flag = EmitCMP(LHS, RHS, TargetCC, CC, dl, DAG);
738
739 // Get the condition codes directly from the status register, if its easy.
740 // Otherwise a branch will be generated. Note that the AND and BIT
741 // instructions generate different flags than CMP, the carry bit can be used
742 // for NE/EQ.
743 bool Invert = false;
744 bool Shift = false;
745 bool Convert = true;
746 switch (cast<ConstantSDNode>(TargetCC)->getZExtValue()) {
747 default:
748 Convert = false;
749 break;
750 case MSP430CC::COND_HS:
751 // Res = SRW & 1, no processing is required
752 break;
753 case MSP430CC::COND_LO:
754 // Res = ~(SRW & 1)
755 Invert = true;
756 break;
757 case MSP430CC::COND_NE:
758 if (andCC) {
759 // C = ~Z, thus Res = SRW & 1, no processing is required
760 } else {
761 // Res = (SRW >> 1) & 1
762 Shift = true;
763 }
764 break;
765 case MSP430CC::COND_E:
766 if (andCC) {
767 // C = ~Z, thus Res = ~(SRW & 1)
768 } else {
769 // Res = ~((SRW >> 1) & 1)
770 Shift = true;
771 }
772 Invert = true;
773 break;
774 }
775 EVT VT = Op.getValueType();
776 SDValue One = DAG.getConstant(1, VT);
777 if (Convert) {
778 SDValue SR = DAG.getCopyFromReg(DAG.getEntryNode(), dl, MSP430::SRW,
779 MVT::i16, Flag);
780 if (Shift)
781 // FIXME: somewhere this is turned into a SRL, lower it MSP specific?
782 SR = DAG.getNode(ISD::SRA, dl, MVT::i16, SR, One);
783 SR = DAG.getNode(ISD::AND, dl, MVT::i16, SR, One);
784 if (Invert)
785 SR = DAG.getNode(ISD::XOR, dl, MVT::i16, SR, One);
786 return SR;
787 } else {
788 SDValue Zero = DAG.getConstant(0, VT);
789 SDVTList VTs = DAG.getVTList(Op.getValueType(), MVT::Flag);
790 SmallVector<SDValue, 4> Ops;
791 Ops.push_back(One);
792 Ops.push_back(Zero);
793 Ops.push_back(TargetCC);
794 Ops.push_back(Flag);
795 return DAG.getNode(MSP430ISD::SELECT_CC, dl, VTs, &Ops[0], Ops.size());
796 }
797}
798
651SDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) {
652 SDValue LHS = Op.getOperand(0);
653 SDValue RHS = Op.getOperand(1);
654 SDValue TrueV = Op.getOperand(2);
655 SDValue FalseV = Op.getOperand(3);
656 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
657 DebugLoc dl = Op.getDebugLoc();
658

--- 18 unchanged lines hidden (view full) ---

677
678 assert(VT == MVT::i16 && "Only support i16 for now!");
679
680 return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT,
681 DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val),
682 DAG.getValueType(Val.getValueType()));
683}
684
799SDValue MSP430TargetLowering::LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) {
800 SDValue LHS = Op.getOperand(0);
801 SDValue RHS = Op.getOperand(1);
802 SDValue TrueV = Op.getOperand(2);
803 SDValue FalseV = Op.getOperand(3);
804 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
805 DebugLoc dl = Op.getDebugLoc();
806

--- 18 unchanged lines hidden (view full) ---

825
826 assert(VT == MVT::i16 && "Only support i16 for now!");
827
828 return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, VT,
829 DAG.getNode(ISD::ANY_EXTEND, dl, VT, Val),
830 DAG.getValueType(Val.getValueType()));
831}
832
833SDValue MSP430TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) {
834 MachineFunction &MF = DAG.getMachineFunction();
835 MSP430MachineFunctionInfo *FuncInfo = MF.getInfo<MSP430MachineFunctionInfo>();
836 int ReturnAddrIndex = FuncInfo->getRAIndex();
837
838 if (ReturnAddrIndex == 0) {
839 // Set up a frame object for the return address.
840 uint64_t SlotSize = TD->getPointerSize();
841 ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize,
842 true, false);
843 FuncInfo->setRAIndex(ReturnAddrIndex);
844 }
845
846 return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy());
847}
848
849SDValue MSP430TargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) {
850 unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
851 DebugLoc dl = Op.getDebugLoc();
852
853 if (Depth > 0) {
854 SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
855 SDValue Offset =
856 DAG.getConstant(TD->getPointerSize(), MVT::i16);
857 return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
858 DAG.getNode(ISD::ADD, dl, getPointerTy(),
859 FrameAddr, Offset),
860 NULL, 0);
861 }
862
863 // Just load the return address.
864 SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
865 return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
866 RetAddrFI, NULL, 0);
867}
868
869SDValue MSP430TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
870 MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
871 MFI->setFrameAddressIsTaken(true);
872 EVT VT = Op.getValueType();
873 DebugLoc dl = Op.getDebugLoc(); // FIXME probably not meaningful
874 unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
875 SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
876 MSP430::FPW, VT);
877 while (Depth--)
878 FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr, NULL, 0);
879 return FrameAddr;
880}
881
685/// getPostIndexedAddressParts - returns true by value, base pointer and
686/// offset pointer and addressing mode by reference if this node can be
687/// combined with a load / store to form a post-indexed load / store.
688bool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
689 SDValue &Base,
690 SDValue &Offset,
691 ISD::MemIndexedMode &AM,
692 SelectionDAG &DAG) const {

--- 24 unchanged lines hidden (view full) ---

717 return false;
718}
719
720
721const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
722 switch (Opcode) {
723 default: return NULL;
724 case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG";
882/// getPostIndexedAddressParts - returns true by value, base pointer and
883/// offset pointer and addressing mode by reference if this node can be
884/// combined with a load / store to form a post-indexed load / store.
885bool MSP430TargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op,
886 SDValue &Base,
887 SDValue &Offset,
888 ISD::MemIndexedMode &AM,
889 SelectionDAG &DAG) const {

--- 24 unchanged lines hidden (view full) ---

914 return false;
915}
916
917
918const char *MSP430TargetLowering::getTargetNodeName(unsigned Opcode) const {
919 switch (Opcode) {
920 default: return NULL;
921 case MSP430ISD::RET_FLAG: return "MSP430ISD::RET_FLAG";
922 case MSP430ISD::RETI_FLAG: return "MSP430ISD::RETI_FLAG";
725 case MSP430ISD::RRA: return "MSP430ISD::RRA";
726 case MSP430ISD::RLA: return "MSP430ISD::RLA";
727 case MSP430ISD::RRC: return "MSP430ISD::RRC";
728 case MSP430ISD::CALL: return "MSP430ISD::CALL";
729 case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper";
730 case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC";
731 case MSP430ISD::CMP: return "MSP430ISD::CMP";
732 case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC";
923 case MSP430ISD::RRA: return "MSP430ISD::RRA";
924 case MSP430ISD::RLA: return "MSP430ISD::RLA";
925 case MSP430ISD::RRC: return "MSP430ISD::RRC";
926 case MSP430ISD::CALL: return "MSP430ISD::CALL";
927 case MSP430ISD::Wrapper: return "MSP430ISD::Wrapper";
928 case MSP430ISD::BR_CC: return "MSP430ISD::BR_CC";
929 case MSP430ISD::CMP: return "MSP430ISD::CMP";
930 case MSP430ISD::SELECT_CC: return "MSP430ISD::SELECT_CC";
931 case MSP430ISD::SHL: return "MSP430ISD::SHL";
932 case MSP430ISD::SRA: return "MSP430ISD::SRA";
733 }
734}
735
736//===----------------------------------------------------------------------===//
737// Other Lowering Code
738//===----------------------------------------------------------------------===//
739
740MachineBasicBlock*
933 }
934}
935
936//===----------------------------------------------------------------------===//
937// Other Lowering Code
938//===----------------------------------------------------------------------===//
939
940MachineBasicBlock*
941MSP430TargetLowering::EmitShiftInstr(MachineInstr *MI,
942 MachineBasicBlock *BB,
943 DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const {
944 MachineFunction *F = BB->getParent();
945 MachineRegisterInfo &RI = F->getRegInfo();
946 DebugLoc dl = MI->getDebugLoc();
947 const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
948
949 unsigned Opc;
950 const TargetRegisterClass * RC;
951 switch (MI->getOpcode()) {
952 default:
953 assert(0 && "Invalid shift opcode!");
954 case MSP430::Shl8:
955 Opc = MSP430::SHL8r1;
956 RC = MSP430::GR8RegisterClass;
957 break;
958 case MSP430::Shl16:
959 Opc = MSP430::SHL16r1;
960 RC = MSP430::GR16RegisterClass;
961 break;
962 case MSP430::Sra8:
963 Opc = MSP430::SAR8r1;
964 RC = MSP430::GR8RegisterClass;
965 break;
966 case MSP430::Sra16:
967 Opc = MSP430::SAR16r1;
968 RC = MSP430::GR16RegisterClass;
969 break;
970 case MSP430::Srl8:
971 Opc = MSP430::SAR8r1c;
972 RC = MSP430::GR8RegisterClass;
973 break;
974 case MSP430::Srl16:
975 Opc = MSP430::SAR16r1c;
976 RC = MSP430::GR16RegisterClass;
977 break;
978 }
979
980 const BasicBlock *LLVM_BB = BB->getBasicBlock();
981 MachineFunction::iterator I = BB;
982 ++I;
983
984 // Create loop block
985 MachineBasicBlock *LoopBB = F->CreateMachineBasicBlock(LLVM_BB);
986 MachineBasicBlock *RemBB = F->CreateMachineBasicBlock(LLVM_BB);
987
988 F->insert(I, LoopBB);
989 F->insert(I, RemBB);
990
991 // Update machine-CFG edges by transferring all successors of the current
992 // block to the block containing instructions after shift.
993 RemBB->transferSuccessors(BB);
994
995 // Inform sdisel of the edge changes.
996 for (MachineBasicBlock::succ_iterator SI = BB->succ_begin(),
997 SE = BB->succ_end(); SI != SE; ++SI)
998 EM->insert(std::make_pair(*SI, RemBB));
999
1000 // Add adges BB => LoopBB => RemBB, BB => RemBB, LoopBB => LoopBB
1001 BB->addSuccessor(LoopBB);
1002 BB->addSuccessor(RemBB);
1003 LoopBB->addSuccessor(RemBB);
1004 LoopBB->addSuccessor(LoopBB);
1005
1006 unsigned ShiftAmtReg = RI.createVirtualRegister(MSP430::GR8RegisterClass);
1007 unsigned ShiftAmtReg2 = RI.createVirtualRegister(MSP430::GR8RegisterClass);
1008 unsigned ShiftReg = RI.createVirtualRegister(RC);
1009 unsigned ShiftReg2 = RI.createVirtualRegister(RC);
1010 unsigned ShiftAmtSrcReg = MI->getOperand(2).getReg();
1011 unsigned SrcReg = MI->getOperand(1).getReg();
1012 unsigned DstReg = MI->getOperand(0).getReg();
1013
1014 // BB:
1015 // cmp 0, N
1016 // je RemBB
1017 BuildMI(BB, dl, TII.get(MSP430::CMP8ir))
1018 .addImm(0).addReg(ShiftAmtSrcReg);
1019 BuildMI(BB, dl, TII.get(MSP430::JCC))
1020 .addMBB(RemBB)
1021 .addImm(MSP430CC::COND_E);
1022
1023 // LoopBB:
1024 // ShiftReg = phi [%SrcReg, BB], [%ShiftReg2, LoopBB]
1025 // ShiftAmt = phi [%N, BB], [%ShiftAmt2, LoopBB]
1026 // ShiftReg2 = shift ShiftReg
1027 // ShiftAmt2 = ShiftAmt - 1;
1028 BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftReg)
1029 .addReg(SrcReg).addMBB(BB)
1030 .addReg(ShiftReg2).addMBB(LoopBB);
1031 BuildMI(LoopBB, dl, TII.get(MSP430::PHI), ShiftAmtReg)
1032 .addReg(ShiftAmtSrcReg).addMBB(BB)
1033 .addReg(ShiftAmtReg2).addMBB(LoopBB);
1034 BuildMI(LoopBB, dl, TII.get(Opc), ShiftReg2)
1035 .addReg(ShiftReg);
1036 BuildMI(LoopBB, dl, TII.get(MSP430::SUB8ri), ShiftAmtReg2)
1037 .addReg(ShiftAmtReg).addImm(1);
1038 BuildMI(LoopBB, dl, TII.get(MSP430::JCC))
1039 .addMBB(LoopBB)
1040 .addImm(MSP430CC::COND_NE);
1041
1042 // RemBB:
1043 // DestReg = phi [%SrcReg, BB], [%ShiftReg, LoopBB]
1044 BuildMI(RemBB, dl, TII.get(MSP430::PHI), DstReg)
1045 .addReg(SrcReg).addMBB(BB)
1046 .addReg(ShiftReg2).addMBB(LoopBB);
1047
1048 return RemBB;
1049}
1050
1051MachineBasicBlock*
741MSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
742 MachineBasicBlock *BB,
743 DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const {
1052MSP430TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
1053 MachineBasicBlock *BB,
1054 DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) const {
1055 unsigned Opc = MI->getOpcode();
1056
1057 if (Opc == MSP430::Shl8 || Opc == MSP430::Shl16 ||
1058 Opc == MSP430::Sra8 || Opc == MSP430::Sra16 ||
1059 Opc == MSP430::Srl8 || Opc == MSP430::Srl16)
1060 return EmitShiftInstr(MI, BB, EM);
1061
744 const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
745 DebugLoc dl = MI->getDebugLoc();
1062 const TargetInstrInfo &TII = *getTargetMachine().getInstrInfo();
1063 DebugLoc dl = MI->getDebugLoc();
746 assert((MI->getOpcode() == MSP430::Select16 ||
747 MI->getOpcode() == MSP430::Select8) &&
1064
1065 assert((Opc == MSP430::Select16 || Opc == MSP430::Select8) &&
748 "Unexpected instr type to insert");
749
750 // To "insert" a SELECT instruction, we actually have to insert the diamond
751 // control-flow pattern. The incoming instruction knows the destination vreg
752 // to set, the condition code register to branch on, the true/false values to
753 // select between, and a branch opcode to use.
754 const BasicBlock *LLVM_BB = BB->getBasicBlock();
755 MachineFunction::iterator I = BB;

--- 48 unchanged lines hidden ---
1066 "Unexpected instr type to insert");
1067
1068 // To "insert" a SELECT instruction, we actually have to insert the diamond
1069 // control-flow pattern. The incoming instruction knows the destination vreg
1070 // to set, the condition code register to branch on, the true/false values to
1071 // select between, and a branch opcode to use.
1072 const BasicBlock *LLVM_BB = BB->getBasicBlock();
1073 MachineFunction::iterator I = BB;

--- 48 unchanged lines hidden ---