1 | //===-- XCoreISelLowering.h - XCore 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 XCore uses to lower LLVM code into a |
10 | // selection DAG. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_LIB_TARGET_XCORE_XCOREISELLOWERING_H |
15 | #define LLVM_LIB_TARGET_XCORE_XCOREISELLOWERING_H |
16 | |
17 | #include "XCore.h" |
18 | #include "llvm/CodeGen/SelectionDAG.h" |
19 | #include "llvm/CodeGen/TargetLowering.h" |
20 | |
21 | namespace llvm { |
22 | |
23 | // Forward delcarations |
24 | class XCoreSubtarget; |
25 | |
26 | namespace XCoreISD { |
27 | enum NodeType : unsigned { |
28 | // Start the numbering where the builtin ops and target ops leave off. |
29 | FIRST_NUMBER = ISD::BUILTIN_OP_END, |
30 | |
31 | // Branch and link (call) |
32 | BL, |
33 | |
34 | // pc relative address |
35 | PCRelativeWrapper, |
36 | |
37 | // dp relative address |
38 | DPRelativeWrapper, |
39 | |
40 | // cp relative address |
41 | CPRelativeWrapper, |
42 | |
43 | // Load word from stack |
44 | LDWSP, |
45 | |
46 | // Store word to stack |
47 | STWSP, |
48 | |
49 | // Corresponds to retsp instruction |
50 | RETSP, |
51 | |
52 | // Corresponds to LADD instruction |
53 | LADD, |
54 | |
55 | // Corresponds to LSUB instruction |
56 | LSUB, |
57 | |
58 | // Corresponds to LMUL instruction |
59 | LMUL, |
60 | |
61 | // Corresponds to MACCU instruction |
62 | MACCU, |
63 | |
64 | // Corresponds to MACCS instruction |
65 | MACCS, |
66 | |
67 | // Corresponds to CRC8 instruction |
68 | CRC8, |
69 | |
70 | // Jumptable branch. |
71 | BR_JT, |
72 | |
73 | // Jumptable branch using long branches for each entry. |
74 | BR_JT32, |
75 | |
76 | // Offset from frame pointer to the first (possible) on-stack argument |
77 | FRAME_TO_ARGS_OFFSET, |
78 | |
79 | // Exception handler return. The stack is restored to the first |
80 | // followed by a jump to the second argument. |
81 | EH_RETURN, |
82 | }; |
83 | } |
84 | |
85 | //===--------------------------------------------------------------------===// |
86 | // TargetLowering Implementation |
87 | //===--------------------------------------------------------------------===// |
88 | class XCoreTargetLowering : public TargetLowering |
89 | { |
90 | public: |
91 | explicit XCoreTargetLowering(const TargetMachine &TM, |
92 | const XCoreSubtarget &Subtarget); |
93 | |
94 | using TargetLowering::isZExtFree; |
95 | bool isZExtFree(SDValue Val, EVT VT2) const override; |
96 | |
97 | |
98 | unsigned getJumpTableEncoding() const override; |
99 | MVT getScalarShiftAmountTy(const DataLayout &DL, EVT) const override { |
100 | return MVT::i32; |
101 | } |
102 | |
103 | /// LowerOperation - Provide custom lowering hooks for some operations. |
104 | SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; |
105 | |
106 | /// ReplaceNodeResults - Replace the results of node with an illegal result |
107 | /// type with new values built out of custom code. |
108 | /// |
109 | void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results, |
110 | SelectionDAG &DAG) const override; |
111 | |
112 | /// getTargetNodeName - This method returns the name of a target specific |
113 | // DAG node. |
114 | const char *getTargetNodeName(unsigned Opcode) const override; |
115 | |
116 | MachineBasicBlock * |
117 | EmitInstrWithCustomInserter(MachineInstr &MI, |
118 | MachineBasicBlock *MBB) const override; |
119 | |
120 | bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, |
121 | Type *Ty, unsigned AS, |
122 | Instruction *I = nullptr) const override; |
123 | |
124 | /// If a physical register, this returns the register that receives the |
125 | /// exception address on entry to an EH pad. |
126 | Register |
127 | getExceptionPointerRegister(const Constant *PersonalityFn) const override { |
128 | return XCore::R0; |
129 | } |
130 | |
131 | /// If a physical register, this returns the register that receives the |
132 | /// exception typeid on entry to a landing pad. |
133 | Register |
134 | getExceptionSelectorRegister(const Constant *PersonalityFn) const override { |
135 | return XCore::R1; |
136 | } |
137 | |
138 | private: |
139 | const TargetMachine &TM; |
140 | const XCoreSubtarget &Subtarget; |
141 | |
142 | // Lower Operand helpers |
143 | SDValue LowerCCCArguments(SDValue Chain, CallingConv::ID CallConv, |
144 | bool isVarArg, |
145 | const SmallVectorImpl<ISD::InputArg> &Ins, |
146 | const SDLoc &dl, SelectionDAG &DAG, |
147 | SmallVectorImpl<SDValue> &InVals) const; |
148 | SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee, |
149 | CallingConv::ID CallConv, bool isVarArg, |
150 | bool isTailCall, |
151 | const SmallVectorImpl<ISD::OutputArg> &Outs, |
152 | const SmallVectorImpl<SDValue> &OutVals, |
153 | const SmallVectorImpl<ISD::InputArg> &Ins, |
154 | const SDLoc &dl, SelectionDAG &DAG, |
155 | SmallVectorImpl<SDValue> &InVals) const; |
156 | SDValue getReturnAddressFrameIndex(SelectionDAG &DAG) const; |
157 | SDValue getGlobalAddressWrapper(SDValue GA, const GlobalValue *GV, |
158 | SelectionDAG &DAG) const; |
159 | SDValue lowerLoadWordFromAlignedBasePlusOffset(const SDLoc &DL, |
160 | SDValue Chain, SDValue Base, |
161 | int64_t Offset, |
162 | SelectionDAG &DAG) const; |
163 | |
164 | // Lower Operand specifics |
165 | SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const; |
166 | SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const; |
167 | SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const; |
168 | SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; |
169 | SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; |
170 | SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; |
171 | SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; |
172 | SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const; |
173 | SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) const; |
174 | SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; |
175 | SDValue LowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const; |
176 | SDValue LowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const; |
177 | SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; |
178 | SDValue LowerFRAME_TO_ARGS_OFFSET(SDValue Op, SelectionDAG &DAG) const; |
179 | SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; |
180 | SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; |
181 | SDValue LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; |
182 | SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; |
183 | SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const; |
184 | |
185 | // Inline asm support |
186 | std::pair<unsigned, const TargetRegisterClass *> |
187 | getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, |
188 | StringRef Constraint, MVT VT) const override; |
189 | |
190 | // Expand specifics |
191 | SDValue TryExpandADDWithMul(SDNode *Op, SelectionDAG &DAG) const; |
192 | SDValue ExpandADDSUB(SDNode *Op, SelectionDAG &DAG) const; |
193 | |
194 | SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; |
195 | |
196 | void computeKnownBitsForTargetNode(const SDValue Op, |
197 | KnownBits &Known, |
198 | const APInt &DemandedElts, |
199 | const SelectionDAG &DAG, |
200 | unsigned Depth = 0) const override; |
201 | |
202 | SDValue |
203 | LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, |
204 | const SmallVectorImpl<ISD::InputArg> &Ins, |
205 | const SDLoc &dl, SelectionDAG &DAG, |
206 | SmallVectorImpl<SDValue> &InVals) const override; |
207 | |
208 | SDValue |
209 | LowerCall(TargetLowering::CallLoweringInfo &CLI, |
210 | SmallVectorImpl<SDValue> &InVals) const override; |
211 | |
212 | SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, |
213 | const SmallVectorImpl<ISD::OutputArg> &Outs, |
214 | const SmallVectorImpl<SDValue> &OutVals, |
215 | const SDLoc &dl, SelectionDAG &DAG) const override; |
216 | |
217 | bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, |
218 | bool isVarArg, |
219 | const SmallVectorImpl<ISD::OutputArg> &ArgsFlags, |
220 | LLVMContext &Context) const override; |
221 | }; |
222 | } |
223 | |
224 | #endif |
225 | |