xref: /netbsd-src/external/apache2/llvm/dist/llvm/lib/Target/AVR/AVRISelLowering.h (revision 82d56013d7b633d116a93943de88e08335357a7c)
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   LSL4,    ///< Logical shift left 4 bits.
40   LSL8,    ///< Logical shift left 8 bits.
41   LSL12,   ///< Logical shift left 12 bits.
42   LSR,     ///< Logical shift right.
43   LSR4,    ///< Logical shift right 4 bits.
44   LSR8,    ///< Logical shift right 8 bits.
45   LSR12,   ///< Logical shift right 12 bits.
46   ASR,     ///< Arithmetic shift right.
47   ASR8,    ///< Arithmetic shift right 8 bits.
48   LSL7,    ///< Logical shift left 7 bits.
49   LSR7,    ///< Logical shift right 7 bits.
50   ASR7,    ///< Arithmetic shift right 7 bits.
51   ROR,     ///< Bit rotate right.
52   ROL,     ///< Bit rotate left.
53   LSLLOOP, ///< A loop of single logical shift left instructions.
54   LSRLOOP, ///< A loop of single logical shift right instructions.
55   ROLLOOP, ///< A loop of single left bit rotate instructions.
56   RORLOOP, ///< A loop of single right bit rotate instructions.
57   ASRLOOP, ///< A loop of single arithmetic shift right instructions.
58   /// AVR conditional branches. Operand 0 is the chain operand, operand 1
59   /// is the block to branch if condition is true, operand 2 is the
60   /// condition code, and operand 3 is the flag operand produced by a CMP
61   /// or TEST instruction.
62   BRCOND,
63   /// Compare instruction.
64   CMP,
65   /// Compare with carry instruction.
66   CMPC,
67   /// Test for zero or minus instruction.
68   TST,
69   /// Swap Rd[7:4] <-> Rd[3:0].
70   SWAP,
71   /// Operand 0 and operand 1 are selection variable, operand 2
72   /// is condition code and operand 3 is flag operand.
73   SELECT_CC
74 };
75 
76 } // end of namespace AVRISD
77 
78 class AVRSubtarget;
79 class AVRTargetMachine;
80 
81 /// Performs target lowering for the AVR.
82 class AVRTargetLowering : public TargetLowering {
83 public:
84   explicit AVRTargetLowering(const AVRTargetMachine &TM,
85                              const AVRSubtarget &STI);
86 
87 public:
getScalarShiftAmountTy(const DataLayout &,EVT LHSTy)88   MVT getScalarShiftAmountTy(const DataLayout &, EVT LHSTy) const override {
89     return MVT::i8;
90   }
91 
getCmpLibcallReturnType()92   MVT::SimpleValueType getCmpLibcallReturnType() const override {
93     return MVT::i8;
94   }
95 
96   const char *getTargetNodeName(unsigned Opcode) const override;
97 
98   SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override;
99 
100   void ReplaceNodeResults(SDNode *N, SmallVectorImpl<SDValue> &Results,
101                           SelectionDAG &DAG) const override;
102 
103   bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, Type *Ty,
104                              unsigned AS,
105                              Instruction *I = nullptr) const override;
106 
107   bool getPreIndexedAddressParts(SDNode *N, SDValue &Base, SDValue &Offset,
108                                  ISD::MemIndexedMode &AM,
109                                  SelectionDAG &DAG) const override;
110 
111   bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, SDValue &Base,
112                                   SDValue &Offset, ISD::MemIndexedMode &AM,
113                                   SelectionDAG &DAG) const override;
114 
115   bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
116 
117   EVT getSetCCResultType(const DataLayout &DL, LLVMContext &Context,
118                          EVT VT) const override;
119 
120   MachineBasicBlock *
121   EmitInstrWithCustomInserter(MachineInstr &MI,
122                               MachineBasicBlock *MBB) const override;
123 
124   ConstraintType getConstraintType(StringRef Constraint) const override;
125 
126   ConstraintWeight
127   getSingleConstraintMatchWeight(AsmOperandInfo &info,
128                                  const char *constraint) const override;
129 
130   std::pair<unsigned, const TargetRegisterClass *>
131   getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
132                                StringRef Constraint, MVT VT) const override;
133 
134   unsigned getInlineAsmMemConstraint(StringRef ConstraintCode) const override;
135 
136   void LowerAsmOperandForConstraint(SDValue Op, std::string &Constraint,
137                                     std::vector<SDValue> &Ops,
138                                     SelectionDAG &DAG) const override;
139 
140   Register getRegisterByName(const char* RegName, LLT VT,
141                              const MachineFunction &MF) const override;
142 
shouldSplitFunctionArgumentsAsLittleEndian(const DataLayout & DL)143   bool shouldSplitFunctionArgumentsAsLittleEndian(const DataLayout &DL)
144     const override {
145     return false;
146   }
147 
148 private:
149   SDValue getAVRCmp(SDValue LHS, SDValue RHS, ISD::CondCode CC, SDValue &AVRcc,
150                     SelectionDAG &DAG, SDLoc dl) const;
151   SDValue getAVRCmp(SDValue LHS, SDValue RHS, SelectionDAG &DAG,
152                     SDLoc dl) const;
153   SDValue LowerShifts(SDValue Op, SelectionDAG &DAG) const;
154   SDValue LowerDivRem(SDValue Op, SelectionDAG &DAG) const;
155   SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
156   SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
157   SDValue LowerBR_CC(SDValue Op, SelectionDAG &DAG) const;
158   SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const;
159   SDValue LowerSELECT_CC(SDValue Op, SelectionDAG &DAG) const;
160   SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
161   SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const;
162 
163   bool CanLowerReturn(CallingConv::ID CallConv, MachineFunction &MF,
164                       bool isVarArg,
165                       const SmallVectorImpl<ISD::OutputArg> &Outs,
166                       LLVMContext &Context) const override;
167 
168   SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg,
169                       const SmallVectorImpl<ISD::OutputArg> &Outs,
170                       const SmallVectorImpl<SDValue> &OutVals, const SDLoc &dl,
171                       SelectionDAG &DAG) const override;
172   SDValue LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv,
173                                bool isVarArg,
174                                const SmallVectorImpl<ISD::InputArg> &Ins,
175                                const SDLoc &dl, SelectionDAG &DAG,
176                                SmallVectorImpl<SDValue> &InVals) const override;
177   SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI,
178                     SmallVectorImpl<SDValue> &InVals) const override;
179   SDValue LowerCallResult(SDValue Chain, SDValue InFlag,
180                           CallingConv::ID CallConv, bool isVarArg,
181                           const SmallVectorImpl<ISD::InputArg> &Ins,
182                           const SDLoc &dl, SelectionDAG &DAG,
183                           SmallVectorImpl<SDValue> &InVals) const;
184 
185 protected:
186 
187   const AVRSubtarget &Subtarget;
188 
189 private:
190   MachineBasicBlock *insertShift(MachineInstr &MI, MachineBasicBlock *BB) const;
191   MachineBasicBlock *insertMul(MachineInstr &MI, MachineBasicBlock *BB) const;
192 };
193 
194 } // end namespace llvm
195 
196 #endif // LLVM_AVR_ISEL_LOWERING_H
197