xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYISelLowering.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1349cc55cSDimitry Andric //===-- CSKYISelLowering.cpp - CSKY DAG Lowering Implementation  ----------===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric //
9349cc55cSDimitry Andric // This file defines the interfaces that CSKY uses to lower LLVM code into a
10349cc55cSDimitry Andric // selection DAG.
11349cc55cSDimitry Andric //
12349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
13349cc55cSDimitry Andric 
14349cc55cSDimitry Andric #ifndef LLVM_LIB_TARGET_CSKY_CSKYISELLOWERING_H
15349cc55cSDimitry Andric #define LLVM_LIB_TARGET_CSKY_CSKYISELLOWERING_H
16349cc55cSDimitry Andric 
17349cc55cSDimitry Andric #include "MCTargetDesc/CSKYBaseInfo.h"
18349cc55cSDimitry Andric #include "llvm/CodeGen/CallingConvLower.h"
19349cc55cSDimitry Andric #include "llvm/CodeGen/TargetLowering.h"
20349cc55cSDimitry Andric 
21349cc55cSDimitry Andric namespace llvm {
22349cc55cSDimitry Andric class CSKYSubtarget;
23349cc55cSDimitry Andric 
24349cc55cSDimitry Andric namespace CSKYISD {
25349cc55cSDimitry Andric enum NodeType : unsigned {
26349cc55cSDimitry Andric   FIRST_NUMBER = ISD::BUILTIN_OP_END,
27349cc55cSDimitry Andric   NIE,
28349cc55cSDimitry Andric   NIR,
29349cc55cSDimitry Andric   RET,
3004eeddc0SDimitry Andric   CALL,
3104eeddc0SDimitry Andric   CALLReg,
3204eeddc0SDimitry Andric   TAIL,
3304eeddc0SDimitry Andric   TAILReg,
3404eeddc0SDimitry Andric   LOAD_ADDR,
3504eeddc0SDimitry Andric   // i32, i32 <-- f64
3604eeddc0SDimitry Andric   BITCAST_TO_LOHI,
3704eeddc0SDimitry Andric   // f64 < -- i32, i32
3804eeddc0SDimitry Andric   BITCAST_FROM_LOHI,
39349cc55cSDimitry Andric };
40349cc55cSDimitry Andric }
41349cc55cSDimitry Andric 
42349cc55cSDimitry Andric class CSKYTargetLowering : public TargetLowering {
43349cc55cSDimitry Andric   const CSKYSubtarget &Subtarget;
44349cc55cSDimitry Andric 
45349cc55cSDimitry Andric public:
46349cc55cSDimitry Andric   explicit CSKYTargetLowering(const TargetMachine &TM,
47349cc55cSDimitry Andric                               const CSKYSubtarget &STI);
48349cc55cSDimitry Andric 
4904eeddc0SDimitry Andric   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
5004eeddc0SDimitry Andric 
51349cc55cSDimitry Andric   EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
52349cc55cSDimitry Andric                          EVT VT) const override;
53349cc55cSDimitry Andric 
54349cc55cSDimitry Andric private:
55349cc55cSDimitry Andric   SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
56349cc55cSDimitry Andric                                bool IsVarArg,
57349cc55cSDimitry Andric                                const SmallVectorImpl<ISD::InputArg> &Ins,
58349cc55cSDimitry Andric                                const SDLoc &DL, SelectionDAG &DAG,
59349cc55cSDimitry Andric                                SmallVectorImpl<SDValue> &InVals) const override;
60349cc55cSDimitry Andric 
61349cc55cSDimitry Andric   bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
62349cc55cSDimitry Andric                       bool IsVarArg,
63349cc55cSDimitry Andric                       const SmallVectorImpl<ISD::OutputArg> &Outs,
64349cc55cSDimitry Andric                       LLVMContext &Context) const override;
65349cc55cSDimitry Andric 
66349cc55cSDimitry Andric   SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
67349cc55cSDimitry Andric                       const SmallVectorImpl<ISD::OutputArg> &Outs,
68349cc55cSDimitry Andric                       const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
69349cc55cSDimitry Andric                       SelectionDAG &DAG) const override;
70349cc55cSDimitry Andric 
7104eeddc0SDimitry Andric   SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
7204eeddc0SDimitry Andric                     SmallVectorImpl<SDValue> &InVals) const override;
7304eeddc0SDimitry Andric 
74349cc55cSDimitry Andric   const char *getTargetNodeName(unsigned Opcode) const override;
75349cc55cSDimitry Andric 
7604eeddc0SDimitry Andric   /// If a physical register, this returns the register that receives the
7704eeddc0SDimitry Andric   /// exception address on entry to an EH pad.
7804eeddc0SDimitry Andric   Register
7904eeddc0SDimitry Andric   getExceptionPointerRegister(const Constant *PersonalityFn) const override;
8004eeddc0SDimitry Andric 
8104eeddc0SDimitry Andric   /// If a physical register, this returns the register that receives the
8204eeddc0SDimitry Andric   /// exception typeid on entry to a landing pad.
8304eeddc0SDimitry Andric   Register
8404eeddc0SDimitry Andric   getExceptionSelectorRegister(const Constant *PersonalityFn) const override;
8504eeddc0SDimitry Andric 
isSelectSupported(SelectSupportKind Kind)8604eeddc0SDimitry Andric   bool isSelectSupported(SelectSupportKind Kind) const override {
8704eeddc0SDimitry Andric     // CSKY does not support scalar condition selects on vectors.
8804eeddc0SDimitry Andric     return (Kind != ScalarCondVectorVal);
8904eeddc0SDimitry Andric   }
9004eeddc0SDimitry Andric 
9181ad6265SDimitry Andric   ConstraintType getConstraintType(StringRef Constraint) const override;
9281ad6265SDimitry Andric 
9381ad6265SDimitry Andric   std::pair<unsigned, const TargetRegisterClass *>
9481ad6265SDimitry Andric   getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
9581ad6265SDimitry Andric                                StringRef Constraint, MVT VT) const override;
9681ad6265SDimitry Andric 
9704eeddc0SDimitry Andric   MachineBasicBlock *
9804eeddc0SDimitry Andric   EmitInstrWithCustomInserter(MachineInstr &MI,
9904eeddc0SDimitry Andric                               MachineBasicBlock *BB) const override;
10004eeddc0SDimitry Andric 
10104eeddc0SDimitry Andric   SDValue getTargetNode(GlobalAddressSDNode *N, SDLoc DL, EVT Ty,
10204eeddc0SDimitry Andric                         SelectionDAG &DAG, unsigned Flags) const;
10304eeddc0SDimitry Andric 
10404eeddc0SDimitry Andric   SDValue getTargetNode(ExternalSymbolSDNode *N, SDLoc DL, EVT Ty,
10504eeddc0SDimitry Andric                         SelectionDAG &DAG, unsigned Flags) const;
10604eeddc0SDimitry Andric 
10704eeddc0SDimitry Andric   SDValue getTargetNode(JumpTableSDNode *N, SDLoc DL, EVT Ty, SelectionDAG &DAG,
10804eeddc0SDimitry Andric                         unsigned Flags) const;
10904eeddc0SDimitry Andric 
11004eeddc0SDimitry Andric   SDValue getTargetNode(BlockAddressSDNode *N, SDLoc DL, EVT Ty,
11104eeddc0SDimitry Andric                         SelectionDAG &DAG, unsigned Flags) const;
11204eeddc0SDimitry Andric 
113bdd1243dSDimitry Andric   SDValue getTargetNode(ConstantPoolSDNode *N, SDLoc DL, EVT Ty,
114bdd1243dSDimitry Andric                         SelectionDAG &DAG, unsigned Flags) const;
115bdd1243dSDimitry Andric 
11604eeddc0SDimitry Andric   SDValue getTargetConstantPoolValue(GlobalAddressSDNode *N, EVT Ty,
11704eeddc0SDimitry Andric                                      SelectionDAG &DAG, unsigned Flags) const;
11804eeddc0SDimitry Andric 
11904eeddc0SDimitry Andric   SDValue getTargetConstantPoolValue(ExternalSymbolSDNode *N, EVT Ty,
12004eeddc0SDimitry Andric                                      SelectionDAG &DAG, unsigned Flags) const;
12104eeddc0SDimitry Andric 
12204eeddc0SDimitry Andric   SDValue getTargetConstantPoolValue(JumpTableSDNode *N, EVT Ty,
12304eeddc0SDimitry Andric                                      SelectionDAG &DAG, unsigned Flags) const;
12404eeddc0SDimitry Andric 
12504eeddc0SDimitry Andric   SDValue getTargetConstantPoolValue(BlockAddressSDNode *N, EVT Ty,
12604eeddc0SDimitry Andric                                      SelectionDAG &DAG, unsigned Flags) const;
12704eeddc0SDimitry Andric 
128bdd1243dSDimitry Andric   SDValue getTargetConstantPoolValue(ConstantPoolSDNode *N, EVT Ty,
129bdd1243dSDimitry Andric                                      SelectionDAG &DAG, unsigned Flags) const;
130bdd1243dSDimitry Andric 
13104eeddc0SDimitry Andric   template <class NodeTy, bool IsCall = false>
13204eeddc0SDimitry Andric   SDValue getAddr(NodeTy *N, SelectionDAG &DAG, bool IsLocal = true) const {
13304eeddc0SDimitry Andric     SDLoc DL(N);
13404eeddc0SDimitry Andric     EVT Ty = getPointerTy(DAG.getDataLayout());
13504eeddc0SDimitry Andric 
13604eeddc0SDimitry Andric     unsigned Flag = CSKYII::MO_None;
13704eeddc0SDimitry Andric     bool IsPIC = isPositionIndependent();
13804eeddc0SDimitry Andric 
13904eeddc0SDimitry Andric     if (IsPIC)
14004eeddc0SDimitry Andric       Flag = IsLocal  ? CSKYII::MO_GOTOFF
14104eeddc0SDimitry Andric              : IsCall ? CSKYII::MO_PLT32
14204eeddc0SDimitry Andric                       : CSKYII::MO_GOT32;
14304eeddc0SDimitry Andric 
14404eeddc0SDimitry Andric     SDValue TCPV = getTargetConstantPoolValue(N, Ty, DAG, Flag);
14504eeddc0SDimitry Andric     SDValue TV = getTargetNode(N, DL, Ty, DAG, Flag);
14604eeddc0SDimitry Andric     SDValue Addr = DAG.getNode(CSKYISD::LOAD_ADDR, DL, Ty, {TV, TCPV});
14704eeddc0SDimitry Andric 
14804eeddc0SDimitry Andric     if (!IsPIC)
14904eeddc0SDimitry Andric       return Addr;
15004eeddc0SDimitry Andric 
15104eeddc0SDimitry Andric     SDValue Result =
15204eeddc0SDimitry Andric         DAG.getNode(ISD::ADD, DL, Ty, {DAG.getGLOBAL_OFFSET_TABLE(Ty), Addr});
15304eeddc0SDimitry Andric     if (IsLocal)
15404eeddc0SDimitry Andric       return Result;
15504eeddc0SDimitry Andric 
15604eeddc0SDimitry Andric     return DAG.getLoad(Ty, DL, DAG.getEntryNode(), Result,
15704eeddc0SDimitry Andric                        MachinePointerInfo::getGOT(DAG.getMachineFunction()));
15804eeddc0SDimitry Andric   }
15904eeddc0SDimitry Andric 
16004eeddc0SDimitry Andric   SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
16104eeddc0SDimitry Andric   SDValue LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) const;
16204eeddc0SDimitry Andric   SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
16304eeddc0SDimitry Andric   SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
164bdd1243dSDimitry Andric   SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
16504eeddc0SDimitry Andric   SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
16604eeddc0SDimitry Andric   SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
16704eeddc0SDimitry Andric   SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
16804eeddc0SDimitry Andric   SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
16904eeddc0SDimitry Andric 
17004eeddc0SDimitry Andric   SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
17104eeddc0SDimitry Andric                            bool UseGOT) const;
17204eeddc0SDimitry Andric   SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG) const;
17304eeddc0SDimitry Andric 
174349cc55cSDimitry Andric   CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const;
175349cc55cSDimitry Andric   CCAssignFn *CCAssignFnForReturn(CallingConv::ID CC, bool IsVarArg) const;
17606c3fb27SDimitry Andric 
17706c3fb27SDimitry Andric   bool decomposeMulByConstant(LLVMContext &Context, EVT VT,
17806c3fb27SDimitry Andric                               SDValue C) const override;
179*5f757f3fSDimitry Andric   bool isCheapToSpeculateCttz(Type *Ty) const override;
180*5f757f3fSDimitry Andric   bool isCheapToSpeculateCtlz(Type *Ty) const override;
181349cc55cSDimitry Andric };
182349cc55cSDimitry Andric 
183349cc55cSDimitry Andric } // namespace llvm
184349cc55cSDimitry Andric 
185349cc55cSDimitry Andric #endif // LLVM_LIB_TARGET_CSKY_CSKYISELLOWERING_H
186