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 | |