1//===- LanaiInstrInfo.h - Lanai 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// This file contains the Lanai implementation of the TargetInstrInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_LIB_TARGET_LANAI_LANAIINSTRINFO_H
14#define LLVM_LIB_TARGET_LANAI_LANAIINSTRINFO_H
15
16#include "LanaiRegisterInfo.h"
17#include "MCTargetDesc/LanaiMCTargetDesc.h"
18#include "llvm/CodeGen/TargetInstrInfo.h"
19
20#define GET_INSTRINFO_HEADER
21#include "LanaiGenInstrInfo.inc"
22
23namespace llvm {
24
25class LanaiSubtarget;
26
27class LanaiInstrInfo : public LanaiGenInstrInfo {
28 const LanaiRegisterInfo RegisterInfo;
29
30public:
31 LanaiInstrInfo(const LanaiSubtarget &STI);
32
33 // getRegisterInfo - TargetInstrInfo is a superset of MRegister info. As
34 // such, whenever a client has an instance of instruction info, it should
35 // always be able to get register info as well (through this method).
36 virtual const LanaiRegisterInfo &getRegisterInfo() const {
37 return RegisterInfo;
38 }
39
40 bool areMemAccessesTriviallyDisjoint(const MachineInstr &MIa,
41 const MachineInstr &MIb) const override;
42
43 Register isLoadFromStackSlot(const MachineInstr &MI,
44 int &FrameIndex) const override;
45
46 Register isLoadFromStackSlotPostFE(const MachineInstr &MI,
47 int &FrameIndex) const override;
48
49 Register isStoreToStackSlot(const MachineInstr &MI,
50 int &FrameIndex) const override;
51
52 void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
53 const DebugLoc &DL, Register DestinationRegister,
54 Register SourceRegister, bool KillSource,
55 bool RenamableDest = false,
56 bool RenamableSrc = false) const override;
57
58 void storeRegToStackSlot(
59 MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
60 Register SourceRegister, bool IsKill, int FrameIndex,
61 const TargetRegisterClass *RegisterClass, Register VReg,
62 MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override;
63
64 void loadRegFromStackSlot(
65 MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
66 Register DestinationRegister, int FrameIndex,
67 const TargetRegisterClass *RegisterClass, Register VReg,
68 unsigned SubReg = 0,
69 MachineInstr::MIFlag Flags = MachineInstr::NoFlags) const override;
70
71 bool expandPostRAPseudo(MachineInstr &MI) const override;
72
73 bool getMemOperandsWithOffsetWidth(
74 const MachineInstr &LdSt,
75 SmallVectorImpl<const MachineOperand *> &BaseOps, int64_t &Offset,
76 bool &OffsetIsScalable, LocationSize &Width,
77 const TargetRegisterInfo *TRI) const override;
78
79 bool getMemOperandWithOffsetWidth(const MachineInstr &LdSt,
80 const MachineOperand *&BaseOp,
81 int64_t &Offset, LocationSize &Width,
82 const TargetRegisterInfo *TRI) const;
83
84 std::pair<unsigned, unsigned>
85 decomposeMachineOperandsTargetFlags(unsigned TF) const override;
86
87 ArrayRef<std::pair<unsigned, const char *>>
88 getSerializableDirectMachineOperandTargetFlags() const override;
89
90 bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TrueBlock,
91 MachineBasicBlock *&FalseBlock,
92 SmallVectorImpl<MachineOperand> &Condition,
93 bool AllowModify) const override;
94
95 unsigned removeBranch(MachineBasicBlock &MBB,
96 int *BytesRemoved = nullptr) const override;
97
98 // For a comparison instruction, return the source registers in SrcReg and
99 // SrcReg2 if having two register operands, and the value it compares against
100 // in CmpValue. Return true if the comparison instruction can be analyzed.
101 bool analyzeCompare(const MachineInstr &MI, Register &SrcReg,
102 Register &SrcReg2, int64_t &CmpMask,
103 int64_t &CmpValue) const override;
104
105 // See if the comparison instruction can be converted into something more
106 // efficient. E.g., on Lanai register-register instructions can set the flag
107 // register, obviating the need for a separate compare.
108 bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg,
109 Register SrcReg2, int64_t CmpMask, int64_t CmpValue,
110 const MachineRegisterInfo *MRI) const override;
111
112 // Given a select instruction that was understood by analyzeSelect and
113 // returned Optimizable = true, attempt to optimize MI by merging it with one
114 // of its operands. Returns NULL on failure.
115 //
116 // When successful, returns the new select instruction. The client is
117 // responsible for deleting MI.
118 //
119 // If both sides of the select can be optimized, the TrueOp is modifed.
120 // PreferFalse is not used.
121 MachineInstr *optimizeSelect(MachineInstr &MI,
122 SmallPtrSetImpl<MachineInstr *> &SeenMIs,
123 bool PreferFalse) const override;
124
125 bool reverseBranchCondition(
126 SmallVectorImpl<MachineOperand> &Condition) const override;
127
128 unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TrueBlock,
129 MachineBasicBlock *FalseBlock,
130 ArrayRef<MachineOperand> Condition,
131 const DebugLoc &DL,
132 int *BytesAdded = nullptr) const override;
133};
134
135static inline bool isSPLSOpcode(unsigned Opcode) {
136 switch (Opcode) {
137 case Lanai::LDBs_RI:
138 case Lanai::LDBz_RI:
139 case Lanai::LDHs_RI:
140 case Lanai::LDHz_RI:
141 case Lanai::STB_RI:
142 case Lanai::STH_RI:
143 return true;
144 default:
145 return false;
146 }
147}
148
149static inline bool isRMOpcode(unsigned Opcode) {
150 switch (Opcode) {
151 case Lanai::LDW_RI:
152 case Lanai::SW_RI:
153 return true;
154 default:
155 return false;
156 }
157}
158
159static inline bool isRRMOpcode(unsigned Opcode) {
160 switch (Opcode) {
161 case Lanai::LDBs_RR:
162 case Lanai::LDBz_RR:
163 case Lanai::LDHs_RR:
164 case Lanai::LDHz_RR:
165 case Lanai::LDWz_RR:
166 case Lanai::LDW_RR:
167 case Lanai::STB_RR:
168 case Lanai::STH_RR:
169 case Lanai::SW_RR:
170 return true;
171 default:
172 return false;
173 }
174}
175
176} // namespace llvm
177
178#endif // LLVM_LIB_TARGET_LANAI_LANAIINSTRINFO_H
179