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