1 | //===-- CSKYISelLowering.cpp - CSKY DAG Lowering Implementation ----------===// |
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 CSKY uses to lower LLVM code into a |
10 | // selection DAG. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_LIB_TARGET_CSKY_CSKYISELLOWERING_H |
15 | #define LLVM_LIB_TARGET_CSKY_CSKYISELLOWERING_H |
16 | |
17 | #include "MCTargetDesc/CSKYBaseInfo.h" |
18 | #include "llvm/CodeGen/CallingConvLower.h" |
19 | #include "llvm/CodeGen/TargetLowering.h" |
20 | |
21 | namespace llvm { |
22 | class CSKYSubtarget; |
23 | |
24 | namespace CSKYISD { |
25 | enum NodeType : unsigned { |
26 | FIRST_NUMBER = ISD::BUILTIN_OP_END, |
27 | NIE, |
28 | NIR, |
29 | RET, |
30 | CALL, |
31 | CALLReg, |
32 | TAIL, |
33 | TAILReg, |
34 | LOAD_ADDR, |
35 | // i32, i32 <-- f64 |
36 | BITCAST_TO_LOHI, |
37 | // f64 < -- i32, i32 |
38 | BITCAST_FROM_LOHI, |
39 | }; |
40 | } |
41 | |
42 | class CSKYTargetLowering : public TargetLowering { |
43 | const CSKYSubtarget &Subtarget; |
44 | |
45 | public: |
46 | explicit CSKYTargetLowering(const TargetMachine &TM, |
47 | const CSKYSubtarget &STI); |
48 | |
49 | SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; |
50 | |
51 | EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, |
52 | EVT VT) const override; |
53 | |
54 | private: |
55 | SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, |
56 | bool IsVarArg, |
57 | const SmallVectorImpl<ISD::InputArg> &Ins, |
58 | const SDLoc &DL, SelectionDAG &DAG, |
59 | SmallVectorImpl<SDValue> &InVals) const override; |
60 | |
61 | bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, |
62 | bool IsVarArg, |
63 | const SmallVectorImpl<ISD::OutputArg> &Outs, |
64 | LLVMContext &Context) const override; |
65 | |
66 | SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, |
67 | const SmallVectorImpl<ISD::OutputArg> &Outs, |
68 | const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL, |
69 | SelectionDAG &DAG) const override; |
70 | |
71 | SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, |
72 | SmallVectorImpl<SDValue> &InVals) const override; |
73 | |
74 | const char *getTargetNodeName(unsigned Opcode) const override; |
75 | |
76 | /// If a physical register, this returns the register that receives the |
77 | /// exception address on entry to an EH pad. |
78 | Register |
79 | getExceptionPointerRegister(const Constant *PersonalityFn) const override; |
80 | |
81 | /// If a physical register, this returns the register that receives the |
82 | /// exception typeid on entry to a landing pad. |
83 | Register |
84 | getExceptionSelectorRegister(const Constant *PersonalityFn) const override; |
85 | |
86 | bool isSelectSupported(SelectSupportKind Kind) const override { |
87 | // CSKY does not support scalar condition selects on vectors. |
88 | return (Kind != ScalarCondVectorVal); |
89 | } |
90 | |
91 | ConstraintType getConstraintType(StringRef Constraint) const override; |
92 | |
93 | std::pair<unsigned, const TargetRegisterClass *> |
94 | getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, |
95 | StringRef Constraint, MVT VT) const override; |
96 | |
97 | MachineBasicBlock * |
98 | EmitInstrWithCustomInserter(MachineInstr &MI, |
99 | MachineBasicBlock *BB) const override; |
100 | |
101 | SDValue getTargetNode(GlobalAddressSDNode *N, SDLoc DL, EVT Ty, |
102 | SelectionDAG &DAG, unsigned Flags) const; |
103 | |
104 | SDValue getTargetNode(ExternalSymbolSDNode *N, SDLoc DL, EVT Ty, |
105 | SelectionDAG &DAG, unsigned Flags) const; |
106 | |
107 | SDValue getTargetNode(JumpTableSDNode *N, SDLoc DL, EVT Ty, SelectionDAG &DAG, |
108 | unsigned Flags) const; |
109 | |
110 | SDValue getTargetNode(BlockAddressSDNode *N, SDLoc DL, EVT Ty, |
111 | SelectionDAG &DAG, unsigned Flags) const; |
112 | |
113 | SDValue getTargetNode(ConstantPoolSDNode *N, SDLoc DL, EVT Ty, |
114 | SelectionDAG &DAG, unsigned Flags) const; |
115 | |
116 | SDValue getTargetConstantPoolValue(GlobalAddressSDNode *N, EVT Ty, |
117 | SelectionDAG &DAG, unsigned Flags) const; |
118 | |
119 | SDValue getTargetConstantPoolValue(ExternalSymbolSDNode *N, EVT Ty, |
120 | SelectionDAG &DAG, unsigned Flags) const; |
121 | |
122 | SDValue getTargetConstantPoolValue(JumpTableSDNode *N, EVT Ty, |
123 | SelectionDAG &DAG, unsigned Flags) const; |
124 | |
125 | SDValue getTargetConstantPoolValue(BlockAddressSDNode *N, EVT Ty, |
126 | SelectionDAG &DAG, unsigned Flags) const; |
127 | |
128 | SDValue getTargetConstantPoolValue(ConstantPoolSDNode *N, EVT Ty, |
129 | SelectionDAG &DAG, unsigned Flags) const; |
130 | |
131 | template <class NodeTy, bool IsCall = false> |
132 | SDValue getAddr(NodeTy *N, SelectionDAG &DAG, bool IsLocal = true) const { |
133 | SDLoc DL(N); |
134 | EVT Ty = getPointerTy(DL: DAG.getDataLayout()); |
135 | |
136 | unsigned Flag = CSKYII::MO_None; |
137 | bool IsPIC = isPositionIndependent(); |
138 | |
139 | if (IsPIC) |
140 | Flag = IsLocal ? CSKYII::MO_GOTOFF |
141 | : IsCall ? CSKYII::MO_PLT32 |
142 | : CSKYII::MO_GOT32; |
143 | |
144 | SDValue TCPV = getTargetConstantPoolValue(N, Ty, DAG, Flag); |
145 | SDValue TV = getTargetNode(N, DL, Ty, DAG, Flag); |
146 | SDValue Addr = DAG.getNode(Opcode: CSKYISD::LOAD_ADDR, DL, VT: Ty, Ops: {TV, TCPV}); |
147 | |
148 | if (!IsPIC) |
149 | return Addr; |
150 | |
151 | SDValue Result = |
152 | DAG.getNode(Opcode: ISD::ADD, DL, VT: Ty, Ops: {DAG.getGLOBAL_OFFSET_TABLE(VT: Ty), Addr}); |
153 | if (IsLocal) |
154 | return Result; |
155 | |
156 | return DAG.getLoad(VT: Ty, dl: DL, Chain: DAG.getEntryNode(), Ptr: Result, |
157 | PtrInfo: MachinePointerInfo::getGOT(MF&: DAG.getMachineFunction())); |
158 | } |
159 | |
160 | SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; |
161 | SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const; |
162 | SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; |
163 | SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; |
164 | SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; |
165 | SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; |
166 | SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; |
167 | SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; |
168 | SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; |
169 | |
170 | SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG, |
171 | bool UseGOT) const; |
172 | SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG) const; |
173 | |
174 | CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const; |
175 | CCAssignFn *CCAssignFnForReturn(CallingConv::ID CC, bool IsVarArg) const; |
176 | |
177 | bool decomposeMulByConstant(LLVMContext &Context, EVT VT, |
178 | SDValue C) const override; |
179 | bool isCheapToSpeculateCttz(Type *Ty) const override; |
180 | bool isCheapToSpeculateCtlz(Type *Ty) const override; |
181 | }; |
182 | |
183 | } // namespace llvm |
184 | |
185 | #endif // LLVM_LIB_TARGET_CSKY_CSKYISELLOWERING_H |
186 | |