]>
Commit | Line | Data |
---|---|---|
223e47cc LB |
1 | //===-- MSP430ISelLowering.h - MSP430 DAG Lowering Interface ----*- C++ -*-===// |
2 | // | |
3 | // The LLVM Compiler Infrastructure | |
4 | // | |
5 | // This file is distributed under the University of Illinois Open Source | |
6 | // License. See LICENSE.TXT for details. | |
7 | // | |
8 | //===----------------------------------------------------------------------===// | |
9 | // | |
10 | // This file defines the interfaces that MSP430 uses to lower LLVM code into a | |
11 | // selection DAG. | |
12 | // | |
13 | //===----------------------------------------------------------------------===// | |
14 | ||
1a4d82fc JJ |
15 | #ifndef LLVM_LIB_TARGET_MSP430_MSP430ISELLOWERING_H |
16 | #define LLVM_LIB_TARGET_MSP430_MSP430ISELLOWERING_H | |
223e47cc LB |
17 | |
18 | #include "MSP430.h" | |
19 | #include "llvm/CodeGen/SelectionDAG.h" | |
20 | #include "llvm/Target/TargetLowering.h" | |
21 | ||
22 | namespace llvm { | |
23 | namespace MSP430ISD { | |
24 | enum { | |
25 | FIRST_NUMBER = ISD::BUILTIN_OP_END, | |
26 | ||
27 | /// Return with a flag operand. Operand 0 is the chain operand. | |
28 | RET_FLAG, | |
29 | ||
30 | /// Same as RET_FLAG, but used for returning from ISRs. | |
31 | RETI_FLAG, | |
32 | ||
33 | /// Y = R{R,L}A X, rotate right (left) arithmetically | |
34 | RRA, RLA, | |
35 | ||
36 | /// Y = RRC X, rotate right via carry | |
37 | RRC, | |
38 | ||
39 | /// CALL - These operations represent an abstract call | |
40 | /// instruction, which includes a bunch of information. | |
41 | CALL, | |
42 | ||
43 | /// Wrapper - A wrapper node for TargetConstantPool, TargetExternalSymbol, | |
44 | /// and TargetGlobalAddress. | |
45 | Wrapper, | |
46 | ||
47 | /// CMP - Compare instruction. | |
48 | CMP, | |
49 | ||
50 | /// SetCC - Operand 0 is condition code, and operand 1 is the flag | |
51 | /// operand produced by a CMP instruction. | |
52 | SETCC, | |
53 | ||
54 | /// MSP430 conditional branches. Operand 0 is the chain operand, operand 1 | |
55 | /// is the block to branch if condition is true, operand 2 is the | |
56 | /// condition code, and operand 3 is the flag operand produced by a CMP | |
57 | /// instruction. | |
58 | BR_CC, | |
59 | ||
60 | /// SELECT_CC - Operand 0 and operand 1 are selection variable, operand 3 | |
61 | /// is condition code and operand 4 is flag operand. | |
62 | SELECT_CC, | |
63 | ||
64 | /// SHL, SRA, SRL - Non-constant shifts. | |
65 | SHL, SRA, SRL | |
66 | }; | |
67 | } | |
68 | ||
223e47cc LB |
69 | class MSP430TargetLowering : public TargetLowering { |
70 | public: | |
1a4d82fc | 71 | explicit MSP430TargetLowering(const TargetMachine &TM); |
223e47cc | 72 | |
1a4d82fc | 73 | MVT getScalarShiftAmountTy(EVT LHSTy) const override { return MVT::i8; } |
223e47cc LB |
74 | |
75 | /// LowerOperation - Provide custom lowering hooks for some operations. | |
1a4d82fc | 76 | SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; |
223e47cc LB |
77 | |
78 | /// getTargetNodeName - This method returns the name of a target specific | |
79 | /// DAG node. | |
1a4d82fc | 80 | const char *getTargetNodeName(unsigned Opcode) const override; |
223e47cc LB |
81 | |
82 | SDValue LowerShifts(SDValue Op, SelectionDAG &DAG) const; | |
83 | SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; | |
84 | SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; | |
85 | SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const; | |
86 | SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const; | |
87 | SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; | |
88 | SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; | |
89 | SDValue LowerSIGN_EXTEND(SDValue Op, SelectionDAG &DAG) const; | |
90 | SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; | |
91 | SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; | |
970d7e83 | 92 | SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; |
1a4d82fc | 93 | SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; |
223e47cc LB |
94 | SDValue getReturnAddressFrameIndex(SelectionDAG &DAG) const; |
95 | ||
96 | TargetLowering::ConstraintType | |
1a4d82fc | 97 | getConstraintType(const std::string &Constraint) const override; |
223e47cc | 98 | std::pair<unsigned, const TargetRegisterClass*> |
1a4d82fc JJ |
99 | getRegForInlineAsmConstraint(const std::string &Constraint, |
100 | MVT VT) const override; | |
223e47cc LB |
101 | |
102 | /// isTruncateFree - Return true if it's free to truncate a value of type | |
103 | /// Ty1 to type Ty2. e.g. On msp430 it's free to truncate a i16 value in | |
104 | /// register R15W to i8 by referencing its sub-register R15B. | |
1a4d82fc JJ |
105 | bool isTruncateFree(Type *Ty1, Type *Ty2) const override; |
106 | bool isTruncateFree(EVT VT1, EVT VT2) const override; | |
223e47cc LB |
107 | |
108 | /// isZExtFree - Return true if any actual instruction that defines a value | |
109 | /// of type Ty1 implicit zero-extends the value to Ty2 in the result | |
110 | /// register. This does not necessarily include registers defined in unknown | |
111 | /// ways, such as incoming arguments, or copies from unknown virtual | |
112 | /// registers. Also, if isTruncateFree(Ty2, Ty1) is true, this does not | |
113 | /// necessarily apply to truncate instructions. e.g. on msp430, all | |
114 | /// instructions that define 8-bit values implicit zero-extend the result | |
115 | /// out to 16 bits. | |
1a4d82fc JJ |
116 | bool isZExtFree(Type *Ty1, Type *Ty2) const override; |
117 | bool isZExtFree(EVT VT1, EVT VT2) const override; | |
118 | bool isZExtFree(SDValue Val, EVT VT2) const override; | |
223e47cc LB |
119 | |
120 | MachineBasicBlock* EmitInstrWithCustomInserter(MachineInstr *MI, | |
1a4d82fc | 121 | MachineBasicBlock *BB) const override; |
223e47cc LB |
122 | MachineBasicBlock* EmitShiftInstr(MachineInstr *MI, |
123 | MachineBasicBlock *BB) const; | |
124 | ||
125 | private: | |
126 | SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee, | |
127 | CallingConv::ID CallConv, bool isVarArg, | |
128 | bool isTailCall, | |
129 | const SmallVectorImpl<ISD::OutputArg> &Outs, | |
130 | const SmallVectorImpl<SDValue> &OutVals, | |
131 | const SmallVectorImpl<ISD::InputArg> &Ins, | |
1a4d82fc | 132 | SDLoc dl, SelectionDAG &DAG, |
223e47cc LB |
133 | SmallVectorImpl<SDValue> &InVals) const; |
134 | ||
135 | SDValue LowerCCCArguments(SDValue Chain, | |
136 | CallingConv::ID CallConv, | |
137 | bool isVarArg, | |
138 | const SmallVectorImpl<ISD::InputArg> &Ins, | |
1a4d82fc | 139 | SDLoc dl, |
223e47cc LB |
140 | SelectionDAG &DAG, |
141 | SmallVectorImpl<SDValue> &InVals) const; | |
142 | ||
143 | SDValue LowerCallResult(SDValue Chain, SDValue InFlag, | |
144 | CallingConv::ID CallConv, bool isVarArg, | |
145 | const SmallVectorImpl<ISD::InputArg> &Ins, | |
1a4d82fc | 146 | SDLoc dl, SelectionDAG &DAG, |
223e47cc LB |
147 | SmallVectorImpl<SDValue> &InVals) const; |
148 | ||
1a4d82fc | 149 | SDValue |
223e47cc LB |
150 | LowerFormalArguments(SDValue Chain, |
151 | CallingConv::ID CallConv, bool isVarArg, | |
152 | const SmallVectorImpl<ISD::InputArg> &Ins, | |
1a4d82fc JJ |
153 | SDLoc dl, SelectionDAG &DAG, |
154 | SmallVectorImpl<SDValue> &InVals) const override; | |
155 | SDValue | |
223e47cc | 156 | LowerCall(TargetLowering::CallLoweringInfo &CLI, |
1a4d82fc JJ |
157 | SmallVectorImpl<SDValue> &InVals) const override; |
158 | ||
159 | SDValue LowerReturn(SDValue Chain, | |
160 | CallingConv::ID CallConv, bool isVarArg, | |
161 | const SmallVectorImpl<ISD::OutputArg> &Outs, | |
162 | const SmallVectorImpl<SDValue> &OutVals, | |
163 | SDLoc dl, SelectionDAG &DAG) const override; | |
164 | ||
165 | bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, | |
166 | SDValue &Base, | |
167 | SDValue &Offset, | |
168 | ISD::MemIndexedMode &AM, | |
169 | SelectionDAG &DAG) const override; | |
223e47cc LB |
170 | }; |
171 | } // namespace llvm | |
172 | ||
1a4d82fc | 173 | #endif |