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
21namespace llvm {
22class CSKYSubtarget;
23
24namespace CSKYISD {
25enum 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
42class CSKYTargetLowering : public TargetLowering {
43 const CSKYSubtarget &Subtarget;
44
45public:
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
54private:
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

source code of llvm/lib/Target/CSKY/CSKYISelLowering.h