xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/BPF/BPFISelLowering.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===-- BPFISelLowering.h - BPF DAG Lowering Interface ----------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines the interfaces that BPF uses to lower LLVM code into a
100b57cec5SDimitry Andric // selection DAG.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_BPF_BPFISELLOWERING_H
150b57cec5SDimitry Andric #define LLVM_LIB_TARGET_BPF_BPFISELLOWERING_H
160b57cec5SDimitry Andric 
170b57cec5SDimitry Andric #include "BPF.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/SelectionDAG.h"
190b57cec5SDimitry Andric #include "llvm/CodeGen/TargetLowering.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric namespace llvm {
220b57cec5SDimitry Andric class BPFSubtarget;
230b57cec5SDimitry Andric namespace BPFISD {
240b57cec5SDimitry Andric enum NodeType : unsigned {
250b57cec5SDimitry Andric   FIRST_NUMBER = ISD::BUILTIN_OP_END,
2606c3fb27SDimitry Andric   RET_GLUE,
270b57cec5SDimitry Andric   CALL,
280b57cec5SDimitry Andric   SELECT_CC,
290b57cec5SDimitry Andric   BR_CC,
300b57cec5SDimitry Andric   Wrapper,
310b57cec5SDimitry Andric   MEMCPY
320b57cec5SDimitry Andric };
330b57cec5SDimitry Andric }
340b57cec5SDimitry Andric 
350b57cec5SDimitry Andric class BPFTargetLowering : public TargetLowering {
360b57cec5SDimitry Andric public:
370b57cec5SDimitry Andric   explicit BPFTargetLowering(const TargetMachine &TM, const BPFSubtarget &STI);
380b57cec5SDimitry Andric 
390b57cec5SDimitry Andric   // Provide custom lowering hooks for some operations.
400b57cec5SDimitry Andric   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric   // This method returns the name of a target specific DAG node.
430b57cec5SDimitry Andric   const char *getTargetNodeName(unsigned Opcode) const override;
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric   // This method decides whether folding a constant offset
460b57cec5SDimitry Andric   // with the given GlobalAddress is legal.
470b57cec5SDimitry Andric   bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
480b57cec5SDimitry Andric 
49fe6060f1SDimitry Andric   BPFTargetLowering::ConstraintType
50fe6060f1SDimitry Andric   getConstraintType(StringRef Constraint) const override;
51fe6060f1SDimitry Andric 
520b57cec5SDimitry Andric   std::pair<unsigned, const TargetRegisterClass *>
530b57cec5SDimitry Andric   getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
540b57cec5SDimitry Andric                                StringRef Constraint, MVT VT) const override;
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric   MachineBasicBlock *
570b57cec5SDimitry Andric   EmitInstrWithCustomInserter(MachineInstr &MI,
580b57cec5SDimitry Andric                               MachineBasicBlock *BB) const override;
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric   bool getHasAlu32() const { return HasAlu32; }
610b57cec5SDimitry Andric   bool getHasJmp32() const { return HasJmp32; }
620b57cec5SDimitry Andric   bool getHasJmpExt() const { return HasJmpExt; }
630b57cec5SDimitry Andric 
640b57cec5SDimitry Andric   EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
650b57cec5SDimitry Andric                          EVT VT) const override;
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric   MVT getScalarShiftAmountTy(const DataLayout &, EVT) const override;
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric private:
700b57cec5SDimitry Andric   // Control Instruction Selection Features
710b57cec5SDimitry Andric   bool HasAlu32;
720b57cec5SDimitry Andric   bool HasJmp32;
730b57cec5SDimitry Andric   bool HasJmpExt;
745f757f3fSDimitry Andric   bool HasMovsx;
750b57cec5SDimitry Andric 
765f757f3fSDimitry Andric   SDValue LowerSDIVSREM(SDValue Op, SelectionDAG &DAG) const;
775f757f3fSDimitry Andric   SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
780b57cec5SDimitry Andric   SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
790b57cec5SDimitry Andric   SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
80*0fca6ea1SDimitry Andric 
81*0fca6ea1SDimitry Andric   SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
820b57cec5SDimitry Andric   SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
830b57cec5SDimitry Andric 
84*0fca6ea1SDimitry Andric   template <class NodeTy>
85*0fca6ea1SDimitry Andric   SDValue getAddr(NodeTy *N, SelectionDAG &DAG, unsigned Flags = 0) const;
86*0fca6ea1SDimitry Andric 
870b57cec5SDimitry Andric   // Lower the result values of a call, copying them out of physregs into vregs
8806c3fb27SDimitry Andric   SDValue LowerCallResult(SDValue Chain, SDValue InGlue,
890b57cec5SDimitry Andric                           CallingConv::ID CallConv, bool IsVarArg,
900b57cec5SDimitry Andric                           const SmallVectorImpl<ISD::InputArg> &Ins,
910b57cec5SDimitry Andric                           const SDLoc &DL, SelectionDAG &DAG,
920b57cec5SDimitry Andric                           SmallVectorImpl<SDValue> &InVals) const;
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric   // Maximum number of arguments to a call
955f757f3fSDimitry Andric   static const size_t MaxArgs;
960b57cec5SDimitry Andric 
970b57cec5SDimitry Andric   // Lower a call into CALLSEQ_START - BPFISD:CALL - CALLSEQ_END chain
980b57cec5SDimitry Andric   SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
990b57cec5SDimitry Andric                     SmallVectorImpl<SDValue> &InVals) const override;
1000b57cec5SDimitry Andric 
1010b57cec5SDimitry Andric   // Lower incoming arguments, copy physregs into vregs
1020b57cec5SDimitry Andric   SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
1030b57cec5SDimitry Andric                                bool IsVarArg,
1040b57cec5SDimitry Andric                                const SmallVectorImpl<ISD::InputArg> &Ins,
1050b57cec5SDimitry Andric                                const SDLoc &DL, SelectionDAG &DAG,
1060b57cec5SDimitry Andric                                SmallVectorImpl<SDValue> &InVals) const override;
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric   SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
1090b57cec5SDimitry Andric                       const SmallVectorImpl<ISD::OutputArg> &Outs,
1100b57cec5SDimitry Andric                       const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
1110b57cec5SDimitry Andric                       SelectionDAG &DAG) const override;
1120b57cec5SDimitry Andric 
113fe6060f1SDimitry Andric   void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
114fe6060f1SDimitry Andric                           SelectionDAG &DAG) const override;
115fe6060f1SDimitry Andric 
1165ffd83dbSDimitry Andric   EVT getOptimalMemOpType(const MemOp &Op,
1170b57cec5SDimitry Andric                           const AttributeList &FuncAttributes) const override {
1185ffd83dbSDimitry Andric     return Op.size() >= 8 ? MVT::i64 : MVT::i32;
1190b57cec5SDimitry Andric   }
1200b57cec5SDimitry Andric 
121fe6060f1SDimitry Andric   bool isIntDivCheap(EVT VT, AttributeList Attr) const override { return true; }
122fe6060f1SDimitry Andric 
1230b57cec5SDimitry Andric   bool shouldConvertConstantLoadToIntImm(const APInt &Imm,
1240b57cec5SDimitry Andric                                          Type *Ty) const override {
1250b57cec5SDimitry Andric     return true;
1260b57cec5SDimitry Andric   }
1270b57cec5SDimitry Andric 
12813138422SDimitry Andric   // Prevent reducing load width during SelectionDag phase.
12913138422SDimitry Andric   // Otherwise, we may transform the following
13013138422SDimitry Andric   //   ctx = ctx + reloc_offset
13113138422SDimitry Andric   //   ... (*(u32 *)ctx) & 0x8000...
13213138422SDimitry Andric   // to
13313138422SDimitry Andric   //   ctx = ctx + reloc_offset
13413138422SDimitry Andric   //   ... (*(u8 *)(ctx + 1)) & 0x80 ...
13513138422SDimitry Andric   // which will be rejected by the verifier.
13613138422SDimitry Andric   bool shouldReduceLoadWidth(SDNode *Load, ISD::LoadExtType ExtTy,
13713138422SDimitry Andric                              EVT NewVT) const override {
13813138422SDimitry Andric     return false;
13913138422SDimitry Andric   }
14013138422SDimitry Andric 
141349cc55cSDimitry Andric   bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
142349cc55cSDimitry Andric                              Type *Ty, unsigned AS,
143349cc55cSDimitry Andric                              Instruction *I = nullptr) const override;
144349cc55cSDimitry Andric 
1455ffd83dbSDimitry Andric   // isTruncateFree - Return true if it's free to truncate a value of
1465ffd83dbSDimitry Andric   // type Ty1 to type Ty2. e.g. On BPF at alu32 mode, it's free to truncate
1475ffd83dbSDimitry Andric   // a i64 value in register R1 to i32 by referencing its sub-register W1.
1485ffd83dbSDimitry Andric   bool isTruncateFree(Type *Ty1, Type *Ty2) const override;
1495ffd83dbSDimitry Andric   bool isTruncateFree(EVT VT1, EVT VT2) const override;
1505ffd83dbSDimitry Andric 
1515ffd83dbSDimitry Andric   // For 32bit ALU result zext to 64bit is free.
1525ffd83dbSDimitry Andric   bool isZExtFree(Type *Ty1, Type *Ty2) const override;
1535ffd83dbSDimitry Andric   bool isZExtFree(EVT VT1, EVT VT2) const override;
1545f757f3fSDimitry Andric   bool isZExtFree(SDValue Val, EVT VT2) const override;
1555ffd83dbSDimitry Andric 
1560b57cec5SDimitry Andric   unsigned EmitSubregExt(MachineInstr &MI, MachineBasicBlock *BB, unsigned Reg,
1570b57cec5SDimitry Andric                          bool isSigned) const;
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric   MachineBasicBlock * EmitInstrWithCustomInserterMemcpy(MachineInstr &MI,
1600b57cec5SDimitry Andric                                                         MachineBasicBlock *BB)
1610b57cec5SDimitry Andric                                                         const;
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric };
1640b57cec5SDimitry Andric }
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric #endif
167