1*0b57cec5SDimitry Andric //===-- AVRInstrInfo.h - AVR Instruction Information ------------*- C++ -*-===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // This file contains the AVR implementation of the TargetInstrInfo class. 10*0b57cec5SDimitry Andric // 11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 12*0b57cec5SDimitry Andric 13*0b57cec5SDimitry Andric #ifndef LLVM_AVR_INSTR_INFO_H 14*0b57cec5SDimitry Andric #define LLVM_AVR_INSTR_INFO_H 15*0b57cec5SDimitry Andric 16*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 17*0b57cec5SDimitry Andric 18*0b57cec5SDimitry Andric #include "AVRRegisterInfo.h" 19*0b57cec5SDimitry Andric 20*0b57cec5SDimitry Andric #define GET_INSTRINFO_HEADER 21*0b57cec5SDimitry Andric #include "AVRGenInstrInfo.inc" 22*0b57cec5SDimitry Andric #undef GET_INSTRINFO_HEADER 23*0b57cec5SDimitry Andric 24*0b57cec5SDimitry Andric namespace llvm { 25*0b57cec5SDimitry Andric 26*0b57cec5SDimitry Andric namespace AVRCC { 27*0b57cec5SDimitry Andric 28*0b57cec5SDimitry Andric /// AVR specific condition codes. 29*0b57cec5SDimitry Andric /// These correspond to `AVR_*_COND` in `AVRInstrInfo.td`. 30*0b57cec5SDimitry Andric /// They must be kept in synch. 31*0b57cec5SDimitry Andric enum CondCodes { 32*0b57cec5SDimitry Andric COND_EQ, //!< Equal 33*0b57cec5SDimitry Andric COND_NE, //!< Not equal 34*0b57cec5SDimitry Andric COND_GE, //!< Greater than or equal 35*0b57cec5SDimitry Andric COND_LT, //!< Less than 36*0b57cec5SDimitry Andric COND_SH, //!< Unsigned same or higher 37*0b57cec5SDimitry Andric COND_LO, //!< Unsigned lower 38*0b57cec5SDimitry Andric COND_MI, //!< Minus 39*0b57cec5SDimitry Andric COND_PL, //!< Plus 40*0b57cec5SDimitry Andric COND_INVALID 41*0b57cec5SDimitry Andric }; 42*0b57cec5SDimitry Andric 43*0b57cec5SDimitry Andric } // end of namespace AVRCC 44*0b57cec5SDimitry Andric 45*0b57cec5SDimitry Andric namespace AVRII { 46*0b57cec5SDimitry Andric 47*0b57cec5SDimitry Andric /// Specifies a target operand flag. 48*0b57cec5SDimitry Andric enum TOF { 49*0b57cec5SDimitry Andric MO_NO_FLAG, 50*0b57cec5SDimitry Andric 51*0b57cec5SDimitry Andric /// On a symbol operand, this represents the lo part. 52*0b57cec5SDimitry Andric MO_LO = (1 << 1), 53*0b57cec5SDimitry Andric 54*0b57cec5SDimitry Andric /// On a symbol operand, this represents the hi part. 55*0b57cec5SDimitry Andric MO_HI = (1 << 2), 56*0b57cec5SDimitry Andric 57*0b57cec5SDimitry Andric /// On a symbol operand, this represents it has to be negated. 58*0b57cec5SDimitry Andric MO_NEG = (1 << 3) 59*0b57cec5SDimitry Andric }; 60*0b57cec5SDimitry Andric 61*0b57cec5SDimitry Andric } // end of namespace AVRII 62*0b57cec5SDimitry Andric 63*0b57cec5SDimitry Andric /// Utilities related to the AVR instruction set. 64*0b57cec5SDimitry Andric class AVRInstrInfo : public AVRGenInstrInfo { 65*0b57cec5SDimitry Andric public: 66*0b57cec5SDimitry Andric explicit AVRInstrInfo(); 67*0b57cec5SDimitry Andric 68*0b57cec5SDimitry Andric const AVRRegisterInfo &getRegisterInfo() const { return RI; } 69*0b57cec5SDimitry Andric const MCInstrDesc &getBrCond(AVRCC::CondCodes CC) const; 70*0b57cec5SDimitry Andric AVRCC::CondCodes getCondFromBranchOpc(unsigned Opc) const; 71*0b57cec5SDimitry Andric AVRCC::CondCodes getOppositeCondition(AVRCC::CondCodes CC) const; 72*0b57cec5SDimitry Andric unsigned getInstSizeInBytes(const MachineInstr &MI) const override; 73*0b57cec5SDimitry Andric 74*0b57cec5SDimitry Andric void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, 75*0b57cec5SDimitry Andric const DebugLoc &DL, unsigned DestReg, unsigned SrcReg, 76*0b57cec5SDimitry Andric bool KillSrc) const override; 77*0b57cec5SDimitry Andric void storeRegToStackSlot(MachineBasicBlock &MBB, 78*0b57cec5SDimitry Andric MachineBasicBlock::iterator MI, unsigned SrcReg, 79*0b57cec5SDimitry Andric bool isKill, int FrameIndex, 80*0b57cec5SDimitry Andric const TargetRegisterClass *RC, 81*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const override; 82*0b57cec5SDimitry Andric void loadRegFromStackSlot(MachineBasicBlock &MBB, 83*0b57cec5SDimitry Andric MachineBasicBlock::iterator MI, unsigned DestReg, 84*0b57cec5SDimitry Andric int FrameIndex, const TargetRegisterClass *RC, 85*0b57cec5SDimitry Andric const TargetRegisterInfo *TRI) const override; 86*0b57cec5SDimitry Andric unsigned isLoadFromStackSlot(const MachineInstr &MI, 87*0b57cec5SDimitry Andric int &FrameIndex) const override; 88*0b57cec5SDimitry Andric unsigned isStoreToStackSlot(const MachineInstr &MI, 89*0b57cec5SDimitry Andric int &FrameIndex) const override; 90*0b57cec5SDimitry Andric 91*0b57cec5SDimitry Andric // Branch analysis. 92*0b57cec5SDimitry Andric bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 93*0b57cec5SDimitry Andric MachineBasicBlock *&FBB, 94*0b57cec5SDimitry Andric SmallVectorImpl<MachineOperand> &Cond, 95*0b57cec5SDimitry Andric bool AllowModify = false) const override; 96*0b57cec5SDimitry Andric unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 97*0b57cec5SDimitry Andric MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond, 98*0b57cec5SDimitry Andric const DebugLoc &DL, 99*0b57cec5SDimitry Andric int *BytesAdded = nullptr) const override; 100*0b57cec5SDimitry Andric unsigned removeBranch(MachineBasicBlock &MBB, 101*0b57cec5SDimitry Andric int *BytesRemoved = nullptr) const override; 102*0b57cec5SDimitry Andric bool 103*0b57cec5SDimitry Andric reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const override; 104*0b57cec5SDimitry Andric 105*0b57cec5SDimitry Andric MachineBasicBlock *getBranchDestBlock(const MachineInstr &MI) const override; 106*0b57cec5SDimitry Andric 107*0b57cec5SDimitry Andric bool isBranchOffsetInRange(unsigned BranchOpc, 108*0b57cec5SDimitry Andric int64_t BrOffset) const override; 109*0b57cec5SDimitry Andric 110*0b57cec5SDimitry Andric unsigned insertIndirectBranch(MachineBasicBlock &MBB, 111*0b57cec5SDimitry Andric MachineBasicBlock &NewDestBB, 112*0b57cec5SDimitry Andric const DebugLoc &DL, 113*0b57cec5SDimitry Andric int64_t BrOffset, 114*0b57cec5SDimitry Andric RegScavenger *RS) const override; 115*0b57cec5SDimitry Andric private: 116*0b57cec5SDimitry Andric const AVRRegisterInfo RI; 117*0b57cec5SDimitry Andric }; 118*0b57cec5SDimitry Andric 119*0b57cec5SDimitry Andric } // end namespace llvm 120*0b57cec5SDimitry Andric 121*0b57cec5SDimitry Andric #endif // LLVM_AVR_INSTR_INFO_H 122