xref: /freebsd/contrib/llvm-project/llvm/lib/Target/Lanai/LanaiInstrInfo.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- LanaiInstrInfo.h - Lanai Instruction Information ---------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file contains the Lanai implementation of the TargetInstrInfo class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_LANAI_LANAIINSTRINFO_H
140b57cec5SDimitry Andric #define LLVM_LIB_TARGET_LANAI_LANAIINSTRINFO_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "LanaiRegisterInfo.h"
170b57cec5SDimitry Andric #include "MCTargetDesc/LanaiMCTargetDesc.h"
180b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
190b57cec5SDimitry Andric 
200b57cec5SDimitry Andric #define GET_INSTRINFO_HEADER
210b57cec5SDimitry Andric #include "LanaiGenInstrInfo.inc"
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric namespace llvm {
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric class LanaiInstrInfo : public LanaiGenInstrInfo {
260b57cec5SDimitry Andric   const LanaiRegisterInfo RegisterInfo;
270b57cec5SDimitry Andric 
280b57cec5SDimitry Andric public:
290b57cec5SDimitry Andric   LanaiInstrInfo();
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric   // getRegisterInfo - TargetInstrInfo is a superset of MRegister info.  As
320b57cec5SDimitry Andric   // such, whenever a client has an instance of instruction info, it should
330b57cec5SDimitry Andric   // always be able to get register info as well (through this method).
getRegisterInfo()340b57cec5SDimitry Andric   virtual const LanaiRegisterInfo &getRegisterInfo() const {
350b57cec5SDimitry Andric     return RegisterInfo;
360b57cec5SDimitry Andric   }
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric   bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
398bcb0991SDimitry Andric                                        const MachineInstr &MIb) const override;
400b57cec5SDimitry Andric 
41*0fca6ea1SDimitry Andric   Register isLoadFromStackSlot(const MachineInstr &MI,
420b57cec5SDimitry Andric                                int &FrameIndex) const override;
430b57cec5SDimitry Andric 
44*0fca6ea1SDimitry Andric   Register isLoadFromStackSlotPostFE(const MachineInstr &MI,
450b57cec5SDimitry Andric                                      int &FrameIndex) const override;
460b57cec5SDimitry Andric 
47*0fca6ea1SDimitry Andric   Register isStoreToStackSlot(const MachineInstr &MI,
480b57cec5SDimitry Andric                               int &FrameIndex) const override;
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
51480093f4SDimitry Andric                    const DebugLoc &DL, MCRegister DestinationRegister,
52480093f4SDimitry Andric                    MCRegister SourceRegister, bool KillSource) const override;
530b57cec5SDimitry Andric 
54bdd1243dSDimitry Andric   void storeRegToStackSlot(MachineBasicBlock &MBB,
550b57cec5SDimitry Andric                            MachineBasicBlock::iterator Position,
565ffd83dbSDimitry Andric                            Register SourceRegister, bool IsKill, int FrameIndex,
570b57cec5SDimitry Andric                            const TargetRegisterClass *RegisterClass,
58bdd1243dSDimitry Andric                            const TargetRegisterInfo *RegisterInfo,
59bdd1243dSDimitry Andric                            Register VReg) const override;
600b57cec5SDimitry Andric 
61bdd1243dSDimitry Andric   void loadRegFromStackSlot(MachineBasicBlock &MBB,
620b57cec5SDimitry Andric                             MachineBasicBlock::iterator Position,
635ffd83dbSDimitry Andric                             Register DestinationRegister, int FrameIndex,
640b57cec5SDimitry Andric                             const TargetRegisterClass *RegisterClass,
65bdd1243dSDimitry Andric                             const TargetRegisterInfo *RegisterInfo,
66bdd1243dSDimitry Andric                             Register VReg) const override;
670b57cec5SDimitry Andric 
680b57cec5SDimitry Andric   bool expandPostRAPseudo(MachineInstr &MI) const override;
690b57cec5SDimitry Andric 
705ffd83dbSDimitry Andric   bool getMemOperandsWithOffsetWidth(
715ffd83dbSDimitry Andric       const MachineInstr &LdSt,
725ffd83dbSDimitry Andric       SmallVectorImpl<const MachineOperand *> &BaseOps, int64_t &Offset,
73*0fca6ea1SDimitry Andric       bool &OffsetIsScalable, LocationSize &Width,
740b57cec5SDimitry Andric       const TargetRegisterInfo *TRI) const override;
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric   bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt,
770b57cec5SDimitry Andric                                     const MachineOperand *&BaseOp,
78*0fca6ea1SDimitry Andric                                     int64_t &Offset, LocationSize &Width,
790b57cec5SDimitry Andric                                     const TargetRegisterInfo *TRI) const;
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric   std::pair<unsigned, unsigned>
820b57cec5SDimitry Andric   decomposeMachineOperandsTargetFlags(unsigned TF) const override;
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric   ArrayRef<std::pair<unsigned, const char *>>
850b57cec5SDimitry Andric   getSerializableDirectMachineOperandTargetFlags() const override;
860b57cec5SDimitry Andric 
870b57cec5SDimitry Andric   bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TrueBlock,
880b57cec5SDimitry Andric                      MachineBasicBlock *&FalseBlock,
890b57cec5SDimitry Andric                      SmallVectorImpl<MachineOperand> &Condition,
900b57cec5SDimitry Andric                      bool AllowModify) const override;
910b57cec5SDimitry Andric 
920b57cec5SDimitry Andric   unsigned removeBranch(MachineBasicBlock &MBB,
930b57cec5SDimitry Andric                         int *BytesRemoved = nullptr) const override;
940b57cec5SDimitry Andric 
950b57cec5SDimitry Andric   // For a comparison instruction, return the source registers in SrcReg and
960b57cec5SDimitry Andric   // SrcReg2 if having two register operands, and the value it compares against
970b57cec5SDimitry Andric   // in CmpValue. Return true if the comparison instruction can be analyzed.
985ffd83dbSDimitry Andric   bool analyzeCompare(const MachineInstr &MI, Register &SrcReg,
99349cc55cSDimitry Andric                       Register &SrcReg2, int64_t &CmpMask,
100349cc55cSDimitry Andric                       int64_t &CmpValue) const override;
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   // See if the comparison instruction can be converted into something more
1030b57cec5SDimitry Andric   // efficient. E.g., on Lanai register-register instructions can set the flag
1040b57cec5SDimitry Andric   // register, obviating the need for a separate compare.
1055ffd83dbSDimitry Andric   bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
106349cc55cSDimitry Andric                             Register SrcReg2, int64_t CmpMask, int64_t CmpValue,
1070b57cec5SDimitry Andric                             const MachineRegisterInfo *MRI) const override;
1080b57cec5SDimitry Andric 
1090b57cec5SDimitry Andric   // Analyze the given select instruction, returning true if it cannot be
1100b57cec5SDimitry Andric   // understood. It is assumed that MI->isSelect() is true.
1110b57cec5SDimitry Andric   //
1120b57cec5SDimitry Andric   // When successful, return the controlling condition and the operands that
1130b57cec5SDimitry Andric   // determine the true and false result values.
1140b57cec5SDimitry Andric   //
1150b57cec5SDimitry Andric   //   Result = SELECT Cond, TrueOp, FalseOp
1160b57cec5SDimitry Andric   //
1170b57cec5SDimitry Andric   // Lanai can optimize certain select instructions, for example by predicating
1180b57cec5SDimitry Andric   // the instruction defining one of the operands and sets Optimizable to true.
1190b57cec5SDimitry Andric   bool analyzeSelect(const MachineInstr &MI,
1200b57cec5SDimitry Andric                      SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp,
1210b57cec5SDimitry Andric                      unsigned &FalseOp, bool &Optimizable) const override;
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric   // Given a select instruction that was understood by analyzeSelect and
1240b57cec5SDimitry Andric   // returned Optimizable = true, attempt to optimize MI by merging it with one
1250b57cec5SDimitry Andric   // of its operands. Returns NULL on failure.
1260b57cec5SDimitry Andric   //
1270b57cec5SDimitry Andric   // When successful, returns the new select instruction. The client is
1280b57cec5SDimitry Andric   // responsible for deleting MI.
1290b57cec5SDimitry Andric   //
1300b57cec5SDimitry Andric   // If both sides of the select can be optimized, the TrueOp is modifed.
1310b57cec5SDimitry Andric   // PreferFalse is not used.
1320b57cec5SDimitry Andric   MachineInstr *optimizeSelect(MachineInstr &MI,
1330b57cec5SDimitry Andric                                SmallPtrSetImpl<MachineInstr *> &SeenMIs,
1340b57cec5SDimitry Andric                                bool PreferFalse) const override;
1350b57cec5SDimitry Andric 
1360b57cec5SDimitry Andric   bool reverseBranchCondition(
1370b57cec5SDimitry Andric       SmallVectorImpl<MachineOperand> &Condition) const override;
1380b57cec5SDimitry Andric 
1390b57cec5SDimitry Andric   unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TrueBlock,
1400b57cec5SDimitry Andric                         MachineBasicBlock *FalseBlock,
1410b57cec5SDimitry Andric                         ArrayRef<MachineOperand> Condition,
1420b57cec5SDimitry Andric                         const DebugLoc &DL,
1430b57cec5SDimitry Andric                         int *BytesAdded = nullptr) const override;
1440b57cec5SDimitry Andric };
1450b57cec5SDimitry Andric 
isSPLSOpcode(unsigned Opcode)1460b57cec5SDimitry Andric static inline bool isSPLSOpcode(unsigned Opcode) {
1470b57cec5SDimitry Andric   switch (Opcode) {
1480b57cec5SDimitry Andric   case Lanai::LDBs_RI:
1490b57cec5SDimitry Andric   case Lanai::LDBz_RI:
1500b57cec5SDimitry Andric   case Lanai::LDHs_RI:
1510b57cec5SDimitry Andric   case Lanai::LDHz_RI:
1520b57cec5SDimitry Andric   case Lanai::STB_RI:
1530b57cec5SDimitry Andric   case Lanai::STH_RI:
1540b57cec5SDimitry Andric     return true;
1550b57cec5SDimitry Andric   default:
1560b57cec5SDimitry Andric     return false;
1570b57cec5SDimitry Andric   }
1580b57cec5SDimitry Andric }
1590b57cec5SDimitry Andric 
isRMOpcode(unsigned Opcode)1600b57cec5SDimitry Andric static inline bool isRMOpcode(unsigned Opcode) {
1610b57cec5SDimitry Andric   switch (Opcode) {
1620b57cec5SDimitry Andric   case Lanai::LDW_RI:
1630b57cec5SDimitry Andric   case Lanai::SW_RI:
1640b57cec5SDimitry Andric     return true;
1650b57cec5SDimitry Andric   default:
1660b57cec5SDimitry Andric     return false;
1670b57cec5SDimitry Andric   }
1680b57cec5SDimitry Andric }
1690b57cec5SDimitry Andric 
isRRMOpcode(unsigned Opcode)1700b57cec5SDimitry Andric static inline bool isRRMOpcode(unsigned Opcode) {
1710b57cec5SDimitry Andric   switch (Opcode) {
1720b57cec5SDimitry Andric   case Lanai::LDBs_RR:
1730b57cec5SDimitry Andric   case Lanai::LDBz_RR:
1740b57cec5SDimitry Andric   case Lanai::LDHs_RR:
1750b57cec5SDimitry Andric   case Lanai::LDHz_RR:
1760b57cec5SDimitry Andric   case Lanai::LDWz_RR:
1770b57cec5SDimitry Andric   case Lanai::LDW_RR:
1780b57cec5SDimitry Andric   case Lanai::STB_RR:
1790b57cec5SDimitry Andric   case Lanai::STH_RR:
1800b57cec5SDimitry Andric   case Lanai::SW_RR:
1810b57cec5SDimitry Andric     return true;
1820b57cec5SDimitry Andric   default:
1830b57cec5SDimitry Andric     return false;
1840b57cec5SDimitry Andric   }
1850b57cec5SDimitry Andric }
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric } // namespace llvm
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_LANAI_LANAIINSTRINFO_H
190