Home | History | Annotate | Line # | Download | only in AVR
      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:
     88   MVT getScalarShiftAmountTy(const DataLayout &, EVT LHSTy) const override {
     89     return MVT::i8;
     90   }
     91 
     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 
    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