xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AVR/AVRISelLowering.h (revision 9f23cbd6cae82fd77edfad7173432fa8dccd0a95)
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 namespace AVRISD {
23 
24 /// AVR Specific DAG Nodes
25 enum NodeType {
26   /// Start the numbering where the builtin ops leave off.
27   FIRST_NUMBER = ISD::BUILTIN_OP_END,
28   /// Return from subroutine.
29   RET_FLAG,
30   /// Return from ISR.
31   RETI_FLAG,
32   /// Represents an abstract call instruction,
33   /// which includes a bunch of information.
34   CALL,
35   /// A wrapper node for TargetConstantPool,
36   /// TargetExternalSymbol, and TargetGlobalAddress.
37   WRAPPER,
38   LSL,     ///< Logical shift left.
39   LSLBN,   ///< Byte logical shift left N bits.
40   LSLWN,   ///< Word logical shift left N bits.
41   LSLHI,   ///< Higher 8-bit of word logical shift left.
42   LSLW,    ///< Wide logical shift left.
43   LSR,     ///< Logical shift right.
44   LSRBN,   ///< Byte logical shift right N bits.
45   LSRWN,   ///< Word logical shift right N bits.
46   LSRLO,   ///< Lower 8-bit of word logical shift right.
47   LSRW,    ///< Wide logical shift right.
48   ASR,     ///< Arithmetic shift right.
49   ASRBN,   ///< Byte arithmetic shift right N bits.
50   ASRWN,   ///< Word arithmetic shift right N bits.
51   ASRLO,   ///< Lower 8-bit of word arithmetic shift right.
52   ASRW,    ///< Wide arithmetic shift right.
53   ROR,     ///< Bit rotate right.
54   ROL,     ///< Bit rotate left.
55   LSLLOOP, ///< A loop of single logical shift left instructions.
56   LSRLOOP, ///< A loop of single logical shift right instructions.
57   ROLLOOP, ///< A loop of single left bit rotate instructions.
58   RORLOOP, ///< A loop of single right bit rotate instructions.
59   ASRLOOP, ///< A loop of single arithmetic shift right instructions.
60   /// AVR conditional branches. Operand 0 is the chain operand, operand 1
61   /// is the block to branch if condition is true, operand 2 is the
62   /// condition code, and operand 3 is the flag operand produced by a CMP
63   /// or TEST instruction.
64   BRCOND,
65   /// Compare instruction.
66   CMP,
67   /// Compare with carry instruction.
68   CMPC,
69   /// Test for zero or minus instruction.
70   TST,
71   /// Swap Rd[7:4] <-> Rd[3:0].
72   SWAP,
73   /// Operand 0 and operand 1 are selection variable, operand 2
74   /// is condition code and operand 3 is flag operand.
75   SELECT_CC
76 };
77 
78 } // end of namespace AVRISD
79 
80 class AVRSubtarget;
81 class AVRTargetMachine;
82 
83 /// Performs target lowering for the AVR.
84 class AVRTargetLowering : public TargetLowering {
85 public:
86   explicit AVRTargetLowering(const AVRTargetMachine &TM,
87                              const AVRSubtarget &STI);
88 
89 public:
90   MVT getScalarShiftAmountTy(const DataLayout &, EVT LHSTy) const override {
91     return MVT::i8;
92   }
93 
94   MVT::SimpleValueType getCmpLibcallReturnType() const override {
95     return MVT::i8;
96   }
97 
98   const char *getTargetNodeName(unsigned Opcode) const override;
99 
100   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
101 
102   void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
103                           SelectionDAG &DAG) const override;
104 
105   bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty,
106                              unsigned AS,
107                              Instruction *I = nullptr) const override;
108 
109   bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset,
110                                  ISD::MemIndexedMode &AM,
111                                  SelectionDAG &DAG) const override;
112 
113   bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, SDValue &Base,
114                                   SDValue &Offset, ISD::MemIndexedMode &AM,
115                                   SelectionDAG &DAG) const override;
116 
117   bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
118 
119   EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
120                          EVT VT) const override;
121 
122   MachineBasicBlock *
123   EmitInstrWithCustomInserter(MachineInstr &MI,
124                               MachineBasicBlock *MBB) const override;
125 
126   ConstraintType getConstraintType(StringRef Constraint) const override;
127 
128   ConstraintWeight
129   getSingleConstraintMatchWeight(AsmOperandInfo &info,
130                                  const char *constraint) const override;
131 
132   std::pair<unsigned, const TargetRegisterClass *>
133   getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
134                                StringRef Constraint, MVT VT) const override;
135 
136   unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const override;
137 
138   void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
139                                     std::vector<SDValue> &Ops,
140                                     SelectionDAG &DAG) const override;
141 
142   Register getRegisterByName(const char *RegName, LLT VT,
143                              const MachineFunction &MF) const override;
144 
145   bool shouldSplitFunctionArgumentsAsLittleEndian(
146       const DataLayout &DL) const override {
147     return false;
148   }
149 
150   ShiftLegalizationStrategy
151   preferredShiftLegalizationStrategy(SelectionDAG &DAG, SDNode *N,
152                                      unsigned ExpansionFactor) const override {
153     return ShiftLegalizationStrategy::LowerToLibcall;
154   }
155 
156 private:
157   SDValue getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue &AVRcc,
158                     SelectionDAG &DAG, SDLoc dl) const;
159   SDValue getAVRCmp(SDValue LHS, SDValue RHS, SelectionDAG &DAG,
160                     SDLoc dl) const;
161   SDValue LowerShifts(SDValue Op, SelectionDAG &DAG) const;
162   SDValue LowerDivRem(SDValue Op, SelectionDAG &DAG) const;
163   SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
164   SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
165   SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
166   SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
167   SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
168   SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
169   SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
170 
171   bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
172                       bool isVarArg,
173                       const SmallVectorImpl<ISD::OutputArg> &Outs,
174                       LLVMContext &Context) const override;
175 
176   SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
177                       const SmallVectorImpl<ISD::OutputArg> &Outs,
178                       const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,
179                       SelectionDAG &DAG) const override;
180   SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
181                                bool isVarArg,
182                                const SmallVectorImpl<ISD::InputArg> &Ins,
183                                const SDLoc &dl, SelectionDAG &DAG,
184                                SmallVectorImpl<SDValue> &InVals) const override;
185   SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
186                     SmallVectorImpl<SDValue> &InVals) const override;
187   SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
188                           CallingConv::ID CallConv, bool isVarArg,
189                           const SmallVectorImpl<ISD::InputArg> &Ins,
190                           const SDLoc &dl, SelectionDAG &DAG,
191                           SmallVectorImpl<SDValue> &InVals) const;
192 
193 protected:
194   const AVRSubtarget &Subtarget;
195 
196 private:
197   MachineBasicBlock *insertShift(MachineInstr &MI, MachineBasicBlock *BB) const;
198   MachineBasicBlock *insertWideShift(MachineInstr &MI,
199                                      MachineBasicBlock *BB) const;
200   MachineBasicBlock *insertMul(MachineInstr &MI, MachineBasicBlock *BB) const;
201   MachineBasicBlock *insertCopyZero(MachineInstr &MI,
202                                     MachineBasicBlock *BB) const;
203   MachineBasicBlock *insertAtomicArithmeticOp(MachineInstr &MI,
204                                               MachineBasicBlock *BB,
205                                               unsigned Opcode, int Width) const;
206 };
207 
208 } // end namespace llvm
209 
210 #endif // LLVM_AVR_ISEL_LOWERING_H
211