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