1//===-- XCoreISelLowering.h - XCore 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 XCore uses to lower LLVM code into a
10// selection DAG.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_LIB_TARGET_XCORE_XCOREISELLOWERING_H
15#define LLVM_LIB_TARGET_XCORE_XCOREISELLOWERING_H
16
17#include "XCore.h"
18#include "llvm/CodeGen/SelectionDAG.h"
19#include "llvm/CodeGen/TargetLowering.h"
20
21namespace llvm {
22
23  // Forward delcarations
24  class XCoreSubtarget;
25  class XCoreTargetMachine;
26
27  namespace XCoreISD {
28    enum NodeType : unsigned {
29      // Start the numbering where the builtin ops and target ops leave off.
30      FIRST_NUMBER = ISD::BUILTIN_OP_END,
31
32      // Branch and link (call)
33      BL,
34
35      // pc relative address
36      PCRelativeWrapper,
37
38      // dp relative address
39      DPRelativeWrapper,
40
41      // cp relative address
42      CPRelativeWrapper,
43
44      // Load word from stack
45      LDWSP,
46
47      // Store word to stack
48      STWSP,
49
50      // Corresponds to retsp instruction
51      RETSP,
52
53      // Corresponds to LADD instruction
54      LADD,
55
56      // Corresponds to LSUB instruction
57      LSUB,
58
59      // Corresponds to LMUL instruction
60      LMUL,
61
62      // Corresponds to MACCU instruction
63      MACCU,
64
65      // Corresponds to MACCS instruction
66      MACCS,
67
68      // Corresponds to CRC8 instruction
69      CRC8,
70
71      // Jumptable branch.
72      BR_JT,
73
74      // Jumptable branch using long branches for each entry.
75      BR_JT32,
76
77      // Offset from frame pointer to the first (possible) on-stack argument
78      FRAME_TO_ARGS_OFFSET,
79
80      // Exception handler return. The stack is restored to the first
81      // followed by a jump to the second argument.
82      EH_RETURN,
83
84      // Memory barrier.
85      MEMBARRIER
86    };
87  }
88
89  //===--------------------------------------------------------------------===//
90  // TargetLowering Implementation
91  //===--------------------------------------------------------------------===//
92  class XCoreTargetLowering : public TargetLowering
93  {
94  public:
95    explicit XCoreTargetLowering(const TargetMachine &TM,
96                                 const XCoreSubtarget &Subtarget);
97
98    using TargetLowering::isZExtFree;
99    bool isZExtFree(SDValue Val, EVT VT2) const override;
100
101
102    unsigned getJumpTableEncoding() const override;
103    MVT getScalarShiftAmountTy(const DataLayout &DL, EVT) const override {
104      return MVT::i32;
105    }
106
107    /// LowerOperation - Provide custom lowering hooks for some operations.
108    SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
109
110    /// ReplaceNodeResults - Replace the results of node with an illegal result
111    /// type with new values built out of custom code.
112    ///
113    void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results,
114                            SelectionDAG &DAG) const override;
115
116    /// getTargetNodeName - This method returns the name of a target specific
117    //  DAG node.
118    const char *getTargetNodeName(unsigned Opcode) const override;
119
120    MachineBasicBlock *
121    EmitInstrWithCustomInserter(MachineInstr &MI,
122                                MachineBasicBlock *MBB) const override;
123
124    bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM,
125                               Type *Ty, unsigned AS,
126                               Instruction *I = nullptr) const override;
127
128    /// If a physical register, this returns the register that receives the
129    /// exception address on entry to an EH pad.
130    unsigned
131    getExceptionPointerRegister(const Constant *PersonalityFn) const override {
132      return XCore::R0;
133    }
134
135    /// If a physical register, this returns the register that receives the
136    /// exception typeid on entry to a landing pad.
137    unsigned
138    getExceptionSelectorRegister(const Constant *PersonalityFn) const override {
139      return XCore::R1;
140    }
141
142  private:
143    const TargetMachine &TM;
144    const XCoreSubtarget &Subtarget;
145
146    // Lower Operand helpers
147    SDValue LowerCCCArguments(SDValue Chain, CallingConv::ID CallConv,
148                              bool isVarArg,
149                              const SmallVectorImpl<ISD::InputArg> &Ins,
150                              const SDLoc &dl, SelectionDAG &DAG,
151                              SmallVectorImpl<SDValue> &InVals) const;
152    SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee,
153                           CallingConv::ID CallConv, bool isVarArg,
154                           bool isTailCall,
155                           const SmallVectorImpl<ISD::OutputArg> &Outs,
156                           const SmallVectorImpl<SDValue> &OutVals,
157                           const SmallVectorImpl<ISD::InputArg> &Ins,
158                           const SDLoc &dl, SelectionDAG &DAG,
159                           SmallVectorImpl<SDValue> &InVals) const;
160    SDValue getReturnAddressFrameIndex(SelectionDAG &DAG) const;
161    SDValue getGlobalAddressWrapper(SDValue GA, const GlobalValue *GV,
162                                    SelectionDAG &DAG) const;
163    SDValue lowerLoadWordFromAlignedBasePlusOffset(const SDLoc &DL,
164                                                   SDValue Chain, SDValue Base,
165                                                   int64_t Offset,
166                                                   SelectionDAG &DAG) const;
167
168    // Lower Operand specifics
169    SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const;
170    SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const;
171    SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const;
172    SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
173    SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
174    SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
175    SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
176    SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const;
177    SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) const;
178    SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
179    SDValue LowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
180    SDValue LowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const;
181    SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
182    SDValue LowerFRAME_TO_ARGS_OFFSET(SDValue Op, SelectionDAG &DAG) const;
183    SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const;
184    SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
185    SDValue LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const;
186    SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const;
187    SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const;
188    SDValue LowerATOMIC_LOAD(SDValue Op, SelectionDAG &DAG) const;
189    SDValue LowerATOMIC_STORE(SDValue Op, SelectionDAG &DAG) const;
190
191    MachineMemOperand::Flags getMMOFlags(const Instruction &I) const override;
192
193    // Inline asm support
194    std::pair<unsigned, const TargetRegisterClass *>
195    getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
196                                 StringRef Constraint, MVT VT) const override;
197
198    // Expand specifics
199    SDValue TryExpandADDWithMul(SDNode *Op, SelectionDAG &DAG) const;
200    SDValue ExpandADDSUB(SDNode *Op, SelectionDAG &DAG) const;
201
202    SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override;
203
204    void computeKnownBitsForTargetNode(const SDValue Op,
205                                       KnownBits &Known,
206                                       const APInt &DemandedElts,
207                                       const SelectionDAG &DAG,
208                                       unsigned Depth = 0) const override;
209
210    SDValue
211    LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
212                         const SmallVectorImpl<ISD::InputArg> &Ins,
213                         const SDLoc &dl, SelectionDAG &DAG,
214                         SmallVectorImpl<SDValue> &InVals) const override;
215
216    SDValue
217      LowerCall(TargetLowering::CallLoweringInfo &CLI,
218                SmallVectorImpl<SDValue> &InVals) const override;
219
220    SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
221                        const SmallVectorImpl<ISD::OutputArg> &Outs,
222                        const SmallVectorImpl<SDValue> &OutVals,
223                        const SDLoc &dl, SelectionDAG &DAG) const override;
224
225    bool
226      CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
227                     bool isVarArg,
228                     const SmallVectorImpl<ISD::OutputArg> &ArgsFlags,
229                     LLVMContext &Context) const override;
230    bool shouldInsertFencesForAtomic(const Instruction *I) const override {
231      return true;
232    }
233  };
234}
235
236#endif
237