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