| 1 | //===-- AVRISelLowering.h - AVR 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 AVR uses to lower LLVM code into a |
| 10 | // selection DAG. |
| 11 | // |
| 12 | //===----------------------------------------------------------------------===// |
| 13 | |
| 14 | #ifndef LLVM_AVR_ISEL_LOWERING_H |
| 15 | #define LLVM_AVR_ISEL_LOWERING_H |
| 16 | |
| 17 | #include "llvm/CodeGen/CallingConvLower.h" |
| 18 | #include "llvm/CodeGen/TargetLowering.h" |
| 19 | |
| 20 | namespace llvm { |
| 21 | |
| 22 | class AVRSubtarget; |
| 23 | class AVRTargetMachine; |
| 24 | |
| 25 | /// Performs target lowering for the AVR. |
| 26 | class AVRTargetLowering : public TargetLowering { |
| 27 | public: |
| 28 | explicit AVRTargetLowering(const AVRTargetMachine &TM, |
| 29 | const AVRSubtarget &STI); |
| 30 | |
| 31 | public: |
| 32 | MVT getScalarShiftAmountTy(const DataLayout &, EVT LHSTy) const override { |
| 33 | return MVT::i8; |
| 34 | } |
| 35 | |
| 36 | MVT::SimpleValueType getCmpLibcallReturnType() const override { |
| 37 | return MVT::i8; |
| 38 | } |
| 39 | |
| 40 | SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; |
| 41 | |
| 42 | void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results, |
| 43 | SelectionDAG &DAG) const override; |
| 44 | |
| 45 | bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty, |
| 46 | unsigned AS, |
| 47 | Instruction *I = nullptr) const override; |
| 48 | |
| 49 | bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset, |
| 50 | ISD::MemIndexedMode &AM, |
| 51 | SelectionDAG &DAG) const override; |
| 52 | |
| 53 | bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, SDValue &Base, |
| 54 | SDValue &Offset, ISD::MemIndexedMode &AM, |
| 55 | SelectionDAG &DAG) const override; |
| 56 | |
| 57 | bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; |
| 58 | |
| 59 | EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context, |
| 60 | EVT VT) const override; |
| 61 | |
| 62 | MachineBasicBlock * |
| 63 | EmitInstrWithCustomInserter(MachineInstr &MI, |
| 64 | MachineBasicBlock *MBB) const override; |
| 65 | |
| 66 | ConstraintType getConstraintType(StringRef Constraint) const override; |
| 67 | |
| 68 | ConstraintWeight |
| 69 | getSingleConstraintMatchWeight(AsmOperandInfo &info, |
| 70 | const char *constraint) const override; |
| 71 | |
| 72 | std::pair<unsigned, const TargetRegisterClass *> |
| 73 | getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, |
| 74 | StringRef Constraint, MVT VT) const override; |
| 75 | |
| 76 | InlineAsm::ConstraintCode |
| 77 | getInlineAsmMemConstraint(StringRef ConstraintCode) const override; |
| 78 | |
| 79 | void LowerAsmOperandForConstraint(SDValue Op, StringRef Constraint, |
| 80 | std::vector<SDValue> &Ops, |
| 81 | SelectionDAG &DAG) const override; |
| 82 | |
| 83 | Register getRegisterByName(const char *RegName, LLT VT, |
| 84 | const MachineFunction &MF) const override; |
| 85 | |
| 86 | bool shouldSplitFunctionArgumentsAsLittleEndian( |
| 87 | const DataLayout &DL) const override { |
| 88 | return false; |
| 89 | } |
| 90 | |
| 91 | ShiftLegalizationStrategy |
| 92 | preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N, |
| 93 | unsigned ExpansionFactor) const override { |
| 94 | return ShiftLegalizationStrategy::LowerToLibcall; |
| 95 | } |
| 96 | |
| 97 | private: |
| 98 | SDValue getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue &AVRcc, |
| 99 | SelectionDAG &DAG, SDLoc dl) const; |
| 100 | SDValue getAVRCmp(SDValue LHS, SDValue RHS, SelectionDAG &DAG, |
| 101 | SDLoc dl) const; |
| 102 | SDValue LowerShifts(SDValue Op, SelectionDAG &DAG) const; |
| 103 | SDValue LowerDivRem(SDValue Op, SelectionDAG &DAG) const; |
| 104 | SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const; |
| 105 | SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; |
| 106 | SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const; |
| 107 | SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const; |
| 108 | SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const; |
| 109 | SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; |
| 110 | SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; |
| 111 | |
| 112 | bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF, |
| 113 | bool isVarArg, |
| 114 | const SmallVectorImpl<ISD::OutputArg> &Outs, |
| 115 | LLVMContext &Context, const Type *RetTy) const override; |
| 116 | |
| 117 | SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, |
| 118 | const SmallVectorImpl<ISD::OutputArg> &Outs, |
| 119 | const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl, |
| 120 | SelectionDAG &DAG) const override; |
| 121 | SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, |
| 122 | bool isVarArg, |
| 123 | const SmallVectorImpl<ISD::InputArg> &Ins, |
| 124 | const SDLoc &dl, SelectionDAG &DAG, |
| 125 | SmallVectorImpl<SDValue> &InVals) const override; |
| 126 | SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, |
| 127 | SmallVectorImpl<SDValue> &InVals) const override; |
| 128 | SDValue LowerCallResult(SDValue Chain, SDValue InGlue, |
| 129 | CallingConv::ID CallConv, bool isVarArg, |
| 130 | const SmallVectorImpl<ISD::InputArg> &Ins, |
| 131 | const SDLoc &dl, SelectionDAG &DAG, |
| 132 | SmallVectorImpl<SDValue> &InVals) const; |
| 133 | |
| 134 | protected: |
| 135 | const AVRSubtarget &Subtarget; |
| 136 | |
| 137 | private: |
| 138 | MachineBasicBlock *insertShift(MachineInstr &MI, MachineBasicBlock *BB, |
| 139 | bool Tiny) const; |
| 140 | MachineBasicBlock *insertWideShift(MachineInstr &MI, |
| 141 | MachineBasicBlock *BB) const; |
| 142 | MachineBasicBlock *insertMul(MachineInstr &MI, MachineBasicBlock *BB) const; |
| 143 | MachineBasicBlock *insertCopyZero(MachineInstr &MI, |
| 144 | MachineBasicBlock *BB) const; |
| 145 | MachineBasicBlock *insertAtomicArithmeticOp(MachineInstr &MI, |
| 146 | MachineBasicBlock *BB, |
| 147 | unsigned Opcode, int Width) const; |
| 148 | }; |
| 149 | |
| 150 | } // end namespace llvm |
| 151 | |
| 152 | #endif // LLVM_AVR_ISEL_LOWERING_H |
| 153 | |