109467b48Spatrick //===- LanaiInstrInfo.h - Lanai Instruction Information ---------*- C++ -*-===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This file contains the Lanai implementation of the TargetInstrInfo class.
1009467b48Spatrick //
1109467b48Spatrick //===----------------------------------------------------------------------===//
1209467b48Spatrick 
1309467b48Spatrick #ifndef LLVM_LIB_TARGET_LANAI_LANAIINSTRINFO_H
1409467b48Spatrick #define LLVM_LIB_TARGET_LANAI_LANAIINSTRINFO_H
1509467b48Spatrick 
1609467b48Spatrick #include "LanaiRegisterInfo.h"
1709467b48Spatrick #include "MCTargetDesc/LanaiMCTargetDesc.h"
1809467b48Spatrick #include "llvm/CodeGen/TargetInstrInfo.h"
1909467b48Spatrick 
2009467b48Spatrick #define GET_INSTRINFO_HEADER
2109467b48Spatrick #include "LanaiGenInstrInfo.inc"
2209467b48Spatrick 
2309467b48Spatrick namespace llvm {
2409467b48Spatrick 
2509467b48Spatrick class LanaiInstrInfo : public LanaiGenInstrInfo {
2609467b48Spatrick   const LanaiRegisterInfo RegisterInfo;
2709467b48Spatrick 
2809467b48Spatrick public:
2909467b48Spatrick   LanaiInstrInfo();
3009467b48Spatrick 
3109467b48Spatrick   // getRegisterInfo - TargetInstrInfo is a superset of MRegister info.  As
3209467b48Spatrick   // such, whenever a client has an instance of instruction info, it should
3309467b48Spatrick   // always be able to get register info as well (through this method).
getRegisterInfo()3409467b48Spatrick   virtual const LanaiRegisterInfo &getRegisterInfo() const {
3509467b48Spatrick     return RegisterInfo;
3609467b48Spatrick   }
3709467b48Spatrick 
3809467b48Spatrick   bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
3909467b48Spatrick                                        const MachineInstr &MIb) const override;
4009467b48Spatrick 
4109467b48Spatrick   unsigned isLoadFromStackSlot(const MachineInstr &MI,
4209467b48Spatrick                                int &FrameIndex) const override;
4309467b48Spatrick 
4409467b48Spatrick   unsigned isLoadFromStackSlotPostFE(const MachineInstr &MI,
4509467b48Spatrick                                      int &FrameIndex) const override;
4609467b48Spatrick 
4709467b48Spatrick   unsigned isStoreToStackSlot(const MachineInstr &MI,
4809467b48Spatrick                               int &FrameIndex) const override;
4909467b48Spatrick 
5009467b48Spatrick   void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
5109467b48Spatrick                    const DebugLoc &DL, MCRegister DestinationRegister,
5209467b48Spatrick                    MCRegister SourceRegister, bool KillSource) const override;
5309467b48Spatrick 
54*d415bd75Srobert   void storeRegToStackSlot(MachineBasicBlock &MBB,
5509467b48Spatrick                            MachineBasicBlock::iterator Position,
56097a140dSpatrick                            Register SourceRegister, bool IsKill, int FrameIndex,
5709467b48Spatrick                            const TargetRegisterClass *RegisterClass,
58*d415bd75Srobert                            const TargetRegisterInfo *RegisterInfo,
59*d415bd75Srobert                            Register VReg) const override;
6009467b48Spatrick 
61*d415bd75Srobert   void loadRegFromStackSlot(MachineBasicBlock &MBB,
6209467b48Spatrick                             MachineBasicBlock::iterator Position,
63097a140dSpatrick                             Register DestinationRegister, int FrameIndex,
6409467b48Spatrick                             const TargetRegisterClass *RegisterClass,
65*d415bd75Srobert                             const TargetRegisterInfo *RegisterInfo,
66*d415bd75Srobert                             Register VReg) const override;
6709467b48Spatrick 
6809467b48Spatrick   bool expandPostRAPseudo(MachineInstr &MI) const override;
6909467b48Spatrick 
70097a140dSpatrick   bool getMemOperandsWithOffsetWidth(
71097a140dSpatrick       const MachineInstr &LdSt,
72097a140dSpatrick       SmallVectorImpl<const MachineOperand *> &BaseOps, int64_t &Offset,
73097a140dSpatrick       bool &OffsetIsScalable, unsigned &Width,
7409467b48Spatrick       const TargetRegisterInfo *TRI) const override;
7509467b48Spatrick 
7609467b48Spatrick   bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt,
7709467b48Spatrick                                     const MachineOperand *&BaseOp,
7809467b48Spatrick                                     int64_t &Offset, unsigned &Width,
7909467b48Spatrick                                     const TargetRegisterInfo *TRI) const;
8009467b48Spatrick 
8109467b48Spatrick   std::pair<unsigned, unsigned>
8209467b48Spatrick   decomposeMachineOperandsTargetFlags(unsigned TF) const override;
8309467b48Spatrick 
8409467b48Spatrick   ArrayRef<std::pair<unsigned, const char *>>
8509467b48Spatrick   getSerializableDirectMachineOperandTargetFlags() const override;
8609467b48Spatrick 
8709467b48Spatrick   bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TrueBlock,
8809467b48Spatrick                      MachineBasicBlock *&FalseBlock,
8909467b48Spatrick                      SmallVectorImpl<MachineOperand> &Condition,
9009467b48Spatrick                      bool AllowModify) const override;
9109467b48Spatrick 
9209467b48Spatrick   unsigned removeBranch(MachineBasicBlock &MBB,
9309467b48Spatrick                         int *BytesRemoved = nullptr) const override;
9409467b48Spatrick 
9509467b48Spatrick   // For a comparison instruction, return the source registers in SrcReg and
9609467b48Spatrick   // SrcReg2 if having two register operands, and the value it compares against
9709467b48Spatrick   // in CmpValue. Return true if the comparison instruction can be analyzed.
98097a140dSpatrick   bool analyzeCompare(const MachineInstr &MI, Register &SrcReg,
99*d415bd75Srobert                       Register &SrcReg2, int64_t &CmpMask,
100*d415bd75Srobert                       int64_t &CmpValue) const override;
10109467b48Spatrick 
10209467b48Spatrick   // See if the comparison instruction can be converted into something more
10309467b48Spatrick   // efficient. E.g., on Lanai register-register instructions can set the flag
10409467b48Spatrick   // register, obviating the need for a separate compare.
105097a140dSpatrick   bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
106*d415bd75Srobert                             Register SrcReg2, int64_t CmpMask, int64_t CmpValue,
10709467b48Spatrick                             const MachineRegisterInfo *MRI) const override;
10809467b48Spatrick 
10909467b48Spatrick   // Analyze the given select instruction, returning true if it cannot be
11009467b48Spatrick   // understood. It is assumed that MI->isSelect() is true.
11109467b48Spatrick   //
11209467b48Spatrick   // When successful, return the controlling condition and the operands that
11309467b48Spatrick   // determine the true and false result values.
11409467b48Spatrick   //
11509467b48Spatrick   //   Result = SELECT Cond, TrueOp, FalseOp
11609467b48Spatrick   //
11709467b48Spatrick   // Lanai can optimize certain select instructions, for example by predicating
11809467b48Spatrick   // the instruction defining one of the operands and sets Optimizable to true.
11909467b48Spatrick   bool analyzeSelect(const MachineInstr &MI,
12009467b48Spatrick                      SmallVectorImpl<MachineOperand> &Cond, unsigned &TrueOp,
12109467b48Spatrick                      unsigned &FalseOp, bool &Optimizable) const override;
12209467b48Spatrick 
12309467b48Spatrick   // Given a select instruction that was understood by analyzeSelect and
12409467b48Spatrick   // returned Optimizable = true, attempt to optimize MI by merging it with one
12509467b48Spatrick   // of its operands. Returns NULL on failure.
12609467b48Spatrick   //
12709467b48Spatrick   // When successful, returns the new select instruction. The client is
12809467b48Spatrick   // responsible for deleting MI.
12909467b48Spatrick   //
13009467b48Spatrick   // If both sides of the select can be optimized, the TrueOp is modifed.
13109467b48Spatrick   // PreferFalse is not used.
13209467b48Spatrick   MachineInstr *optimizeSelect(MachineInstr &MI,
13309467b48Spatrick                                SmallPtrSetImpl<MachineInstr *> &SeenMIs,
13409467b48Spatrick                                bool PreferFalse) const override;
13509467b48Spatrick 
13609467b48Spatrick   bool reverseBranchCondition(
13709467b48Spatrick       SmallVectorImpl<MachineOperand> &Condition) const override;
13809467b48Spatrick 
13909467b48Spatrick   unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TrueBlock,
14009467b48Spatrick                         MachineBasicBlock *FalseBlock,
14109467b48Spatrick                         ArrayRef<MachineOperand> Condition,
14209467b48Spatrick                         const DebugLoc &DL,
14309467b48Spatrick                         int *BytesAdded = nullptr) const override;
14409467b48Spatrick };
14509467b48Spatrick 
isSPLSOpcode(unsigned Opcode)14609467b48Spatrick static inline bool isSPLSOpcode(unsigned Opcode) {
14709467b48Spatrick   switch (Opcode) {
14809467b48Spatrick   case Lanai::LDBs_RI:
14909467b48Spatrick   case Lanai::LDBz_RI:
15009467b48Spatrick   case Lanai::LDHs_RI:
15109467b48Spatrick   case Lanai::LDHz_RI:
15209467b48Spatrick   case Lanai::STB_RI:
15309467b48Spatrick   case Lanai::STH_RI:
15409467b48Spatrick     return true;
15509467b48Spatrick   default:
15609467b48Spatrick     return false;
15709467b48Spatrick   }
15809467b48Spatrick }
15909467b48Spatrick 
isRMOpcode(unsigned Opcode)16009467b48Spatrick static inline bool isRMOpcode(unsigned Opcode) {
16109467b48Spatrick   switch (Opcode) {
16209467b48Spatrick   case Lanai::LDW_RI:
16309467b48Spatrick   case Lanai::SW_RI:
16409467b48Spatrick     return true;
16509467b48Spatrick   default:
16609467b48Spatrick     return false;
16709467b48Spatrick   }
16809467b48Spatrick }
16909467b48Spatrick 
isRRMOpcode(unsigned Opcode)17009467b48Spatrick static inline bool isRRMOpcode(unsigned Opcode) {
17109467b48Spatrick   switch (Opcode) {
17209467b48Spatrick   case Lanai::LDBs_RR:
17309467b48Spatrick   case Lanai::LDBz_RR:
17409467b48Spatrick   case Lanai::LDHs_RR:
17509467b48Spatrick   case Lanai::LDHz_RR:
17609467b48Spatrick   case Lanai::LDWz_RR:
17709467b48Spatrick   case Lanai::LDW_RR:
17809467b48Spatrick   case Lanai::STB_RR:
17909467b48Spatrick   case Lanai::STH_RR:
18009467b48Spatrick   case Lanai::SW_RR:
18109467b48Spatrick     return true;
18209467b48Spatrick   default:
18309467b48Spatrick     return false;
18409467b48Spatrick   }
18509467b48Spatrick }
18609467b48Spatrick 
18709467b48Spatrick } // namespace llvm
18809467b48Spatrick 
18909467b48Spatrick #endif // LLVM_LIB_TARGET_LANAI_LANAIINSTRINFO_H
190