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