LoongArchISelLowering.h 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  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. #ifndef LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H
  14. #define LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H
  15. #include "LoongArch.h"
  16. #include "llvm/CodeGen/CallingConvLower.h"
  17. #include "llvm/CodeGen/SelectionDAG.h"
  18. #include "llvm/CodeGen/TargetLowering.h"
  19. namespace llvm {
  20. class LoongArchSubtarget;
  21. struct LoongArchRegisterInfo;
  22. namespace LoongArchISD {
  23. enum NodeType : unsigned {
  24. FIRST_NUMBER = ISD::BUILTIN_OP_END,
  25. // TODO: add more LoongArchISDs
  26. CALL,
  27. RET,
  28. TAIL,
  29. // 32-bit shifts, directly matching the semantics of the named LoongArch
  30. // instructions.
  31. SLL_W,
  32. SRA_W,
  33. SRL_W,
  34. ROTL_W,
  35. ROTR_W,
  36. // FPR<->GPR transfer operations
  37. MOVGR2FR_W_LA64,
  38. MOVFR2GR_S_LA64,
  39. MOVFCSR2GR,
  40. MOVGR2FCSR,
  41. FTINT,
  42. // Bit counting operations
  43. CLZ_W,
  44. CTZ_W,
  45. BSTRINS,
  46. BSTRPICK,
  47. // Byte-swapping and bit-reversal
  48. REVB_2H,
  49. REVB_2W,
  50. BITREV_4B,
  51. BITREV_W,
  52. // Intrinsic operations start ============================================
  53. BREAK,
  54. CACOP_D,
  55. CACOP_W,
  56. DBAR,
  57. IBAR,
  58. SYSCALL,
  59. // CRC check operations
  60. CRC_W_B_W,
  61. CRC_W_H_W,
  62. CRC_W_W_W,
  63. CRC_W_D_W,
  64. CRCC_W_B_W,
  65. CRCC_W_H_W,
  66. CRCC_W_W_W,
  67. CRCC_W_D_W,
  68. CSRRD,
  69. CSRWR,
  70. CSRXCHG,
  71. // IOCSR access operations
  72. IOCSRRD_B,
  73. IOCSRRD_W,
  74. IOCSRRD_H,
  75. IOCSRRD_D,
  76. IOCSRWR_B,
  77. IOCSRWR_H,
  78. IOCSRWR_W,
  79. IOCSRWR_D,
  80. // Read CPU configuration information operation
  81. CPUCFG,
  82. // Intrinsic operations end =============================================
  83. };
  84. } // end namespace LoongArchISD
  85. class LoongArchTargetLowering : public TargetLowering {
  86. const LoongArchSubtarget &Subtarget;
  87. public:
  88. explicit LoongArchTargetLowering(const TargetMachine &TM,
  89. const LoongArchSubtarget &STI);
  90. const LoongArchSubtarget &getSubtarget() const { return Subtarget; }
  91. bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
  92. // Provide custom lowering hooks for some operations.
  93. SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
  94. void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
  95. SelectionDAG &DAG) const override;
  96. SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
  97. // This method returns the name of a target specific DAG node.
  98. const char *getTargetNodeName(unsigned Opcode) const override;
  99. // Lower incoming arguments, copy physregs into vregs.
  100. SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
  101. bool IsVarArg,
  102. const SmallVectorImpl<ISD::InputArg> &Ins,
  103. const SDLoc &DL, SelectionDAG &DAG,
  104. SmallVectorImpl<SDValue> &InVals) const override;
  105. bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
  106. bool IsVarArg,
  107. const SmallVectorImpl<ISD::OutputArg> &Outs,
  108. LLVMContext &Context) const override;
  109. SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
  110. const SmallVectorImpl<ISD::OutputArg> &Outs,
  111. const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
  112. SelectionDAG &DAG) const override;
  113. SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
  114. SmallVectorImpl<SDValue> &InVals) const override;
  115. bool isCheapToSpeculateCttz(Type *Ty) const override;
  116. bool isCheapToSpeculateCtlz(Type *Ty) const override;
  117. bool hasAndNot(SDValue Y) const override;
  118. TargetLowering::AtomicExpansionKind
  119. shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override;
  120. Value *emitMaskedAtomicRMWIntrinsic(IRBuilderBase &Builder, AtomicRMWInst *AI,
  121. Value *AlignedAddr, Value *Incr,
  122. Value *Mask, Value *ShiftAmt,
  123. AtomicOrdering Ord) const override;
  124. EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
  125. EVT VT) const override;
  126. TargetLowering::AtomicExpansionKind
  127. shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *CI) const override;
  128. Value *emitMaskedAtomicCmpXchgIntrinsic(IRBuilderBase &Builder,
  129. AtomicCmpXchgInst *CI,
  130. Value *AlignedAddr, Value *CmpVal,
  131. Value *NewVal, Value *Mask,
  132. AtomicOrdering Ord) const override;
  133. bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I,
  134. MachineFunction &MF,
  135. unsigned Intrinsic) const override;
  136. bool isFMAFasterThanFMulAndFAdd(const MachineFunction &MF,
  137. EVT VT) const override;
  138. Register
  139. getExceptionPointerRegister(const Constant *PersonalityFn) const override;
  140. Register
  141. getExceptionSelectorRegister(const Constant *PersonalityFn) const override;
  142. ISD::NodeType getExtendForAtomicOps() const override {
  143. return ISD::SIGN_EXTEND;
  144. }
  145. Register getRegisterByName(const char *RegName, LLT VT,
  146. const MachineFunction &MF) const override;
  147. bool mayBeEmittedAsTailCall(const CallInst *CI) const override;
  148. bool decomposeMulByConstant(LLVMContext &Context, EVT VT,
  149. SDValue C) const override;
  150. private:
  151. /// Target-specific function used to lower LoongArch calling conventions.
  152. typedef bool LoongArchCCAssignFn(const DataLayout &DL, LoongArchABI::ABI ABI,
  153. unsigned ValNo, MVT ValVT,
  154. CCValAssign::LocInfo LocInfo,
  155. ISD::ArgFlagsTy ArgFlags, CCState &State,
  156. bool IsFixed, bool IsReg, Type *OrigTy);
  157. void analyzeInputArgs(MachineFunction &MF, CCState &CCInfo,
  158. const SmallVectorImpl<ISD::InputArg> &Ins, bool IsRet,
  159. LoongArchCCAssignFn Fn) const;
  160. void analyzeOutputArgs(MachineFunction &MF, CCState &CCInfo,
  161. const SmallVectorImpl<ISD::OutputArg> &Outs,
  162. bool IsRet, CallLoweringInfo *CLI,
  163. LoongArchCCAssignFn Fn) const;
  164. template <class NodeTy>
  165. SDValue getAddr(NodeTy *N, SelectionDAG &DAG, bool IsLocal = true) const;
  166. SDValue getStaticTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
  167. unsigned Opc) const;
  168. SDValue getDynamicTLSAddr(GlobalAddressSDNode *N, SelectionDAG &DAG,
  169. unsigned Opc) const;
  170. SDValue lowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
  171. SDValue lowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
  172. SDValue lowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
  173. SDValue lowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
  174. SDValue lowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const;
  175. SDValue lowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const;
  176. MachineBasicBlock *
  177. EmitInstrWithCustomInserter(MachineInstr &MI,
  178. MachineBasicBlock *BB) const override;
  179. SDValue lowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
  180. SDValue lowerEH_DWARF_CFA(SDValue Op, SelectionDAG &DAG) const;
  181. SDValue lowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) const;
  182. SDValue lowerBITCAST(SDValue Op, SelectionDAG &DAG) const;
  183. SDValue lowerUINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
  184. SDValue lowerSINT_TO_FP(SDValue Op, SelectionDAG &DAG) const;
  185. SDValue lowerVASTART(SDValue Op, SelectionDAG &DAG) const;
  186. SDValue lowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
  187. SDValue lowerINTRINSIC_W_CHAIN(SDValue Op, SelectionDAG &DAG) const;
  188. SDValue lowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const;
  189. SDValue lowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
  190. SDValue lowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
  191. SDValue lowerWRITE_REGISTER(SDValue Op, SelectionDAG &DAG) const;
  192. bool isFPImmLegal(const APFloat &Imm, EVT VT,
  193. bool ForCodeSize) const override;
  194. bool shouldInsertFencesForAtomic(const Instruction *I) const override;
  195. ConstraintType getConstraintType(StringRef Constraint) const override;
  196. unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const override;
  197. std::pair<unsigned, const TargetRegisterClass *>
  198. getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
  199. StringRef Constraint, MVT VT) const override;
  200. void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
  201. std::vector<SDValue> &Ops,
  202. SelectionDAG &DAG) const override;
  203. bool isEligibleForTailCallOptimization(
  204. CCState &CCInfo, CallLoweringInfo &CLI, MachineFunction &MF,
  205. const SmallVectorImpl<CCValAssign> &ArgLocs) const;
  206. };
  207. } // end namespace llvm
  208. #endif // LLVM_LIB_TARGET_LOONGARCH_LOONGARCHISELLOWERING_H