xref: /aosp_15_r20/external/llvm/lib/Target/Lanai/LanaiInstrInfo.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- LanaiInstrInfo.cpp - Lanai Instruction Information ------*- C++ -*-===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker //                     The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file contains the Lanai implementation of the TargetInstrInfo class.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker 
14*9880d681SAndroid Build Coastguard Worker #include "Lanai.h"
15*9880d681SAndroid Build Coastguard Worker #include "LanaiInstrInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "LanaiMachineFunctionInfo.h"
17*9880d681SAndroid Build Coastguard Worker #include "LanaiTargetMachine.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/TargetRegistry.h"
25*9880d681SAndroid Build Coastguard Worker 
26*9880d681SAndroid Build Coastguard Worker using namespace llvm;
27*9880d681SAndroid Build Coastguard Worker 
28*9880d681SAndroid Build Coastguard Worker #define GET_INSTRINFO_CTOR_DTOR
29*9880d681SAndroid Build Coastguard Worker #include "LanaiGenInstrInfo.inc"
30*9880d681SAndroid Build Coastguard Worker 
LanaiInstrInfo()31*9880d681SAndroid Build Coastguard Worker LanaiInstrInfo::LanaiInstrInfo()
32*9880d681SAndroid Build Coastguard Worker     : LanaiGenInstrInfo(Lanai::ADJCALLSTACKDOWN, Lanai::ADJCALLSTACKUP),
33*9880d681SAndroid Build Coastguard Worker       RegisterInfo() {}
34*9880d681SAndroid Build Coastguard Worker 
copyPhysReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator Position,const DebugLoc & DL,unsigned DestinationRegister,unsigned SourceRegister,bool KillSource) const35*9880d681SAndroid Build Coastguard Worker void LanaiInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
36*9880d681SAndroid Build Coastguard Worker                                  MachineBasicBlock::iterator Position,
37*9880d681SAndroid Build Coastguard Worker                                  const DebugLoc &DL,
38*9880d681SAndroid Build Coastguard Worker                                  unsigned DestinationRegister,
39*9880d681SAndroid Build Coastguard Worker                                  unsigned SourceRegister,
40*9880d681SAndroid Build Coastguard Worker                                  bool KillSource) const {
41*9880d681SAndroid Build Coastguard Worker   if (!Lanai::GPRRegClass.contains(DestinationRegister, SourceRegister)) {
42*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Impossible reg-to-reg copy");
43*9880d681SAndroid Build Coastguard Worker   }
44*9880d681SAndroid Build Coastguard Worker 
45*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, Position, DL, get(Lanai::OR_I_LO), DestinationRegister)
46*9880d681SAndroid Build Coastguard Worker       .addReg(SourceRegister, getKillRegState(KillSource))
47*9880d681SAndroid Build Coastguard Worker       .addImm(0);
48*9880d681SAndroid Build Coastguard Worker }
49*9880d681SAndroid Build Coastguard Worker 
storeRegToStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator Position,unsigned SourceRegister,bool IsKill,int FrameIndex,const TargetRegisterClass * RegisterClass,const TargetRegisterInfo * RegisterInfo) const50*9880d681SAndroid Build Coastguard Worker void LanaiInstrInfo::storeRegToStackSlot(
51*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
52*9880d681SAndroid Build Coastguard Worker     unsigned SourceRegister, bool IsKill, int FrameIndex,
53*9880d681SAndroid Build Coastguard Worker     const TargetRegisterClass *RegisterClass,
54*9880d681SAndroid Build Coastguard Worker     const TargetRegisterInfo *RegisterInfo) const {
55*9880d681SAndroid Build Coastguard Worker   DebugLoc DL;
56*9880d681SAndroid Build Coastguard Worker   if (Position != MBB.end()) {
57*9880d681SAndroid Build Coastguard Worker     DL = Position->getDebugLoc();
58*9880d681SAndroid Build Coastguard Worker   }
59*9880d681SAndroid Build Coastguard Worker 
60*9880d681SAndroid Build Coastguard Worker   if (!Lanai::GPRRegClass.hasSubClassEq(RegisterClass)) {
61*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Can't store this register to stack slot");
62*9880d681SAndroid Build Coastguard Worker   }
63*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, Position, DL, get(Lanai::SW_RI))
64*9880d681SAndroid Build Coastguard Worker       .addReg(SourceRegister, getKillRegState(IsKill))
65*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FrameIndex)
66*9880d681SAndroid Build Coastguard Worker       .addImm(0)
67*9880d681SAndroid Build Coastguard Worker       .addImm(LPAC::ADD);
68*9880d681SAndroid Build Coastguard Worker }
69*9880d681SAndroid Build Coastguard Worker 
loadRegFromStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator Position,unsigned DestinationRegister,int FrameIndex,const TargetRegisterClass * RegisterClass,const TargetRegisterInfo * RegisterInfo) const70*9880d681SAndroid Build Coastguard Worker void LanaiInstrInfo::loadRegFromStackSlot(
71*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock &MBB, MachineBasicBlock::iterator Position,
72*9880d681SAndroid Build Coastguard Worker     unsigned DestinationRegister, int FrameIndex,
73*9880d681SAndroid Build Coastguard Worker     const TargetRegisterClass *RegisterClass,
74*9880d681SAndroid Build Coastguard Worker     const TargetRegisterInfo *RegisterInfo) const {
75*9880d681SAndroid Build Coastguard Worker   DebugLoc DL;
76*9880d681SAndroid Build Coastguard Worker   if (Position != MBB.end()) {
77*9880d681SAndroid Build Coastguard Worker     DL = Position->getDebugLoc();
78*9880d681SAndroid Build Coastguard Worker   }
79*9880d681SAndroid Build Coastguard Worker 
80*9880d681SAndroid Build Coastguard Worker   if (!Lanai::GPRRegClass.hasSubClassEq(RegisterClass)) {
81*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Can't load this register from stack slot");
82*9880d681SAndroid Build Coastguard Worker   }
83*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, Position, DL, get(Lanai::LDW_RI), DestinationRegister)
84*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FrameIndex)
85*9880d681SAndroid Build Coastguard Worker       .addImm(0)
86*9880d681SAndroid Build Coastguard Worker       .addImm(LPAC::ADD);
87*9880d681SAndroid Build Coastguard Worker }
88*9880d681SAndroid Build Coastguard Worker 
areMemAccessesTriviallyDisjoint(MachineInstr & MIa,MachineInstr & MIb,AliasAnalysis * AA) const89*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::areMemAccessesTriviallyDisjoint(MachineInstr &MIa,
90*9880d681SAndroid Build Coastguard Worker                                                      MachineInstr &MIb,
91*9880d681SAndroid Build Coastguard Worker                                                      AliasAnalysis *AA) const {
92*9880d681SAndroid Build Coastguard Worker   assert(MIa.mayLoadOrStore() && "MIa must be a load or store.");
93*9880d681SAndroid Build Coastguard Worker   assert(MIb.mayLoadOrStore() && "MIb must be a load or store.");
94*9880d681SAndroid Build Coastguard Worker 
95*9880d681SAndroid Build Coastguard Worker   if (MIa.hasUnmodeledSideEffects() || MIb.hasUnmodeledSideEffects() ||
96*9880d681SAndroid Build Coastguard Worker       MIa.hasOrderedMemoryRef() || MIb.hasOrderedMemoryRef())
97*9880d681SAndroid Build Coastguard Worker     return false;
98*9880d681SAndroid Build Coastguard Worker 
99*9880d681SAndroid Build Coastguard Worker   // Retrieve the base register, offset from the base register and width. Width
100*9880d681SAndroid Build Coastguard Worker   // is the size of memory that is being loaded/stored (e.g. 1, 2, 4).  If
101*9880d681SAndroid Build Coastguard Worker   // base registers are identical, and the offset of a lower memory access +
102*9880d681SAndroid Build Coastguard Worker   // the width doesn't overlap the offset of a higher memory access,
103*9880d681SAndroid Build Coastguard Worker   // then the memory accesses are different.
104*9880d681SAndroid Build Coastguard Worker   const TargetRegisterInfo *TRI = &getRegisterInfo();
105*9880d681SAndroid Build Coastguard Worker   unsigned BaseRegA = 0, BaseRegB = 0;
106*9880d681SAndroid Build Coastguard Worker   int64_t OffsetA = 0, OffsetB = 0;
107*9880d681SAndroid Build Coastguard Worker   unsigned int WidthA = 0, WidthB = 0;
108*9880d681SAndroid Build Coastguard Worker   if (getMemOpBaseRegImmOfsWidth(MIa, BaseRegA, OffsetA, WidthA, TRI) &&
109*9880d681SAndroid Build Coastguard Worker       getMemOpBaseRegImmOfsWidth(MIb, BaseRegB, OffsetB, WidthB, TRI)) {
110*9880d681SAndroid Build Coastguard Worker     if (BaseRegA == BaseRegB) {
111*9880d681SAndroid Build Coastguard Worker       int LowOffset = std::min(OffsetA, OffsetB);
112*9880d681SAndroid Build Coastguard Worker       int HighOffset = std::max(OffsetA, OffsetB);
113*9880d681SAndroid Build Coastguard Worker       int LowWidth = (LowOffset == OffsetA) ? WidthA : WidthB;
114*9880d681SAndroid Build Coastguard Worker       if (LowOffset + LowWidth <= HighOffset)
115*9880d681SAndroid Build Coastguard Worker         return true;
116*9880d681SAndroid Build Coastguard Worker     }
117*9880d681SAndroid Build Coastguard Worker   }
118*9880d681SAndroid Build Coastguard Worker   return false;
119*9880d681SAndroid Build Coastguard Worker }
120*9880d681SAndroid Build Coastguard Worker 
expandPostRAPseudo(MachineInstr & MI) const121*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
122*9880d681SAndroid Build Coastguard Worker   return false;
123*9880d681SAndroid Build Coastguard Worker }
124*9880d681SAndroid Build Coastguard Worker 
getOppositeCondition(LPCC::CondCode CC)125*9880d681SAndroid Build Coastguard Worker static LPCC::CondCode getOppositeCondition(LPCC::CondCode CC) {
126*9880d681SAndroid Build Coastguard Worker   switch (CC) {
127*9880d681SAndroid Build Coastguard Worker   case LPCC::ICC_T: //  true
128*9880d681SAndroid Build Coastguard Worker     return LPCC::ICC_F;
129*9880d681SAndroid Build Coastguard Worker   case LPCC::ICC_F: //  false
130*9880d681SAndroid Build Coastguard Worker     return LPCC::ICC_T;
131*9880d681SAndroid Build Coastguard Worker   case LPCC::ICC_HI: //  high
132*9880d681SAndroid Build Coastguard Worker     return LPCC::ICC_LS;
133*9880d681SAndroid Build Coastguard Worker   case LPCC::ICC_LS: //  low or same
134*9880d681SAndroid Build Coastguard Worker     return LPCC::ICC_HI;
135*9880d681SAndroid Build Coastguard Worker   case LPCC::ICC_CC: //  carry cleared
136*9880d681SAndroid Build Coastguard Worker     return LPCC::ICC_CS;
137*9880d681SAndroid Build Coastguard Worker   case LPCC::ICC_CS: //  carry set
138*9880d681SAndroid Build Coastguard Worker     return LPCC::ICC_CC;
139*9880d681SAndroid Build Coastguard Worker   case LPCC::ICC_NE: //  not equal
140*9880d681SAndroid Build Coastguard Worker     return LPCC::ICC_EQ;
141*9880d681SAndroid Build Coastguard Worker   case LPCC::ICC_EQ: //  equal
142*9880d681SAndroid Build Coastguard Worker     return LPCC::ICC_NE;
143*9880d681SAndroid Build Coastguard Worker   case LPCC::ICC_VC: //  oVerflow cleared
144*9880d681SAndroid Build Coastguard Worker     return LPCC::ICC_VS;
145*9880d681SAndroid Build Coastguard Worker   case LPCC::ICC_VS: //  oVerflow set
146*9880d681SAndroid Build Coastguard Worker     return LPCC::ICC_VC;
147*9880d681SAndroid Build Coastguard Worker   case LPCC::ICC_PL: //  plus (note: 0 is "minus" too here)
148*9880d681SAndroid Build Coastguard Worker     return LPCC::ICC_MI;
149*9880d681SAndroid Build Coastguard Worker   case LPCC::ICC_MI: //  minus
150*9880d681SAndroid Build Coastguard Worker     return LPCC::ICC_PL;
151*9880d681SAndroid Build Coastguard Worker   case LPCC::ICC_GE: //  greater than or equal
152*9880d681SAndroid Build Coastguard Worker     return LPCC::ICC_LT;
153*9880d681SAndroid Build Coastguard Worker   case LPCC::ICC_LT: //  less than
154*9880d681SAndroid Build Coastguard Worker     return LPCC::ICC_GE;
155*9880d681SAndroid Build Coastguard Worker   case LPCC::ICC_GT: //  greater than
156*9880d681SAndroid Build Coastguard Worker     return LPCC::ICC_LE;
157*9880d681SAndroid Build Coastguard Worker   case LPCC::ICC_LE: //  less than or equal
158*9880d681SAndroid Build Coastguard Worker     return LPCC::ICC_GT;
159*9880d681SAndroid Build Coastguard Worker   default:
160*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Invalid condtional code");
161*9880d681SAndroid Build Coastguard Worker   }
162*9880d681SAndroid Build Coastguard Worker }
163*9880d681SAndroid Build Coastguard Worker 
164*9880d681SAndroid Build Coastguard Worker std::pair<unsigned, unsigned>
decomposeMachineOperandsTargetFlags(unsigned TF) const165*9880d681SAndroid Build Coastguard Worker LanaiInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
166*9880d681SAndroid Build Coastguard Worker   return std::make_pair(TF, 0u);
167*9880d681SAndroid Build Coastguard Worker }
168*9880d681SAndroid Build Coastguard Worker 
169*9880d681SAndroid Build Coastguard Worker ArrayRef<std::pair<unsigned, const char *>>
getSerializableDirectMachineOperandTargetFlags() const170*9880d681SAndroid Build Coastguard Worker LanaiInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
171*9880d681SAndroid Build Coastguard Worker   using namespace LanaiII;
172*9880d681SAndroid Build Coastguard Worker   static const std::pair<unsigned, const char *> TargetFlags[] = {
173*9880d681SAndroid Build Coastguard Worker       {MO_ABS_HI, "lanai-hi"},
174*9880d681SAndroid Build Coastguard Worker       {MO_ABS_LO, "lanai-lo"},
175*9880d681SAndroid Build Coastguard Worker       {MO_NO_FLAG, "lanai-nf"}};
176*9880d681SAndroid Build Coastguard Worker   return makeArrayRef(TargetFlags);
177*9880d681SAndroid Build Coastguard Worker }
178*9880d681SAndroid Build Coastguard Worker 
analyzeCompare(const MachineInstr & MI,unsigned & SrcReg,unsigned & SrcReg2,int & CmpMask,int & CmpValue) const179*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
180*9880d681SAndroid Build Coastguard Worker                                     unsigned &SrcReg2, int &CmpMask,
181*9880d681SAndroid Build Coastguard Worker                                     int &CmpValue) const {
182*9880d681SAndroid Build Coastguard Worker   switch (MI.getOpcode()) {
183*9880d681SAndroid Build Coastguard Worker   default:
184*9880d681SAndroid Build Coastguard Worker     break;
185*9880d681SAndroid Build Coastguard Worker   case Lanai::SFSUB_F_RI_LO:
186*9880d681SAndroid Build Coastguard Worker   case Lanai::SFSUB_F_RI_HI:
187*9880d681SAndroid Build Coastguard Worker     SrcReg = MI.getOperand(0).getReg();
188*9880d681SAndroid Build Coastguard Worker     SrcReg2 = 0;
189*9880d681SAndroid Build Coastguard Worker     CmpMask = ~0;
190*9880d681SAndroid Build Coastguard Worker     CmpValue = MI.getOperand(1).getImm();
191*9880d681SAndroid Build Coastguard Worker     return true;
192*9880d681SAndroid Build Coastguard Worker   case Lanai::SFSUB_F_RR:
193*9880d681SAndroid Build Coastguard Worker     SrcReg = MI.getOperand(0).getReg();
194*9880d681SAndroid Build Coastguard Worker     SrcReg2 = MI.getOperand(1).getReg();
195*9880d681SAndroid Build Coastguard Worker     CmpMask = ~0;
196*9880d681SAndroid Build Coastguard Worker     CmpValue = 0;
197*9880d681SAndroid Build Coastguard Worker     return true;
198*9880d681SAndroid Build Coastguard Worker   }
199*9880d681SAndroid Build Coastguard Worker 
200*9880d681SAndroid Build Coastguard Worker   return false;
201*9880d681SAndroid Build Coastguard Worker }
202*9880d681SAndroid Build Coastguard Worker 
203*9880d681SAndroid Build Coastguard Worker // isRedundantFlagInstr - check whether the first instruction, whose only
204*9880d681SAndroid Build Coastguard Worker // purpose is to update flags, can be made redundant.
205*9880d681SAndroid Build Coastguard Worker // * SFSUB_F_RR can be made redundant by SUB_RI if the operands are the same.
206*9880d681SAndroid Build Coastguard Worker // * SFSUB_F_RI can be made redundant by SUB_I if the operands are the same.
isRedundantFlagInstr(MachineInstr * CmpI,unsigned SrcReg,unsigned SrcReg2,int ImmValue,MachineInstr * OI)207*9880d681SAndroid Build Coastguard Worker inline static bool isRedundantFlagInstr(MachineInstr *CmpI, unsigned SrcReg,
208*9880d681SAndroid Build Coastguard Worker                                         unsigned SrcReg2, int ImmValue,
209*9880d681SAndroid Build Coastguard Worker                                         MachineInstr *OI) {
210*9880d681SAndroid Build Coastguard Worker   if (CmpI->getOpcode() == Lanai::SFSUB_F_RR &&
211*9880d681SAndroid Build Coastguard Worker       OI->getOpcode() == Lanai::SUB_R &&
212*9880d681SAndroid Build Coastguard Worker       ((OI->getOperand(1).getReg() == SrcReg &&
213*9880d681SAndroid Build Coastguard Worker         OI->getOperand(2).getReg() == SrcReg2) ||
214*9880d681SAndroid Build Coastguard Worker        (OI->getOperand(1).getReg() == SrcReg2 &&
215*9880d681SAndroid Build Coastguard Worker         OI->getOperand(2).getReg() == SrcReg)))
216*9880d681SAndroid Build Coastguard Worker     return true;
217*9880d681SAndroid Build Coastguard Worker 
218*9880d681SAndroid Build Coastguard Worker   if (((CmpI->getOpcode() == Lanai::SFSUB_F_RI_LO &&
219*9880d681SAndroid Build Coastguard Worker         OI->getOpcode() == Lanai::SUB_I_LO) ||
220*9880d681SAndroid Build Coastguard Worker        (CmpI->getOpcode() == Lanai::SFSUB_F_RI_HI &&
221*9880d681SAndroid Build Coastguard Worker         OI->getOpcode() == Lanai::SUB_I_HI)) &&
222*9880d681SAndroid Build Coastguard Worker       OI->getOperand(1).getReg() == SrcReg &&
223*9880d681SAndroid Build Coastguard Worker       OI->getOperand(2).getImm() == ImmValue)
224*9880d681SAndroid Build Coastguard Worker     return true;
225*9880d681SAndroid Build Coastguard Worker   return false;
226*9880d681SAndroid Build Coastguard Worker }
227*9880d681SAndroid Build Coastguard Worker 
flagSettingOpcodeVariant(unsigned OldOpcode)228*9880d681SAndroid Build Coastguard Worker inline static unsigned flagSettingOpcodeVariant(unsigned OldOpcode) {
229*9880d681SAndroid Build Coastguard Worker   switch (OldOpcode) {
230*9880d681SAndroid Build Coastguard Worker   case Lanai::ADD_I_HI:
231*9880d681SAndroid Build Coastguard Worker     return Lanai::ADD_F_I_HI;
232*9880d681SAndroid Build Coastguard Worker   case Lanai::ADD_I_LO:
233*9880d681SAndroid Build Coastguard Worker     return Lanai::ADD_F_I_LO;
234*9880d681SAndroid Build Coastguard Worker   case Lanai::ADD_R:
235*9880d681SAndroid Build Coastguard Worker     return Lanai::ADD_F_R;
236*9880d681SAndroid Build Coastguard Worker   case Lanai::ADDC_I_HI:
237*9880d681SAndroid Build Coastguard Worker     return Lanai::ADDC_F_I_HI;
238*9880d681SAndroid Build Coastguard Worker   case Lanai::ADDC_I_LO:
239*9880d681SAndroid Build Coastguard Worker     return Lanai::ADDC_F_I_LO;
240*9880d681SAndroid Build Coastguard Worker   case Lanai::ADDC_R:
241*9880d681SAndroid Build Coastguard Worker     return Lanai::ADDC_F_R;
242*9880d681SAndroid Build Coastguard Worker   case Lanai::AND_I_HI:
243*9880d681SAndroid Build Coastguard Worker     return Lanai::AND_F_I_HI;
244*9880d681SAndroid Build Coastguard Worker   case Lanai::AND_I_LO:
245*9880d681SAndroid Build Coastguard Worker     return Lanai::AND_F_I_LO;
246*9880d681SAndroid Build Coastguard Worker   case Lanai::AND_R:
247*9880d681SAndroid Build Coastguard Worker     return Lanai::AND_F_R;
248*9880d681SAndroid Build Coastguard Worker   case Lanai::OR_I_HI:
249*9880d681SAndroid Build Coastguard Worker     return Lanai::OR_F_I_HI;
250*9880d681SAndroid Build Coastguard Worker   case Lanai::OR_I_LO:
251*9880d681SAndroid Build Coastguard Worker     return Lanai::OR_F_I_LO;
252*9880d681SAndroid Build Coastguard Worker   case Lanai::OR_R:
253*9880d681SAndroid Build Coastguard Worker     return Lanai::OR_F_R;
254*9880d681SAndroid Build Coastguard Worker   case Lanai::SL_I:
255*9880d681SAndroid Build Coastguard Worker     return Lanai::SL_F_I;
256*9880d681SAndroid Build Coastguard Worker   case Lanai::SRL_R:
257*9880d681SAndroid Build Coastguard Worker     return Lanai::SRL_F_R;
258*9880d681SAndroid Build Coastguard Worker   case Lanai::SA_I:
259*9880d681SAndroid Build Coastguard Worker     return Lanai::SA_F_I;
260*9880d681SAndroid Build Coastguard Worker   case Lanai::SRA_R:
261*9880d681SAndroid Build Coastguard Worker     return Lanai::SRA_F_R;
262*9880d681SAndroid Build Coastguard Worker   case Lanai::SUB_I_HI:
263*9880d681SAndroid Build Coastguard Worker     return Lanai::SUB_F_I_HI;
264*9880d681SAndroid Build Coastguard Worker   case Lanai::SUB_I_LO:
265*9880d681SAndroid Build Coastguard Worker     return Lanai::SUB_F_I_LO;
266*9880d681SAndroid Build Coastguard Worker   case Lanai::SUB_R:
267*9880d681SAndroid Build Coastguard Worker     return Lanai::SUB_F_R;
268*9880d681SAndroid Build Coastguard Worker   case Lanai::SUBB_I_HI:
269*9880d681SAndroid Build Coastguard Worker     return Lanai::SUBB_F_I_HI;
270*9880d681SAndroid Build Coastguard Worker   case Lanai::SUBB_I_LO:
271*9880d681SAndroid Build Coastguard Worker     return Lanai::SUBB_F_I_LO;
272*9880d681SAndroid Build Coastguard Worker   case Lanai::SUBB_R:
273*9880d681SAndroid Build Coastguard Worker     return Lanai::SUBB_F_R;
274*9880d681SAndroid Build Coastguard Worker   case Lanai::XOR_I_HI:
275*9880d681SAndroid Build Coastguard Worker     return Lanai::XOR_F_I_HI;
276*9880d681SAndroid Build Coastguard Worker   case Lanai::XOR_I_LO:
277*9880d681SAndroid Build Coastguard Worker     return Lanai::XOR_F_I_LO;
278*9880d681SAndroid Build Coastguard Worker   case Lanai::XOR_R:
279*9880d681SAndroid Build Coastguard Worker     return Lanai::XOR_F_R;
280*9880d681SAndroid Build Coastguard Worker   default:
281*9880d681SAndroid Build Coastguard Worker     return Lanai::NOP;
282*9880d681SAndroid Build Coastguard Worker   }
283*9880d681SAndroid Build Coastguard Worker }
284*9880d681SAndroid Build Coastguard Worker 
optimizeCompareInstr(MachineInstr & CmpInstr,unsigned SrcReg,unsigned SrcReg2,int CmpMask,int CmpValue,const MachineRegisterInfo * MRI) const285*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::optimizeCompareInstr(
286*9880d681SAndroid Build Coastguard Worker     MachineInstr &CmpInstr, unsigned SrcReg, unsigned SrcReg2, int CmpMask,
287*9880d681SAndroid Build Coastguard Worker     int CmpValue, const MachineRegisterInfo *MRI) const {
288*9880d681SAndroid Build Coastguard Worker   // Get the unique definition of SrcReg.
289*9880d681SAndroid Build Coastguard Worker   MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
290*9880d681SAndroid Build Coastguard Worker   if (!MI)
291*9880d681SAndroid Build Coastguard Worker     return false;
292*9880d681SAndroid Build Coastguard Worker 
293*9880d681SAndroid Build Coastguard Worker   // Get ready to iterate backward from CmpInstr.
294*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator I = CmpInstr, E = MI,
295*9880d681SAndroid Build Coastguard Worker                               B = CmpInstr.getParent()->begin();
296*9880d681SAndroid Build Coastguard Worker 
297*9880d681SAndroid Build Coastguard Worker   // Early exit if CmpInstr is at the beginning of the BB.
298*9880d681SAndroid Build Coastguard Worker   if (I == B)
299*9880d681SAndroid Build Coastguard Worker     return false;
300*9880d681SAndroid Build Coastguard Worker 
301*9880d681SAndroid Build Coastguard Worker   // There are two possible candidates which can be changed to set SR:
302*9880d681SAndroid Build Coastguard Worker   // One is MI, the other is a SUB instruction.
303*9880d681SAndroid Build Coastguard Worker   // * For SFSUB_F_RR(r1,r2), we are looking for SUB(r1,r2) or SUB(r2,r1).
304*9880d681SAndroid Build Coastguard Worker   // * For SFSUB_F_RI(r1, CmpValue), we are looking for SUB(r1, CmpValue).
305*9880d681SAndroid Build Coastguard Worker   MachineInstr *Sub = nullptr;
306*9880d681SAndroid Build Coastguard Worker   if (SrcReg2 != 0)
307*9880d681SAndroid Build Coastguard Worker     // MI is not a candidate to transform into a flag setting instruction.
308*9880d681SAndroid Build Coastguard Worker     MI = nullptr;
309*9880d681SAndroid Build Coastguard Worker   else if (MI->getParent() != CmpInstr.getParent() || CmpValue != 0) {
310*9880d681SAndroid Build Coastguard Worker     // Conservatively refuse to convert an instruction which isn't in the same
311*9880d681SAndroid Build Coastguard Worker     // BB as the comparison. Don't return if SFSUB_F_RI and CmpValue != 0 as Sub
312*9880d681SAndroid Build Coastguard Worker     // may still be a candidate.
313*9880d681SAndroid Build Coastguard Worker     if (CmpInstr.getOpcode() == Lanai::SFSUB_F_RI_LO)
314*9880d681SAndroid Build Coastguard Worker       MI = nullptr;
315*9880d681SAndroid Build Coastguard Worker     else
316*9880d681SAndroid Build Coastguard Worker       return false;
317*9880d681SAndroid Build Coastguard Worker   }
318*9880d681SAndroid Build Coastguard Worker 
319*9880d681SAndroid Build Coastguard Worker   // Check that SR isn't set between the comparison instruction and the
320*9880d681SAndroid Build Coastguard Worker   // instruction we want to change while searching for Sub.
321*9880d681SAndroid Build Coastguard Worker   const TargetRegisterInfo *TRI = &getRegisterInfo();
322*9880d681SAndroid Build Coastguard Worker   for (--I; I != E; --I) {
323*9880d681SAndroid Build Coastguard Worker     const MachineInstr &Instr = *I;
324*9880d681SAndroid Build Coastguard Worker 
325*9880d681SAndroid Build Coastguard Worker     if (Instr.modifiesRegister(Lanai::SR, TRI) ||
326*9880d681SAndroid Build Coastguard Worker         Instr.readsRegister(Lanai::SR, TRI))
327*9880d681SAndroid Build Coastguard Worker       // This instruction modifies or uses SR after the one we want to change.
328*9880d681SAndroid Build Coastguard Worker       // We can't do this transformation.
329*9880d681SAndroid Build Coastguard Worker       return false;
330*9880d681SAndroid Build Coastguard Worker 
331*9880d681SAndroid Build Coastguard Worker     // Check whether CmpInstr can be made redundant by the current instruction.
332*9880d681SAndroid Build Coastguard Worker     if (isRedundantFlagInstr(&CmpInstr, SrcReg, SrcReg2, CmpValue, &*I)) {
333*9880d681SAndroid Build Coastguard Worker       Sub = &*I;
334*9880d681SAndroid Build Coastguard Worker       break;
335*9880d681SAndroid Build Coastguard Worker     }
336*9880d681SAndroid Build Coastguard Worker 
337*9880d681SAndroid Build Coastguard Worker     // Don't search outside the containing basic block.
338*9880d681SAndroid Build Coastguard Worker     if (I == B)
339*9880d681SAndroid Build Coastguard Worker       return false;
340*9880d681SAndroid Build Coastguard Worker   }
341*9880d681SAndroid Build Coastguard Worker 
342*9880d681SAndroid Build Coastguard Worker   // Return false if no candidates exist.
343*9880d681SAndroid Build Coastguard Worker   if (!MI && !Sub)
344*9880d681SAndroid Build Coastguard Worker     return false;
345*9880d681SAndroid Build Coastguard Worker 
346*9880d681SAndroid Build Coastguard Worker   // The single candidate is called MI.
347*9880d681SAndroid Build Coastguard Worker   if (!MI)
348*9880d681SAndroid Build Coastguard Worker     MI = Sub;
349*9880d681SAndroid Build Coastguard Worker 
350*9880d681SAndroid Build Coastguard Worker   if (flagSettingOpcodeVariant(MI->getOpcode()) != Lanai::NOP) {
351*9880d681SAndroid Build Coastguard Worker     bool isSafe = false;
352*9880d681SAndroid Build Coastguard Worker 
353*9880d681SAndroid Build Coastguard Worker     SmallVector<std::pair<MachineOperand *, LPCC::CondCode>, 4>
354*9880d681SAndroid Build Coastguard Worker         OperandsToUpdate;
355*9880d681SAndroid Build Coastguard Worker     I = CmpInstr;
356*9880d681SAndroid Build Coastguard Worker     E = CmpInstr.getParent()->end();
357*9880d681SAndroid Build Coastguard Worker     while (!isSafe && ++I != E) {
358*9880d681SAndroid Build Coastguard Worker       const MachineInstr &Instr = *I;
359*9880d681SAndroid Build Coastguard Worker       for (unsigned IO = 0, EO = Instr.getNumOperands(); !isSafe && IO != EO;
360*9880d681SAndroid Build Coastguard Worker            ++IO) {
361*9880d681SAndroid Build Coastguard Worker         const MachineOperand &MO = Instr.getOperand(IO);
362*9880d681SAndroid Build Coastguard Worker         if (MO.isRegMask() && MO.clobbersPhysReg(Lanai::SR)) {
363*9880d681SAndroid Build Coastguard Worker           isSafe = true;
364*9880d681SAndroid Build Coastguard Worker           break;
365*9880d681SAndroid Build Coastguard Worker         }
366*9880d681SAndroid Build Coastguard Worker         if (!MO.isReg() || MO.getReg() != Lanai::SR)
367*9880d681SAndroid Build Coastguard Worker           continue;
368*9880d681SAndroid Build Coastguard Worker         if (MO.isDef()) {
369*9880d681SAndroid Build Coastguard Worker           isSafe = true;
370*9880d681SAndroid Build Coastguard Worker           break;
371*9880d681SAndroid Build Coastguard Worker         }
372*9880d681SAndroid Build Coastguard Worker         // Condition code is after the operand before SR.
373*9880d681SAndroid Build Coastguard Worker         LPCC::CondCode CC;
374*9880d681SAndroid Build Coastguard Worker         CC = (LPCC::CondCode)Instr.getOperand(IO - 1).getImm();
375*9880d681SAndroid Build Coastguard Worker 
376*9880d681SAndroid Build Coastguard Worker         if (Sub) {
377*9880d681SAndroid Build Coastguard Worker           LPCC::CondCode NewCC = getOppositeCondition(CC);
378*9880d681SAndroid Build Coastguard Worker           if (NewCC == LPCC::ICC_T)
379*9880d681SAndroid Build Coastguard Worker             return false;
380*9880d681SAndroid Build Coastguard Worker           // If we have SUB(r1, r2) and CMP(r2, r1), the condition code based on
381*9880d681SAndroid Build Coastguard Worker           // CMP needs to be updated to be based on SUB.  Push the condition
382*9880d681SAndroid Build Coastguard Worker           // code operands to OperandsToUpdate.  If it is safe to remove
383*9880d681SAndroid Build Coastguard Worker           // CmpInstr, the condition code of these operands will be modified.
384*9880d681SAndroid Build Coastguard Worker           if (SrcReg2 != 0 && Sub->getOperand(1).getReg() == SrcReg2 &&
385*9880d681SAndroid Build Coastguard Worker               Sub->getOperand(2).getReg() == SrcReg) {
386*9880d681SAndroid Build Coastguard Worker             OperandsToUpdate.push_back(
387*9880d681SAndroid Build Coastguard Worker                 std::make_pair(&((*I).getOperand(IO - 1)), NewCC));
388*9880d681SAndroid Build Coastguard Worker           }
389*9880d681SAndroid Build Coastguard Worker         } else {
390*9880d681SAndroid Build Coastguard Worker           // No Sub, so this is x = <op> y, z; cmp x, 0.
391*9880d681SAndroid Build Coastguard Worker           switch (CC) {
392*9880d681SAndroid Build Coastguard Worker           case LPCC::ICC_EQ: // Z
393*9880d681SAndroid Build Coastguard Worker           case LPCC::ICC_NE: // Z
394*9880d681SAndroid Build Coastguard Worker           case LPCC::ICC_MI: // N
395*9880d681SAndroid Build Coastguard Worker           case LPCC::ICC_PL: // N
396*9880d681SAndroid Build Coastguard Worker           case LPCC::ICC_F:  // none
397*9880d681SAndroid Build Coastguard Worker           case LPCC::ICC_T:  // none
398*9880d681SAndroid Build Coastguard Worker             // SR can be used multiple times, we should continue.
399*9880d681SAndroid Build Coastguard Worker             break;
400*9880d681SAndroid Build Coastguard Worker           case LPCC::ICC_CS: // C
401*9880d681SAndroid Build Coastguard Worker           case LPCC::ICC_CC: // C
402*9880d681SAndroid Build Coastguard Worker           case LPCC::ICC_VS: // V
403*9880d681SAndroid Build Coastguard Worker           case LPCC::ICC_VC: // V
404*9880d681SAndroid Build Coastguard Worker           case LPCC::ICC_HI: // C Z
405*9880d681SAndroid Build Coastguard Worker           case LPCC::ICC_LS: // C Z
406*9880d681SAndroid Build Coastguard Worker           case LPCC::ICC_GE: // N V
407*9880d681SAndroid Build Coastguard Worker           case LPCC::ICC_LT: // N V
408*9880d681SAndroid Build Coastguard Worker           case LPCC::ICC_GT: // Z N V
409*9880d681SAndroid Build Coastguard Worker           case LPCC::ICC_LE: // Z N V
410*9880d681SAndroid Build Coastguard Worker             // The instruction uses the V bit or C bit which is not safe.
411*9880d681SAndroid Build Coastguard Worker             return false;
412*9880d681SAndroid Build Coastguard Worker           case LPCC::UNKNOWN:
413*9880d681SAndroid Build Coastguard Worker             return false;
414*9880d681SAndroid Build Coastguard Worker           }
415*9880d681SAndroid Build Coastguard Worker         }
416*9880d681SAndroid Build Coastguard Worker       }
417*9880d681SAndroid Build Coastguard Worker     }
418*9880d681SAndroid Build Coastguard Worker 
419*9880d681SAndroid Build Coastguard Worker     // If SR is not killed nor re-defined, we should check whether it is
420*9880d681SAndroid Build Coastguard Worker     // live-out. If it is live-out, do not optimize.
421*9880d681SAndroid Build Coastguard Worker     if (!isSafe) {
422*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock *MBB = CmpInstr.getParent();
423*9880d681SAndroid Build Coastguard Worker       for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(),
424*9880d681SAndroid Build Coastguard Worker                                             SE = MBB->succ_end();
425*9880d681SAndroid Build Coastguard Worker            SI != SE; ++SI)
426*9880d681SAndroid Build Coastguard Worker         if ((*SI)->isLiveIn(Lanai::SR))
427*9880d681SAndroid Build Coastguard Worker           return false;
428*9880d681SAndroid Build Coastguard Worker     }
429*9880d681SAndroid Build Coastguard Worker 
430*9880d681SAndroid Build Coastguard Worker     // Toggle the optional operand to SR.
431*9880d681SAndroid Build Coastguard Worker     MI->setDesc(get(flagSettingOpcodeVariant(MI->getOpcode())));
432*9880d681SAndroid Build Coastguard Worker     MI->addRegisterDefined(Lanai::SR);
433*9880d681SAndroid Build Coastguard Worker     CmpInstr.eraseFromParent();
434*9880d681SAndroid Build Coastguard Worker     return true;
435*9880d681SAndroid Build Coastguard Worker   }
436*9880d681SAndroid Build Coastguard Worker 
437*9880d681SAndroid Build Coastguard Worker   return false;
438*9880d681SAndroid Build Coastguard Worker }
439*9880d681SAndroid Build Coastguard Worker 
analyzeSelect(const MachineInstr & MI,SmallVectorImpl<MachineOperand> & Cond,unsigned & TrueOp,unsigned & FalseOp,bool & Optimizable) const440*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::analyzeSelect(const MachineInstr &MI,
441*9880d681SAndroid Build Coastguard Worker                                    SmallVectorImpl<MachineOperand> &Cond,
442*9880d681SAndroid Build Coastguard Worker                                    unsigned &TrueOp, unsigned &FalseOp,
443*9880d681SAndroid Build Coastguard Worker                                    bool &Optimizable) const {
444*9880d681SAndroid Build Coastguard Worker   assert(MI.getOpcode() == Lanai::SELECT && "unknown select instruction");
445*9880d681SAndroid Build Coastguard Worker   // Select operands:
446*9880d681SAndroid Build Coastguard Worker   // 0: Def.
447*9880d681SAndroid Build Coastguard Worker   // 1: True use.
448*9880d681SAndroid Build Coastguard Worker   // 2: False use.
449*9880d681SAndroid Build Coastguard Worker   // 3: Condition code.
450*9880d681SAndroid Build Coastguard Worker   TrueOp = 1;
451*9880d681SAndroid Build Coastguard Worker   FalseOp = 2;
452*9880d681SAndroid Build Coastguard Worker   Cond.push_back(MI.getOperand(3));
453*9880d681SAndroid Build Coastguard Worker   Optimizable = true;
454*9880d681SAndroid Build Coastguard Worker   return false;
455*9880d681SAndroid Build Coastguard Worker }
456*9880d681SAndroid Build Coastguard Worker 
457*9880d681SAndroid Build Coastguard Worker // Identify instructions that can be folded into a SELECT instruction, and
458*9880d681SAndroid Build Coastguard Worker // return the defining instruction.
canFoldIntoSelect(unsigned Reg,const MachineRegisterInfo & MRI,const TargetInstrInfo * TII)459*9880d681SAndroid Build Coastguard Worker static MachineInstr *canFoldIntoSelect(unsigned Reg,
460*9880d681SAndroid Build Coastguard Worker                                        const MachineRegisterInfo &MRI,
461*9880d681SAndroid Build Coastguard Worker                                        const TargetInstrInfo *TII) {
462*9880d681SAndroid Build Coastguard Worker   if (!TargetRegisterInfo::isVirtualRegister(Reg))
463*9880d681SAndroid Build Coastguard Worker     return nullptr;
464*9880d681SAndroid Build Coastguard Worker   if (!MRI.hasOneNonDBGUse(Reg))
465*9880d681SAndroid Build Coastguard Worker     return nullptr;
466*9880d681SAndroid Build Coastguard Worker   MachineInstr *MI = MRI.getVRegDef(Reg);
467*9880d681SAndroid Build Coastguard Worker   if (!MI)
468*9880d681SAndroid Build Coastguard Worker     return nullptr;
469*9880d681SAndroid Build Coastguard Worker   // MI is folded into the SELECT by predicating it.
470*9880d681SAndroid Build Coastguard Worker   if (!MI->isPredicable())
471*9880d681SAndroid Build Coastguard Worker     return nullptr;
472*9880d681SAndroid Build Coastguard Worker   // Check if MI has any non-dead defs or physreg uses. This also detects
473*9880d681SAndroid Build Coastguard Worker   // predicated instructions which will be reading SR.
474*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 1, e = MI->getNumOperands(); i != e; ++i) {
475*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(i);
476*9880d681SAndroid Build Coastguard Worker     // Reject frame index operands.
477*9880d681SAndroid Build Coastguard Worker     if (MO.isFI() || MO.isCPI() || MO.isJTI())
478*9880d681SAndroid Build Coastguard Worker       return nullptr;
479*9880d681SAndroid Build Coastguard Worker     if (!MO.isReg())
480*9880d681SAndroid Build Coastguard Worker       continue;
481*9880d681SAndroid Build Coastguard Worker     // MI can't have any tied operands, that would conflict with predication.
482*9880d681SAndroid Build Coastguard Worker     if (MO.isTied())
483*9880d681SAndroid Build Coastguard Worker       return nullptr;
484*9880d681SAndroid Build Coastguard Worker     if (TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
485*9880d681SAndroid Build Coastguard Worker       return nullptr;
486*9880d681SAndroid Build Coastguard Worker     if (MO.isDef() && !MO.isDead())
487*9880d681SAndroid Build Coastguard Worker       return nullptr;
488*9880d681SAndroid Build Coastguard Worker   }
489*9880d681SAndroid Build Coastguard Worker   bool DontMoveAcrossStores = true;
490*9880d681SAndroid Build Coastguard Worker   if (!MI->isSafeToMove(/*AliasAnalysis=*/nullptr, DontMoveAcrossStores))
491*9880d681SAndroid Build Coastguard Worker     return nullptr;
492*9880d681SAndroid Build Coastguard Worker   return MI;
493*9880d681SAndroid Build Coastguard Worker }
494*9880d681SAndroid Build Coastguard Worker 
495*9880d681SAndroid Build Coastguard Worker MachineInstr *
optimizeSelect(MachineInstr & MI,SmallPtrSetImpl<MachineInstr * > & SeenMIs,bool PreferFalse) const496*9880d681SAndroid Build Coastguard Worker LanaiInstrInfo::optimizeSelect(MachineInstr &MI,
497*9880d681SAndroid Build Coastguard Worker                                SmallPtrSetImpl<MachineInstr *> &SeenMIs,
498*9880d681SAndroid Build Coastguard Worker                                bool PreferFalse) const {
499*9880d681SAndroid Build Coastguard Worker   assert(MI.getOpcode() == Lanai::SELECT && "unknown select instruction");
500*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
501*9880d681SAndroid Build Coastguard Worker   MachineInstr *DefMI = canFoldIntoSelect(MI.getOperand(1).getReg(), MRI, this);
502*9880d681SAndroid Build Coastguard Worker   bool Invert = !DefMI;
503*9880d681SAndroid Build Coastguard Worker   if (!DefMI)
504*9880d681SAndroid Build Coastguard Worker     DefMI = canFoldIntoSelect(MI.getOperand(2).getReg(), MRI, this);
505*9880d681SAndroid Build Coastguard Worker   if (!DefMI)
506*9880d681SAndroid Build Coastguard Worker     return nullptr;
507*9880d681SAndroid Build Coastguard Worker 
508*9880d681SAndroid Build Coastguard Worker   // Find new register class to use.
509*9880d681SAndroid Build Coastguard Worker   MachineOperand FalseReg = MI.getOperand(Invert ? 1 : 2);
510*9880d681SAndroid Build Coastguard Worker   unsigned DestReg = MI.getOperand(0).getReg();
511*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *PreviousClass = MRI.getRegClass(FalseReg.getReg());
512*9880d681SAndroid Build Coastguard Worker   if (!MRI.constrainRegClass(DestReg, PreviousClass))
513*9880d681SAndroid Build Coastguard Worker     return nullptr;
514*9880d681SAndroid Build Coastguard Worker 
515*9880d681SAndroid Build Coastguard Worker   // Create a new predicated version of DefMI.
516*9880d681SAndroid Build Coastguard Worker   MachineInstrBuilder NewMI =
517*9880d681SAndroid Build Coastguard Worker       BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), DefMI->getDesc(), DestReg);
518*9880d681SAndroid Build Coastguard Worker 
519*9880d681SAndroid Build Coastguard Worker   // Copy all the DefMI operands, excluding its (null) predicate.
520*9880d681SAndroid Build Coastguard Worker   const MCInstrDesc &DefDesc = DefMI->getDesc();
521*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 1, e = DefDesc.getNumOperands();
522*9880d681SAndroid Build Coastguard Worker        i != e && !DefDesc.OpInfo[i].isPredicate(); ++i)
523*9880d681SAndroid Build Coastguard Worker     NewMI.addOperand(DefMI->getOperand(i));
524*9880d681SAndroid Build Coastguard Worker 
525*9880d681SAndroid Build Coastguard Worker   unsigned CondCode = MI.getOperand(3).getImm();
526*9880d681SAndroid Build Coastguard Worker   if (Invert)
527*9880d681SAndroid Build Coastguard Worker     NewMI.addImm(getOppositeCondition(LPCC::CondCode(CondCode)));
528*9880d681SAndroid Build Coastguard Worker   else
529*9880d681SAndroid Build Coastguard Worker     NewMI.addImm(CondCode);
530*9880d681SAndroid Build Coastguard Worker   NewMI.copyImplicitOps(MI);
531*9880d681SAndroid Build Coastguard Worker 
532*9880d681SAndroid Build Coastguard Worker   // The output register value when the predicate is false is an implicit
533*9880d681SAndroid Build Coastguard Worker   // register operand tied to the first def.  The tie makes the register
534*9880d681SAndroid Build Coastguard Worker   // allocator ensure the FalseReg is allocated the same register as operand 0.
535*9880d681SAndroid Build Coastguard Worker   FalseReg.setImplicit();
536*9880d681SAndroid Build Coastguard Worker   NewMI.addOperand(FalseReg);
537*9880d681SAndroid Build Coastguard Worker   NewMI->tieOperands(0, NewMI->getNumOperands() - 1);
538*9880d681SAndroid Build Coastguard Worker 
539*9880d681SAndroid Build Coastguard Worker   // Update SeenMIs set: register newly created MI and erase removed DefMI.
540*9880d681SAndroid Build Coastguard Worker   SeenMIs.insert(NewMI);
541*9880d681SAndroid Build Coastguard Worker   SeenMIs.erase(DefMI);
542*9880d681SAndroid Build Coastguard Worker 
543*9880d681SAndroid Build Coastguard Worker   // If MI is inside a loop, and DefMI is outside the loop, then kill flags on
544*9880d681SAndroid Build Coastguard Worker   // DefMI would be invalid when transferred inside the loop.  Checking for a
545*9880d681SAndroid Build Coastguard Worker   // loop is expensive, but at least remove kill flags if they are in different
546*9880d681SAndroid Build Coastguard Worker   // BBs.
547*9880d681SAndroid Build Coastguard Worker   if (DefMI->getParent() != MI.getParent())
548*9880d681SAndroid Build Coastguard Worker     NewMI->clearKillInfo();
549*9880d681SAndroid Build Coastguard Worker 
550*9880d681SAndroid Build Coastguard Worker   // The caller will erase MI, but not DefMI.
551*9880d681SAndroid Build Coastguard Worker   DefMI->eraseFromParent();
552*9880d681SAndroid Build Coastguard Worker   return NewMI;
553*9880d681SAndroid Build Coastguard Worker }
554*9880d681SAndroid Build Coastguard Worker 
555*9880d681SAndroid Build Coastguard Worker // The AnalyzeBranch function is used to examine conditional instructions and
556*9880d681SAndroid Build Coastguard Worker // remove unnecessary instructions. This method is used by BranchFolder and
557*9880d681SAndroid Build Coastguard Worker // IfConverter machine function passes to improve the CFG.
558*9880d681SAndroid Build Coastguard Worker // - TrueBlock is set to the destination if condition evaluates true (it is the
559*9880d681SAndroid Build Coastguard Worker //   nullptr if the destination is the fall-through branch);
560*9880d681SAndroid Build Coastguard Worker // - FalseBlock is set to the destination if condition evaluates to false (it
561*9880d681SAndroid Build Coastguard Worker //   is the nullptr if the branch is unconditional);
562*9880d681SAndroid Build Coastguard Worker // - condition is populated with machine operands needed to generate the branch
563*9880d681SAndroid Build Coastguard Worker //   to insert in InsertBranch;
564*9880d681SAndroid Build Coastguard Worker // Returns: false if branch could successfully be analyzed.
analyzeBranch(MachineBasicBlock & MBB,MachineBasicBlock * & TrueBlock,MachineBasicBlock * & FalseBlock,SmallVectorImpl<MachineOperand> & Condition,bool AllowModify) const565*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
566*9880d681SAndroid Build Coastguard Worker                                    MachineBasicBlock *&TrueBlock,
567*9880d681SAndroid Build Coastguard Worker                                    MachineBasicBlock *&FalseBlock,
568*9880d681SAndroid Build Coastguard Worker                                    SmallVectorImpl<MachineOperand> &Condition,
569*9880d681SAndroid Build Coastguard Worker                                    bool AllowModify) const {
570*9880d681SAndroid Build Coastguard Worker   // Iterator to current instruction being considered.
571*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator Instruction = MBB.end();
572*9880d681SAndroid Build Coastguard Worker 
573*9880d681SAndroid Build Coastguard Worker   // Start from the bottom of the block and work up, examining the
574*9880d681SAndroid Build Coastguard Worker   // terminator instructions.
575*9880d681SAndroid Build Coastguard Worker   while (Instruction != MBB.begin()) {
576*9880d681SAndroid Build Coastguard Worker     --Instruction;
577*9880d681SAndroid Build Coastguard Worker 
578*9880d681SAndroid Build Coastguard Worker     // Skip over debug values.
579*9880d681SAndroid Build Coastguard Worker     if (Instruction->isDebugValue())
580*9880d681SAndroid Build Coastguard Worker       continue;
581*9880d681SAndroid Build Coastguard Worker 
582*9880d681SAndroid Build Coastguard Worker     // Working from the bottom, when we see a non-terminator
583*9880d681SAndroid Build Coastguard Worker     // instruction, we're done.
584*9880d681SAndroid Build Coastguard Worker     if (!isUnpredicatedTerminator(*Instruction))
585*9880d681SAndroid Build Coastguard Worker       break;
586*9880d681SAndroid Build Coastguard Worker 
587*9880d681SAndroid Build Coastguard Worker     // A terminator that isn't a branch can't easily be handled
588*9880d681SAndroid Build Coastguard Worker     // by this analysis.
589*9880d681SAndroid Build Coastguard Worker     if (!Instruction->isBranch())
590*9880d681SAndroid Build Coastguard Worker       return true;
591*9880d681SAndroid Build Coastguard Worker 
592*9880d681SAndroid Build Coastguard Worker     // Handle unconditional branches.
593*9880d681SAndroid Build Coastguard Worker     if (Instruction->getOpcode() == Lanai::BT) {
594*9880d681SAndroid Build Coastguard Worker       if (!AllowModify) {
595*9880d681SAndroid Build Coastguard Worker         TrueBlock = Instruction->getOperand(0).getMBB();
596*9880d681SAndroid Build Coastguard Worker         continue;
597*9880d681SAndroid Build Coastguard Worker       }
598*9880d681SAndroid Build Coastguard Worker 
599*9880d681SAndroid Build Coastguard Worker       // If the block has any instructions after a branch, delete them.
600*9880d681SAndroid Build Coastguard Worker       while (std::next(Instruction) != MBB.end()) {
601*9880d681SAndroid Build Coastguard Worker         std::next(Instruction)->eraseFromParent();
602*9880d681SAndroid Build Coastguard Worker       }
603*9880d681SAndroid Build Coastguard Worker 
604*9880d681SAndroid Build Coastguard Worker       Condition.clear();
605*9880d681SAndroid Build Coastguard Worker       FalseBlock = nullptr;
606*9880d681SAndroid Build Coastguard Worker 
607*9880d681SAndroid Build Coastguard Worker       // Delete the jump if it's equivalent to a fall-through.
608*9880d681SAndroid Build Coastguard Worker       if (MBB.isLayoutSuccessor(Instruction->getOperand(0).getMBB())) {
609*9880d681SAndroid Build Coastguard Worker         TrueBlock = nullptr;
610*9880d681SAndroid Build Coastguard Worker         Instruction->eraseFromParent();
611*9880d681SAndroid Build Coastguard Worker         Instruction = MBB.end();
612*9880d681SAndroid Build Coastguard Worker         continue;
613*9880d681SAndroid Build Coastguard Worker       }
614*9880d681SAndroid Build Coastguard Worker 
615*9880d681SAndroid Build Coastguard Worker       // TrueBlock is used to indicate the unconditional destination.
616*9880d681SAndroid Build Coastguard Worker       TrueBlock = Instruction->getOperand(0).getMBB();
617*9880d681SAndroid Build Coastguard Worker       continue;
618*9880d681SAndroid Build Coastguard Worker     }
619*9880d681SAndroid Build Coastguard Worker 
620*9880d681SAndroid Build Coastguard Worker     // Handle conditional branches
621*9880d681SAndroid Build Coastguard Worker     unsigned Opcode = Instruction->getOpcode();
622*9880d681SAndroid Build Coastguard Worker     if (Opcode != Lanai::BRCC)
623*9880d681SAndroid Build Coastguard Worker       return true; // Unknown opcode.
624*9880d681SAndroid Build Coastguard Worker 
625*9880d681SAndroid Build Coastguard Worker     // Multiple conditional branches are not handled here so only proceed if
626*9880d681SAndroid Build Coastguard Worker     // there are no conditions enqueued.
627*9880d681SAndroid Build Coastguard Worker     if (Condition.empty()) {
628*9880d681SAndroid Build Coastguard Worker       LPCC::CondCode BranchCond =
629*9880d681SAndroid Build Coastguard Worker           static_cast<LPCC::CondCode>(Instruction->getOperand(1).getImm());
630*9880d681SAndroid Build Coastguard Worker 
631*9880d681SAndroid Build Coastguard Worker       // TrueBlock is the target of the previously seen unconditional branch.
632*9880d681SAndroid Build Coastguard Worker       FalseBlock = TrueBlock;
633*9880d681SAndroid Build Coastguard Worker       TrueBlock = Instruction->getOperand(0).getMBB();
634*9880d681SAndroid Build Coastguard Worker       Condition.push_back(MachineOperand::CreateImm(BranchCond));
635*9880d681SAndroid Build Coastguard Worker       continue;
636*9880d681SAndroid Build Coastguard Worker     }
637*9880d681SAndroid Build Coastguard Worker 
638*9880d681SAndroid Build Coastguard Worker     // Multiple conditional branches are not handled.
639*9880d681SAndroid Build Coastguard Worker     return true;
640*9880d681SAndroid Build Coastguard Worker   }
641*9880d681SAndroid Build Coastguard Worker 
642*9880d681SAndroid Build Coastguard Worker   // Return false indicating branch successfully analyzed.
643*9880d681SAndroid Build Coastguard Worker   return false;
644*9880d681SAndroid Build Coastguard Worker }
645*9880d681SAndroid Build Coastguard Worker 
646*9880d681SAndroid Build Coastguard Worker // ReverseBranchCondition - Reverses the branch condition of the specified
647*9880d681SAndroid Build Coastguard Worker // condition list, returning false on success and true if it cannot be
648*9880d681SAndroid Build Coastguard Worker // reversed.
ReverseBranchCondition(SmallVectorImpl<llvm::MachineOperand> & Condition) const649*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::ReverseBranchCondition(
650*9880d681SAndroid Build Coastguard Worker     SmallVectorImpl<llvm::MachineOperand> &Condition) const {
651*9880d681SAndroid Build Coastguard Worker   assert((Condition.size() == 1) &&
652*9880d681SAndroid Build Coastguard Worker          "Lanai branch conditions should have one component.");
653*9880d681SAndroid Build Coastguard Worker 
654*9880d681SAndroid Build Coastguard Worker   LPCC::CondCode BranchCond =
655*9880d681SAndroid Build Coastguard Worker       static_cast<LPCC::CondCode>(Condition[0].getImm());
656*9880d681SAndroid Build Coastguard Worker   Condition[0].setImm(getOppositeCondition(BranchCond));
657*9880d681SAndroid Build Coastguard Worker   return false;
658*9880d681SAndroid Build Coastguard Worker }
659*9880d681SAndroid Build Coastguard Worker 
660*9880d681SAndroid Build Coastguard Worker // Insert the branch with condition specified in condition and given targets
661*9880d681SAndroid Build Coastguard Worker // (TrueBlock and FalseBlock). This function returns the number of machine
662*9880d681SAndroid Build Coastguard Worker // instructions inserted.
InsertBranch(MachineBasicBlock & MBB,MachineBasicBlock * TrueBlock,MachineBasicBlock * FalseBlock,ArrayRef<MachineOperand> Condition,const DebugLoc & DL) const663*9880d681SAndroid Build Coastguard Worker unsigned LanaiInstrInfo::InsertBranch(MachineBasicBlock &MBB,
664*9880d681SAndroid Build Coastguard Worker                                       MachineBasicBlock *TrueBlock,
665*9880d681SAndroid Build Coastguard Worker                                       MachineBasicBlock *FalseBlock,
666*9880d681SAndroid Build Coastguard Worker                                       ArrayRef<MachineOperand> Condition,
667*9880d681SAndroid Build Coastguard Worker                                       const DebugLoc &DL) const {
668*9880d681SAndroid Build Coastguard Worker   // Shouldn't be a fall through.
669*9880d681SAndroid Build Coastguard Worker   assert(TrueBlock && "InsertBranch must not be told to insert a fallthrough");
670*9880d681SAndroid Build Coastguard Worker 
671*9880d681SAndroid Build Coastguard Worker   // If condition is empty then an unconditional branch is being inserted.
672*9880d681SAndroid Build Coastguard Worker   if (Condition.empty()) {
673*9880d681SAndroid Build Coastguard Worker     assert(!FalseBlock && "Unconditional branch with multiple successors!");
674*9880d681SAndroid Build Coastguard Worker     BuildMI(&MBB, DL, get(Lanai::BT)).addMBB(TrueBlock);
675*9880d681SAndroid Build Coastguard Worker     return 1;
676*9880d681SAndroid Build Coastguard Worker   }
677*9880d681SAndroid Build Coastguard Worker 
678*9880d681SAndroid Build Coastguard Worker   // Else a conditional branch is inserted.
679*9880d681SAndroid Build Coastguard Worker   assert((Condition.size() == 1) &&
680*9880d681SAndroid Build Coastguard Worker          "Lanai branch conditions should have one component.");
681*9880d681SAndroid Build Coastguard Worker   unsigned ConditionalCode = Condition[0].getImm();
682*9880d681SAndroid Build Coastguard Worker   BuildMI(&MBB, DL, get(Lanai::BRCC)).addMBB(TrueBlock).addImm(ConditionalCode);
683*9880d681SAndroid Build Coastguard Worker 
684*9880d681SAndroid Build Coastguard Worker   // If no false block, then false behavior is fall through and no branch needs
685*9880d681SAndroid Build Coastguard Worker   // to be inserted.
686*9880d681SAndroid Build Coastguard Worker   if (!FalseBlock)
687*9880d681SAndroid Build Coastguard Worker     return 1;
688*9880d681SAndroid Build Coastguard Worker 
689*9880d681SAndroid Build Coastguard Worker   BuildMI(&MBB, DL, get(Lanai::BT)).addMBB(FalseBlock);
690*9880d681SAndroid Build Coastguard Worker   return 2;
691*9880d681SAndroid Build Coastguard Worker }
692*9880d681SAndroid Build Coastguard Worker 
RemoveBranch(MachineBasicBlock & MBB) const693*9880d681SAndroid Build Coastguard Worker unsigned LanaiInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
694*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator Instruction = MBB.end();
695*9880d681SAndroid Build Coastguard Worker   unsigned Count = 0;
696*9880d681SAndroid Build Coastguard Worker 
697*9880d681SAndroid Build Coastguard Worker   while (Instruction != MBB.begin()) {
698*9880d681SAndroid Build Coastguard Worker     --Instruction;
699*9880d681SAndroid Build Coastguard Worker     if (Instruction->isDebugValue())
700*9880d681SAndroid Build Coastguard Worker       continue;
701*9880d681SAndroid Build Coastguard Worker     if (Instruction->getOpcode() != Lanai::BT &&
702*9880d681SAndroid Build Coastguard Worker         Instruction->getOpcode() != Lanai::BRCC) {
703*9880d681SAndroid Build Coastguard Worker       break;
704*9880d681SAndroid Build Coastguard Worker     }
705*9880d681SAndroid Build Coastguard Worker 
706*9880d681SAndroid Build Coastguard Worker     // Remove the branch.
707*9880d681SAndroid Build Coastguard Worker     Instruction->eraseFromParent();
708*9880d681SAndroid Build Coastguard Worker     Instruction = MBB.end();
709*9880d681SAndroid Build Coastguard Worker     ++Count;
710*9880d681SAndroid Build Coastguard Worker   }
711*9880d681SAndroid Build Coastguard Worker 
712*9880d681SAndroid Build Coastguard Worker   return Count;
713*9880d681SAndroid Build Coastguard Worker }
714*9880d681SAndroid Build Coastguard Worker 
isLoadFromStackSlot(const MachineInstr & MI,int & FrameIndex) const715*9880d681SAndroid Build Coastguard Worker unsigned LanaiInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
716*9880d681SAndroid Build Coastguard Worker                                              int &FrameIndex) const {
717*9880d681SAndroid Build Coastguard Worker   if (MI.getOpcode() == Lanai::LDW_RI)
718*9880d681SAndroid Build Coastguard Worker     if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
719*9880d681SAndroid Build Coastguard Worker         MI.getOperand(2).getImm() == 0) {
720*9880d681SAndroid Build Coastguard Worker       FrameIndex = MI.getOperand(1).getIndex();
721*9880d681SAndroid Build Coastguard Worker       return MI.getOperand(0).getReg();
722*9880d681SAndroid Build Coastguard Worker     }
723*9880d681SAndroid Build Coastguard Worker   return 0;
724*9880d681SAndroid Build Coastguard Worker }
725*9880d681SAndroid Build Coastguard Worker 
isLoadFromStackSlotPostFE(const MachineInstr & MI,int & FrameIndex) const726*9880d681SAndroid Build Coastguard Worker unsigned LanaiInstrInfo::isLoadFromStackSlotPostFE(const MachineInstr &MI,
727*9880d681SAndroid Build Coastguard Worker                                                    int &FrameIndex) const {
728*9880d681SAndroid Build Coastguard Worker   if (MI.getOpcode() == Lanai::LDW_RI) {
729*9880d681SAndroid Build Coastguard Worker     unsigned Reg;
730*9880d681SAndroid Build Coastguard Worker     if ((Reg = isLoadFromStackSlot(MI, FrameIndex)))
731*9880d681SAndroid Build Coastguard Worker       return Reg;
732*9880d681SAndroid Build Coastguard Worker     // Check for post-frame index elimination operations
733*9880d681SAndroid Build Coastguard Worker     const MachineMemOperand *Dummy;
734*9880d681SAndroid Build Coastguard Worker     return hasLoadFromStackSlot(MI, Dummy, FrameIndex);
735*9880d681SAndroid Build Coastguard Worker   }
736*9880d681SAndroid Build Coastguard Worker   return 0;
737*9880d681SAndroid Build Coastguard Worker }
738*9880d681SAndroid Build Coastguard Worker 
isStoreToStackSlot(const MachineInstr & MI,int & FrameIndex) const739*9880d681SAndroid Build Coastguard Worker unsigned LanaiInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
740*9880d681SAndroid Build Coastguard Worker                                             int &FrameIndex) const {
741*9880d681SAndroid Build Coastguard Worker   if (MI.getOpcode() == Lanai::SW_RI)
742*9880d681SAndroid Build Coastguard Worker     if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&
743*9880d681SAndroid Build Coastguard Worker         MI.getOperand(1).getImm() == 0) {
744*9880d681SAndroid Build Coastguard Worker       FrameIndex = MI.getOperand(0).getIndex();
745*9880d681SAndroid Build Coastguard Worker       return MI.getOperand(2).getReg();
746*9880d681SAndroid Build Coastguard Worker     }
747*9880d681SAndroid Build Coastguard Worker   return 0;
748*9880d681SAndroid Build Coastguard Worker }
749*9880d681SAndroid Build Coastguard Worker 
getMemOpBaseRegImmOfsWidth(MachineInstr & LdSt,unsigned & BaseReg,int64_t & Offset,unsigned & Width,const TargetRegisterInfo * TRI) const750*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::getMemOpBaseRegImmOfsWidth(
751*9880d681SAndroid Build Coastguard Worker     MachineInstr &LdSt, unsigned &BaseReg, int64_t &Offset, unsigned &Width,
752*9880d681SAndroid Build Coastguard Worker     const TargetRegisterInfo *TRI) const {
753*9880d681SAndroid Build Coastguard Worker   // Handle only loads/stores with base register followed by immediate offset
754*9880d681SAndroid Build Coastguard Worker   // and with add as ALU op.
755*9880d681SAndroid Build Coastguard Worker   if (LdSt.getNumOperands() != 4)
756*9880d681SAndroid Build Coastguard Worker     return false;
757*9880d681SAndroid Build Coastguard Worker   if (!LdSt.getOperand(1).isReg() || !LdSt.getOperand(2).isImm() ||
758*9880d681SAndroid Build Coastguard Worker       !(LdSt.getOperand(3).isImm() && LdSt.getOperand(3).getImm() == LPAC::ADD))
759*9880d681SAndroid Build Coastguard Worker     return false;
760*9880d681SAndroid Build Coastguard Worker 
761*9880d681SAndroid Build Coastguard Worker   switch (LdSt.getOpcode()) {
762*9880d681SAndroid Build Coastguard Worker   default:
763*9880d681SAndroid Build Coastguard Worker     return false;
764*9880d681SAndroid Build Coastguard Worker   case Lanai::LDW_RI:
765*9880d681SAndroid Build Coastguard Worker   case Lanai::LDW_RR:
766*9880d681SAndroid Build Coastguard Worker   case Lanai::SW_RR:
767*9880d681SAndroid Build Coastguard Worker   case Lanai::SW_RI:
768*9880d681SAndroid Build Coastguard Worker     Width = 4;
769*9880d681SAndroid Build Coastguard Worker     break;
770*9880d681SAndroid Build Coastguard Worker   case Lanai::LDHs_RI:
771*9880d681SAndroid Build Coastguard Worker   case Lanai::LDHz_RI:
772*9880d681SAndroid Build Coastguard Worker   case Lanai::STH_RI:
773*9880d681SAndroid Build Coastguard Worker     Width = 2;
774*9880d681SAndroid Build Coastguard Worker     break;
775*9880d681SAndroid Build Coastguard Worker   case Lanai::LDBs_RI:
776*9880d681SAndroid Build Coastguard Worker   case Lanai::LDBz_RI:
777*9880d681SAndroid Build Coastguard Worker   case Lanai::STB_RI:
778*9880d681SAndroid Build Coastguard Worker     Width = 1;
779*9880d681SAndroid Build Coastguard Worker     break;
780*9880d681SAndroid Build Coastguard Worker   }
781*9880d681SAndroid Build Coastguard Worker 
782*9880d681SAndroid Build Coastguard Worker   BaseReg = LdSt.getOperand(1).getReg();
783*9880d681SAndroid Build Coastguard Worker   Offset = LdSt.getOperand(2).getImm();
784*9880d681SAndroid Build Coastguard Worker   return true;
785*9880d681SAndroid Build Coastguard Worker }
786*9880d681SAndroid Build Coastguard Worker 
getMemOpBaseRegImmOfs(MachineInstr & LdSt,unsigned & BaseReg,int64_t & Offset,const TargetRegisterInfo * TRI) const787*9880d681SAndroid Build Coastguard Worker bool LanaiInstrInfo::getMemOpBaseRegImmOfs(
788*9880d681SAndroid Build Coastguard Worker     MachineInstr &LdSt, unsigned &BaseReg, int64_t &Offset,
789*9880d681SAndroid Build Coastguard Worker     const TargetRegisterInfo *TRI) const {
790*9880d681SAndroid Build Coastguard Worker   switch (LdSt.getOpcode()) {
791*9880d681SAndroid Build Coastguard Worker   default:
792*9880d681SAndroid Build Coastguard Worker     return false;
793*9880d681SAndroid Build Coastguard Worker   case Lanai::LDW_RI:
794*9880d681SAndroid Build Coastguard Worker   case Lanai::LDW_RR:
795*9880d681SAndroid Build Coastguard Worker   case Lanai::SW_RR:
796*9880d681SAndroid Build Coastguard Worker   case Lanai::SW_RI:
797*9880d681SAndroid Build Coastguard Worker   case Lanai::LDHs_RI:
798*9880d681SAndroid Build Coastguard Worker   case Lanai::LDHz_RI:
799*9880d681SAndroid Build Coastguard Worker   case Lanai::STH_RI:
800*9880d681SAndroid Build Coastguard Worker   case Lanai::LDBs_RI:
801*9880d681SAndroid Build Coastguard Worker   case Lanai::LDBz_RI:
802*9880d681SAndroid Build Coastguard Worker     unsigned Width;
803*9880d681SAndroid Build Coastguard Worker     return getMemOpBaseRegImmOfsWidth(LdSt, BaseReg, Offset, Width, TRI);
804*9880d681SAndroid Build Coastguard Worker   }
805*9880d681SAndroid Build Coastguard Worker }
806