1 //=- LoongArchISelLowering.h - LoongArch 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 LoongArch uses to lower LLVM code into
10 // a selection DAG.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H
15 #define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H
16 
17 #include "LoongArch.h"
18 #include "llvm/CodeGen/CallingConvLower.h"
19 #include "llvm/CodeGen/SelectionDAG.h"
20 #include "llvm/CodeGen/TargetLowering.h"
21 
22 namespace llvm {
23 class LoongArchSubtarget;
24 struct LoongArchRegisterInfo;
25 namespace LoongArchISD {
26 enum NodeType : unsigned {
27   FIRST_NUMBER = ISD::BUILTIN_OP_END,
28 
29   // TODO: add more LoongArchISDs
30   CALL,
31   RET,
32   // 32-bit shifts, directly matching the semantics of the named LoongArch
33   // instructions.
34   SLL_W,
35   SRA_W,
36   SRL_W,
37 
38   // FPR<->GPR transfer operations
39   MOVGR2FR_W_LA64,
40   MOVFR2GR_S_LA64,
41 
42   FTINT,
43 
44   BSTRINS,
45   BSTRPICK,
46 
47 };
48 } // end namespace LoongArchISD
49 
50 class LoongArchTargetLowering : public TargetLowering {
51   const LoongArchSubtarget &Subtarget;
52 
53 public:
54   explicit LoongArchTargetLowering(const TargetMachine &TM,
55                                    const LoongArchSubtarget &STI);
56 
57   const LoongArchSubtarget &getSubtarget() const { return Subtarget; }
58 
59   // Provide custom lowering hooks for some operations.
60   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
61   void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
62                           SelectionDAG &DAG) const override;
63 
64   SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
65 
66   // This method returns the name of a target specific DAG node.
67   const char *getTargetNodeName(unsigned Opcode) const override;
68 
69   // Lower incoming arguments, copy physregs into vregs.
70   SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
71                                bool IsVarArg,
72                                const SmallVectorImpl<ISD::InputArg> &Ins,
73                                const SDLoc &DL, SelectionDAG &DAG,
74                                SmallVectorImpl<SDValue> &InVals) const override;
75   bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
76                       bool IsVarArg,
77                       const SmallVectorImpl<ISD::OutputArg> &Outs,
78                       LLVMContext &Context) const override;
79   SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
80                       const SmallVectorImpl<ISD::OutputArg> &Outs,
81                       const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
82                       SelectionDAG &DAG) const override;
83   SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
84                     SmallVectorImpl<SDValue> &InVals) const override;
85 
86 private:
87   /// Target-specific function used to lower LoongArch calling conventions.
88   typedef bool LoongArchCCAssignFn(unsigned ValNo, MVT ValVT,
89                                    CCValAssign::LocInfo LocInfo,
90                                    CCState &State);
91 
92   void analyzeInputArgs(CCState &CCInfo,
93                         const SmallVectorImpl<ISD::InputArg> &Ins,
94                         LoongArchCCAssignFn Fn) const;
95   void analyzeOutputArgs(CCState &CCInfo,
96                          const SmallVectorImpl<ISD::OutputArg> &Outs,
97                          LoongArchCCAssignFn Fn) const;
98 
99   SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
100   SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
101   SDValue lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const;
102 
103   MachineBasicBlock *
104   EmitInstrWithCustomInserter(MachineInstr &MI,
105                               MachineBasicBlock *BB) const override;
106   SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
107   SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;
108   SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const;
109   SDValue lowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
110 
111   bool isFPImmLegal(const APFloat &Imm, EVT VT,
112                     bool ForCodeSize) const override;
113 
114   bool shouldInsertFencesForAtomic(const Instruction *I) const override {
115     return isa<LoadInst>(I) || isa<StoreInst>(I);
116   }
117 };
118 
119 } // end namespace llvm
120 
121 #endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H
122