| 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 | |
| 21 | namespace llvm { |
| 22 | |
| 23 | // Forward delcarations |
| 24 | class XCoreSubtarget; |
| 25 | |
| 26 | //===--------------------------------------------------------------------===// |
| 27 | // TargetLowering Implementation |
| 28 | //===--------------------------------------------------------------------===// |
| 29 | class XCoreTargetLowering : public TargetLowering |
| 30 | { |
| 31 | public: |
| 32 | explicit XCoreTargetLowering(const TargetMachine &TM, |
| 33 | const XCoreSubtarget &Subtarget); |
| 34 | |
| 35 | using TargetLowering::isZExtFree; |
| 36 | bool isZExtFree(SDValue Val, EVT VT2) const override; |
| 37 | |
| 38 | |
| 39 | unsigned getJumpTableEncoding() const override; |
| 40 | MVT getScalarShiftAmountTy(const DataLayout &DL, EVT) const override { |
| 41 | return MVT::i32; |
| 42 | } |
| 43 | |
| 44 | /// LowerOperation - Provide custom lowering hooks for some operations. |
| 45 | SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; |
| 46 | |
| 47 | /// ReplaceNodeResults - Replace the results of node with an illegal result |
| 48 | /// type with new values built out of custom code. |
| 49 | /// |
| 50 | void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue>&Results, |
| 51 | SelectionDAG &DAG) const override; |
| 52 | |
| 53 | MachineBasicBlock * |
| 54 | EmitInstrWithCustomInserter(MachineInstr &MI, |
| 55 | MachineBasicBlock *MBB) const override; |
| 56 | |
| 57 | bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, |
| 58 | Type *Ty, unsigned AS, |
| 59 | Instruction *I = nullptr) const override; |
| 60 | |
| 61 | /// If a physical register, this returns the register that receives the |
| 62 | /// exception address on entry to an EH pad. |
| 63 | Register |
| 64 | getExceptionPointerRegister(const Constant *PersonalityFn) const override { |
| 65 | return XCore::R0; |
| 66 | } |
| 67 | |
| 68 | /// If a physical register, this returns the register that receives the |
| 69 | /// exception typeid on entry to a landing pad. |
| 70 | Register |
| 71 | getExceptionSelectorRegister(const Constant *PersonalityFn) const override { |
| 72 | return XCore::R1; |
| 73 | } |
| 74 | |
| 75 | private: |
| 76 | const TargetMachine &TM; |
| 77 | const XCoreSubtarget &Subtarget; |
| 78 | |
| 79 | // Lower Operand helpers |
| 80 | SDValue LowerCCCArguments(SDValue Chain, CallingConv::ID CallConv, |
| 81 | bool isVarArg, |
| 82 | const SmallVectorImpl<ISD::InputArg> &Ins, |
| 83 | const SDLoc &dl, SelectionDAG &DAG, |
| 84 | SmallVectorImpl<SDValue> &InVals) const; |
| 85 | SDValue LowerCCCCallTo(SDValue Chain, SDValue Callee, |
| 86 | CallingConv::ID CallConv, bool isVarArg, |
| 87 | bool isTailCall, |
| 88 | const SmallVectorImpl<ISD::OutputArg> &Outs, |
| 89 | const SmallVectorImpl<SDValue> &OutVals, |
| 90 | const SmallVectorImpl<ISD::InputArg> &Ins, |
| 91 | const SDLoc &dl, SelectionDAG &DAG, |
| 92 | SmallVectorImpl<SDValue> &InVals) const; |
| 93 | SDValue getReturnAddressFrameIndex(SelectionDAG &DAG) const; |
| 94 | SDValue getGlobalAddressWrapper(SDValue GA, const GlobalValue *GV, |
| 95 | SelectionDAG &DAG) const; |
| 96 | SDValue lowerLoadWordFromAlignedBasePlusOffset(const SDLoc &DL, |
| 97 | SDValue Chain, SDValue Base, |
| 98 | int64_t Offset, |
| 99 | SelectionDAG &DAG) const; |
| 100 | |
| 101 | // Lower Operand specifics |
| 102 | SDValue LowerLOAD(SDValue Op, SelectionDAG &DAG) const; |
| 103 | SDValue LowerSTORE(SDValue Op, SelectionDAG &DAG) const; |
| 104 | SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const; |
| 105 | SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; |
| 106 | SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; |
| 107 | SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; |
| 108 | SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; |
| 109 | SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const; |
| 110 | SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) const; |
| 111 | SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; |
| 112 | SDValue LowerUMUL_LOHI(SDValue Op, SelectionDAG &DAG) const; |
| 113 | SDValue LowerSMUL_LOHI(SDValue Op, SelectionDAG &DAG) const; |
| 114 | SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; |
| 115 | SDValue LowerFRAME_TO_ARGS_OFFSET(SDValue Op, SelectionDAG &DAG) const; |
| 116 | SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; |
| 117 | SDValue LowerINIT_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; |
| 118 | SDValue LowerADJUST_TRAMPOLINE(SDValue Op, SelectionDAG &DAG) const; |
| 119 | SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; |
| 120 | SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG &DAG) const; |
| 121 | |
| 122 | // Inline asm support |
| 123 | std::pair<unsigned, const TargetRegisterClass *> |
| 124 | getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, |
| 125 | StringRef Constraint, MVT VT) const override; |
| 126 | |
| 127 | // Expand specifics |
| 128 | SDValue TryExpandADDWithMul(SDNode *Op, SelectionDAG &DAG) const; |
| 129 | SDValue ExpandADDSUB(SDNode *Op, SelectionDAG &DAG) const; |
| 130 | |
| 131 | SDValue PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const override; |
| 132 | |
| 133 | void computeKnownBitsForTargetNode(const SDValue Op, |
| 134 | KnownBits &Known, |
| 135 | const APInt &DemandedElts, |
| 136 | const SelectionDAG &DAG, |
| 137 | unsigned Depth = 0) const override; |
| 138 | |
| 139 | SDValue |
| 140 | LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, |
| 141 | const SmallVectorImpl<ISD::InputArg> &Ins, |
| 142 | const SDLoc &dl, SelectionDAG &DAG, |
| 143 | SmallVectorImpl<SDValue> &InVals) const override; |
| 144 | |
| 145 | SDValue |
| 146 | LowerCall(TargetLowering::CallLoweringInfo &CLI, |
| 147 | SmallVectorImpl<SDValue> &InVals) const override; |
| 148 | |
| 149 | SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, |
| 150 | const SmallVectorImpl<ISD::OutputArg> &Outs, |
| 151 | const SmallVectorImpl<SDValue> &OutVals, |
| 152 | const SDLoc &dl, SelectionDAG &DAG) const override; |
| 153 | |
| 154 | bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, |
| 155 | bool isVarArg, |
| 156 | const SmallVectorImpl<ISD::OutputArg> &ArgsFlags, |
| 157 | LLVMContext &Context, const Type *RetTy) const override; |
| 158 | }; |
| 159 | } |
| 160 | |
| 161 | #endif |
| 162 | |