1 //===- XtensaISelLowering.h - Xtensa 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 Xtensa uses to lower LLVM code into a 10 // selection DAG. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_LIB_TARGET_XTENSA_XTENSAISELLOWERING_H 15 #define LLVM_LIB_TARGET_XTENSA_XTENSAISELLOWERING_H 16 17 #include "llvm/CodeGen/CallingConvLower.h" 18 #include "llvm/CodeGen/SelectionDAG.h" 19 #include "llvm/CodeGen/TargetLowering.h" 20 21 namespace llvm { 22 23 namespace XtensaISD { 24 enum { 25 FIRST_NUMBER = ISD::BUILTIN_OP_END, 26 BR_JT, 27 28 // Calls a function. Operand 0 is the chain operand and operand 1 29 // is the target address. The arguments start at operand 2. 30 // There is an optional glue operand at the end. 31 CALL, 32 33 // Extract unsigned immediate. Operand 0 is value, operand 1 34 // is bit position of the field [0..31], operand 2 is bit size 35 // of the field [1..16] 36 EXTUI, 37 38 // Wraps a TargetGlobalAddress that should be loaded using PC-relative 39 // accesses. Operand 0 is the address. 40 PCREL_WRAPPER, 41 RET, 42 43 // Select with condition operator - This selects between a true value and 44 // a false value (ops #2 and #3) based on the boolean result of comparing 45 // the lhs and rhs (ops #0 and #1) of a conditional expression with the 46 // condition code in op #4 47 SELECT_CC, 48 49 // SRCL(R) performs shift left(right) of the concatenation of 2 registers 50 // and returns high(low) 32-bit part of 64-bit result 51 SRCL, 52 // Shift Right Combined 53 SRCR, 54 }; 55 } 56 57 class XtensaSubtarget; 58 59 class XtensaTargetLowering : public TargetLowering { 60 public: 61 explicit XtensaTargetLowering(const TargetMachine &TM, 62 const XtensaSubtarget &STI); 63 64 MVT getScalarShiftAmountTy(const DataLayout &, EVT LHSTy) const override { 65 return LHSTy.getSizeInBits() <= 32 ? MVT::i32 : MVT::i64; 66 } 67 68 EVT getSetCCResultType(const DataLayout &, LLVMContext &, 69 EVT VT) const override { 70 if (!VT.isVector()) 71 return MVT::i32; 72 return VT.changeVectorElementTypeToInteger(); 73 } 74 75 bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; 76 77 const char *getTargetNodeName(unsigned Opcode) const override; 78 79 std::pair<unsigned, const TargetRegisterClass *> 80 getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, 81 StringRef Constraint, MVT VT) const override; 82 83 TargetLowering::ConstraintType 84 getConstraintType(StringRef Constraint) const override; 85 86 TargetLowering::ConstraintWeight 87 getSingleConstraintMatchWeight(AsmOperandInfo &Info, 88 const char *Constraint) const override; 89 90 void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, 91 std::vector<SDValue> &Ops, 92 SelectionDAG &DAG) const override; 93 94 SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; 95 96 SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, 97 bool isVarArg, 98 const SmallVectorImpl<ISD::InputArg> &Ins, 99 const SDLoc &DL, SelectionDAG &DAG, 100 SmallVectorImpl<SDValue> &InVals) const override; 101 102 SDValue LowerCall(CallLoweringInfo &CLI, 103 SmallVectorImpl<SDValue> &InVals) const override; 104 105 bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, 106 bool isVarArg, 107 const SmallVectorImpl<ISD::OutputArg> &Outs, 108 LLVMContext &Context, const Type *RetTy) const override; 109 110 SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool IsVarArg, 111 const SmallVectorImpl<ISD::OutputArg> &Outs, 112 const SmallVectorImpl<SDValue> &OutVals, const SDLoc &DL, 113 SelectionDAG &DAG) const override; 114 115 bool decomposeMulByConstant(LLVMContext &Context, EVT VT, 116 SDValue C) const override; 117 118 const XtensaSubtarget &getSubtarget() const { return Subtarget; } 119 120 MachineBasicBlock * 121 EmitInstrWithCustomInserter(MachineInstr &MI, 122 MachineBasicBlock *BB) const override; 123 124 private: 125 const XtensaSubtarget &Subtarget; 126 127 SDValue LowerBR_JT(SDValue Op, SelectionDAG &DAG) const; 128 129 SDValue LowerImmediate(SDValue Op, SelectionDAG &DAG) const; 130 131 SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; 132 133 SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; 134 135 SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; 136 137 SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; 138 139 SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) const; 140 141 SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; 142 143 SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; 144 145 SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; 146 147 SDValue LowerSTACKSAVE(SDValue Op, SelectionDAG &DAG) const; 148 149 SDValue LowerSTACKRESTORE(SDValue Op, SelectionDAG &DAG) const; 150 151 SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; 152 153 SDValue LowerVAARG(SDValue Op, SelectionDAG &DAG) const; 154 155 SDValue LowerVACOPY(SDValue Op, SelectionDAG &DAG) const; 156 157 SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; 158 159 SDValue LowerShiftLeftParts(SDValue Op, SelectionDAG &DAG) const; 160 161 SDValue LowerShiftRightParts(SDValue Op, SelectionDAG &DAG, bool IsSRA) const; 162 163 SDValue getAddrPCRel(SDValue Op, SelectionDAG &DAG) const; 164 165 CCAssignFn *CCAssignFnForCall(CallingConv::ID CC, bool IsVarArg) const; 166 167 MachineBasicBlock *emitSelectCC(MachineInstr &MI, 168 MachineBasicBlock *BB) const; 169 }; 170 171 } // end namespace llvm 172 173 #endif /* LLVM_LIB_TARGET_XTENSA_XTENSAISELLOWERING_H */ 174