Home | History | Annotate | Line # | Download | only in M68k
      1 //===-- M68kInstrInfo.h - M68k Instruction Information ------*- 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 /// \file
     10 /// This file contains the M68k implementation of the TargetInstrInfo class.
     11 ///
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_LIB_TARGET_M68K_M68KINSTRINFO_H
     15 #define LLVM_LIB_TARGET_M68K_M68KINSTRINFO_H
     16 
     17 #include "M68k.h"
     18 #include "M68kRegisterInfo.h"
     19 
     20 #include "MCTargetDesc/M68kBaseInfo.h"
     21 
     22 #include "llvm/CodeGen/MachineInstrBuilder.h"
     23 #include "llvm/CodeGen/TargetInstrInfo.h"
     24 
     25 #define GET_INSTRINFO_HEADER
     26 #include "M68kGenInstrInfo.inc"
     27 
     28 namespace llvm {
     29 
     30 class M68kSubtarget;
     31 
     32 namespace M68k {
     33 // These MUST be kept in sync with codes definitions in M68kInstrInfo.td
     34 enum CondCode {
     35   COND_T = 0,   // True
     36   COND_F = 1,   // False
     37   COND_HI = 2,  // High
     38   COND_LS = 3,  // Less or Same
     39   COND_CC = 4,  // Carry Clear
     40   COND_CS = 5,  // Carry Set
     41   COND_NE = 6,  // Not Equal
     42   COND_EQ = 7,  // Equal
     43   COND_VC = 8,  // Overflow Clear
     44   COND_VS = 9,  // Overflow Set
     45   COND_PL = 10, // Plus
     46   COND_MI = 11, // Minus
     47   COND_GE = 12, // Greater or Equal
     48   COND_LT = 13, // Less Than
     49   COND_GT = 14, // Greater Than
     50   COND_LE = 15, // Less or Equal
     51   LAST_VALID_COND = COND_LE,
     52   COND_INVALID
     53 };
     54 
     55 // FIXME would be nice tablegen to generate these predicates and converters
     56 // mb tag based
     57 
     58 static inline M68k::CondCode GetOppositeBranchCondition(M68k::CondCode CC) {
     59   switch (CC) {
     60   default:
     61     llvm_unreachable("Illegal condition code!");
     62   case M68k::COND_T:
     63     return M68k::COND_F;
     64   case M68k::COND_F:
     65     return M68k::COND_T;
     66   case M68k::COND_HI:
     67     return M68k::COND_LS;
     68   case M68k::COND_LS:
     69     return M68k::COND_HI;
     70   case M68k::COND_CC:
     71     return M68k::COND_CS;
     72   case M68k::COND_CS:
     73     return M68k::COND_CC;
     74   case M68k::COND_NE:
     75     return M68k::COND_EQ;
     76   case M68k::COND_EQ:
     77     return M68k::COND_NE;
     78   case M68k::COND_VC:
     79     return M68k::COND_VS;
     80   case M68k::COND_VS:
     81     return M68k::COND_VC;
     82   case M68k::COND_PL:
     83     return M68k::COND_MI;
     84   case M68k::COND_MI:
     85     return M68k::COND_PL;
     86   case M68k::COND_GE:
     87     return M68k::COND_LT;
     88   case M68k::COND_LT:
     89     return M68k::COND_GE;
     90   case M68k::COND_GT:
     91     return M68k::COND_LE;
     92   case M68k::COND_LE:
     93     return M68k::COND_GT;
     94   }
     95 }
     96 
     97 static inline unsigned GetCondBranchFromCond(M68k::CondCode CC) {
     98   switch (CC) {
     99   default:
    100     llvm_unreachable("Illegal condition code!");
    101   case M68k::COND_EQ:
    102     return M68k::Beq8;
    103   case M68k::COND_NE:
    104     return M68k::Bne8;
    105   case M68k::COND_LT:
    106     return M68k::Blt8;
    107   case M68k::COND_LE:
    108     return M68k::Ble8;
    109   case M68k::COND_GT:
    110     return M68k::Bgt8;
    111   case M68k::COND_GE:
    112     return M68k::Bge8;
    113   case M68k::COND_CS:
    114     return M68k::Bcs8;
    115   case M68k::COND_LS:
    116     return M68k::Bls8;
    117   case M68k::COND_HI:
    118     return M68k::Bhi8;
    119   case M68k::COND_CC:
    120     return M68k::Bcc8;
    121   case M68k::COND_MI:
    122     return M68k::Bmi8;
    123   case M68k::COND_PL:
    124     return M68k::Bpl8;
    125   case M68k::COND_VS:
    126     return M68k::Bvs8;
    127   case M68k::COND_VC:
    128     return M68k::Bvc8;
    129   }
    130 }
    131 
    132 static inline M68k::CondCode GetCondFromBranchOpc(unsigned Opcode) {
    133   switch (Opcode) {
    134   default:
    135     return M68k::COND_INVALID;
    136   case M68k::Beq8:
    137     return M68k::COND_EQ;
    138   case M68k::Bne8:
    139     return M68k::COND_NE;
    140   case M68k::Blt8:
    141     return M68k::COND_LT;
    142   case M68k::Ble8:
    143     return M68k::COND_LE;
    144   case M68k::Bgt8:
    145     return M68k::COND_GT;
    146   case M68k::Bge8:
    147     return M68k::COND_GE;
    148   case M68k::Bcs8:
    149     return M68k::COND_CS;
    150   case M68k::Bls8:
    151     return M68k::COND_LS;
    152   case M68k::Bhi8:
    153     return M68k::COND_HI;
    154   case M68k::Bcc8:
    155     return M68k::COND_CC;
    156   case M68k::Bmi8:
    157     return M68k::COND_MI;
    158   case M68k::Bpl8:
    159     return M68k::COND_PL;
    160   case M68k::Bvs8:
    161     return M68k::COND_VS;
    162   case M68k::Bvc8:
    163     return M68k::COND_VC;
    164   }
    165 }
    166 
    167 static inline unsigned IsCMP(unsigned Op) {
    168   switch (Op) {
    169   default:
    170     return false;
    171   case M68k::CMP8dd:
    172   case M68k::CMP8df:
    173   case M68k::CMP8di:
    174   case M68k::CMP8dj:
    175   case M68k::CMP8dp:
    176   case M68k::CMP16dd:
    177   case M68k::CMP16df:
    178   case M68k::CMP16di:
    179   case M68k::CMP16dj:
    180   case M68k::CMP16dp:
    181     return true;
    182   }
    183 }
    184 
    185 static inline bool IsSETCC(unsigned SETCC) {
    186   switch (SETCC) {
    187   default:
    188     return false;
    189   case M68k::SETd8eq:
    190   case M68k::SETd8ne:
    191   case M68k::SETd8lt:
    192   case M68k::SETd8ge:
    193   case M68k::SETd8le:
    194   case M68k::SETd8gt:
    195   case M68k::SETd8cs:
    196   case M68k::SETd8cc:
    197   case M68k::SETd8ls:
    198   case M68k::SETd8hi:
    199   case M68k::SETd8pl:
    200   case M68k::SETd8mi:
    201   case M68k::SETd8vc:
    202   case M68k::SETd8vs:
    203   case M68k::SETj8eq:
    204   case M68k::SETj8ne:
    205   case M68k::SETj8lt:
    206   case M68k::SETj8ge:
    207   case M68k::SETj8le:
    208   case M68k::SETj8gt:
    209   case M68k::SETj8cs:
    210   case M68k::SETj8cc:
    211   case M68k::SETj8ls:
    212   case M68k::SETj8hi:
    213   case M68k::SETj8pl:
    214   case M68k::SETj8mi:
    215   case M68k::SETj8vc:
    216   case M68k::SETj8vs:
    217   case M68k::SETp8eq:
    218   case M68k::SETp8ne:
    219   case M68k::SETp8lt:
    220   case M68k::SETp8ge:
    221   case M68k::SETp8le:
    222   case M68k::SETp8gt:
    223   case M68k::SETp8cs:
    224   case M68k::SETp8cc:
    225   case M68k::SETp8ls:
    226   case M68k::SETp8hi:
    227   case M68k::SETp8pl:
    228   case M68k::SETp8mi:
    229   case M68k::SETp8vc:
    230   case M68k::SETp8vs:
    231     return true;
    232   }
    233 }
    234 
    235 } // namespace M68k
    236 
    237 class M68kInstrInfo : public M68kGenInstrInfo {
    238   virtual void anchor();
    239 
    240 protected:
    241   const M68kSubtarget &Subtarget;
    242   const M68kRegisterInfo RI;
    243 
    244 public:
    245   explicit M68kInstrInfo(const M68kSubtarget &STI);
    246 
    247   static const M68kInstrInfo *create(M68kSubtarget &STI);
    248 
    249   /// TargetInstrInfo is a superset of MRegister info. As such, whenever a
    250   /// client has an instance of instruction info, it should always be able to
    251   /// get register info as well (through this method).
    252   const M68kRegisterInfo &getRegisterInfo() const { return RI; };
    253 
    254   bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
    255                      MachineBasicBlock *&FBB,
    256                      SmallVectorImpl<MachineOperand> &Cond,
    257                      bool AllowModify) const override;
    258 
    259   bool AnalyzeBranchImpl(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
    260                          MachineBasicBlock *&FBB,
    261                          SmallVectorImpl<MachineOperand> &Cond,
    262                          bool AllowModify) const;
    263 
    264   unsigned removeBranch(MachineBasicBlock &MBB,
    265                         int *BytesRemoved = nullptr) const override;
    266 
    267   unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,
    268                         MachineBasicBlock *FBB, ArrayRef<MachineOperand> Cond,
    269                         const DebugLoc &DL,
    270                         int *BytesAdded = nullptr) const override;
    271 
    272   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI,
    273                    const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg,
    274                    bool KillSrc) const override;
    275 
    276   bool getStackSlotRange(const TargetRegisterClass *RC, unsigned SubIdx,
    277                          unsigned &Size, unsigned &Offset,
    278                          const MachineFunction &MF) const override;
    279 
    280   void storeRegToStackSlot(MachineBasicBlock &MBB,
    281                            MachineBasicBlock::iterator MI, Register SrcReg,
    282                            bool IsKill, int FrameIndex,
    283                            const TargetRegisterClass *RC,
    284                            const TargetRegisterInfo *TRI) const override;
    285 
    286   void loadRegFromStackSlot(MachineBasicBlock &MBB,
    287                             MachineBasicBlock::iterator MI, Register DestReg,
    288                             int FrameIndex, const TargetRegisterClass *RC,
    289                             const TargetRegisterInfo *TRI) const override;
    290 
    291   bool expandPostRAPseudo(MachineInstr &MI) const override;
    292 
    293   bool isPCRelRegisterOperandLegal(const MachineOperand &MO) const override;
    294 
    295   /// Add appropriate SExt nodes
    296   void AddSExt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
    297                DebugLoc DL, unsigned Reg, MVT From, MVT To) const;
    298 
    299   /// Add appropriate ZExt nodes
    300   void AddZExt(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
    301                DebugLoc DL, unsigned Reg, MVT From, MVT To) const;
    302 
    303   /// Move across register classes without extension
    304   bool ExpandMOVX_RR(MachineInstrBuilder &MIB, MVT MVTDst, MVT MVTSrc) const;
    305 
    306   /// Move from register and extend
    307   bool ExpandMOVSZX_RR(MachineInstrBuilder &MIB, bool IsSigned, MVT MVTDst,
    308                        MVT MVTSrc) const;
    309 
    310   /// Move from memory and extend
    311   bool ExpandMOVSZX_RM(MachineInstrBuilder &MIB, bool IsSigned,
    312                        const MCInstrDesc &Desc, MVT MVTDst, MVT MVTSrc) const;
    313 
    314   /// Push/Pop to/from stack
    315   bool ExpandPUSH_POP(MachineInstrBuilder &MIB, const MCInstrDesc &Desc,
    316                       bool IsPush) const;
    317 
    318   /// Moves to/from CCR
    319   bool ExpandCCR(MachineInstrBuilder &MIB, bool IsToCCR) const;
    320 
    321   /// Expand all MOVEM pseudos into real MOVEMs
    322   bool ExpandMOVEM(MachineInstrBuilder &MIB, const MCInstrDesc &Desc,
    323                    bool IsRM) const;
    324 
    325   /// Return a virtual register initialized with the the global base register
    326   /// value. Output instructions required to initialize the register in the
    327   /// function entry block, if necessary.
    328   unsigned getGlobalBaseReg(MachineFunction *MF) const;
    329 
    330   std::pair<unsigned, unsigned>
    331   decomposeMachineOperandsTargetFlags(unsigned TF) const override;
    332 
    333   ArrayRef<std::pair<unsigned, const char *>>
    334   getSerializableDirectMachineOperandTargetFlags() const override;
    335 };
    336 
    337 } // namespace llvm
    338 
    339 #endif
    340