xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Xtensa/XtensaISelLowering.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1*0fca6ea1SDimitry Andric //===- XtensaISelLowering.h - Xtensa DAG Lowering Interface -----*- C++ -*-===//
2*0fca6ea1SDimitry Andric //
3*0fca6ea1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0fca6ea1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0fca6ea1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0fca6ea1SDimitry Andric //
7*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
8*0fca6ea1SDimitry Andric //
9*0fca6ea1SDimitry Andric // This file defines the interfaces that Xtensa uses to lower LLVM code into a
10*0fca6ea1SDimitry Andric // selection DAG.
11*0fca6ea1SDimitry Andric //
12*0fca6ea1SDimitry Andric //===----------------------------------------------------------------------===//
13*0fca6ea1SDimitry Andric 
14*0fca6ea1SDimitry Andric #ifndef LLVM_LIB_TARGET_XTENSA_XTENSAISELLOWERING_H
15*0fca6ea1SDimitry Andric #define LLVM_LIB_TARGET_XTENSA_XTENSAISELLOWERING_H
16*0fca6ea1SDimitry Andric 
17*0fca6ea1SDimitry Andric #include "llvm/CodeGen/CallingConvLower.h"
18*0fca6ea1SDimitry Andric #include "llvm/CodeGen/SelectionDAG.h"
19*0fca6ea1SDimitry Andric #include "llvm/CodeGen/TargetLowering.h"
20*0fca6ea1SDimitry Andric 
21*0fca6ea1SDimitry Andric namespace llvm {
22*0fca6ea1SDimitry Andric 
23*0fca6ea1SDimitry Andric namespace XtensaISD {
24*0fca6ea1SDimitry Andric enum {
25*0fca6ea1SDimitry Andric   FIRST_NUMBER = ISD::BUILTIN_OP_END,
26*0fca6ea1SDimitry Andric   BR_JT,
27*0fca6ea1SDimitry Andric 
28*0fca6ea1SDimitry Andric   // Calls a function.  Operand 0 is the chain operand and operand 1
29*0fca6ea1SDimitry Andric   // is the target address.  The arguments start at operand 2.
30*0fca6ea1SDimitry Andric   // There is an optional glue operand at the end.
31*0fca6ea1SDimitry Andric   CALL,
32*0fca6ea1SDimitry Andric 
33*0fca6ea1SDimitry Andric   // Wraps a TargetGlobalAddress that should be loaded using PC-relative
34*0fca6ea1SDimitry Andric   // accesses.  Operand 0 is the address.
35*0fca6ea1SDimitry Andric   PCREL_WRAPPER,
36*0fca6ea1SDimitry Andric   RET,
37*0fca6ea1SDimitry Andric 
38*0fca6ea1SDimitry Andric   // Select with condition operator - This selects between a true value and
39*0fca6ea1SDimitry Andric   // a false value (ops #2 and #3) based on the boolean result of comparing
40*0fca6ea1SDimitry Andric   // the lhs and rhs (ops #0 and #1) of a conditional expression with the
41*0fca6ea1SDimitry Andric   // condition code in op #4
42*0fca6ea1SDimitry Andric   SELECT_CC,
43*0fca6ea1SDimitry Andric };
44*0fca6ea1SDimitry Andric }
45*0fca6ea1SDimitry Andric 
46*0fca6ea1SDimitry Andric class XtensaSubtarget;
47*0fca6ea1SDimitry Andric 
48*0fca6ea1SDimitry Andric class XtensaTargetLowering : public TargetLowering {
49*0fca6ea1SDimitry Andric public:
50*0fca6ea1SDimitry Andric   explicit XtensaTargetLowering(const TargetMachine &TM,
51*0fca6ea1SDimitry Andric                                 const XtensaSubtarget &STI);
52*0fca6ea1SDimitry Andric 
getSetCCResultType(const DataLayout &,LLVMContext &,EVT VT)53*0fca6ea1SDimitry Andric   EVT getSetCCResultType(const DataLayout &, LLVMContext &,
54*0fca6ea1SDimitry Andric                          EVT VT) const override {
55*0fca6ea1SDimitry Andric     if (!VT.isVector())
56*0fca6ea1SDimitry Andric       return MVT::i32;
57*0fca6ea1SDimitry Andric     return VT.changeVectorElementTypeToInteger();
58*0fca6ea1SDimitry Andric   }
59*0fca6ea1SDimitry Andric 
60*0fca6ea1SDimitry Andric   bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
61*0fca6ea1SDimitry Andric 
62*0fca6ea1SDimitry Andric   const char *getTargetNodeName(unsigned Opcode) const override;
63*0fca6ea1SDimitry Andric 
64*0fca6ea1SDimitry Andric   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
65*0fca6ea1SDimitry Andric 
66*0fca6ea1SDimitry Andric   SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
67*0fca6ea1SDimitry Andric                                bool isVarArg,
68*0fca6ea1SDimitry Andric                                const SmallVectorImpl<ISD::InputArg> &Ins,
69*0fca6ea1SDimitry Andric                                const SDLoc &DL, SelectionDAG &DAG,
70*0fca6ea1SDimitry Andric                                SmallVectorImpl<SDValue> &InVals) const override;
71*0fca6ea1SDimitry Andric 
72*0fca6ea1SDimitry Andric   SDValue LowerCall(CallLoweringInfo &CLI,
73*0fca6ea1SDimitry Andric                     SmallVectorImpl<SDValue> &InVals) const override;
74*0fca6ea1SDimitry Andric 
75*0fca6ea1SDimitry Andric   bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
76*0fca6ea1SDimitry Andric                       bool isVarArg,
77*0fca6ea1SDimitry Andric                       const SmallVectorImpl<ISD::OutputArg> &Outs,
78*0fca6ea1SDimitry Andric                       LLVMContext &Context) const override;
79*0fca6ea1SDimitry Andric 
80*0fca6ea1SDimitry Andric   SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg,
81*0fca6ea1SDimitry Andric                       const SmallVectorImpl<ISD::OutputArg> &Outs,
82*0fca6ea1SDimitry Andric                       const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL,
83*0fca6ea1SDimitry Andric                       SelectionDAG &DAG) const override;
84*0fca6ea1SDimitry Andric 
getSubtarget()85*0fca6ea1SDimitry Andric   const XtensaSubtarget &getSubtarget() const { return Subtarget; }
86*0fca6ea1SDimitry Andric 
87*0fca6ea1SDimitry Andric   MachineBasicBlock *
88*0fca6ea1SDimitry Andric   EmitInstrWithCustomInserter(MachineInstr &MI,
89*0fca6ea1SDimitry Andric                               MachineBasicBlock *BB) const override;
90*0fca6ea1SDimitry Andric 
91*0fca6ea1SDimitry Andric private:
92*0fca6ea1SDimitry Andric   const XtensaSubtarget &Subtarget;
93*0fca6ea1SDimitry Andric 
94*0fca6ea1SDimitry Andric   SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
95*0fca6ea1SDimitry Andric 
96*0fca6ea1SDimitry Andric   SDValue LowerImmediate(SDValue Op, SelectionDAG &DAG) const;
97*0fca6ea1SDimitry Andric 
98*0fca6ea1SDimitry Andric   SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
99*0fca6ea1SDimitry Andric 
100*0fca6ea1SDimitry Andric   SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
101*0fca6ea1SDimitry Andric 
102*0fca6ea1SDimitry Andric   SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
103*0fca6ea1SDimitry Andric 
104*0fca6ea1SDimitry Andric   SDValue LowerConstantPool(ConstantPoolSDNode *CP, SelectionDAG &DAG) const;
105*0fca6ea1SDimitry Andric 
106*0fca6ea1SDimitry Andric   SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
107*0fca6ea1SDimitry Andric 
108*0fca6ea1SDimitry Andric   SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const;
109*0fca6ea1SDimitry Andric 
110*0fca6ea1SDimitry Andric   SDValue LowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const;
111*0fca6ea1SDimitry Andric 
112*0fca6ea1SDimitry Andric   SDValue LowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const;
113*0fca6ea1SDimitry Andric 
114*0fca6ea1SDimitry Andric   SDValue getAddrPCRel(SDValue Op, SelectionDAG &DAG) const;
115*0fca6ea1SDimitry Andric 
116*0fca6ea1SDimitry Andric   CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const;
117*0fca6ea1SDimitry Andric 
118*0fca6ea1SDimitry Andric   MachineBasicBlock *emitSelectCC(MachineInstr &MI,
119*0fca6ea1SDimitry Andric                                   MachineBasicBlock *BB) const;
120*0fca6ea1SDimitry Andric };
121*0fca6ea1SDimitry Andric 
122*0fca6ea1SDimitry Andric } // end namespace llvm
123*0fca6ea1SDimitry Andric 
124*0fca6ea1SDimitry Andric #endif /* LLVM_LIB_TARGET_XTENSA_XTENSAISELLOWERING_H */
125