xref: /aosp_15_r20/external/llvm/lib/Target/Hexagon/HexagonInstrInfo.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
1*9880d681SAndroid Build Coastguard Worker //===-- HexagonInstrInfo.cpp - Hexagon Instruction Information ------------===//
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 Hexagon 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 "HexagonInstrInfo.h"
15*9880d681SAndroid Build Coastguard Worker #include "Hexagon.h"
16*9880d681SAndroid Build Coastguard Worker #include "HexagonRegisterInfo.h"
17*9880d681SAndroid Build Coastguard Worker #include "HexagonSubtarget.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/DFAPacketizer.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFrameInfo.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineInstrBuilder.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineMemOperand.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/PseudoSourceValue.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/CommandLine.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MathExtras.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
31*9880d681SAndroid Build Coastguard Worker #include <cctype>
32*9880d681SAndroid Build Coastguard Worker 
33*9880d681SAndroid Build Coastguard Worker using namespace llvm;
34*9880d681SAndroid Build Coastguard Worker 
35*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "hexagon-instrinfo"
36*9880d681SAndroid Build Coastguard Worker 
37*9880d681SAndroid Build Coastguard Worker #define GET_INSTRINFO_CTOR_DTOR
38*9880d681SAndroid Build Coastguard Worker #define GET_INSTRMAP_INFO
39*9880d681SAndroid Build Coastguard Worker #include "HexagonGenInstrInfo.inc"
40*9880d681SAndroid Build Coastguard Worker #include "HexagonGenDFAPacketizer.inc"
41*9880d681SAndroid Build Coastguard Worker 
42*9880d681SAndroid Build Coastguard Worker using namespace llvm;
43*9880d681SAndroid Build Coastguard Worker 
44*9880d681SAndroid Build Coastguard Worker cl::opt<bool> ScheduleInlineAsm("hexagon-sched-inline-asm", cl::Hidden,
45*9880d681SAndroid Build Coastguard Worker   cl::init(false), cl::desc("Do not consider inline-asm a scheduling/"
46*9880d681SAndroid Build Coastguard Worker                             "packetization boundary."));
47*9880d681SAndroid Build Coastguard Worker 
48*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> EnableBranchPrediction("hexagon-enable-branch-prediction",
49*9880d681SAndroid Build Coastguard Worker   cl::Hidden, cl::init(true), cl::desc("Enable branch prediction"));
50*9880d681SAndroid Build Coastguard Worker 
51*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> DisableNVSchedule("disable-hexagon-nv-schedule",
52*9880d681SAndroid Build Coastguard Worker   cl::Hidden, cl::ZeroOrMore, cl::init(false),
53*9880d681SAndroid Build Coastguard Worker   cl::desc("Disable schedule adjustment for new value stores."));
54*9880d681SAndroid Build Coastguard Worker 
55*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> EnableTimingClassLatency(
56*9880d681SAndroid Build Coastguard Worker   "enable-timing-class-latency", cl::Hidden, cl::init(false),
57*9880d681SAndroid Build Coastguard Worker   cl::desc("Enable timing class latency"));
58*9880d681SAndroid Build Coastguard Worker 
59*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> EnableALUForwarding(
60*9880d681SAndroid Build Coastguard Worker   "enable-alu-forwarding", cl::Hidden, cl::init(true),
61*9880d681SAndroid Build Coastguard Worker   cl::desc("Enable vec alu forwarding"));
62*9880d681SAndroid Build Coastguard Worker 
63*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> EnableACCForwarding(
64*9880d681SAndroid Build Coastguard Worker   "enable-acc-forwarding", cl::Hidden, cl::init(true),
65*9880d681SAndroid Build Coastguard Worker   cl::desc("Enable vec acc forwarding"));
66*9880d681SAndroid Build Coastguard Worker 
67*9880d681SAndroid Build Coastguard Worker static cl::opt<bool> BranchRelaxAsmLarge("branch-relax-asm-large",
68*9880d681SAndroid Build Coastguard Worker   cl::init(true), cl::Hidden, cl::ZeroOrMore, cl::desc("branch relax asm"));
69*9880d681SAndroid Build Coastguard Worker 
70*9880d681SAndroid Build Coastguard Worker ///
71*9880d681SAndroid Build Coastguard Worker /// Constants for Hexagon instructions.
72*9880d681SAndroid Build Coastguard Worker ///
73*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMV_OFFSET_MAX_128B = 896;   // #s4: -8*128...7*128
74*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMV_OFFSET_MIN_128B = -1024; // #s4
75*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMV_OFFSET_MAX = 448;  // #s4: -8*64...7*64
76*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMV_OFFSET_MIN = -512; // #s4
77*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMW_OFFSET_MAX = 4095;
78*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMW_OFFSET_MIN = -4096;
79*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMD_OFFSET_MAX = 8191;
80*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMD_OFFSET_MIN = -8192;
81*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMH_OFFSET_MAX = 2047;
82*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMH_OFFSET_MIN = -2048;
83*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMB_OFFSET_MAX = 1023;
84*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMB_OFFSET_MIN = -1024;
85*9880d681SAndroid Build Coastguard Worker const int Hexagon_ADDI_OFFSET_MAX = 32767;
86*9880d681SAndroid Build Coastguard Worker const int Hexagon_ADDI_OFFSET_MIN = -32768;
87*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMD_AUTOINC_MAX = 56;
88*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMD_AUTOINC_MIN = -64;
89*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMW_AUTOINC_MAX = 28;
90*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMW_AUTOINC_MIN = -32;
91*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMH_AUTOINC_MAX = 14;
92*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMH_AUTOINC_MIN = -16;
93*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMB_AUTOINC_MAX = 7;
94*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMB_AUTOINC_MIN = -8;
95*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMV_AUTOINC_MAX = 192;   // #s3
96*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMV_AUTOINC_MIN = -256;  // #s3
97*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMV_AUTOINC_MAX_128B = 384;  // #s3
98*9880d681SAndroid Build Coastguard Worker const int Hexagon_MEMV_AUTOINC_MIN_128B = -512; // #s3
99*9880d681SAndroid Build Coastguard Worker 
100*9880d681SAndroid Build Coastguard Worker // Pin the vtable to this file.
anchor()101*9880d681SAndroid Build Coastguard Worker void HexagonInstrInfo::anchor() {}
102*9880d681SAndroid Build Coastguard Worker 
HexagonInstrInfo(HexagonSubtarget & ST)103*9880d681SAndroid Build Coastguard Worker HexagonInstrInfo::HexagonInstrInfo(HexagonSubtarget &ST)
104*9880d681SAndroid Build Coastguard Worker     : HexagonGenInstrInfo(Hexagon::ADJCALLSTACKDOWN, Hexagon::ADJCALLSTACKUP),
105*9880d681SAndroid Build Coastguard Worker       RI() {}
106*9880d681SAndroid Build Coastguard Worker 
107*9880d681SAndroid Build Coastguard Worker 
isIntRegForSubInst(unsigned Reg)108*9880d681SAndroid Build Coastguard Worker static bool isIntRegForSubInst(unsigned Reg) {
109*9880d681SAndroid Build Coastguard Worker   return (Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||
110*9880d681SAndroid Build Coastguard Worker          (Reg >= Hexagon::R16 && Reg <= Hexagon::R23);
111*9880d681SAndroid Build Coastguard Worker }
112*9880d681SAndroid Build Coastguard Worker 
113*9880d681SAndroid Build Coastguard Worker 
isDblRegForSubInst(unsigned Reg,const HexagonRegisterInfo & HRI)114*9880d681SAndroid Build Coastguard Worker static bool isDblRegForSubInst(unsigned Reg, const HexagonRegisterInfo &HRI) {
115*9880d681SAndroid Build Coastguard Worker   return isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::subreg_loreg)) &&
116*9880d681SAndroid Build Coastguard Worker          isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::subreg_hireg));
117*9880d681SAndroid Build Coastguard Worker }
118*9880d681SAndroid Build Coastguard Worker 
119*9880d681SAndroid Build Coastguard Worker 
120*9880d681SAndroid Build Coastguard Worker /// Calculate number of instructions excluding the debug instructions.
nonDbgMICount(MachineBasicBlock::const_instr_iterator MIB,MachineBasicBlock::const_instr_iterator MIE)121*9880d681SAndroid Build Coastguard Worker static unsigned nonDbgMICount(MachineBasicBlock::const_instr_iterator MIB,
122*9880d681SAndroid Build Coastguard Worker                               MachineBasicBlock::const_instr_iterator MIE) {
123*9880d681SAndroid Build Coastguard Worker   unsigned Count = 0;
124*9880d681SAndroid Build Coastguard Worker   for (; MIB != MIE; ++MIB) {
125*9880d681SAndroid Build Coastguard Worker     if (!MIB->isDebugValue())
126*9880d681SAndroid Build Coastguard Worker       ++Count;
127*9880d681SAndroid Build Coastguard Worker   }
128*9880d681SAndroid Build Coastguard Worker   return Count;
129*9880d681SAndroid Build Coastguard Worker }
130*9880d681SAndroid Build Coastguard Worker 
131*9880d681SAndroid Build Coastguard Worker 
132*9880d681SAndroid Build Coastguard Worker /// Find the hardware loop instruction used to set-up the specified loop.
133*9880d681SAndroid Build Coastguard Worker /// On Hexagon, we have two instructions used to set-up the hardware loop
134*9880d681SAndroid Build Coastguard Worker /// (LOOP0, LOOP1) with corresponding endloop (ENDLOOP0, ENDLOOP1) instructions
135*9880d681SAndroid Build Coastguard Worker /// to indicate the end of a loop.
findLoopInstr(MachineBasicBlock * BB,int EndLoopOp,SmallPtrSet<MachineBasicBlock *,8> & Visited)136*9880d681SAndroid Build Coastguard Worker static MachineInstr *findLoopInstr(MachineBasicBlock *BB, int EndLoopOp,
137*9880d681SAndroid Build Coastguard Worker       SmallPtrSet<MachineBasicBlock *, 8> &Visited) {
138*9880d681SAndroid Build Coastguard Worker   int LOOPi;
139*9880d681SAndroid Build Coastguard Worker   int LOOPr;
140*9880d681SAndroid Build Coastguard Worker   if (EndLoopOp == Hexagon::ENDLOOP0) {
141*9880d681SAndroid Build Coastguard Worker     LOOPi = Hexagon::J2_loop0i;
142*9880d681SAndroid Build Coastguard Worker     LOOPr = Hexagon::J2_loop0r;
143*9880d681SAndroid Build Coastguard Worker   } else { // EndLoopOp == Hexagon::EndLOOP1
144*9880d681SAndroid Build Coastguard Worker     LOOPi = Hexagon::J2_loop1i;
145*9880d681SAndroid Build Coastguard Worker     LOOPr = Hexagon::J2_loop1r;
146*9880d681SAndroid Build Coastguard Worker   }
147*9880d681SAndroid Build Coastguard Worker 
148*9880d681SAndroid Build Coastguard Worker   // The loop set-up instruction will be in a predecessor block
149*9880d681SAndroid Build Coastguard Worker   for (MachineBasicBlock::pred_iterator PB = BB->pred_begin(),
150*9880d681SAndroid Build Coastguard Worker          PE = BB->pred_end(); PB != PE; ++PB) {
151*9880d681SAndroid Build Coastguard Worker     // If this has been visited, already skip it.
152*9880d681SAndroid Build Coastguard Worker     if (!Visited.insert(*PB).second)
153*9880d681SAndroid Build Coastguard Worker       continue;
154*9880d681SAndroid Build Coastguard Worker     if (*PB == BB)
155*9880d681SAndroid Build Coastguard Worker       continue;
156*9880d681SAndroid Build Coastguard Worker     for (MachineBasicBlock::reverse_instr_iterator I = (*PB)->instr_rbegin(),
157*9880d681SAndroid Build Coastguard Worker            E = (*PB)->instr_rend(); I != E; ++I) {
158*9880d681SAndroid Build Coastguard Worker       int Opc = I->getOpcode();
159*9880d681SAndroid Build Coastguard Worker       if (Opc == LOOPi || Opc == LOOPr)
160*9880d681SAndroid Build Coastguard Worker         return &*I;
161*9880d681SAndroid Build Coastguard Worker       // We've reached a different loop, which means the loop0 has been removed.
162*9880d681SAndroid Build Coastguard Worker       if (Opc == EndLoopOp)
163*9880d681SAndroid Build Coastguard Worker         return 0;
164*9880d681SAndroid Build Coastguard Worker     }
165*9880d681SAndroid Build Coastguard Worker     // Check the predecessors for the LOOP instruction.
166*9880d681SAndroid Build Coastguard Worker     MachineInstr *loop = findLoopInstr(*PB, EndLoopOp, Visited);
167*9880d681SAndroid Build Coastguard Worker     if (loop)
168*9880d681SAndroid Build Coastguard Worker       return loop;
169*9880d681SAndroid Build Coastguard Worker   }
170*9880d681SAndroid Build Coastguard Worker   return 0;
171*9880d681SAndroid Build Coastguard Worker }
172*9880d681SAndroid Build Coastguard Worker 
173*9880d681SAndroid Build Coastguard Worker 
174*9880d681SAndroid Build Coastguard Worker /// Gather register def/uses from MI.
175*9880d681SAndroid Build Coastguard Worker /// This treats possible (predicated) defs as actually happening ones
176*9880d681SAndroid Build Coastguard Worker /// (conservatively).
parseOperands(const MachineInstr * MI,SmallVector<unsigned,4> & Defs,SmallVector<unsigned,8> & Uses)177*9880d681SAndroid Build Coastguard Worker static inline void parseOperands(const MachineInstr *MI,
178*9880d681SAndroid Build Coastguard Worker       SmallVector<unsigned, 4> &Defs, SmallVector<unsigned, 8> &Uses) {
179*9880d681SAndroid Build Coastguard Worker   Defs.clear();
180*9880d681SAndroid Build Coastguard Worker   Uses.clear();
181*9880d681SAndroid Build Coastguard Worker 
182*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
183*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(i);
184*9880d681SAndroid Build Coastguard Worker 
185*9880d681SAndroid Build Coastguard Worker     if (!MO.isReg())
186*9880d681SAndroid Build Coastguard Worker       continue;
187*9880d681SAndroid Build Coastguard Worker 
188*9880d681SAndroid Build Coastguard Worker     unsigned Reg = MO.getReg();
189*9880d681SAndroid Build Coastguard Worker     if (!Reg)
190*9880d681SAndroid Build Coastguard Worker       continue;
191*9880d681SAndroid Build Coastguard Worker 
192*9880d681SAndroid Build Coastguard Worker     if (MO.isUse())
193*9880d681SAndroid Build Coastguard Worker       Uses.push_back(MO.getReg());
194*9880d681SAndroid Build Coastguard Worker 
195*9880d681SAndroid Build Coastguard Worker     if (MO.isDef())
196*9880d681SAndroid Build Coastguard Worker       Defs.push_back(MO.getReg());
197*9880d681SAndroid Build Coastguard Worker   }
198*9880d681SAndroid Build Coastguard Worker }
199*9880d681SAndroid Build Coastguard Worker 
200*9880d681SAndroid Build Coastguard Worker 
201*9880d681SAndroid Build Coastguard Worker // Position dependent, so check twice for swap.
isDuplexPairMatch(unsigned Ga,unsigned Gb)202*9880d681SAndroid Build Coastguard Worker static bool isDuplexPairMatch(unsigned Ga, unsigned Gb) {
203*9880d681SAndroid Build Coastguard Worker   switch (Ga) {
204*9880d681SAndroid Build Coastguard Worker   case HexagonII::HSIG_None:
205*9880d681SAndroid Build Coastguard Worker   default:
206*9880d681SAndroid Build Coastguard Worker     return false;
207*9880d681SAndroid Build Coastguard Worker   case HexagonII::HSIG_L1:
208*9880d681SAndroid Build Coastguard Worker     return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_A);
209*9880d681SAndroid Build Coastguard Worker   case HexagonII::HSIG_L2:
210*9880d681SAndroid Build Coastguard Worker     return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
211*9880d681SAndroid Build Coastguard Worker             Gb == HexagonII::HSIG_A);
212*9880d681SAndroid Build Coastguard Worker   case HexagonII::HSIG_S1:
213*9880d681SAndroid Build Coastguard Worker     return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
214*9880d681SAndroid Build Coastguard Worker             Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_A);
215*9880d681SAndroid Build Coastguard Worker   case HexagonII::HSIG_S2:
216*9880d681SAndroid Build Coastguard Worker     return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
217*9880d681SAndroid Build Coastguard Worker             Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_S2 ||
218*9880d681SAndroid Build Coastguard Worker             Gb == HexagonII::HSIG_A);
219*9880d681SAndroid Build Coastguard Worker   case HexagonII::HSIG_A:
220*9880d681SAndroid Build Coastguard Worker     return (Gb == HexagonII::HSIG_A);
221*9880d681SAndroid Build Coastguard Worker   case HexagonII::HSIG_Compound:
222*9880d681SAndroid Build Coastguard Worker     return (Gb == HexagonII::HSIG_Compound);
223*9880d681SAndroid Build Coastguard Worker   }
224*9880d681SAndroid Build Coastguard Worker   return false;
225*9880d681SAndroid Build Coastguard Worker }
226*9880d681SAndroid Build Coastguard Worker 
227*9880d681SAndroid Build Coastguard Worker 
228*9880d681SAndroid Build Coastguard Worker 
229*9880d681SAndroid Build Coastguard Worker /// isLoadFromStackSlot - If the specified machine instruction is a direct
230*9880d681SAndroid Build Coastguard Worker /// load from a stack slot, return the virtual or physical register number of
231*9880d681SAndroid Build Coastguard Worker /// the destination along with the FrameIndex of the loaded stack slot.  If
232*9880d681SAndroid Build Coastguard Worker /// not, return 0.  This predicate must return 0 if the instruction has
233*9880d681SAndroid Build Coastguard Worker /// any side effects other than loading from the stack slot.
isLoadFromStackSlot(const MachineInstr & MI,int & FrameIndex) const234*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
235*9880d681SAndroid Build Coastguard Worker                                                int &FrameIndex) const {
236*9880d681SAndroid Build Coastguard Worker   switch (MI.getOpcode()) {
237*9880d681SAndroid Build Coastguard Worker   default:
238*9880d681SAndroid Build Coastguard Worker     break;
239*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrb_io:
240*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrub_io:
241*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrh_io:
242*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadruh_io:
243*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadri_io:
244*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrd_io:
245*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vL32b_ai:
246*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vL32b_ai_128B:
247*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vL32Ub_ai:
248*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vL32Ub_ai_128B:
249*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriw_pred:
250*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriw_mod:
251*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriq_pred_V6:
252*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriq_pred_vec_V6:
253*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriv_pseudo_V6:
254*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDrivv_pseudo_V6:
255*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriq_pred_V6_128B:
256*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriq_pred_vec_V6_128B:
257*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriv_pseudo_V6_128B:
258*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDrivv_pseudo_V6_128B: {
259*9880d681SAndroid Build Coastguard Worker     const MachineOperand OpFI = MI.getOperand(1);
260*9880d681SAndroid Build Coastguard Worker     if (!OpFI.isFI())
261*9880d681SAndroid Build Coastguard Worker       return 0;
262*9880d681SAndroid Build Coastguard Worker     const MachineOperand OpOff = MI.getOperand(2);
263*9880d681SAndroid Build Coastguard Worker     if (!OpOff.isImm() || OpOff.getImm() != 0)
264*9880d681SAndroid Build Coastguard Worker       return 0;
265*9880d681SAndroid Build Coastguard Worker     FrameIndex = OpFI.getIndex();
266*9880d681SAndroid Build Coastguard Worker     return MI.getOperand(0).getReg();
267*9880d681SAndroid Build Coastguard Worker   }
268*9880d681SAndroid Build Coastguard Worker 
269*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrbt_io:
270*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrbf_io:
271*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrubt_io:
272*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrubf_io:
273*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrht_io:
274*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrhf_io:
275*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadruht_io:
276*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadruhf_io:
277*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrit_io:
278*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrif_io:
279*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrdt_io:
280*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrdf_io: {
281*9880d681SAndroid Build Coastguard Worker     const MachineOperand OpFI = MI.getOperand(2);
282*9880d681SAndroid Build Coastguard Worker     if (!OpFI.isFI())
283*9880d681SAndroid Build Coastguard Worker       return 0;
284*9880d681SAndroid Build Coastguard Worker     const MachineOperand OpOff = MI.getOperand(3);
285*9880d681SAndroid Build Coastguard Worker     if (!OpOff.isImm() || OpOff.getImm() != 0)
286*9880d681SAndroid Build Coastguard Worker       return 0;
287*9880d681SAndroid Build Coastguard Worker     FrameIndex = OpFI.getIndex();
288*9880d681SAndroid Build Coastguard Worker     return MI.getOperand(0).getReg();
289*9880d681SAndroid Build Coastguard Worker   }
290*9880d681SAndroid Build Coastguard Worker   }
291*9880d681SAndroid Build Coastguard Worker 
292*9880d681SAndroid Build Coastguard Worker   return 0;
293*9880d681SAndroid Build Coastguard Worker }
294*9880d681SAndroid Build Coastguard Worker 
295*9880d681SAndroid Build Coastguard Worker 
296*9880d681SAndroid Build Coastguard Worker /// isStoreToStackSlot - If the specified machine instruction is a direct
297*9880d681SAndroid Build Coastguard Worker /// store to a stack slot, return the virtual or physical register number of
298*9880d681SAndroid Build Coastguard Worker /// the source reg along with the FrameIndex of the loaded stack slot.  If
299*9880d681SAndroid Build Coastguard Worker /// not, return 0.  This predicate must return 0 if the instruction has
300*9880d681SAndroid Build Coastguard Worker /// any side effects other than storing to the stack slot.
isStoreToStackSlot(const MachineInstr & MI,int & FrameIndex) const301*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
302*9880d681SAndroid Build Coastguard Worker                                               int &FrameIndex) const {
303*9880d681SAndroid Build Coastguard Worker   switch (MI.getOpcode()) {
304*9880d681SAndroid Build Coastguard Worker   default:
305*9880d681SAndroid Build Coastguard Worker     break;
306*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storerb_io:
307*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storerh_io:
308*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storeri_io:
309*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storerd_io:
310*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vS32b_ai:
311*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vS32b_ai_128B:
312*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vS32Ub_ai:
313*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vS32Ub_ai_128B:
314*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriw_pred:
315*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriw_mod:
316*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriq_pred_V6:
317*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriq_pred_vec_V6:
318*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriv_pseudo_V6:
319*9880d681SAndroid Build Coastguard Worker   case Hexagon::STrivv_pseudo_V6:
320*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriq_pred_V6_128B:
321*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriq_pred_vec_V6_128B:
322*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriv_pseudo_V6_128B:
323*9880d681SAndroid Build Coastguard Worker   case Hexagon::STrivv_pseudo_V6_128B: {
324*9880d681SAndroid Build Coastguard Worker     const MachineOperand &OpFI = MI.getOperand(0);
325*9880d681SAndroid Build Coastguard Worker     if (!OpFI.isFI())
326*9880d681SAndroid Build Coastguard Worker       return 0;
327*9880d681SAndroid Build Coastguard Worker     const MachineOperand &OpOff = MI.getOperand(1);
328*9880d681SAndroid Build Coastguard Worker     if (!OpOff.isImm() || OpOff.getImm() != 0)
329*9880d681SAndroid Build Coastguard Worker       return 0;
330*9880d681SAndroid Build Coastguard Worker     FrameIndex = OpFI.getIndex();
331*9880d681SAndroid Build Coastguard Worker     return MI.getOperand(2).getReg();
332*9880d681SAndroid Build Coastguard Worker   }
333*9880d681SAndroid Build Coastguard Worker 
334*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_pstorerbt_io:
335*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_pstorerbf_io:
336*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_pstorerht_io:
337*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_pstorerhf_io:
338*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_pstorerit_io:
339*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_pstorerif_io:
340*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_pstorerdt_io:
341*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_pstorerdf_io: {
342*9880d681SAndroid Build Coastguard Worker     const MachineOperand &OpFI = MI.getOperand(1);
343*9880d681SAndroid Build Coastguard Worker     if (!OpFI.isFI())
344*9880d681SAndroid Build Coastguard Worker       return 0;
345*9880d681SAndroid Build Coastguard Worker     const MachineOperand &OpOff = MI.getOperand(2);
346*9880d681SAndroid Build Coastguard Worker     if (!OpOff.isImm() || OpOff.getImm() != 0)
347*9880d681SAndroid Build Coastguard Worker       return 0;
348*9880d681SAndroid Build Coastguard Worker     FrameIndex = OpFI.getIndex();
349*9880d681SAndroid Build Coastguard Worker     return MI.getOperand(3).getReg();
350*9880d681SAndroid Build Coastguard Worker   }
351*9880d681SAndroid Build Coastguard Worker   }
352*9880d681SAndroid Build Coastguard Worker 
353*9880d681SAndroid Build Coastguard Worker   return 0;
354*9880d681SAndroid Build Coastguard Worker }
355*9880d681SAndroid Build Coastguard Worker 
356*9880d681SAndroid Build Coastguard Worker 
357*9880d681SAndroid Build Coastguard Worker /// This function can analyze one/two way branching only and should (mostly) be
358*9880d681SAndroid Build Coastguard Worker /// called by target independent side.
359*9880d681SAndroid Build Coastguard Worker /// First entry is always the opcode of the branching instruction, except when
360*9880d681SAndroid Build Coastguard Worker /// the Cond vector is supposed to be empty, e.g., when AnalyzeBranch fails, a
361*9880d681SAndroid Build Coastguard Worker /// BB with only unconditional jump. Subsequent entries depend upon the opcode,
362*9880d681SAndroid Build Coastguard Worker /// e.g. Jump_c p will have
363*9880d681SAndroid Build Coastguard Worker /// Cond[0] = Jump_c
364*9880d681SAndroid Build Coastguard Worker /// Cond[1] = p
365*9880d681SAndroid Build Coastguard Worker /// HW-loop ENDLOOP:
366*9880d681SAndroid Build Coastguard Worker /// Cond[0] = ENDLOOP
367*9880d681SAndroid Build Coastguard Worker /// Cond[1] = MBB
368*9880d681SAndroid Build Coastguard Worker /// New value jump:
369*9880d681SAndroid Build Coastguard Worker /// Cond[0] = Hexagon::CMPEQri_f_Jumpnv_t_V4 -- specific opcode
370*9880d681SAndroid Build Coastguard Worker /// Cond[1] = R
371*9880d681SAndroid Build Coastguard Worker /// Cond[2] = Imm
372*9880d681SAndroid Build Coastguard Worker ///
analyzeBranch(MachineBasicBlock & MBB,MachineBasicBlock * & TBB,MachineBasicBlock * & FBB,SmallVectorImpl<MachineOperand> & Cond,bool AllowModify) const373*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
374*9880d681SAndroid Build Coastguard Worker                                      MachineBasicBlock *&TBB,
375*9880d681SAndroid Build Coastguard Worker                                      MachineBasicBlock *&FBB,
376*9880d681SAndroid Build Coastguard Worker                                      SmallVectorImpl<MachineOperand> &Cond,
377*9880d681SAndroid Build Coastguard Worker                                      bool AllowModify) const {
378*9880d681SAndroid Build Coastguard Worker   TBB = nullptr;
379*9880d681SAndroid Build Coastguard Worker   FBB = nullptr;
380*9880d681SAndroid Build Coastguard Worker   Cond.clear();
381*9880d681SAndroid Build Coastguard Worker 
382*9880d681SAndroid Build Coastguard Worker   // If the block has no terminators, it just falls into the block after it.
383*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::instr_iterator I = MBB.instr_end();
384*9880d681SAndroid Build Coastguard Worker   if (I == MBB.instr_begin())
385*9880d681SAndroid Build Coastguard Worker     return false;
386*9880d681SAndroid Build Coastguard Worker 
387*9880d681SAndroid Build Coastguard Worker   // A basic block may looks like this:
388*9880d681SAndroid Build Coastguard Worker   //
389*9880d681SAndroid Build Coastguard Worker   //  [   insn
390*9880d681SAndroid Build Coastguard Worker   //     EH_LABEL
391*9880d681SAndroid Build Coastguard Worker   //      insn
392*9880d681SAndroid Build Coastguard Worker   //      insn
393*9880d681SAndroid Build Coastguard Worker   //      insn
394*9880d681SAndroid Build Coastguard Worker   //     EH_LABEL
395*9880d681SAndroid Build Coastguard Worker   //      insn     ]
396*9880d681SAndroid Build Coastguard Worker   //
397*9880d681SAndroid Build Coastguard Worker   // It has two succs but does not have a terminator
398*9880d681SAndroid Build Coastguard Worker   // Don't know how to handle it.
399*9880d681SAndroid Build Coastguard Worker   do {
400*9880d681SAndroid Build Coastguard Worker     --I;
401*9880d681SAndroid Build Coastguard Worker     if (I->isEHLabel())
402*9880d681SAndroid Build Coastguard Worker       // Don't analyze EH branches.
403*9880d681SAndroid Build Coastguard Worker       return true;
404*9880d681SAndroid Build Coastguard Worker   } while (I != MBB.instr_begin());
405*9880d681SAndroid Build Coastguard Worker 
406*9880d681SAndroid Build Coastguard Worker   I = MBB.instr_end();
407*9880d681SAndroid Build Coastguard Worker   --I;
408*9880d681SAndroid Build Coastguard Worker 
409*9880d681SAndroid Build Coastguard Worker   while (I->isDebugValue()) {
410*9880d681SAndroid Build Coastguard Worker     if (I == MBB.instr_begin())
411*9880d681SAndroid Build Coastguard Worker       return false;
412*9880d681SAndroid Build Coastguard Worker     --I;
413*9880d681SAndroid Build Coastguard Worker   }
414*9880d681SAndroid Build Coastguard Worker 
415*9880d681SAndroid Build Coastguard Worker   bool JumpToBlock = I->getOpcode() == Hexagon::J2_jump &&
416*9880d681SAndroid Build Coastguard Worker                      I->getOperand(0).isMBB();
417*9880d681SAndroid Build Coastguard Worker   // Delete the J2_jump if it's equivalent to a fall-through.
418*9880d681SAndroid Build Coastguard Worker   if (AllowModify && JumpToBlock &&
419*9880d681SAndroid Build Coastguard Worker       MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
420*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs()<< "\nErasing the jump to successor block\n";);
421*9880d681SAndroid Build Coastguard Worker     I->eraseFromParent();
422*9880d681SAndroid Build Coastguard Worker     I = MBB.instr_end();
423*9880d681SAndroid Build Coastguard Worker     if (I == MBB.instr_begin())
424*9880d681SAndroid Build Coastguard Worker       return false;
425*9880d681SAndroid Build Coastguard Worker     --I;
426*9880d681SAndroid Build Coastguard Worker   }
427*9880d681SAndroid Build Coastguard Worker   if (!isUnpredicatedTerminator(*I))
428*9880d681SAndroid Build Coastguard Worker     return false;
429*9880d681SAndroid Build Coastguard Worker 
430*9880d681SAndroid Build Coastguard Worker   // Get the last instruction in the block.
431*9880d681SAndroid Build Coastguard Worker   MachineInstr *LastInst = &*I;
432*9880d681SAndroid Build Coastguard Worker   MachineInstr *SecondLastInst = nullptr;
433*9880d681SAndroid Build Coastguard Worker   // Find one more terminator if present.
434*9880d681SAndroid Build Coastguard Worker   for (;;) {
435*9880d681SAndroid Build Coastguard Worker     if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
436*9880d681SAndroid Build Coastguard Worker       if (!SecondLastInst)
437*9880d681SAndroid Build Coastguard Worker         SecondLastInst = &*I;
438*9880d681SAndroid Build Coastguard Worker       else
439*9880d681SAndroid Build Coastguard Worker         // This is a third branch.
440*9880d681SAndroid Build Coastguard Worker         return true;
441*9880d681SAndroid Build Coastguard Worker     }
442*9880d681SAndroid Build Coastguard Worker     if (I == MBB.instr_begin())
443*9880d681SAndroid Build Coastguard Worker       break;
444*9880d681SAndroid Build Coastguard Worker     --I;
445*9880d681SAndroid Build Coastguard Worker   }
446*9880d681SAndroid Build Coastguard Worker 
447*9880d681SAndroid Build Coastguard Worker   int LastOpcode = LastInst->getOpcode();
448*9880d681SAndroid Build Coastguard Worker   int SecLastOpcode = SecondLastInst ? SecondLastInst->getOpcode() : 0;
449*9880d681SAndroid Build Coastguard Worker   // If the branch target is not a basic block, it could be a tail call.
450*9880d681SAndroid Build Coastguard Worker   // (It is, if the target is a function.)
451*9880d681SAndroid Build Coastguard Worker   if (LastOpcode == Hexagon::J2_jump && !LastInst->getOperand(0).isMBB())
452*9880d681SAndroid Build Coastguard Worker     return true;
453*9880d681SAndroid Build Coastguard Worker   if (SecLastOpcode == Hexagon::J2_jump &&
454*9880d681SAndroid Build Coastguard Worker       !SecondLastInst->getOperand(0).isMBB())
455*9880d681SAndroid Build Coastguard Worker     return true;
456*9880d681SAndroid Build Coastguard Worker 
457*9880d681SAndroid Build Coastguard Worker   bool LastOpcodeHasJMP_c = PredOpcodeHasJMP_c(LastOpcode);
458*9880d681SAndroid Build Coastguard Worker   bool LastOpcodeHasNVJump = isNewValueJump(LastInst);
459*9880d681SAndroid Build Coastguard Worker 
460*9880d681SAndroid Build Coastguard Worker   if (LastOpcodeHasJMP_c && !LastInst->getOperand(1).isMBB())
461*9880d681SAndroid Build Coastguard Worker     return true;
462*9880d681SAndroid Build Coastguard Worker 
463*9880d681SAndroid Build Coastguard Worker   // If there is only one terminator instruction, process it.
464*9880d681SAndroid Build Coastguard Worker   if (LastInst && !SecondLastInst) {
465*9880d681SAndroid Build Coastguard Worker     if (LastOpcode == Hexagon::J2_jump) {
466*9880d681SAndroid Build Coastguard Worker       TBB = LastInst->getOperand(0).getMBB();
467*9880d681SAndroid Build Coastguard Worker       return false;
468*9880d681SAndroid Build Coastguard Worker     }
469*9880d681SAndroid Build Coastguard Worker     if (isEndLoopN(LastOpcode)) {
470*9880d681SAndroid Build Coastguard Worker       TBB = LastInst->getOperand(0).getMBB();
471*9880d681SAndroid Build Coastguard Worker       Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
472*9880d681SAndroid Build Coastguard Worker       Cond.push_back(LastInst->getOperand(0));
473*9880d681SAndroid Build Coastguard Worker       return false;
474*9880d681SAndroid Build Coastguard Worker     }
475*9880d681SAndroid Build Coastguard Worker     if (LastOpcodeHasJMP_c) {
476*9880d681SAndroid Build Coastguard Worker       TBB = LastInst->getOperand(1).getMBB();
477*9880d681SAndroid Build Coastguard Worker       Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
478*9880d681SAndroid Build Coastguard Worker       Cond.push_back(LastInst->getOperand(0));
479*9880d681SAndroid Build Coastguard Worker       return false;
480*9880d681SAndroid Build Coastguard Worker     }
481*9880d681SAndroid Build Coastguard Worker     // Only supporting rr/ri versions of new-value jumps.
482*9880d681SAndroid Build Coastguard Worker     if (LastOpcodeHasNVJump && (LastInst->getNumExplicitOperands() == 3)) {
483*9880d681SAndroid Build Coastguard Worker       TBB = LastInst->getOperand(2).getMBB();
484*9880d681SAndroid Build Coastguard Worker       Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
485*9880d681SAndroid Build Coastguard Worker       Cond.push_back(LastInst->getOperand(0));
486*9880d681SAndroid Build Coastguard Worker       Cond.push_back(LastInst->getOperand(1));
487*9880d681SAndroid Build Coastguard Worker       return false;
488*9880d681SAndroid Build Coastguard Worker     }
489*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "\nCant analyze BB#" << MBB.getNumber()
490*9880d681SAndroid Build Coastguard Worker                  << " with one jump\n";);
491*9880d681SAndroid Build Coastguard Worker     // Otherwise, don't know what this is.
492*9880d681SAndroid Build Coastguard Worker     return true;
493*9880d681SAndroid Build Coastguard Worker   }
494*9880d681SAndroid Build Coastguard Worker 
495*9880d681SAndroid Build Coastguard Worker   bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
496*9880d681SAndroid Build Coastguard Worker   bool SecLastOpcodeHasNVJump = isNewValueJump(SecondLastInst);
497*9880d681SAndroid Build Coastguard Worker   if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) {
498*9880d681SAndroid Build Coastguard Worker     if (!SecondLastInst->getOperand(1).isMBB())
499*9880d681SAndroid Build Coastguard Worker       return true;
500*9880d681SAndroid Build Coastguard Worker     TBB =  SecondLastInst->getOperand(1).getMBB();
501*9880d681SAndroid Build Coastguard Worker     Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
502*9880d681SAndroid Build Coastguard Worker     Cond.push_back(SecondLastInst->getOperand(0));
503*9880d681SAndroid Build Coastguard Worker     FBB = LastInst->getOperand(0).getMBB();
504*9880d681SAndroid Build Coastguard Worker     return false;
505*9880d681SAndroid Build Coastguard Worker   }
506*9880d681SAndroid Build Coastguard Worker 
507*9880d681SAndroid Build Coastguard Worker   // Only supporting rr/ri versions of new-value jumps.
508*9880d681SAndroid Build Coastguard Worker   if (SecLastOpcodeHasNVJump &&
509*9880d681SAndroid Build Coastguard Worker       (SecondLastInst->getNumExplicitOperands() == 3) &&
510*9880d681SAndroid Build Coastguard Worker       (LastOpcode == Hexagon::J2_jump)) {
511*9880d681SAndroid Build Coastguard Worker     TBB = SecondLastInst->getOperand(2).getMBB();
512*9880d681SAndroid Build Coastguard Worker     Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
513*9880d681SAndroid Build Coastguard Worker     Cond.push_back(SecondLastInst->getOperand(0));
514*9880d681SAndroid Build Coastguard Worker     Cond.push_back(SecondLastInst->getOperand(1));
515*9880d681SAndroid Build Coastguard Worker     FBB = LastInst->getOperand(0).getMBB();
516*9880d681SAndroid Build Coastguard Worker     return false;
517*9880d681SAndroid Build Coastguard Worker   }
518*9880d681SAndroid Build Coastguard Worker 
519*9880d681SAndroid Build Coastguard Worker   // If the block ends with two Hexagon:JMPs, handle it.  The second one is not
520*9880d681SAndroid Build Coastguard Worker   // executed, so remove it.
521*9880d681SAndroid Build Coastguard Worker   if (SecLastOpcode == Hexagon::J2_jump && LastOpcode == Hexagon::J2_jump) {
522*9880d681SAndroid Build Coastguard Worker     TBB = SecondLastInst->getOperand(0).getMBB();
523*9880d681SAndroid Build Coastguard Worker     I = LastInst->getIterator();
524*9880d681SAndroid Build Coastguard Worker     if (AllowModify)
525*9880d681SAndroid Build Coastguard Worker       I->eraseFromParent();
526*9880d681SAndroid Build Coastguard Worker     return false;
527*9880d681SAndroid Build Coastguard Worker   }
528*9880d681SAndroid Build Coastguard Worker 
529*9880d681SAndroid Build Coastguard Worker   // If the block ends with an ENDLOOP, and J2_jump, handle it.
530*9880d681SAndroid Build Coastguard Worker   if (isEndLoopN(SecLastOpcode) && LastOpcode == Hexagon::J2_jump) {
531*9880d681SAndroid Build Coastguard Worker     TBB = SecondLastInst->getOperand(0).getMBB();
532*9880d681SAndroid Build Coastguard Worker     Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
533*9880d681SAndroid Build Coastguard Worker     Cond.push_back(SecondLastInst->getOperand(0));
534*9880d681SAndroid Build Coastguard Worker     FBB = LastInst->getOperand(0).getMBB();
535*9880d681SAndroid Build Coastguard Worker     return false;
536*9880d681SAndroid Build Coastguard Worker   }
537*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "\nCant analyze BB#" << MBB.getNumber()
538*9880d681SAndroid Build Coastguard Worker                << " with two jumps";);
539*9880d681SAndroid Build Coastguard Worker   // Otherwise, can't handle this.
540*9880d681SAndroid Build Coastguard Worker   return true;
541*9880d681SAndroid Build Coastguard Worker }
542*9880d681SAndroid Build Coastguard Worker 
543*9880d681SAndroid Build Coastguard Worker 
RemoveBranch(MachineBasicBlock & MBB) const544*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
545*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "\nRemoving branches out of BB#" << MBB.getNumber());
546*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator I = MBB.end();
547*9880d681SAndroid Build Coastguard Worker   unsigned Count = 0;
548*9880d681SAndroid Build Coastguard Worker   while (I != MBB.begin()) {
549*9880d681SAndroid Build Coastguard Worker     --I;
550*9880d681SAndroid Build Coastguard Worker     if (I->isDebugValue())
551*9880d681SAndroid Build Coastguard Worker       continue;
552*9880d681SAndroid Build Coastguard Worker     // Only removing branches from end of MBB.
553*9880d681SAndroid Build Coastguard Worker     if (!I->isBranch())
554*9880d681SAndroid Build Coastguard Worker       return Count;
555*9880d681SAndroid Build Coastguard Worker     if (Count && (I->getOpcode() == Hexagon::J2_jump))
556*9880d681SAndroid Build Coastguard Worker       llvm_unreachable("Malformed basic block: unconditional branch not last");
557*9880d681SAndroid Build Coastguard Worker     MBB.erase(&MBB.back());
558*9880d681SAndroid Build Coastguard Worker     I = MBB.end();
559*9880d681SAndroid Build Coastguard Worker     ++Count;
560*9880d681SAndroid Build Coastguard Worker   }
561*9880d681SAndroid Build Coastguard Worker   return Count;
562*9880d681SAndroid Build Coastguard Worker }
563*9880d681SAndroid Build Coastguard Worker 
InsertBranch(MachineBasicBlock & MBB,MachineBasicBlock * TBB,MachineBasicBlock * FBB,ArrayRef<MachineOperand> Cond,const DebugLoc & DL) const564*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::InsertBranch(MachineBasicBlock &MBB,
565*9880d681SAndroid Build Coastguard Worker                                         MachineBasicBlock *TBB,
566*9880d681SAndroid Build Coastguard Worker                                         MachineBasicBlock *FBB,
567*9880d681SAndroid Build Coastguard Worker                                         ArrayRef<MachineOperand> Cond,
568*9880d681SAndroid Build Coastguard Worker                                         const DebugLoc &DL) const {
569*9880d681SAndroid Build Coastguard Worker   unsigned BOpc   = Hexagon::J2_jump;
570*9880d681SAndroid Build Coastguard Worker   unsigned BccOpc = Hexagon::J2_jumpt;
571*9880d681SAndroid Build Coastguard Worker   assert(validateBranchCond(Cond) && "Invalid branching condition");
572*9880d681SAndroid Build Coastguard Worker   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
573*9880d681SAndroid Build Coastguard Worker 
574*9880d681SAndroid Build Coastguard Worker   // Check if ReverseBranchCondition has asked to reverse this branch
575*9880d681SAndroid Build Coastguard Worker   // If we want to reverse the branch an odd number of times, we want
576*9880d681SAndroid Build Coastguard Worker   // J2_jumpf.
577*9880d681SAndroid Build Coastguard Worker   if (!Cond.empty() && Cond[0].isImm())
578*9880d681SAndroid Build Coastguard Worker     BccOpc = Cond[0].getImm();
579*9880d681SAndroid Build Coastguard Worker 
580*9880d681SAndroid Build Coastguard Worker   if (!FBB) {
581*9880d681SAndroid Build Coastguard Worker     if (Cond.empty()) {
582*9880d681SAndroid Build Coastguard Worker       // Due to a bug in TailMerging/CFG Optimization, we need to add a
583*9880d681SAndroid Build Coastguard Worker       // special case handling of a predicated jump followed by an
584*9880d681SAndroid Build Coastguard Worker       // unconditional jump. If not, Tail Merging and CFG Optimization go
585*9880d681SAndroid Build Coastguard Worker       // into an infinite loop.
586*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock *NewTBB, *NewFBB;
587*9880d681SAndroid Build Coastguard Worker       SmallVector<MachineOperand, 4> Cond;
588*9880d681SAndroid Build Coastguard Worker       auto Term = MBB.getFirstTerminator();
589*9880d681SAndroid Build Coastguard Worker       if (Term != MBB.end() && isPredicated(*Term) &&
590*9880d681SAndroid Build Coastguard Worker           !analyzeBranch(MBB, NewTBB, NewFBB, Cond, false)) {
591*9880d681SAndroid Build Coastguard Worker         MachineBasicBlock *NextBB = &*++MBB.getIterator();
592*9880d681SAndroid Build Coastguard Worker         if (NewTBB == NextBB) {
593*9880d681SAndroid Build Coastguard Worker           ReverseBranchCondition(Cond);
594*9880d681SAndroid Build Coastguard Worker           RemoveBranch(MBB);
595*9880d681SAndroid Build Coastguard Worker           return InsertBranch(MBB, TBB, nullptr, Cond, DL);
596*9880d681SAndroid Build Coastguard Worker         }
597*9880d681SAndroid Build Coastguard Worker       }
598*9880d681SAndroid Build Coastguard Worker       BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);
599*9880d681SAndroid Build Coastguard Worker     } else if (isEndLoopN(Cond[0].getImm())) {
600*9880d681SAndroid Build Coastguard Worker       int EndLoopOp = Cond[0].getImm();
601*9880d681SAndroid Build Coastguard Worker       assert(Cond[1].isMBB());
602*9880d681SAndroid Build Coastguard Worker       // Since we're adding an ENDLOOP, there better be a LOOP instruction.
603*9880d681SAndroid Build Coastguard Worker       // Check for it, and change the BB target if needed.
604*9880d681SAndroid Build Coastguard Worker       SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
605*9880d681SAndroid Build Coastguard Worker       MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, VisitedBBs);
606*9880d681SAndroid Build Coastguard Worker       assert(Loop != 0 && "Inserting an ENDLOOP without a LOOP");
607*9880d681SAndroid Build Coastguard Worker       Loop->getOperand(0).setMBB(TBB);
608*9880d681SAndroid Build Coastguard Worker       // Add the ENDLOOP after the finding the LOOP0.
609*9880d681SAndroid Build Coastguard Worker       BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
610*9880d681SAndroid Build Coastguard Worker     } else if (isNewValueJump(Cond[0].getImm())) {
611*9880d681SAndroid Build Coastguard Worker       assert((Cond.size() == 3) && "Only supporting rr/ri version of nvjump");
612*9880d681SAndroid Build Coastguard Worker       // New value jump
613*9880d681SAndroid Build Coastguard Worker       // (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset)
614*9880d681SAndroid Build Coastguard Worker       // (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset)
615*9880d681SAndroid Build Coastguard Worker       unsigned Flags1 = getUndefRegState(Cond[1].isUndef());
616*9880d681SAndroid Build Coastguard Worker       DEBUG(dbgs() << "\nInserting NVJump for BB#" << MBB.getNumber(););
617*9880d681SAndroid Build Coastguard Worker       if (Cond[2].isReg()) {
618*9880d681SAndroid Build Coastguard Worker         unsigned Flags2 = getUndefRegState(Cond[2].isUndef());
619*9880d681SAndroid Build Coastguard Worker         BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).
620*9880d681SAndroid Build Coastguard Worker           addReg(Cond[2].getReg(), Flags2).addMBB(TBB);
621*9880d681SAndroid Build Coastguard Worker       } else if(Cond[2].isImm()) {
622*9880d681SAndroid Build Coastguard Worker         BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).
623*9880d681SAndroid Build Coastguard Worker           addImm(Cond[2].getImm()).addMBB(TBB);
624*9880d681SAndroid Build Coastguard Worker       } else
625*9880d681SAndroid Build Coastguard Worker         llvm_unreachable("Invalid condition for branching");
626*9880d681SAndroid Build Coastguard Worker     } else {
627*9880d681SAndroid Build Coastguard Worker       assert((Cond.size() == 2) && "Malformed cond vector");
628*9880d681SAndroid Build Coastguard Worker       const MachineOperand &RO = Cond[1];
629*9880d681SAndroid Build Coastguard Worker       unsigned Flags = getUndefRegState(RO.isUndef());
630*9880d681SAndroid Build Coastguard Worker       BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);
631*9880d681SAndroid Build Coastguard Worker     }
632*9880d681SAndroid Build Coastguard Worker     return 1;
633*9880d681SAndroid Build Coastguard Worker   }
634*9880d681SAndroid Build Coastguard Worker   assert((!Cond.empty()) &&
635*9880d681SAndroid Build Coastguard Worker          "Cond. cannot be empty when multiple branchings are required");
636*9880d681SAndroid Build Coastguard Worker   assert((!isNewValueJump(Cond[0].getImm())) &&
637*9880d681SAndroid Build Coastguard Worker          "NV-jump cannot be inserted with another branch");
638*9880d681SAndroid Build Coastguard Worker   // Special case for hardware loops.  The condition is a basic block.
639*9880d681SAndroid Build Coastguard Worker   if (isEndLoopN(Cond[0].getImm())) {
640*9880d681SAndroid Build Coastguard Worker     int EndLoopOp = Cond[0].getImm();
641*9880d681SAndroid Build Coastguard Worker     assert(Cond[1].isMBB());
642*9880d681SAndroid Build Coastguard Worker     // Since we're adding an ENDLOOP, there better be a LOOP instruction.
643*9880d681SAndroid Build Coastguard Worker     // Check for it, and change the BB target if needed.
644*9880d681SAndroid Build Coastguard Worker     SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
645*9880d681SAndroid Build Coastguard Worker     MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, VisitedBBs);
646*9880d681SAndroid Build Coastguard Worker     assert(Loop != 0 && "Inserting an ENDLOOP without a LOOP");
647*9880d681SAndroid Build Coastguard Worker     Loop->getOperand(0).setMBB(TBB);
648*9880d681SAndroid Build Coastguard Worker     // Add the ENDLOOP after the finding the LOOP0.
649*9880d681SAndroid Build Coastguard Worker     BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
650*9880d681SAndroid Build Coastguard Worker   } else {
651*9880d681SAndroid Build Coastguard Worker     const MachineOperand &RO = Cond[1];
652*9880d681SAndroid Build Coastguard Worker     unsigned Flags = getUndefRegState(RO.isUndef());
653*9880d681SAndroid Build Coastguard Worker     BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);
654*9880d681SAndroid Build Coastguard Worker   }
655*9880d681SAndroid Build Coastguard Worker   BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB);
656*9880d681SAndroid Build Coastguard Worker 
657*9880d681SAndroid Build Coastguard Worker   return 2;
658*9880d681SAndroid Build Coastguard Worker }
659*9880d681SAndroid Build Coastguard Worker 
660*9880d681SAndroid Build Coastguard Worker /// Analyze the loop code to find the loop induction variable and compare used
661*9880d681SAndroid Build Coastguard Worker /// to compute the number of iterations. Currently, we analyze loop that are
662*9880d681SAndroid Build Coastguard Worker /// controlled using hardware loops.  In this case, the induction variable
663*9880d681SAndroid Build Coastguard Worker /// instruction is null.  For all other cases, this function returns true, which
664*9880d681SAndroid Build Coastguard Worker /// means we're unable to analyze it.
analyzeLoop(MachineLoop & L,MachineInstr * & IndVarInst,MachineInstr * & CmpInst) const665*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::analyzeLoop(MachineLoop &L,
666*9880d681SAndroid Build Coastguard Worker                                    MachineInstr *&IndVarInst,
667*9880d681SAndroid Build Coastguard Worker                                    MachineInstr *&CmpInst) const {
668*9880d681SAndroid Build Coastguard Worker 
669*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock *LoopEnd = L.getBottomBlock();
670*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator I = LoopEnd->getFirstTerminator();
671*9880d681SAndroid Build Coastguard Worker   // We really "analyze" only hardware loops right now.
672*9880d681SAndroid Build Coastguard Worker   if (I != LoopEnd->end() && isEndLoopN(I->getOpcode())) {
673*9880d681SAndroid Build Coastguard Worker     IndVarInst = nullptr;
674*9880d681SAndroid Build Coastguard Worker     CmpInst = &*I;
675*9880d681SAndroid Build Coastguard Worker     return false;
676*9880d681SAndroid Build Coastguard Worker   }
677*9880d681SAndroid Build Coastguard Worker   return true;
678*9880d681SAndroid Build Coastguard Worker }
679*9880d681SAndroid Build Coastguard Worker 
680*9880d681SAndroid Build Coastguard Worker /// Generate code to reduce the loop iteration by one and check if the loop is
681*9880d681SAndroid Build Coastguard Worker /// finished. Return the value/register of the new loop count. this function
682*9880d681SAndroid Build Coastguard Worker /// assumes the nth iteration is peeled first.
reduceLoopCount(MachineBasicBlock & MBB,MachineInstr * IndVar,MachineInstr * Cmp,SmallVectorImpl<MachineOperand> & Cond,SmallVectorImpl<MachineInstr * > & PrevInsts,unsigned Iter,unsigned MaxIter) const683*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::reduceLoopCount(MachineBasicBlock &MBB,
684*9880d681SAndroid Build Coastguard Worker       MachineInstr *IndVar, MachineInstr *Cmp,
685*9880d681SAndroid Build Coastguard Worker       SmallVectorImpl<MachineOperand> &Cond,
686*9880d681SAndroid Build Coastguard Worker       SmallVectorImpl<MachineInstr *> &PrevInsts,
687*9880d681SAndroid Build Coastguard Worker       unsigned Iter, unsigned MaxIter) const {
688*9880d681SAndroid Build Coastguard Worker   // We expect a hardware loop currently. This means that IndVar is set
689*9880d681SAndroid Build Coastguard Worker   // to null, and the compare is the ENDLOOP instruction.
690*9880d681SAndroid Build Coastguard Worker   assert((!IndVar) && isEndLoopN(Cmp->getOpcode())
691*9880d681SAndroid Build Coastguard Worker                    && "Expecting a hardware loop");
692*9880d681SAndroid Build Coastguard Worker   MachineFunction *MF = MBB.getParent();
693*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = Cmp->getDebugLoc();
694*9880d681SAndroid Build Coastguard Worker   SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
695*9880d681SAndroid Build Coastguard Worker   MachineInstr *Loop = findLoopInstr(&MBB, Cmp->getOpcode(), VisitedBBs);
696*9880d681SAndroid Build Coastguard Worker   if (!Loop)
697*9880d681SAndroid Build Coastguard Worker     return 0;
698*9880d681SAndroid Build Coastguard Worker   // If the loop trip count is a compile-time value, then just change the
699*9880d681SAndroid Build Coastguard Worker   // value.
700*9880d681SAndroid Build Coastguard Worker   if (Loop->getOpcode() == Hexagon::J2_loop0i ||
701*9880d681SAndroid Build Coastguard Worker       Loop->getOpcode() == Hexagon::J2_loop1i) {
702*9880d681SAndroid Build Coastguard Worker     int64_t Offset = Loop->getOperand(1).getImm();
703*9880d681SAndroid Build Coastguard Worker     if (Offset <= 1)
704*9880d681SAndroid Build Coastguard Worker       Loop->eraseFromParent();
705*9880d681SAndroid Build Coastguard Worker     else
706*9880d681SAndroid Build Coastguard Worker       Loop->getOperand(1).setImm(Offset - 1);
707*9880d681SAndroid Build Coastguard Worker     return Offset - 1;
708*9880d681SAndroid Build Coastguard Worker   }
709*9880d681SAndroid Build Coastguard Worker   // The loop trip count is a run-time value. We generate code to subtract
710*9880d681SAndroid Build Coastguard Worker   // one from the trip count, and update the loop instruction.
711*9880d681SAndroid Build Coastguard Worker   assert(Loop->getOpcode() == Hexagon::J2_loop0r && "Unexpected instruction");
712*9880d681SAndroid Build Coastguard Worker   unsigned LoopCount = Loop->getOperand(1).getReg();
713*9880d681SAndroid Build Coastguard Worker   // Check if we're done with the loop.
714*9880d681SAndroid Build Coastguard Worker   unsigned LoopEnd = createVR(MF, MVT::i1);
715*9880d681SAndroid Build Coastguard Worker   MachineInstr *NewCmp = BuildMI(&MBB, DL, get(Hexagon::C2_cmpgtui), LoopEnd).
716*9880d681SAndroid Build Coastguard Worker     addReg(LoopCount).addImm(1);
717*9880d681SAndroid Build Coastguard Worker   unsigned NewLoopCount = createVR(MF, MVT::i32);
718*9880d681SAndroid Build Coastguard Worker   MachineInstr *NewAdd = BuildMI(&MBB, DL, get(Hexagon::A2_addi), NewLoopCount).
719*9880d681SAndroid Build Coastguard Worker     addReg(LoopCount).addImm(-1);
720*9880d681SAndroid Build Coastguard Worker   // Update the previously generated instructions with the new loop counter.
721*9880d681SAndroid Build Coastguard Worker   for (SmallVectorImpl<MachineInstr *>::iterator I = PrevInsts.begin(),
722*9880d681SAndroid Build Coastguard Worker          E = PrevInsts.end(); I != E; ++I)
723*9880d681SAndroid Build Coastguard Worker     (*I)->substituteRegister(LoopCount, NewLoopCount, 0, getRegisterInfo());
724*9880d681SAndroid Build Coastguard Worker   PrevInsts.clear();
725*9880d681SAndroid Build Coastguard Worker   PrevInsts.push_back(NewCmp);
726*9880d681SAndroid Build Coastguard Worker   PrevInsts.push_back(NewAdd);
727*9880d681SAndroid Build Coastguard Worker   // Insert the new loop instruction if this is the last time the loop is
728*9880d681SAndroid Build Coastguard Worker   // decremented.
729*9880d681SAndroid Build Coastguard Worker   if (Iter == MaxIter)
730*9880d681SAndroid Build Coastguard Worker     BuildMI(&MBB, DL, get(Hexagon::J2_loop0r)).
731*9880d681SAndroid Build Coastguard Worker       addMBB(Loop->getOperand(0).getMBB()).addReg(NewLoopCount);
732*9880d681SAndroid Build Coastguard Worker   // Delete the old loop instruction.
733*9880d681SAndroid Build Coastguard Worker   if (Iter == 0)
734*9880d681SAndroid Build Coastguard Worker     Loop->eraseFromParent();
735*9880d681SAndroid Build Coastguard Worker   Cond.push_back(MachineOperand::CreateImm(Hexagon::J2_jumpf));
736*9880d681SAndroid Build Coastguard Worker   Cond.push_back(NewCmp->getOperand(0));
737*9880d681SAndroid Build Coastguard Worker   return NewLoopCount;
738*9880d681SAndroid Build Coastguard Worker }
739*9880d681SAndroid Build Coastguard Worker 
isProfitableToIfCvt(MachineBasicBlock & MBB,unsigned NumCycles,unsigned ExtraPredCycles,BranchProbability Probability) const740*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,
741*9880d681SAndroid Build Coastguard Worker       unsigned NumCycles, unsigned ExtraPredCycles,
742*9880d681SAndroid Build Coastguard Worker       BranchProbability Probability) const {
743*9880d681SAndroid Build Coastguard Worker   return nonDbgBBSize(&MBB) <= 3;
744*9880d681SAndroid Build Coastguard Worker }
745*9880d681SAndroid Build Coastguard Worker 
746*9880d681SAndroid Build Coastguard Worker 
isProfitableToIfCvt(MachineBasicBlock & TMBB,unsigned NumTCycles,unsigned ExtraTCycles,MachineBasicBlock & FMBB,unsigned NumFCycles,unsigned ExtraFCycles,BranchProbability Probability) const747*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB,
748*9880d681SAndroid Build Coastguard Worker       unsigned NumTCycles, unsigned ExtraTCycles, MachineBasicBlock &FMBB,
749*9880d681SAndroid Build Coastguard Worker       unsigned NumFCycles, unsigned ExtraFCycles, BranchProbability Probability)
750*9880d681SAndroid Build Coastguard Worker       const {
751*9880d681SAndroid Build Coastguard Worker   return nonDbgBBSize(&TMBB) <= 3 && nonDbgBBSize(&FMBB) <= 3;
752*9880d681SAndroid Build Coastguard Worker }
753*9880d681SAndroid Build Coastguard Worker 
754*9880d681SAndroid Build Coastguard Worker 
isProfitableToDupForIfCvt(MachineBasicBlock & MBB,unsigned NumInstrs,BranchProbability Probability) const755*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock &MBB,
756*9880d681SAndroid Build Coastguard Worker       unsigned NumInstrs, BranchProbability Probability) const {
757*9880d681SAndroid Build Coastguard Worker   return NumInstrs <= 4;
758*9880d681SAndroid Build Coastguard Worker }
759*9880d681SAndroid Build Coastguard Worker 
copyPhysReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,const DebugLoc & DL,unsigned DestReg,unsigned SrcReg,bool KillSrc) const760*9880d681SAndroid Build Coastguard Worker void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
761*9880d681SAndroid Build Coastguard Worker                                    MachineBasicBlock::iterator I,
762*9880d681SAndroid Build Coastguard Worker                                    const DebugLoc &DL, unsigned DestReg,
763*9880d681SAndroid Build Coastguard Worker                                    unsigned SrcReg, bool KillSrc) const {
764*9880d681SAndroid Build Coastguard Worker   auto &HRI = getRegisterInfo();
765*9880d681SAndroid Build Coastguard Worker   unsigned KillFlag = getKillRegState(KillSrc);
766*9880d681SAndroid Build Coastguard Worker 
767*9880d681SAndroid Build Coastguard Worker   if (Hexagon::IntRegsRegClass.contains(SrcReg, DestReg)) {
768*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::A2_tfr), DestReg)
769*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag);
770*9880d681SAndroid Build Coastguard Worker     return;
771*9880d681SAndroid Build Coastguard Worker   }
772*9880d681SAndroid Build Coastguard Worker   if (Hexagon::DoubleRegsRegClass.contains(SrcReg, DestReg)) {
773*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::A2_tfrp), DestReg)
774*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag);
775*9880d681SAndroid Build Coastguard Worker     return;
776*9880d681SAndroid Build Coastguard Worker   }
777*9880d681SAndroid Build Coastguard Worker   if (Hexagon::PredRegsRegClass.contains(SrcReg, DestReg)) {
778*9880d681SAndroid Build Coastguard Worker     // Map Pd = Ps to Pd = or(Ps, Ps).
779*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::C2_or), DestReg)
780*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg).addReg(SrcReg, KillFlag);
781*9880d681SAndroid Build Coastguard Worker     return;
782*9880d681SAndroid Build Coastguard Worker   }
783*9880d681SAndroid Build Coastguard Worker   if (Hexagon::CtrRegsRegClass.contains(DestReg) &&
784*9880d681SAndroid Build Coastguard Worker       Hexagon::IntRegsRegClass.contains(SrcReg)) {
785*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg)
786*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag);
787*9880d681SAndroid Build Coastguard Worker     return;
788*9880d681SAndroid Build Coastguard Worker   }
789*9880d681SAndroid Build Coastguard Worker   if (Hexagon::IntRegsRegClass.contains(DestReg) &&
790*9880d681SAndroid Build Coastguard Worker       Hexagon::CtrRegsRegClass.contains(SrcReg)) {
791*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::A2_tfrcrr), DestReg)
792*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag);
793*9880d681SAndroid Build Coastguard Worker     return;
794*9880d681SAndroid Build Coastguard Worker   }
795*9880d681SAndroid Build Coastguard Worker   if (Hexagon::ModRegsRegClass.contains(DestReg) &&
796*9880d681SAndroid Build Coastguard Worker       Hexagon::IntRegsRegClass.contains(SrcReg)) {
797*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg)
798*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag);
799*9880d681SAndroid Build Coastguard Worker     return;
800*9880d681SAndroid Build Coastguard Worker   }
801*9880d681SAndroid Build Coastguard Worker   if (Hexagon::PredRegsRegClass.contains(SrcReg) &&
802*9880d681SAndroid Build Coastguard Worker       Hexagon::IntRegsRegClass.contains(DestReg)) {
803*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg)
804*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag);
805*9880d681SAndroid Build Coastguard Worker     return;
806*9880d681SAndroid Build Coastguard Worker   }
807*9880d681SAndroid Build Coastguard Worker   if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
808*9880d681SAndroid Build Coastguard Worker       Hexagon::PredRegsRegClass.contains(DestReg)) {
809*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::C2_tfrrp), DestReg)
810*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag);
811*9880d681SAndroid Build Coastguard Worker     return;
812*9880d681SAndroid Build Coastguard Worker   }
813*9880d681SAndroid Build Coastguard Worker   if (Hexagon::PredRegsRegClass.contains(SrcReg) &&
814*9880d681SAndroid Build Coastguard Worker       Hexagon::IntRegsRegClass.contains(DestReg)) {
815*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg)
816*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag);
817*9880d681SAndroid Build Coastguard Worker     return;
818*9880d681SAndroid Build Coastguard Worker   }
819*9880d681SAndroid Build Coastguard Worker   if (Hexagon::VectorRegsRegClass.contains(SrcReg, DestReg)) {
820*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::V6_vassign), DestReg).
821*9880d681SAndroid Build Coastguard Worker       addReg(SrcReg, KillFlag);
822*9880d681SAndroid Build Coastguard Worker     return;
823*9880d681SAndroid Build Coastguard Worker   }
824*9880d681SAndroid Build Coastguard Worker   if (Hexagon::VecDblRegsRegClass.contains(SrcReg, DestReg)) {
825*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::V6_vcombine), DestReg)
826*9880d681SAndroid Build Coastguard Worker       .addReg(HRI.getSubReg(SrcReg, Hexagon::subreg_hireg), KillFlag)
827*9880d681SAndroid Build Coastguard Worker       .addReg(HRI.getSubReg(SrcReg, Hexagon::subreg_loreg), KillFlag);
828*9880d681SAndroid Build Coastguard Worker     return;
829*9880d681SAndroid Build Coastguard Worker   }
830*9880d681SAndroid Build Coastguard Worker   if (Hexagon::VecPredRegsRegClass.contains(SrcReg, DestReg)) {
831*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::V6_pred_and), DestReg)
832*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg)
833*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag);
834*9880d681SAndroid Build Coastguard Worker     return;
835*9880d681SAndroid Build Coastguard Worker   }
836*9880d681SAndroid Build Coastguard Worker   if (Hexagon::VecPredRegsRegClass.contains(SrcReg) &&
837*9880d681SAndroid Build Coastguard Worker       Hexagon::VectorRegsRegClass.contains(DestReg)) {
838*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Unimplemented pred to vec");
839*9880d681SAndroid Build Coastguard Worker     return;
840*9880d681SAndroid Build Coastguard Worker   }
841*9880d681SAndroid Build Coastguard Worker   if (Hexagon::VecPredRegsRegClass.contains(DestReg) &&
842*9880d681SAndroid Build Coastguard Worker       Hexagon::VectorRegsRegClass.contains(SrcReg)) {
843*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Unimplemented vec to pred");
844*9880d681SAndroid Build Coastguard Worker     return;
845*9880d681SAndroid Build Coastguard Worker   }
846*9880d681SAndroid Build Coastguard Worker   if (Hexagon::VecPredRegs128BRegClass.contains(SrcReg, DestReg)) {
847*9880d681SAndroid Build Coastguard Worker     unsigned DstHi = HRI.getSubReg(DestReg, Hexagon::subreg_hireg);
848*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::V6_pred_and), DstHi)
849*9880d681SAndroid Build Coastguard Worker       .addReg(HRI.getSubReg(SrcReg, Hexagon::subreg_hireg), KillFlag);
850*9880d681SAndroid Build Coastguard Worker     unsigned DstLo = HRI.getSubReg(DestReg, Hexagon::subreg_loreg);
851*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::V6_pred_and), DstLo)
852*9880d681SAndroid Build Coastguard Worker       .addReg(HRI.getSubReg(SrcReg, Hexagon::subreg_loreg), KillFlag);
853*9880d681SAndroid Build Coastguard Worker     return;
854*9880d681SAndroid Build Coastguard Worker   }
855*9880d681SAndroid Build Coastguard Worker 
856*9880d681SAndroid Build Coastguard Worker #ifndef NDEBUG
857*9880d681SAndroid Build Coastguard Worker   // Show the invalid registers to ease debugging.
858*9880d681SAndroid Build Coastguard Worker   dbgs() << "Invalid registers for copy in BB#" << MBB.getNumber()
859*9880d681SAndroid Build Coastguard Worker          << ": " << PrintReg(DestReg, &HRI)
860*9880d681SAndroid Build Coastguard Worker          << " = " << PrintReg(SrcReg, &HRI) << '\n';
861*9880d681SAndroid Build Coastguard Worker #endif
862*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Unimplemented");
863*9880d681SAndroid Build Coastguard Worker }
864*9880d681SAndroid Build Coastguard Worker 
865*9880d681SAndroid Build Coastguard Worker 
storeRegToStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,unsigned SrcReg,bool isKill,int FI,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI) const866*9880d681SAndroid Build Coastguard Worker void HexagonInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
867*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock::iterator I, unsigned SrcReg, bool isKill, int FI,
868*9880d681SAndroid Build Coastguard Worker       const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const {
869*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = MBB.findDebugLoc(I);
870*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB.getParent();
871*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo &MFI = *MF.getFrameInfo();
872*9880d681SAndroid Build Coastguard Worker   unsigned Align = MFI.getObjectAlignment(FI);
873*9880d681SAndroid Build Coastguard Worker   unsigned KillFlag = getKillRegState(isKill);
874*9880d681SAndroid Build Coastguard Worker 
875*9880d681SAndroid Build Coastguard Worker   MachineMemOperand *MMO = MF.getMachineMemOperand(
876*9880d681SAndroid Build Coastguard Worker       MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
877*9880d681SAndroid Build Coastguard Worker       MFI.getObjectSize(FI), Align);
878*9880d681SAndroid Build Coastguard Worker 
879*9880d681SAndroid Build Coastguard Worker   if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {
880*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::S2_storeri_io))
881*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0)
882*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag).addMemOperand(MMO);
883*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {
884*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::S2_storerd_io))
885*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0)
886*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag).addMemOperand(MMO);
887*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {
888*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::STriw_pred))
889*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0)
890*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag).addMemOperand(MMO);
891*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {
892*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::STriw_mod))
893*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0)
894*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag).addMemOperand(MMO);
895*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::VecPredRegs128BRegClass.hasSubClassEq(RC)) {
896*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::STriq_pred_V6_128B))
897*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0)
898*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag).addMemOperand(MMO);
899*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::VecPredRegsRegClass.hasSubClassEq(RC)) {
900*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::STriq_pred_V6))
901*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0)
902*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag).addMemOperand(MMO);
903*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::VectorRegs128BRegClass.hasSubClassEq(RC)) {
904*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "++Generating 128B vector spill");
905*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::STriv_pseudo_V6_128B))
906*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0)
907*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag).addMemOperand(MMO);
908*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::VectorRegsRegClass.hasSubClassEq(RC)) {
909*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "++Generating vector spill");
910*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::STriv_pseudo_V6))
911*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0)
912*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag).addMemOperand(MMO);
913*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::VecDblRegsRegClass.hasSubClassEq(RC)) {
914*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "++Generating double vector spill");
915*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::STrivv_pseudo_V6))
916*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0)
917*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag).addMemOperand(MMO);
918*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::VecDblRegs128BRegClass.hasSubClassEq(RC)) {
919*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "++Generating 128B double vector spill");
920*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::STrivv_pseudo_V6_128B))
921*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0)
922*9880d681SAndroid Build Coastguard Worker       .addReg(SrcReg, KillFlag).addMemOperand(MMO);
923*9880d681SAndroid Build Coastguard Worker   } else {
924*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Unimplemented");
925*9880d681SAndroid Build Coastguard Worker   }
926*9880d681SAndroid Build Coastguard Worker }
927*9880d681SAndroid Build Coastguard Worker 
loadRegFromStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,unsigned DestReg,int FI,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI) const928*9880d681SAndroid Build Coastguard Worker void HexagonInstrInfo::loadRegFromStackSlot(
929*9880d681SAndroid Build Coastguard Worker     MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg,
930*9880d681SAndroid Build Coastguard Worker     int FI, const TargetRegisterClass *RC,
931*9880d681SAndroid Build Coastguard Worker     const TargetRegisterInfo *TRI) const {
932*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = MBB.findDebugLoc(I);
933*9880d681SAndroid Build Coastguard Worker   MachineFunction &MF = *MBB.getParent();
934*9880d681SAndroid Build Coastguard Worker   MachineFrameInfo &MFI = *MF.getFrameInfo();
935*9880d681SAndroid Build Coastguard Worker   unsigned Align = MFI.getObjectAlignment(FI);
936*9880d681SAndroid Build Coastguard Worker 
937*9880d681SAndroid Build Coastguard Worker   MachineMemOperand *MMO = MF.getMachineMemOperand(
938*9880d681SAndroid Build Coastguard Worker       MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
939*9880d681SAndroid Build Coastguard Worker       MFI.getObjectSize(FI), Align);
940*9880d681SAndroid Build Coastguard Worker 
941*9880d681SAndroid Build Coastguard Worker   if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {
942*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::L2_loadri_io), DestReg)
943*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
944*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {
945*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::L2_loadrd_io), DestReg)
946*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
947*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {
948*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::LDriw_pred), DestReg)
949*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
950*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {
951*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::LDriw_mod), DestReg)
952*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
953*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::VecPredRegs128BRegClass.hasSubClassEq(RC)) {
954*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::LDriq_pred_V6_128B), DestReg)
955*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
956*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::VecPredRegsRegClass.hasSubClassEq(RC)) {
957*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::LDriq_pred_V6), DestReg)
958*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
959*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::VecDblRegs128BRegClass.hasSubClassEq(RC)) {
960*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "++Generating 128B double vector restore");
961*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::LDrivv_pseudo_V6_128B), DestReg)
962*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
963*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::VectorRegs128BRegClass.hasSubClassEq(RC)) {
964*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "++Generating 128B vector restore");
965*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::LDriv_pseudo_V6_128B), DestReg)
966*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
967*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::VectorRegsRegClass.hasSubClassEq(RC)) {
968*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "++Generating vector restore");
969*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::LDriv_pseudo_V6), DestReg)
970*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
971*9880d681SAndroid Build Coastguard Worker   } else if (Hexagon::VecDblRegsRegClass.hasSubClassEq(RC)) {
972*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "++Generating double vector restore");
973*9880d681SAndroid Build Coastguard Worker     BuildMI(MBB, I, DL, get(Hexagon::LDrivv_pseudo_V6), DestReg)
974*9880d681SAndroid Build Coastguard Worker       .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
975*9880d681SAndroid Build Coastguard Worker   } else {
976*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Can't store this register to stack slot");
977*9880d681SAndroid Build Coastguard Worker   }
978*9880d681SAndroid Build Coastguard Worker }
979*9880d681SAndroid Build Coastguard Worker 
980*9880d681SAndroid Build Coastguard Worker 
981*9880d681SAndroid Build Coastguard Worker /// expandPostRAPseudo - This function is called for all pseudo instructions
982*9880d681SAndroid Build Coastguard Worker /// that remain after register allocation. Many pseudo instructions are
983*9880d681SAndroid Build Coastguard Worker /// created to help register allocation. This is the place to convert them
984*9880d681SAndroid Build Coastguard Worker /// into real instructions. The target can edit MI in place, or it can insert
985*9880d681SAndroid Build Coastguard Worker /// new instructions and erase MI. The function should return true if
986*9880d681SAndroid Build Coastguard Worker /// anything was changed.
expandPostRAPseudo(MachineInstr & MI) const987*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
988*9880d681SAndroid Build Coastguard Worker   const HexagonRegisterInfo &HRI = getRegisterInfo();
989*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MI.getParent()->getParent()->getRegInfo();
990*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &MBB = *MI.getParent();
991*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = MI.getDebugLoc();
992*9880d681SAndroid Build Coastguard Worker   unsigned Opc = MI.getOpcode();
993*9880d681SAndroid Build Coastguard Worker   const unsigned VecOffset = 1;
994*9880d681SAndroid Build Coastguard Worker   bool Is128B = false;
995*9880d681SAndroid Build Coastguard Worker 
996*9880d681SAndroid Build Coastguard Worker   switch (Opc) {
997*9880d681SAndroid Build Coastguard Worker     case TargetOpcode::COPY: {
998*9880d681SAndroid Build Coastguard Worker       MachineOperand &MD = MI.getOperand(0);
999*9880d681SAndroid Build Coastguard Worker       MachineOperand &MS = MI.getOperand(1);
1000*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock::iterator MBBI = MI.getIterator();
1001*9880d681SAndroid Build Coastguard Worker       if (MD.getReg() != MS.getReg() && !MS.isUndef()) {
1002*9880d681SAndroid Build Coastguard Worker         copyPhysReg(MBB, MI, DL, MD.getReg(), MS.getReg(), MS.isKill());
1003*9880d681SAndroid Build Coastguard Worker         std::prev(MBBI)->copyImplicitOps(*MBB.getParent(), MI);
1004*9880d681SAndroid Build Coastguard Worker       }
1005*9880d681SAndroid Build Coastguard Worker       MBB.erase(MBBI);
1006*9880d681SAndroid Build Coastguard Worker       return true;
1007*9880d681SAndroid Build Coastguard Worker     }
1008*9880d681SAndroid Build Coastguard Worker     case Hexagon::ALIGNA:
1009*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, DL, get(Hexagon::A2_andir), MI.getOperand(0).getReg())
1010*9880d681SAndroid Build Coastguard Worker           .addReg(HRI.getFrameRegister())
1011*9880d681SAndroid Build Coastguard Worker           .addImm(-MI.getOperand(1).getImm());
1012*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
1013*9880d681SAndroid Build Coastguard Worker       return true;
1014*9880d681SAndroid Build Coastguard Worker     case Hexagon::HEXAGON_V6_vassignp_128B:
1015*9880d681SAndroid Build Coastguard Worker     case Hexagon::HEXAGON_V6_vassignp: {
1016*9880d681SAndroid Build Coastguard Worker       unsigned SrcReg = MI.getOperand(1).getReg();
1017*9880d681SAndroid Build Coastguard Worker       unsigned DstReg = MI.getOperand(0).getReg();
1018*9880d681SAndroid Build Coastguard Worker       if (SrcReg != DstReg)
1019*9880d681SAndroid Build Coastguard Worker         copyPhysReg(MBB, MI, DL, DstReg, SrcReg, MI.getOperand(1).isKill());
1020*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
1021*9880d681SAndroid Build Coastguard Worker       return true;
1022*9880d681SAndroid Build Coastguard Worker     }
1023*9880d681SAndroid Build Coastguard Worker     case Hexagon::HEXAGON_V6_lo_128B:
1024*9880d681SAndroid Build Coastguard Worker     case Hexagon::HEXAGON_V6_lo: {
1025*9880d681SAndroid Build Coastguard Worker       unsigned SrcReg = MI.getOperand(1).getReg();
1026*9880d681SAndroid Build Coastguard Worker       unsigned DstReg = MI.getOperand(0).getReg();
1027*9880d681SAndroid Build Coastguard Worker       unsigned SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::subreg_loreg);
1028*9880d681SAndroid Build Coastguard Worker       copyPhysReg(MBB, MI, DL, DstReg, SrcSubLo, MI.getOperand(1).isKill());
1029*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
1030*9880d681SAndroid Build Coastguard Worker       MRI.clearKillFlags(SrcSubLo);
1031*9880d681SAndroid Build Coastguard Worker       return true;
1032*9880d681SAndroid Build Coastguard Worker     }
1033*9880d681SAndroid Build Coastguard Worker     case Hexagon::HEXAGON_V6_hi_128B:
1034*9880d681SAndroid Build Coastguard Worker     case Hexagon::HEXAGON_V6_hi: {
1035*9880d681SAndroid Build Coastguard Worker       unsigned SrcReg = MI.getOperand(1).getReg();
1036*9880d681SAndroid Build Coastguard Worker       unsigned DstReg = MI.getOperand(0).getReg();
1037*9880d681SAndroid Build Coastguard Worker       unsigned SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::subreg_hireg);
1038*9880d681SAndroid Build Coastguard Worker       copyPhysReg(MBB, MI, DL, DstReg, SrcSubHi, MI.getOperand(1).isKill());
1039*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
1040*9880d681SAndroid Build Coastguard Worker       MRI.clearKillFlags(SrcSubHi);
1041*9880d681SAndroid Build Coastguard Worker       return true;
1042*9880d681SAndroid Build Coastguard Worker     }
1043*9880d681SAndroid Build Coastguard Worker     case Hexagon::STrivv_indexed_128B:
1044*9880d681SAndroid Build Coastguard Worker       Is128B = true;
1045*9880d681SAndroid Build Coastguard Worker     case Hexagon::STrivv_indexed: {
1046*9880d681SAndroid Build Coastguard Worker       unsigned SrcReg = MI.getOperand(2).getReg();
1047*9880d681SAndroid Build Coastguard Worker       unsigned SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::subreg_hireg);
1048*9880d681SAndroid Build Coastguard Worker       unsigned SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::subreg_loreg);
1049*9880d681SAndroid Build Coastguard Worker       unsigned NewOpcd = Is128B ? Hexagon::V6_vS32b_ai_128B
1050*9880d681SAndroid Build Coastguard Worker                                 : Hexagon::V6_vS32b_ai;
1051*9880d681SAndroid Build Coastguard Worker       unsigned Offset = Is128B ? VecOffset << 7 : VecOffset << 6;
1052*9880d681SAndroid Build Coastguard Worker       MachineInstr *MI1New =
1053*9880d681SAndroid Build Coastguard Worker           BuildMI(MBB, MI, DL, get(NewOpcd))
1054*9880d681SAndroid Build Coastguard Worker               .addOperand(MI.getOperand(0))
1055*9880d681SAndroid Build Coastguard Worker               .addImm(MI.getOperand(1).getImm())
1056*9880d681SAndroid Build Coastguard Worker               .addReg(SrcSubLo)
1057*9880d681SAndroid Build Coastguard Worker               .setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1058*9880d681SAndroid Build Coastguard Worker       MI1New->getOperand(0).setIsKill(false);
1059*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, DL, get(NewOpcd))
1060*9880d681SAndroid Build Coastguard Worker           .addOperand(MI.getOperand(0))
1061*9880d681SAndroid Build Coastguard Worker           // The Vectors are indexed in multiples of vector size.
1062*9880d681SAndroid Build Coastguard Worker           .addImm(MI.getOperand(1).getImm() + Offset)
1063*9880d681SAndroid Build Coastguard Worker           .addReg(SrcSubHi)
1064*9880d681SAndroid Build Coastguard Worker           .setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1065*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
1066*9880d681SAndroid Build Coastguard Worker       return true;
1067*9880d681SAndroid Build Coastguard Worker     }
1068*9880d681SAndroid Build Coastguard Worker     case Hexagon::LDrivv_pseudo_V6_128B:
1069*9880d681SAndroid Build Coastguard Worker     case Hexagon::LDrivv_indexed_128B:
1070*9880d681SAndroid Build Coastguard Worker       Is128B = true;
1071*9880d681SAndroid Build Coastguard Worker     case Hexagon::LDrivv_pseudo_V6:
1072*9880d681SAndroid Build Coastguard Worker     case Hexagon::LDrivv_indexed: {
1073*9880d681SAndroid Build Coastguard Worker       unsigned NewOpcd = Is128B ? Hexagon::V6_vL32b_ai_128B
1074*9880d681SAndroid Build Coastguard Worker                                 : Hexagon::V6_vL32b_ai;
1075*9880d681SAndroid Build Coastguard Worker       unsigned DstReg = MI.getOperand(0).getReg();
1076*9880d681SAndroid Build Coastguard Worker       unsigned Offset = Is128B ? VecOffset << 7 : VecOffset << 6;
1077*9880d681SAndroid Build Coastguard Worker       MachineInstr *MI1New =
1078*9880d681SAndroid Build Coastguard Worker           BuildMI(MBB, MI, DL, get(NewOpcd),
1079*9880d681SAndroid Build Coastguard Worker                   HRI.getSubReg(DstReg, Hexagon::subreg_loreg))
1080*9880d681SAndroid Build Coastguard Worker               .addOperand(MI.getOperand(1))
1081*9880d681SAndroid Build Coastguard Worker               .addImm(MI.getOperand(2).getImm());
1082*9880d681SAndroid Build Coastguard Worker       MI1New->getOperand(1).setIsKill(false);
1083*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, DL, get(NewOpcd),
1084*9880d681SAndroid Build Coastguard Worker               HRI.getSubReg(DstReg, Hexagon::subreg_hireg))
1085*9880d681SAndroid Build Coastguard Worker           .addOperand(MI.getOperand(1))
1086*9880d681SAndroid Build Coastguard Worker           // The Vectors are indexed in multiples of vector size.
1087*9880d681SAndroid Build Coastguard Worker           .addImm(MI.getOperand(2).getImm() + Offset)
1088*9880d681SAndroid Build Coastguard Worker           .setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1089*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
1090*9880d681SAndroid Build Coastguard Worker       return true;
1091*9880d681SAndroid Build Coastguard Worker     }
1092*9880d681SAndroid Build Coastguard Worker     case Hexagon::LDriv_pseudo_V6_128B:
1093*9880d681SAndroid Build Coastguard Worker       Is128B = true;
1094*9880d681SAndroid Build Coastguard Worker     case Hexagon::LDriv_pseudo_V6: {
1095*9880d681SAndroid Build Coastguard Worker       unsigned DstReg = MI.getOperand(0).getReg();
1096*9880d681SAndroid Build Coastguard Worker       unsigned NewOpc = Is128B ? Hexagon::V6_vL32b_ai_128B
1097*9880d681SAndroid Build Coastguard Worker                                : Hexagon::V6_vL32b_ai;
1098*9880d681SAndroid Build Coastguard Worker       int32_t Off = MI.getOperand(2).getImm();
1099*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, DL, get(NewOpc), DstReg)
1100*9880d681SAndroid Build Coastguard Worker           .addOperand(MI.getOperand(1))
1101*9880d681SAndroid Build Coastguard Worker           .addImm(Off)
1102*9880d681SAndroid Build Coastguard Worker           .setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1103*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
1104*9880d681SAndroid Build Coastguard Worker       return true;
1105*9880d681SAndroid Build Coastguard Worker     }
1106*9880d681SAndroid Build Coastguard Worker     case Hexagon::STriv_pseudo_V6_128B:
1107*9880d681SAndroid Build Coastguard Worker       Is128B = true;
1108*9880d681SAndroid Build Coastguard Worker     case Hexagon::STriv_pseudo_V6: {
1109*9880d681SAndroid Build Coastguard Worker       unsigned NewOpc = Is128B ? Hexagon::V6_vS32b_ai_128B
1110*9880d681SAndroid Build Coastguard Worker                                : Hexagon::V6_vS32b_ai;
1111*9880d681SAndroid Build Coastguard Worker       int32_t Off = MI.getOperand(1).getImm();
1112*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, DL, get(NewOpc))
1113*9880d681SAndroid Build Coastguard Worker           .addOperand(MI.getOperand(0))
1114*9880d681SAndroid Build Coastguard Worker           .addImm(Off)
1115*9880d681SAndroid Build Coastguard Worker           .addOperand(MI.getOperand(2))
1116*9880d681SAndroid Build Coastguard Worker           .setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
1117*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
1118*9880d681SAndroid Build Coastguard Worker       return true;
1119*9880d681SAndroid Build Coastguard Worker     }
1120*9880d681SAndroid Build Coastguard Worker     case Hexagon::TFR_PdTrue: {
1121*9880d681SAndroid Build Coastguard Worker       unsigned Reg = MI.getOperand(0).getReg();
1122*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, DL, get(Hexagon::C2_orn), Reg)
1123*9880d681SAndroid Build Coastguard Worker         .addReg(Reg, RegState::Undef)
1124*9880d681SAndroid Build Coastguard Worker         .addReg(Reg, RegState::Undef);
1125*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
1126*9880d681SAndroid Build Coastguard Worker       return true;
1127*9880d681SAndroid Build Coastguard Worker     }
1128*9880d681SAndroid Build Coastguard Worker     case Hexagon::TFR_PdFalse: {
1129*9880d681SAndroid Build Coastguard Worker       unsigned Reg = MI.getOperand(0).getReg();
1130*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, DL, get(Hexagon::C2_andn), Reg)
1131*9880d681SAndroid Build Coastguard Worker         .addReg(Reg, RegState::Undef)
1132*9880d681SAndroid Build Coastguard Worker         .addReg(Reg, RegState::Undef);
1133*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
1134*9880d681SAndroid Build Coastguard Worker       return true;
1135*9880d681SAndroid Build Coastguard Worker     }
1136*9880d681SAndroid Build Coastguard Worker     case Hexagon::VMULW: {
1137*9880d681SAndroid Build Coastguard Worker       // Expand a 64-bit vector multiply into 2 32-bit scalar multiplies.
1138*9880d681SAndroid Build Coastguard Worker       unsigned DstReg = MI.getOperand(0).getReg();
1139*9880d681SAndroid Build Coastguard Worker       unsigned Src1Reg = MI.getOperand(1).getReg();
1140*9880d681SAndroid Build Coastguard Worker       unsigned Src2Reg = MI.getOperand(2).getReg();
1141*9880d681SAndroid Build Coastguard Worker       unsigned Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::subreg_hireg);
1142*9880d681SAndroid Build Coastguard Worker       unsigned Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::subreg_loreg);
1143*9880d681SAndroid Build Coastguard Worker       unsigned Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::subreg_hireg);
1144*9880d681SAndroid Build Coastguard Worker       unsigned Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::subreg_loreg);
1145*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi),
1146*9880d681SAndroid Build Coastguard Worker               HRI.getSubReg(DstReg, Hexagon::subreg_hireg))
1147*9880d681SAndroid Build Coastguard Worker           .addReg(Src1SubHi)
1148*9880d681SAndroid Build Coastguard Worker           .addReg(Src2SubHi);
1149*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi),
1150*9880d681SAndroid Build Coastguard Worker               HRI.getSubReg(DstReg, Hexagon::subreg_loreg))
1151*9880d681SAndroid Build Coastguard Worker           .addReg(Src1SubLo)
1152*9880d681SAndroid Build Coastguard Worker           .addReg(Src2SubLo);
1153*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
1154*9880d681SAndroid Build Coastguard Worker       MRI.clearKillFlags(Src1SubHi);
1155*9880d681SAndroid Build Coastguard Worker       MRI.clearKillFlags(Src1SubLo);
1156*9880d681SAndroid Build Coastguard Worker       MRI.clearKillFlags(Src2SubHi);
1157*9880d681SAndroid Build Coastguard Worker       MRI.clearKillFlags(Src2SubLo);
1158*9880d681SAndroid Build Coastguard Worker       return true;
1159*9880d681SAndroid Build Coastguard Worker     }
1160*9880d681SAndroid Build Coastguard Worker     case Hexagon::VMULW_ACC: {
1161*9880d681SAndroid Build Coastguard Worker       // Expand 64-bit vector multiply with addition into 2 scalar multiplies.
1162*9880d681SAndroid Build Coastguard Worker       unsigned DstReg = MI.getOperand(0).getReg();
1163*9880d681SAndroid Build Coastguard Worker       unsigned Src1Reg = MI.getOperand(1).getReg();
1164*9880d681SAndroid Build Coastguard Worker       unsigned Src2Reg = MI.getOperand(2).getReg();
1165*9880d681SAndroid Build Coastguard Worker       unsigned Src3Reg = MI.getOperand(3).getReg();
1166*9880d681SAndroid Build Coastguard Worker       unsigned Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::subreg_hireg);
1167*9880d681SAndroid Build Coastguard Worker       unsigned Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::subreg_loreg);
1168*9880d681SAndroid Build Coastguard Worker       unsigned Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::subreg_hireg);
1169*9880d681SAndroid Build Coastguard Worker       unsigned Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::subreg_loreg);
1170*9880d681SAndroid Build Coastguard Worker       unsigned Src3SubHi = HRI.getSubReg(Src3Reg, Hexagon::subreg_hireg);
1171*9880d681SAndroid Build Coastguard Worker       unsigned Src3SubLo = HRI.getSubReg(Src3Reg, Hexagon::subreg_loreg);
1172*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci),
1173*9880d681SAndroid Build Coastguard Worker               HRI.getSubReg(DstReg, Hexagon::subreg_hireg))
1174*9880d681SAndroid Build Coastguard Worker           .addReg(Src1SubHi)
1175*9880d681SAndroid Build Coastguard Worker           .addReg(Src2SubHi)
1176*9880d681SAndroid Build Coastguard Worker           .addReg(Src3SubHi);
1177*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci),
1178*9880d681SAndroid Build Coastguard Worker               HRI.getSubReg(DstReg, Hexagon::subreg_loreg))
1179*9880d681SAndroid Build Coastguard Worker           .addReg(Src1SubLo)
1180*9880d681SAndroid Build Coastguard Worker           .addReg(Src2SubLo)
1181*9880d681SAndroid Build Coastguard Worker           .addReg(Src3SubLo);
1182*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
1183*9880d681SAndroid Build Coastguard Worker       MRI.clearKillFlags(Src1SubHi);
1184*9880d681SAndroid Build Coastguard Worker       MRI.clearKillFlags(Src1SubLo);
1185*9880d681SAndroid Build Coastguard Worker       MRI.clearKillFlags(Src2SubHi);
1186*9880d681SAndroid Build Coastguard Worker       MRI.clearKillFlags(Src2SubLo);
1187*9880d681SAndroid Build Coastguard Worker       MRI.clearKillFlags(Src3SubHi);
1188*9880d681SAndroid Build Coastguard Worker       MRI.clearKillFlags(Src3SubLo);
1189*9880d681SAndroid Build Coastguard Worker       return true;
1190*9880d681SAndroid Build Coastguard Worker     }
1191*9880d681SAndroid Build Coastguard Worker     case Hexagon::Insert4: {
1192*9880d681SAndroid Build Coastguard Worker       unsigned DstReg = MI.getOperand(0).getReg();
1193*9880d681SAndroid Build Coastguard Worker       unsigned Src1Reg = MI.getOperand(1).getReg();
1194*9880d681SAndroid Build Coastguard Worker       unsigned Src2Reg = MI.getOperand(2).getReg();
1195*9880d681SAndroid Build Coastguard Worker       unsigned Src3Reg = MI.getOperand(3).getReg();
1196*9880d681SAndroid Build Coastguard Worker       unsigned Src4Reg = MI.getOperand(4).getReg();
1197*9880d681SAndroid Build Coastguard Worker       unsigned Src1RegIsKill = getKillRegState(MI.getOperand(1).isKill());
1198*9880d681SAndroid Build Coastguard Worker       unsigned Src2RegIsKill = getKillRegState(MI.getOperand(2).isKill());
1199*9880d681SAndroid Build Coastguard Worker       unsigned Src3RegIsKill = getKillRegState(MI.getOperand(3).isKill());
1200*9880d681SAndroid Build Coastguard Worker       unsigned Src4RegIsKill = getKillRegState(MI.getOperand(4).isKill());
1201*9880d681SAndroid Build Coastguard Worker       unsigned DstSubHi = HRI.getSubReg(DstReg, Hexagon::subreg_hireg);
1202*9880d681SAndroid Build Coastguard Worker       unsigned DstSubLo = HRI.getSubReg(DstReg, Hexagon::subreg_loreg);
1203*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::S2_insert),
1204*9880d681SAndroid Build Coastguard Worker               HRI.getSubReg(DstReg, Hexagon::subreg_loreg))
1205*9880d681SAndroid Build Coastguard Worker           .addReg(DstSubLo)
1206*9880d681SAndroid Build Coastguard Worker           .addReg(Src1Reg, Src1RegIsKill)
1207*9880d681SAndroid Build Coastguard Worker           .addImm(16)
1208*9880d681SAndroid Build Coastguard Worker           .addImm(0);
1209*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::S2_insert),
1210*9880d681SAndroid Build Coastguard Worker               HRI.getSubReg(DstReg, Hexagon::subreg_loreg))
1211*9880d681SAndroid Build Coastguard Worker           .addReg(DstSubLo)
1212*9880d681SAndroid Build Coastguard Worker           .addReg(Src2Reg, Src2RegIsKill)
1213*9880d681SAndroid Build Coastguard Worker           .addImm(16)
1214*9880d681SAndroid Build Coastguard Worker           .addImm(16);
1215*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::S2_insert),
1216*9880d681SAndroid Build Coastguard Worker               HRI.getSubReg(DstReg, Hexagon::subreg_hireg))
1217*9880d681SAndroid Build Coastguard Worker           .addReg(DstSubHi)
1218*9880d681SAndroid Build Coastguard Worker           .addReg(Src3Reg, Src3RegIsKill)
1219*9880d681SAndroid Build Coastguard Worker           .addImm(16)
1220*9880d681SAndroid Build Coastguard Worker           .addImm(0);
1221*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::S2_insert),
1222*9880d681SAndroid Build Coastguard Worker               HRI.getSubReg(DstReg, Hexagon::subreg_hireg))
1223*9880d681SAndroid Build Coastguard Worker           .addReg(DstSubHi)
1224*9880d681SAndroid Build Coastguard Worker           .addReg(Src4Reg, Src4RegIsKill)
1225*9880d681SAndroid Build Coastguard Worker           .addImm(16)
1226*9880d681SAndroid Build Coastguard Worker           .addImm(16);
1227*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
1228*9880d681SAndroid Build Coastguard Worker       MRI.clearKillFlags(DstReg);
1229*9880d681SAndroid Build Coastguard Worker       MRI.clearKillFlags(DstSubHi);
1230*9880d681SAndroid Build Coastguard Worker       MRI.clearKillFlags(DstSubLo);
1231*9880d681SAndroid Build Coastguard Worker       return true;
1232*9880d681SAndroid Build Coastguard Worker     }
1233*9880d681SAndroid Build Coastguard Worker     case Hexagon::MUX64_rr: {
1234*9880d681SAndroid Build Coastguard Worker       const MachineOperand &Op0 = MI.getOperand(0);
1235*9880d681SAndroid Build Coastguard Worker       const MachineOperand &Op1 = MI.getOperand(1);
1236*9880d681SAndroid Build Coastguard Worker       const MachineOperand &Op2 = MI.getOperand(2);
1237*9880d681SAndroid Build Coastguard Worker       const MachineOperand &Op3 = MI.getOperand(3);
1238*9880d681SAndroid Build Coastguard Worker       unsigned Rd = Op0.getReg();
1239*9880d681SAndroid Build Coastguard Worker       unsigned Pu = Op1.getReg();
1240*9880d681SAndroid Build Coastguard Worker       unsigned Rs = Op2.getReg();
1241*9880d681SAndroid Build Coastguard Worker       unsigned Rt = Op3.getReg();
1242*9880d681SAndroid Build Coastguard Worker       DebugLoc DL = MI.getDebugLoc();
1243*9880d681SAndroid Build Coastguard Worker       unsigned K1 = getKillRegState(Op1.isKill());
1244*9880d681SAndroid Build Coastguard Worker       unsigned K2 = getKillRegState(Op2.isKill());
1245*9880d681SAndroid Build Coastguard Worker       unsigned K3 = getKillRegState(Op3.isKill());
1246*9880d681SAndroid Build Coastguard Worker       if (Rd != Rs)
1247*9880d681SAndroid Build Coastguard Worker         BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpt), Rd)
1248*9880d681SAndroid Build Coastguard Worker           .addReg(Pu, (Rd == Rt) ? K1 : 0)
1249*9880d681SAndroid Build Coastguard Worker           .addReg(Rs, K2);
1250*9880d681SAndroid Build Coastguard Worker       if (Rd != Rt)
1251*9880d681SAndroid Build Coastguard Worker         BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpf), Rd)
1252*9880d681SAndroid Build Coastguard Worker           .addReg(Pu, K1)
1253*9880d681SAndroid Build Coastguard Worker           .addReg(Rt, K3);
1254*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
1255*9880d681SAndroid Build Coastguard Worker       return true;
1256*9880d681SAndroid Build Coastguard Worker     }
1257*9880d681SAndroid Build Coastguard Worker     case Hexagon::VSelectPseudo_V6: {
1258*9880d681SAndroid Build Coastguard Worker       const MachineOperand &Op0 = MI.getOperand(0);
1259*9880d681SAndroid Build Coastguard Worker       const MachineOperand &Op1 = MI.getOperand(1);
1260*9880d681SAndroid Build Coastguard Worker       const MachineOperand &Op2 = MI.getOperand(2);
1261*9880d681SAndroid Build Coastguard Worker       const MachineOperand &Op3 = MI.getOperand(3);
1262*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, DL, get(Hexagon::V6_vcmov))
1263*9880d681SAndroid Build Coastguard Worker         .addOperand(Op0)
1264*9880d681SAndroid Build Coastguard Worker         .addOperand(Op1)
1265*9880d681SAndroid Build Coastguard Worker         .addOperand(Op2);
1266*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, DL, get(Hexagon::V6_vncmov))
1267*9880d681SAndroid Build Coastguard Worker         .addOperand(Op0)
1268*9880d681SAndroid Build Coastguard Worker         .addOperand(Op1)
1269*9880d681SAndroid Build Coastguard Worker         .addOperand(Op3);
1270*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
1271*9880d681SAndroid Build Coastguard Worker       return true;
1272*9880d681SAndroid Build Coastguard Worker     }
1273*9880d681SAndroid Build Coastguard Worker     case Hexagon::VSelectDblPseudo_V6: {
1274*9880d681SAndroid Build Coastguard Worker       MachineOperand &Op0 = MI.getOperand(0);
1275*9880d681SAndroid Build Coastguard Worker       MachineOperand &Op1 = MI.getOperand(1);
1276*9880d681SAndroid Build Coastguard Worker       MachineOperand &Op2 = MI.getOperand(2);
1277*9880d681SAndroid Build Coastguard Worker       MachineOperand &Op3 = MI.getOperand(3);
1278*9880d681SAndroid Build Coastguard Worker       unsigned SrcLo = HRI.getSubReg(Op2.getReg(), Hexagon::subreg_loreg);
1279*9880d681SAndroid Build Coastguard Worker       unsigned SrcHi = HRI.getSubReg(Op2.getReg(), Hexagon::subreg_hireg);
1280*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, DL, get(Hexagon::V6_vccombine))
1281*9880d681SAndroid Build Coastguard Worker         .addOperand(Op0)
1282*9880d681SAndroid Build Coastguard Worker         .addOperand(Op1)
1283*9880d681SAndroid Build Coastguard Worker         .addReg(SrcHi)
1284*9880d681SAndroid Build Coastguard Worker         .addReg(SrcLo);
1285*9880d681SAndroid Build Coastguard Worker       SrcLo = HRI.getSubReg(Op3.getReg(), Hexagon::subreg_loreg);
1286*9880d681SAndroid Build Coastguard Worker       SrcHi = HRI.getSubReg(Op3.getReg(), Hexagon::subreg_hireg);
1287*9880d681SAndroid Build Coastguard Worker       BuildMI(MBB, MI, DL, get(Hexagon::V6_vnccombine))
1288*9880d681SAndroid Build Coastguard Worker         .addOperand(Op0)
1289*9880d681SAndroid Build Coastguard Worker         .addOperand(Op1)
1290*9880d681SAndroid Build Coastguard Worker         .addReg(SrcHi)
1291*9880d681SAndroid Build Coastguard Worker         .addReg(SrcLo);
1292*9880d681SAndroid Build Coastguard Worker       MBB.erase(MI);
1293*9880d681SAndroid Build Coastguard Worker       return true;
1294*9880d681SAndroid Build Coastguard Worker     }
1295*9880d681SAndroid Build Coastguard Worker     case Hexagon::TCRETURNi:
1296*9880d681SAndroid Build Coastguard Worker       MI.setDesc(get(Hexagon::J2_jump));
1297*9880d681SAndroid Build Coastguard Worker       return true;
1298*9880d681SAndroid Build Coastguard Worker     case Hexagon::TCRETURNr:
1299*9880d681SAndroid Build Coastguard Worker       MI.setDesc(get(Hexagon::J2_jumpr));
1300*9880d681SAndroid Build Coastguard Worker       return true;
1301*9880d681SAndroid Build Coastguard Worker     case Hexagon::TFRI_f:
1302*9880d681SAndroid Build Coastguard Worker     case Hexagon::TFRI_cPt_f:
1303*9880d681SAndroid Build Coastguard Worker     case Hexagon::TFRI_cNotPt_f: {
1304*9880d681SAndroid Build Coastguard Worker       unsigned Opx = (Opc == Hexagon::TFRI_f) ? 1 : 2;
1305*9880d681SAndroid Build Coastguard Worker       APFloat FVal = MI.getOperand(Opx).getFPImm()->getValueAPF();
1306*9880d681SAndroid Build Coastguard Worker       APInt IVal = FVal.bitcastToAPInt();
1307*9880d681SAndroid Build Coastguard Worker       MI.RemoveOperand(Opx);
1308*9880d681SAndroid Build Coastguard Worker       unsigned NewOpc = (Opc == Hexagon::TFRI_f)     ? Hexagon::A2_tfrsi   :
1309*9880d681SAndroid Build Coastguard Worker                         (Opc == Hexagon::TFRI_cPt_f) ? Hexagon::C2_cmoveit :
1310*9880d681SAndroid Build Coastguard Worker                                                        Hexagon::C2_cmoveif;
1311*9880d681SAndroid Build Coastguard Worker       MI.setDesc(get(NewOpc));
1312*9880d681SAndroid Build Coastguard Worker       MI.addOperand(MachineOperand::CreateImm(IVal.getZExtValue()));
1313*9880d681SAndroid Build Coastguard Worker       return true;
1314*9880d681SAndroid Build Coastguard Worker     }
1315*9880d681SAndroid Build Coastguard Worker   }
1316*9880d681SAndroid Build Coastguard Worker 
1317*9880d681SAndroid Build Coastguard Worker   return false;
1318*9880d681SAndroid Build Coastguard Worker }
1319*9880d681SAndroid Build Coastguard Worker 
1320*9880d681SAndroid Build Coastguard Worker 
1321*9880d681SAndroid Build Coastguard Worker // We indicate that we want to reverse the branch by
1322*9880d681SAndroid Build Coastguard Worker // inserting the reversed branching opcode.
ReverseBranchCondition(SmallVectorImpl<MachineOperand> & Cond) const1323*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::ReverseBranchCondition(
1324*9880d681SAndroid Build Coastguard Worker       SmallVectorImpl<MachineOperand> &Cond) const {
1325*9880d681SAndroid Build Coastguard Worker   if (Cond.empty())
1326*9880d681SAndroid Build Coastguard Worker     return true;
1327*9880d681SAndroid Build Coastguard Worker   assert(Cond[0].isImm() && "First entry in the cond vector not imm-val");
1328*9880d681SAndroid Build Coastguard Worker   unsigned opcode = Cond[0].getImm();
1329*9880d681SAndroid Build Coastguard Worker   //unsigned temp;
1330*9880d681SAndroid Build Coastguard Worker   assert(get(opcode).isBranch() && "Should be a branching condition.");
1331*9880d681SAndroid Build Coastguard Worker   if (isEndLoopN(opcode))
1332*9880d681SAndroid Build Coastguard Worker     return true;
1333*9880d681SAndroid Build Coastguard Worker   unsigned NewOpcode = getInvertedPredicatedOpcode(opcode);
1334*9880d681SAndroid Build Coastguard Worker   Cond[0].setImm(NewOpcode);
1335*9880d681SAndroid Build Coastguard Worker   return false;
1336*9880d681SAndroid Build Coastguard Worker }
1337*9880d681SAndroid Build Coastguard Worker 
1338*9880d681SAndroid Build Coastguard Worker 
insertNoop(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI) const1339*9880d681SAndroid Build Coastguard Worker void HexagonInstrInfo::insertNoop(MachineBasicBlock &MBB,
1340*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock::iterator MI) const {
1341*9880d681SAndroid Build Coastguard Worker   DebugLoc DL;
1342*9880d681SAndroid Build Coastguard Worker   BuildMI(MBB, MI, DL, get(Hexagon::A2_nop));
1343*9880d681SAndroid Build Coastguard Worker }
1344*9880d681SAndroid Build Coastguard Worker 
1345*9880d681SAndroid Build Coastguard Worker 
1346*9880d681SAndroid Build Coastguard Worker // Returns true if an instruction is predicated irrespective of the predicate
1347*9880d681SAndroid Build Coastguard Worker // sense. For example, all of the following will return true.
1348*9880d681SAndroid Build Coastguard Worker // if (p0) R1 = add(R2, R3)
1349*9880d681SAndroid Build Coastguard Worker // if (!p0) R1 = add(R2, R3)
1350*9880d681SAndroid Build Coastguard Worker // if (p0.new) R1 = add(R2, R3)
1351*9880d681SAndroid Build Coastguard Worker // if (!p0.new) R1 = add(R2, R3)
1352*9880d681SAndroid Build Coastguard Worker // Note: New-value stores are not included here as in the current
1353*9880d681SAndroid Build Coastguard Worker // implementation, we don't need to check their predicate sense.
isPredicated(const MachineInstr & MI) const1354*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isPredicated(const MachineInstr &MI) const {
1355*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI.getDesc().TSFlags;
1356*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask;
1357*9880d681SAndroid Build Coastguard Worker }
1358*9880d681SAndroid Build Coastguard Worker 
1359*9880d681SAndroid Build Coastguard Worker 
PredicateInstruction(MachineInstr & MI,ArrayRef<MachineOperand> Cond) const1360*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::PredicateInstruction(
1361*9880d681SAndroid Build Coastguard Worker     MachineInstr &MI, ArrayRef<MachineOperand> Cond) const {
1362*9880d681SAndroid Build Coastguard Worker   if (Cond.empty() || isNewValueJump(Cond[0].getImm()) ||
1363*9880d681SAndroid Build Coastguard Worker       isEndLoopN(Cond[0].getImm())) {
1364*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "\nCannot predicate:"; MI.dump(););
1365*9880d681SAndroid Build Coastguard Worker     return false;
1366*9880d681SAndroid Build Coastguard Worker   }
1367*9880d681SAndroid Build Coastguard Worker   int Opc = MI.getOpcode();
1368*9880d681SAndroid Build Coastguard Worker   assert (isPredicable(MI) && "Expected predicable instruction");
1369*9880d681SAndroid Build Coastguard Worker   bool invertJump = predOpcodeHasNot(Cond);
1370*9880d681SAndroid Build Coastguard Worker 
1371*9880d681SAndroid Build Coastguard Worker   // We have to predicate MI "in place", i.e. after this function returns,
1372*9880d681SAndroid Build Coastguard Worker   // MI will need to be transformed into a predicated form. To avoid com-
1373*9880d681SAndroid Build Coastguard Worker   // plicated manipulations with the operands (handling tied operands,
1374*9880d681SAndroid Build Coastguard Worker   // etc.), build a new temporary instruction, then overwrite MI with it.
1375*9880d681SAndroid Build Coastguard Worker 
1376*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &B = *MI.getParent();
1377*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = MI.getDebugLoc();
1378*9880d681SAndroid Build Coastguard Worker   unsigned PredOpc = getCondOpcode(Opc, invertJump);
1379*9880d681SAndroid Build Coastguard Worker   MachineInstrBuilder T = BuildMI(B, MI, DL, get(PredOpc));
1380*9880d681SAndroid Build Coastguard Worker   unsigned NOp = 0, NumOps = MI.getNumOperands();
1381*9880d681SAndroid Build Coastguard Worker   while (NOp < NumOps) {
1382*9880d681SAndroid Build Coastguard Worker     MachineOperand &Op = MI.getOperand(NOp);
1383*9880d681SAndroid Build Coastguard Worker     if (!Op.isReg() || !Op.isDef() || Op.isImplicit())
1384*9880d681SAndroid Build Coastguard Worker       break;
1385*9880d681SAndroid Build Coastguard Worker     T.addOperand(Op);
1386*9880d681SAndroid Build Coastguard Worker     NOp++;
1387*9880d681SAndroid Build Coastguard Worker   }
1388*9880d681SAndroid Build Coastguard Worker 
1389*9880d681SAndroid Build Coastguard Worker   unsigned PredReg, PredRegPos, PredRegFlags;
1390*9880d681SAndroid Build Coastguard Worker   bool GotPredReg = getPredReg(Cond, PredReg, PredRegPos, PredRegFlags);
1391*9880d681SAndroid Build Coastguard Worker   (void)GotPredReg;
1392*9880d681SAndroid Build Coastguard Worker   assert(GotPredReg);
1393*9880d681SAndroid Build Coastguard Worker   T.addReg(PredReg, PredRegFlags);
1394*9880d681SAndroid Build Coastguard Worker   while (NOp < NumOps)
1395*9880d681SAndroid Build Coastguard Worker     T.addOperand(MI.getOperand(NOp++));
1396*9880d681SAndroid Build Coastguard Worker 
1397*9880d681SAndroid Build Coastguard Worker   MI.setDesc(get(PredOpc));
1398*9880d681SAndroid Build Coastguard Worker   while (unsigned n = MI.getNumOperands())
1399*9880d681SAndroid Build Coastguard Worker     MI.RemoveOperand(n-1);
1400*9880d681SAndroid Build Coastguard Worker   for (unsigned i = 0, n = T->getNumOperands(); i < n; ++i)
1401*9880d681SAndroid Build Coastguard Worker     MI.addOperand(T->getOperand(i));
1402*9880d681SAndroid Build Coastguard Worker 
1403*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::instr_iterator TI = T->getIterator();
1404*9880d681SAndroid Build Coastguard Worker   B.erase(TI);
1405*9880d681SAndroid Build Coastguard Worker 
1406*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = B.getParent()->getRegInfo();
1407*9880d681SAndroid Build Coastguard Worker   MRI.clearKillFlags(PredReg);
1408*9880d681SAndroid Build Coastguard Worker   return true;
1409*9880d681SAndroid Build Coastguard Worker }
1410*9880d681SAndroid Build Coastguard Worker 
1411*9880d681SAndroid Build Coastguard Worker 
SubsumesPredicate(ArrayRef<MachineOperand> Pred1,ArrayRef<MachineOperand> Pred2) const1412*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
1413*9880d681SAndroid Build Coastguard Worker       ArrayRef<MachineOperand> Pred2) const {
1414*9880d681SAndroid Build Coastguard Worker   // TODO: Fix this
1415*9880d681SAndroid Build Coastguard Worker   return false;
1416*9880d681SAndroid Build Coastguard Worker }
1417*9880d681SAndroid Build Coastguard Worker 
1418*9880d681SAndroid Build Coastguard Worker 
DefinesPredicate(MachineInstr & MI,std::vector<MachineOperand> & Pred) const1419*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::DefinesPredicate(
1420*9880d681SAndroid Build Coastguard Worker     MachineInstr &MI, std::vector<MachineOperand> &Pred) const {
1421*9880d681SAndroid Build Coastguard Worker   auto &HRI = getRegisterInfo();
1422*9880d681SAndroid Build Coastguard Worker   for (unsigned oper = 0; oper < MI.getNumOperands(); ++oper) {
1423*9880d681SAndroid Build Coastguard Worker     MachineOperand MO = MI.getOperand(oper);
1424*9880d681SAndroid Build Coastguard Worker     if (MO.isReg() && MO.isDef()) {
1425*9880d681SAndroid Build Coastguard Worker       const TargetRegisterClass* RC = HRI.getMinimalPhysRegClass(MO.getReg());
1426*9880d681SAndroid Build Coastguard Worker       if (RC == &Hexagon::PredRegsRegClass) {
1427*9880d681SAndroid Build Coastguard Worker         Pred.push_back(MO);
1428*9880d681SAndroid Build Coastguard Worker         return true;
1429*9880d681SAndroid Build Coastguard Worker       }
1430*9880d681SAndroid Build Coastguard Worker     }
1431*9880d681SAndroid Build Coastguard Worker   }
1432*9880d681SAndroid Build Coastguard Worker   return false;
1433*9880d681SAndroid Build Coastguard Worker }
1434*9880d681SAndroid Build Coastguard Worker 
1435*9880d681SAndroid Build Coastguard Worker 
isPredicable(MachineInstr & MI) const1436*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isPredicable(MachineInstr &MI) const {
1437*9880d681SAndroid Build Coastguard Worker   return MI.getDesc().isPredicable();
1438*9880d681SAndroid Build Coastguard Worker }
1439*9880d681SAndroid Build Coastguard Worker 
isSchedulingBoundary(const MachineInstr & MI,const MachineBasicBlock * MBB,const MachineFunction & MF) const1440*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
1441*9880d681SAndroid Build Coastguard Worker                                             const MachineBasicBlock *MBB,
1442*9880d681SAndroid Build Coastguard Worker                                             const MachineFunction &MF) const {
1443*9880d681SAndroid Build Coastguard Worker   // Debug info is never a scheduling boundary. It's necessary to be explicit
1444*9880d681SAndroid Build Coastguard Worker   // due to the special treatment of IT instructions below, otherwise a
1445*9880d681SAndroid Build Coastguard Worker   // dbg_value followed by an IT will result in the IT instruction being
1446*9880d681SAndroid Build Coastguard Worker   // considered a scheduling hazard, which is wrong. It should be the actual
1447*9880d681SAndroid Build Coastguard Worker   // instruction preceding the dbg_value instruction(s), just like it is
1448*9880d681SAndroid Build Coastguard Worker   // when debug info is not present.
1449*9880d681SAndroid Build Coastguard Worker   if (MI.isDebugValue())
1450*9880d681SAndroid Build Coastguard Worker     return false;
1451*9880d681SAndroid Build Coastguard Worker 
1452*9880d681SAndroid Build Coastguard Worker   // Throwing call is a boundary.
1453*9880d681SAndroid Build Coastguard Worker   if (MI.isCall()) {
1454*9880d681SAndroid Build Coastguard Worker     // If any of the block's successors is a landing pad, this could be a
1455*9880d681SAndroid Build Coastguard Worker     // throwing call.
1456*9880d681SAndroid Build Coastguard Worker     for (auto I : MBB->successors())
1457*9880d681SAndroid Build Coastguard Worker       if (I->isEHPad())
1458*9880d681SAndroid Build Coastguard Worker         return true;
1459*9880d681SAndroid Build Coastguard Worker   }
1460*9880d681SAndroid Build Coastguard Worker 
1461*9880d681SAndroid Build Coastguard Worker   // Don't mess around with no return calls.
1462*9880d681SAndroid Build Coastguard Worker   if (MI.getOpcode() == Hexagon::CALLv3nr)
1463*9880d681SAndroid Build Coastguard Worker     return true;
1464*9880d681SAndroid Build Coastguard Worker 
1465*9880d681SAndroid Build Coastguard Worker   // Terminators and labels can't be scheduled around.
1466*9880d681SAndroid Build Coastguard Worker   if (MI.getDesc().isTerminator() || MI.isPosition())
1467*9880d681SAndroid Build Coastguard Worker     return true;
1468*9880d681SAndroid Build Coastguard Worker 
1469*9880d681SAndroid Build Coastguard Worker   if (MI.isInlineAsm() && !ScheduleInlineAsm)
1470*9880d681SAndroid Build Coastguard Worker     return true;
1471*9880d681SAndroid Build Coastguard Worker 
1472*9880d681SAndroid Build Coastguard Worker   return false;
1473*9880d681SAndroid Build Coastguard Worker }
1474*9880d681SAndroid Build Coastguard Worker 
1475*9880d681SAndroid Build Coastguard Worker 
1476*9880d681SAndroid Build Coastguard Worker /// Measure the specified inline asm to determine an approximation of its
1477*9880d681SAndroid Build Coastguard Worker /// length.
1478*9880d681SAndroid Build Coastguard Worker /// Comments (which run till the next SeparatorString or newline) do not
1479*9880d681SAndroid Build Coastguard Worker /// count as an instruction.
1480*9880d681SAndroid Build Coastguard Worker /// Any other non-whitespace text is considered an instruction, with
1481*9880d681SAndroid Build Coastguard Worker /// multiple instructions separated by SeparatorString or newlines.
1482*9880d681SAndroid Build Coastguard Worker /// Variable-length instructions are not handled here; this function
1483*9880d681SAndroid Build Coastguard Worker /// may be overloaded in the target code to do that.
1484*9880d681SAndroid Build Coastguard Worker /// Hexagon counts the number of ##'s and adjust for that many
1485*9880d681SAndroid Build Coastguard Worker /// constant exenders.
getInlineAsmLength(const char * Str,const MCAsmInfo & MAI) const1486*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::getInlineAsmLength(const char *Str,
1487*9880d681SAndroid Build Coastguard Worker       const MCAsmInfo &MAI) const {
1488*9880d681SAndroid Build Coastguard Worker   StringRef AStr(Str);
1489*9880d681SAndroid Build Coastguard Worker   // Count the number of instructions in the asm.
1490*9880d681SAndroid Build Coastguard Worker   bool atInsnStart = true;
1491*9880d681SAndroid Build Coastguard Worker   unsigned Length = 0;
1492*9880d681SAndroid Build Coastguard Worker   for (; *Str; ++Str) {
1493*9880d681SAndroid Build Coastguard Worker     if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
1494*9880d681SAndroid Build Coastguard Worker                                 strlen(MAI.getSeparatorString())) == 0)
1495*9880d681SAndroid Build Coastguard Worker       atInsnStart = true;
1496*9880d681SAndroid Build Coastguard Worker     if (atInsnStart && !std::isspace(static_cast<unsigned char>(*Str))) {
1497*9880d681SAndroid Build Coastguard Worker       Length += MAI.getMaxInstLength();
1498*9880d681SAndroid Build Coastguard Worker       atInsnStart = false;
1499*9880d681SAndroid Build Coastguard Worker     }
1500*9880d681SAndroid Build Coastguard Worker     if (atInsnStart && strncmp(Str, MAI.getCommentString(),
1501*9880d681SAndroid Build Coastguard Worker                                strlen(MAI.getCommentString())) == 0)
1502*9880d681SAndroid Build Coastguard Worker       atInsnStart = false;
1503*9880d681SAndroid Build Coastguard Worker   }
1504*9880d681SAndroid Build Coastguard Worker 
1505*9880d681SAndroid Build Coastguard Worker   // Add to size number of constant extenders seen * 4.
1506*9880d681SAndroid Build Coastguard Worker   StringRef Occ("##");
1507*9880d681SAndroid Build Coastguard Worker   Length += AStr.count(Occ)*4;
1508*9880d681SAndroid Build Coastguard Worker   return Length;
1509*9880d681SAndroid Build Coastguard Worker }
1510*9880d681SAndroid Build Coastguard Worker 
1511*9880d681SAndroid Build Coastguard Worker 
1512*9880d681SAndroid Build Coastguard Worker ScheduleHazardRecognizer*
CreateTargetPostRAHazardRecognizer(const InstrItineraryData * II,const ScheduleDAG * DAG) const1513*9880d681SAndroid Build Coastguard Worker HexagonInstrInfo::CreateTargetPostRAHazardRecognizer(
1514*9880d681SAndroid Build Coastguard Worker       const InstrItineraryData *II, const ScheduleDAG *DAG) const {
1515*9880d681SAndroid Build Coastguard Worker   return TargetInstrInfo::CreateTargetPostRAHazardRecognizer(II, DAG);
1516*9880d681SAndroid Build Coastguard Worker }
1517*9880d681SAndroid Build Coastguard Worker 
1518*9880d681SAndroid Build Coastguard Worker 
1519*9880d681SAndroid Build Coastguard Worker /// \brief For a comparison instruction, return the source registers in
1520*9880d681SAndroid Build Coastguard Worker /// \p SrcReg and \p SrcReg2 if having two register operands, and the value it
1521*9880d681SAndroid Build Coastguard Worker /// compares against in CmpValue. Return true if the comparison instruction
1522*9880d681SAndroid Build Coastguard Worker /// can be analyzed.
analyzeCompare(const MachineInstr & MI,unsigned & SrcReg,unsigned & SrcReg2,int & Mask,int & Value) const1523*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
1524*9880d681SAndroid Build Coastguard Worker                                       unsigned &SrcReg2, int &Mask,
1525*9880d681SAndroid Build Coastguard Worker                                       int &Value) const {
1526*9880d681SAndroid Build Coastguard Worker   unsigned Opc = MI.getOpcode();
1527*9880d681SAndroid Build Coastguard Worker 
1528*9880d681SAndroid Build Coastguard Worker   // Set mask and the first source register.
1529*9880d681SAndroid Build Coastguard Worker   switch (Opc) {
1530*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpeq:
1531*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpeqp:
1532*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpgt:
1533*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpgtp:
1534*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpgtu:
1535*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpgtup:
1536*9880d681SAndroid Build Coastguard Worker     case Hexagon::C4_cmpneq:
1537*9880d681SAndroid Build Coastguard Worker     case Hexagon::C4_cmplte:
1538*9880d681SAndroid Build Coastguard Worker     case Hexagon::C4_cmplteu:
1539*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpeqi:
1540*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpgti:
1541*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpgtui:
1542*9880d681SAndroid Build Coastguard Worker     case Hexagon::C4_cmpneqi:
1543*9880d681SAndroid Build Coastguard Worker     case Hexagon::C4_cmplteui:
1544*9880d681SAndroid Build Coastguard Worker     case Hexagon::C4_cmpltei:
1545*9880d681SAndroid Build Coastguard Worker       SrcReg = MI.getOperand(1).getReg();
1546*9880d681SAndroid Build Coastguard Worker       Mask = ~0;
1547*9880d681SAndroid Build Coastguard Worker       break;
1548*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmpbeq:
1549*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmpbgt:
1550*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmpbgtu:
1551*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmpbeqi:
1552*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmpbgti:
1553*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmpbgtui:
1554*9880d681SAndroid Build Coastguard Worker       SrcReg = MI.getOperand(1).getReg();
1555*9880d681SAndroid Build Coastguard Worker       Mask = 0xFF;
1556*9880d681SAndroid Build Coastguard Worker       break;
1557*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmpheq:
1558*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmphgt:
1559*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmphgtu:
1560*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmpheqi:
1561*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmphgti:
1562*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmphgtui:
1563*9880d681SAndroid Build Coastguard Worker       SrcReg = MI.getOperand(1).getReg();
1564*9880d681SAndroid Build Coastguard Worker       Mask = 0xFFFF;
1565*9880d681SAndroid Build Coastguard Worker       break;
1566*9880d681SAndroid Build Coastguard Worker   }
1567*9880d681SAndroid Build Coastguard Worker 
1568*9880d681SAndroid Build Coastguard Worker   // Set the value/second source register.
1569*9880d681SAndroid Build Coastguard Worker   switch (Opc) {
1570*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpeq:
1571*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpeqp:
1572*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpgt:
1573*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpgtp:
1574*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpgtu:
1575*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpgtup:
1576*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmpbeq:
1577*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmpbgt:
1578*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmpbgtu:
1579*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmpheq:
1580*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmphgt:
1581*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmphgtu:
1582*9880d681SAndroid Build Coastguard Worker     case Hexagon::C4_cmpneq:
1583*9880d681SAndroid Build Coastguard Worker     case Hexagon::C4_cmplte:
1584*9880d681SAndroid Build Coastguard Worker     case Hexagon::C4_cmplteu:
1585*9880d681SAndroid Build Coastguard Worker       SrcReg2 = MI.getOperand(2).getReg();
1586*9880d681SAndroid Build Coastguard Worker       return true;
1587*9880d681SAndroid Build Coastguard Worker 
1588*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpeqi:
1589*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpgtui:
1590*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmpgti:
1591*9880d681SAndroid Build Coastguard Worker     case Hexagon::C4_cmpneqi:
1592*9880d681SAndroid Build Coastguard Worker     case Hexagon::C4_cmplteui:
1593*9880d681SAndroid Build Coastguard Worker     case Hexagon::C4_cmpltei:
1594*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmpbeqi:
1595*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmpbgti:
1596*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmpbgtui:
1597*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmpheqi:
1598*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmphgti:
1599*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_cmphgtui:
1600*9880d681SAndroid Build Coastguard Worker       SrcReg2 = 0;
1601*9880d681SAndroid Build Coastguard Worker       Value = MI.getOperand(2).getImm();
1602*9880d681SAndroid Build Coastguard Worker       return true;
1603*9880d681SAndroid Build Coastguard Worker   }
1604*9880d681SAndroid Build Coastguard Worker 
1605*9880d681SAndroid Build Coastguard Worker   return false;
1606*9880d681SAndroid Build Coastguard Worker }
1607*9880d681SAndroid Build Coastguard Worker 
getInstrLatency(const InstrItineraryData * ItinData,const MachineInstr & MI,unsigned * PredCost) const1608*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
1609*9880d681SAndroid Build Coastguard Worker                                            const MachineInstr &MI,
1610*9880d681SAndroid Build Coastguard Worker                                            unsigned *PredCost) const {
1611*9880d681SAndroid Build Coastguard Worker   return getInstrTimingClassLatency(ItinData, &MI);
1612*9880d681SAndroid Build Coastguard Worker }
1613*9880d681SAndroid Build Coastguard Worker 
1614*9880d681SAndroid Build Coastguard Worker 
CreateTargetScheduleState(const TargetSubtargetInfo & STI) const1615*9880d681SAndroid Build Coastguard Worker DFAPacketizer *HexagonInstrInfo::CreateTargetScheduleState(
1616*9880d681SAndroid Build Coastguard Worker     const TargetSubtargetInfo &STI) const {
1617*9880d681SAndroid Build Coastguard Worker   const InstrItineraryData *II = STI.getInstrItineraryData();
1618*9880d681SAndroid Build Coastguard Worker   return static_cast<const HexagonSubtarget&>(STI).createDFAPacketizer(II);
1619*9880d681SAndroid Build Coastguard Worker }
1620*9880d681SAndroid Build Coastguard Worker 
1621*9880d681SAndroid Build Coastguard Worker 
1622*9880d681SAndroid Build Coastguard Worker // Inspired by this pair:
1623*9880d681SAndroid Build Coastguard Worker //  %R13<def> = L2_loadri_io %R29, 136; mem:LD4[FixedStack0]
1624*9880d681SAndroid Build Coastguard Worker //  S2_storeri_io %R29, 132, %R1<kill>; flags:  mem:ST4[FixedStack1]
1625*9880d681SAndroid Build Coastguard Worker // Currently AA considers the addresses in these instructions to be aliasing.
areMemAccessesTriviallyDisjoint(MachineInstr & MIa,MachineInstr & MIb,AliasAnalysis * AA) const1626*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::areMemAccessesTriviallyDisjoint(
1627*9880d681SAndroid Build Coastguard Worker     MachineInstr &MIa, MachineInstr &MIb, AliasAnalysis *AA) const {
1628*9880d681SAndroid Build Coastguard Worker   int OffsetA = 0, OffsetB = 0;
1629*9880d681SAndroid Build Coastguard Worker   unsigned SizeA = 0, SizeB = 0;
1630*9880d681SAndroid Build Coastguard Worker 
1631*9880d681SAndroid Build Coastguard Worker   if (MIa.hasUnmodeledSideEffects() || MIb.hasUnmodeledSideEffects() ||
1632*9880d681SAndroid Build Coastguard Worker       MIa.hasOrderedMemoryRef() || MIb.hasOrderedMemoryRef())
1633*9880d681SAndroid Build Coastguard Worker     return false;
1634*9880d681SAndroid Build Coastguard Worker 
1635*9880d681SAndroid Build Coastguard Worker   // Instructions that are pure loads, not loads and stores like memops are not
1636*9880d681SAndroid Build Coastguard Worker   // dependent.
1637*9880d681SAndroid Build Coastguard Worker   if (MIa.mayLoad() && !isMemOp(&MIa) && MIb.mayLoad() && !isMemOp(&MIb))
1638*9880d681SAndroid Build Coastguard Worker     return true;
1639*9880d681SAndroid Build Coastguard Worker 
1640*9880d681SAndroid Build Coastguard Worker   // Get base, offset, and access size in MIa.
1641*9880d681SAndroid Build Coastguard Worker   unsigned BaseRegA = getBaseAndOffset(&MIa, OffsetA, SizeA);
1642*9880d681SAndroid Build Coastguard Worker   if (!BaseRegA || !SizeA)
1643*9880d681SAndroid Build Coastguard Worker     return false;
1644*9880d681SAndroid Build Coastguard Worker 
1645*9880d681SAndroid Build Coastguard Worker   // Get base, offset, and access size in MIb.
1646*9880d681SAndroid Build Coastguard Worker   unsigned BaseRegB = getBaseAndOffset(&MIb, OffsetB, SizeB);
1647*9880d681SAndroid Build Coastguard Worker   if (!BaseRegB || !SizeB)
1648*9880d681SAndroid Build Coastguard Worker     return false;
1649*9880d681SAndroid Build Coastguard Worker 
1650*9880d681SAndroid Build Coastguard Worker   if (BaseRegA != BaseRegB)
1651*9880d681SAndroid Build Coastguard Worker     return false;
1652*9880d681SAndroid Build Coastguard Worker 
1653*9880d681SAndroid Build Coastguard Worker   // This is a mem access with the same base register and known offsets from it.
1654*9880d681SAndroid Build Coastguard Worker   // Reason about it.
1655*9880d681SAndroid Build Coastguard Worker   if (OffsetA > OffsetB) {
1656*9880d681SAndroid Build Coastguard Worker     uint64_t offDiff = (uint64_t)((int64_t)OffsetA - (int64_t)OffsetB);
1657*9880d681SAndroid Build Coastguard Worker     return (SizeB <= offDiff);
1658*9880d681SAndroid Build Coastguard Worker   } else if (OffsetA < OffsetB) {
1659*9880d681SAndroid Build Coastguard Worker     uint64_t offDiff = (uint64_t)((int64_t)OffsetB - (int64_t)OffsetA);
1660*9880d681SAndroid Build Coastguard Worker     return (SizeA <= offDiff);
1661*9880d681SAndroid Build Coastguard Worker   }
1662*9880d681SAndroid Build Coastguard Worker 
1663*9880d681SAndroid Build Coastguard Worker   return false;
1664*9880d681SAndroid Build Coastguard Worker }
1665*9880d681SAndroid Build Coastguard Worker 
1666*9880d681SAndroid Build Coastguard Worker 
1667*9880d681SAndroid Build Coastguard Worker /// If the instruction is an increment of a constant value, return the amount.
getIncrementValue(const MachineInstr * MI,int & Value) const1668*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::getIncrementValue(const MachineInstr *MI,
1669*9880d681SAndroid Build Coastguard Worker       int &Value) const {
1670*9880d681SAndroid Build Coastguard Worker   if (isPostIncrement(MI)) {
1671*9880d681SAndroid Build Coastguard Worker     unsigned AccessSize;
1672*9880d681SAndroid Build Coastguard Worker     return getBaseAndOffset(MI, Value, AccessSize);
1673*9880d681SAndroid Build Coastguard Worker   }
1674*9880d681SAndroid Build Coastguard Worker   if (MI->getOpcode() == Hexagon::A2_addi) {
1675*9880d681SAndroid Build Coastguard Worker     Value = MI->getOperand(2).getImm();
1676*9880d681SAndroid Build Coastguard Worker     return true;
1677*9880d681SAndroid Build Coastguard Worker   }
1678*9880d681SAndroid Build Coastguard Worker 
1679*9880d681SAndroid Build Coastguard Worker   return false;
1680*9880d681SAndroid Build Coastguard Worker }
1681*9880d681SAndroid Build Coastguard Worker 
1682*9880d681SAndroid Build Coastguard Worker 
createVR(MachineFunction * MF,MVT VT) const1683*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::createVR(MachineFunction* MF, MVT VT) const {
1684*9880d681SAndroid Build Coastguard Worker   MachineRegisterInfo &MRI = MF->getRegInfo();
1685*9880d681SAndroid Build Coastguard Worker   const TargetRegisterClass *TRC;
1686*9880d681SAndroid Build Coastguard Worker   if (VT == MVT::i1) {
1687*9880d681SAndroid Build Coastguard Worker     TRC = &Hexagon::PredRegsRegClass;
1688*9880d681SAndroid Build Coastguard Worker   } else if (VT == MVT::i32 || VT == MVT::f32) {
1689*9880d681SAndroid Build Coastguard Worker     TRC = &Hexagon::IntRegsRegClass;
1690*9880d681SAndroid Build Coastguard Worker   } else if (VT == MVT::i64 || VT == MVT::f64) {
1691*9880d681SAndroid Build Coastguard Worker     TRC = &Hexagon::DoubleRegsRegClass;
1692*9880d681SAndroid Build Coastguard Worker   } else {
1693*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Cannot handle this register class");
1694*9880d681SAndroid Build Coastguard Worker   }
1695*9880d681SAndroid Build Coastguard Worker 
1696*9880d681SAndroid Build Coastguard Worker   unsigned NewReg = MRI.createVirtualRegister(TRC);
1697*9880d681SAndroid Build Coastguard Worker   return NewReg;
1698*9880d681SAndroid Build Coastguard Worker }
1699*9880d681SAndroid Build Coastguard Worker 
1700*9880d681SAndroid Build Coastguard Worker 
isAbsoluteSet(const MachineInstr * MI) const1701*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isAbsoluteSet(const MachineInstr* MI) const {
1702*9880d681SAndroid Build Coastguard Worker   return (getAddrMode(MI) == HexagonII::AbsoluteSet);
1703*9880d681SAndroid Build Coastguard Worker }
1704*9880d681SAndroid Build Coastguard Worker 
1705*9880d681SAndroid Build Coastguard Worker 
isAccumulator(const MachineInstr * MI) const1706*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isAccumulator(const MachineInstr *MI) const {
1707*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI->getDesc().TSFlags;
1708*9880d681SAndroid Build Coastguard Worker   return((F >> HexagonII::AccumulatorPos) & HexagonII::AccumulatorMask);
1709*9880d681SAndroid Build Coastguard Worker }
1710*9880d681SAndroid Build Coastguard Worker 
1711*9880d681SAndroid Build Coastguard Worker 
isComplex(const MachineInstr * MI) const1712*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isComplex(const MachineInstr *MI) const {
1713*9880d681SAndroid Build Coastguard Worker   const MachineFunction *MF = MI->getParent()->getParent();
1714*9880d681SAndroid Build Coastguard Worker   const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
1715*9880d681SAndroid Build Coastguard Worker   const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
1716*9880d681SAndroid Build Coastguard Worker 
1717*9880d681SAndroid Build Coastguard Worker   if (!(isTC1(MI))
1718*9880d681SAndroid Build Coastguard Worker       && !(QII->isTC2Early(MI))
1719*9880d681SAndroid Build Coastguard Worker       && !(MI->getDesc().mayLoad())
1720*9880d681SAndroid Build Coastguard Worker       && !(MI->getDesc().mayStore())
1721*9880d681SAndroid Build Coastguard Worker       && (MI->getDesc().getOpcode() != Hexagon::S2_allocframe)
1722*9880d681SAndroid Build Coastguard Worker       && (MI->getDesc().getOpcode() != Hexagon::L2_deallocframe)
1723*9880d681SAndroid Build Coastguard Worker       && !(QII->isMemOp(MI))
1724*9880d681SAndroid Build Coastguard Worker       && !(MI->isBranch())
1725*9880d681SAndroid Build Coastguard Worker       && !(MI->isReturn())
1726*9880d681SAndroid Build Coastguard Worker       && !MI->isCall())
1727*9880d681SAndroid Build Coastguard Worker     return true;
1728*9880d681SAndroid Build Coastguard Worker 
1729*9880d681SAndroid Build Coastguard Worker   return false;
1730*9880d681SAndroid Build Coastguard Worker }
1731*9880d681SAndroid Build Coastguard Worker 
1732*9880d681SAndroid Build Coastguard Worker 
1733*9880d681SAndroid Build Coastguard Worker // Return true if the instruction is a compund branch instruction.
isCompoundBranchInstr(const MachineInstr * MI) const1734*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isCompoundBranchInstr(const MachineInstr *MI) const {
1735*9880d681SAndroid Build Coastguard Worker   return (getType(MI) == HexagonII::TypeCOMPOUND && MI->isBranch());
1736*9880d681SAndroid Build Coastguard Worker }
1737*9880d681SAndroid Build Coastguard Worker 
1738*9880d681SAndroid Build Coastguard Worker 
isCondInst(const MachineInstr * MI) const1739*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isCondInst(const MachineInstr *MI) const {
1740*9880d681SAndroid Build Coastguard Worker   return (MI->isBranch() && isPredicated(*MI)) ||
1741*9880d681SAndroid Build Coastguard Worker          isConditionalTransfer(MI) ||
1742*9880d681SAndroid Build Coastguard Worker          isConditionalALU32(MI)    ||
1743*9880d681SAndroid Build Coastguard Worker          isConditionalLoad(MI)     ||
1744*9880d681SAndroid Build Coastguard Worker          // Predicated stores which don't have a .new on any operands.
1745*9880d681SAndroid Build Coastguard Worker          (MI->mayStore() && isPredicated(*MI) && !isNewValueStore(MI) &&
1746*9880d681SAndroid Build Coastguard Worker           !isPredicatedNew(*MI));
1747*9880d681SAndroid Build Coastguard Worker }
1748*9880d681SAndroid Build Coastguard Worker 
1749*9880d681SAndroid Build Coastguard Worker 
isConditionalALU32(const MachineInstr * MI) const1750*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isConditionalALU32(const MachineInstr* MI) const {
1751*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
1752*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_paddf:
1753*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_paddfnew:
1754*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_paddif:
1755*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_paddifnew:
1756*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_paddit:
1757*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_padditnew:
1758*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_paddt:
1759*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_paddtnew:
1760*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_pandf:
1761*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_pandfnew:
1762*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_pandt:
1763*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_pandtnew:
1764*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_porf:
1765*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_porfnew:
1766*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_port:
1767*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_portnew:
1768*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_psubf:
1769*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_psubfnew:
1770*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_psubt:
1771*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_psubtnew:
1772*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_pxorf:
1773*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_pxorfnew:
1774*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_pxort:
1775*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_pxortnew:
1776*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_paslhf:
1777*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_paslhfnew:
1778*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_paslht:
1779*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_paslhtnew:
1780*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_pasrhf:
1781*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_pasrhfnew:
1782*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_pasrht:
1783*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_pasrhtnew:
1784*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_psxtbf:
1785*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_psxtbfnew:
1786*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_psxtbt:
1787*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_psxtbtnew:
1788*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_psxthf:
1789*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_psxthfnew:
1790*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_psxtht:
1791*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_psxthtnew:
1792*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_pzxtbf:
1793*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_pzxtbfnew:
1794*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_pzxtbt:
1795*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_pzxtbtnew:
1796*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_pzxthf:
1797*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_pzxthfnew:
1798*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_pzxtht:
1799*9880d681SAndroid Build Coastguard Worker     case Hexagon::A4_pzxthtnew:
1800*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_ccombinewf:
1801*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_ccombinewt:
1802*9880d681SAndroid Build Coastguard Worker       return true;
1803*9880d681SAndroid Build Coastguard Worker   }
1804*9880d681SAndroid Build Coastguard Worker   return false;
1805*9880d681SAndroid Build Coastguard Worker }
1806*9880d681SAndroid Build Coastguard Worker 
1807*9880d681SAndroid Build Coastguard Worker 
1808*9880d681SAndroid Build Coastguard Worker // FIXME - Function name and it's functionality don't match.
1809*9880d681SAndroid Build Coastguard Worker // It should be renamed to hasPredNewOpcode()
isConditionalLoad(const MachineInstr * MI) const1810*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isConditionalLoad(const MachineInstr* MI) const {
1811*9880d681SAndroid Build Coastguard Worker   if (!MI->getDesc().mayLoad() || !isPredicated(*MI))
1812*9880d681SAndroid Build Coastguard Worker     return false;
1813*9880d681SAndroid Build Coastguard Worker 
1814*9880d681SAndroid Build Coastguard Worker   int PNewOpcode = Hexagon::getPredNewOpcode(MI->getOpcode());
1815*9880d681SAndroid Build Coastguard Worker   // Instruction with valid predicated-new opcode can be promoted to .new.
1816*9880d681SAndroid Build Coastguard Worker   return PNewOpcode >= 0;
1817*9880d681SAndroid Build Coastguard Worker }
1818*9880d681SAndroid Build Coastguard Worker 
1819*9880d681SAndroid Build Coastguard Worker 
1820*9880d681SAndroid Build Coastguard Worker // Returns true if an instruction is a conditional store.
1821*9880d681SAndroid Build Coastguard Worker //
1822*9880d681SAndroid Build Coastguard Worker // Note: It doesn't include conditional new-value stores as they can't be
1823*9880d681SAndroid Build Coastguard Worker // converted to .new predicate.
isConditionalStore(const MachineInstr * MI) const1824*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isConditionalStore(const MachineInstr* MI) const {
1825*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
1826*9880d681SAndroid Build Coastguard Worker     default: return false;
1827*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_storeirbt_io:
1828*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_storeirbf_io:
1829*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_pstorerbt_rr:
1830*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_pstorerbf_rr:
1831*9880d681SAndroid Build Coastguard Worker     case Hexagon::S2_pstorerbt_io:
1832*9880d681SAndroid Build Coastguard Worker     case Hexagon::S2_pstorerbf_io:
1833*9880d681SAndroid Build Coastguard Worker     case Hexagon::S2_pstorerbt_pi:
1834*9880d681SAndroid Build Coastguard Worker     case Hexagon::S2_pstorerbf_pi:
1835*9880d681SAndroid Build Coastguard Worker     case Hexagon::S2_pstorerdt_io:
1836*9880d681SAndroid Build Coastguard Worker     case Hexagon::S2_pstorerdf_io:
1837*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_pstorerdt_rr:
1838*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_pstorerdf_rr:
1839*9880d681SAndroid Build Coastguard Worker     case Hexagon::S2_pstorerdt_pi:
1840*9880d681SAndroid Build Coastguard Worker     case Hexagon::S2_pstorerdf_pi:
1841*9880d681SAndroid Build Coastguard Worker     case Hexagon::S2_pstorerht_io:
1842*9880d681SAndroid Build Coastguard Worker     case Hexagon::S2_pstorerhf_io:
1843*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_storeirht_io:
1844*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_storeirhf_io:
1845*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_pstorerht_rr:
1846*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_pstorerhf_rr:
1847*9880d681SAndroid Build Coastguard Worker     case Hexagon::S2_pstorerht_pi:
1848*9880d681SAndroid Build Coastguard Worker     case Hexagon::S2_pstorerhf_pi:
1849*9880d681SAndroid Build Coastguard Worker     case Hexagon::S2_pstorerit_io:
1850*9880d681SAndroid Build Coastguard Worker     case Hexagon::S2_pstorerif_io:
1851*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_storeirit_io:
1852*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_storeirif_io:
1853*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_pstorerit_rr:
1854*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_pstorerif_rr:
1855*9880d681SAndroid Build Coastguard Worker     case Hexagon::S2_pstorerit_pi:
1856*9880d681SAndroid Build Coastguard Worker     case Hexagon::S2_pstorerif_pi:
1857*9880d681SAndroid Build Coastguard Worker 
1858*9880d681SAndroid Build Coastguard Worker     // V4 global address store before promoting to dot new.
1859*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_pstorerdt_abs:
1860*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_pstorerdf_abs:
1861*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_pstorerbt_abs:
1862*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_pstorerbf_abs:
1863*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_pstorerht_abs:
1864*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_pstorerhf_abs:
1865*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_pstorerit_abs:
1866*9880d681SAndroid Build Coastguard Worker     case Hexagon::S4_pstorerif_abs:
1867*9880d681SAndroid Build Coastguard Worker       return true;
1868*9880d681SAndroid Build Coastguard Worker 
1869*9880d681SAndroid Build Coastguard Worker     // Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded
1870*9880d681SAndroid Build Coastguard Worker     // from the "Conditional Store" list. Because a predicated new value store
1871*9880d681SAndroid Build Coastguard Worker     // would NOT be promoted to a double dot new store.
1872*9880d681SAndroid Build Coastguard Worker     // This function returns yes for those stores that are predicated but not
1873*9880d681SAndroid Build Coastguard Worker     // yet promoted to predicate dot new instructions.
1874*9880d681SAndroid Build Coastguard Worker   }
1875*9880d681SAndroid Build Coastguard Worker }
1876*9880d681SAndroid Build Coastguard Worker 
1877*9880d681SAndroid Build Coastguard Worker 
isConditionalTransfer(const MachineInstr * MI) const1878*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isConditionalTransfer(const MachineInstr *MI) const {
1879*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
1880*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_tfrt:
1881*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_tfrf:
1882*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmoveit:
1883*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmoveif:
1884*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_tfrtnew:
1885*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_tfrfnew:
1886*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmovenewit:
1887*9880d681SAndroid Build Coastguard Worker     case Hexagon::C2_cmovenewif:
1888*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_tfrpt:
1889*9880d681SAndroid Build Coastguard Worker     case Hexagon::A2_tfrpf:
1890*9880d681SAndroid Build Coastguard Worker       return true;
1891*9880d681SAndroid Build Coastguard Worker 
1892*9880d681SAndroid Build Coastguard Worker     default:
1893*9880d681SAndroid Build Coastguard Worker       return false;
1894*9880d681SAndroid Build Coastguard Worker   }
1895*9880d681SAndroid Build Coastguard Worker   return false;
1896*9880d681SAndroid Build Coastguard Worker }
1897*9880d681SAndroid Build Coastguard Worker 
1898*9880d681SAndroid Build Coastguard Worker 
1899*9880d681SAndroid Build Coastguard Worker // TODO: In order to have isExtendable for fpimm/f32Ext, we need to handle
1900*9880d681SAndroid Build Coastguard Worker // isFPImm and later getFPImm as well.
isConstExtended(const MachineInstr * MI) const1901*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isConstExtended(const MachineInstr *MI) const {
1902*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI->getDesc().TSFlags;
1903*9880d681SAndroid Build Coastguard Worker   unsigned isExtended = (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
1904*9880d681SAndroid Build Coastguard Worker   if (isExtended) // Instruction must be extended.
1905*9880d681SAndroid Build Coastguard Worker     return true;
1906*9880d681SAndroid Build Coastguard Worker 
1907*9880d681SAndroid Build Coastguard Worker   unsigned isExtendable =
1908*9880d681SAndroid Build Coastguard Worker     (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;
1909*9880d681SAndroid Build Coastguard Worker   if (!isExtendable)
1910*9880d681SAndroid Build Coastguard Worker     return false;
1911*9880d681SAndroid Build Coastguard Worker 
1912*9880d681SAndroid Build Coastguard Worker   if (MI->isCall())
1913*9880d681SAndroid Build Coastguard Worker     return false;
1914*9880d681SAndroid Build Coastguard Worker 
1915*9880d681SAndroid Build Coastguard Worker   short ExtOpNum = getCExtOpNum(MI);
1916*9880d681SAndroid Build Coastguard Worker   const MachineOperand &MO = MI->getOperand(ExtOpNum);
1917*9880d681SAndroid Build Coastguard Worker   // Use MO operand flags to determine if MO
1918*9880d681SAndroid Build Coastguard Worker   // has the HMOTF_ConstExtended flag set.
1919*9880d681SAndroid Build Coastguard Worker   if (MO.getTargetFlags() && HexagonII::HMOTF_ConstExtended)
1920*9880d681SAndroid Build Coastguard Worker     return true;
1921*9880d681SAndroid Build Coastguard Worker   // If this is a Machine BB address we are talking about, and it is
1922*9880d681SAndroid Build Coastguard Worker   // not marked as extended, say so.
1923*9880d681SAndroid Build Coastguard Worker   if (MO.isMBB())
1924*9880d681SAndroid Build Coastguard Worker     return false;
1925*9880d681SAndroid Build Coastguard Worker 
1926*9880d681SAndroid Build Coastguard Worker   // We could be using an instruction with an extendable immediate and shoehorn
1927*9880d681SAndroid Build Coastguard Worker   // a global address into it. If it is a global address it will be constant
1928*9880d681SAndroid Build Coastguard Worker   // extended. We do this for COMBINE.
1929*9880d681SAndroid Build Coastguard Worker   // We currently only handle isGlobal() because it is the only kind of
1930*9880d681SAndroid Build Coastguard Worker   // object we are going to end up with here for now.
1931*9880d681SAndroid Build Coastguard Worker   // In the future we probably should add isSymbol(), etc.
1932*9880d681SAndroid Build Coastguard Worker   if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress() ||
1933*9880d681SAndroid Build Coastguard Worker       MO.isJTI() || MO.isCPI())
1934*9880d681SAndroid Build Coastguard Worker     return true;
1935*9880d681SAndroid Build Coastguard Worker 
1936*9880d681SAndroid Build Coastguard Worker   // If the extendable operand is not 'Immediate' type, the instruction should
1937*9880d681SAndroid Build Coastguard Worker   // have 'isExtended' flag set.
1938*9880d681SAndroid Build Coastguard Worker   assert(MO.isImm() && "Extendable operand must be Immediate type");
1939*9880d681SAndroid Build Coastguard Worker 
1940*9880d681SAndroid Build Coastguard Worker   int MinValue = getMinValue(MI);
1941*9880d681SAndroid Build Coastguard Worker   int MaxValue = getMaxValue(MI);
1942*9880d681SAndroid Build Coastguard Worker   int ImmValue = MO.getImm();
1943*9880d681SAndroid Build Coastguard Worker 
1944*9880d681SAndroid Build Coastguard Worker   return (ImmValue < MinValue || ImmValue > MaxValue);
1945*9880d681SAndroid Build Coastguard Worker }
1946*9880d681SAndroid Build Coastguard Worker 
1947*9880d681SAndroid Build Coastguard Worker 
isDeallocRet(const MachineInstr * MI) const1948*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isDeallocRet(const MachineInstr *MI) const {
1949*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
1950*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return :
1951*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_t :
1952*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_f :
1953*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_tnew_pnt :
1954*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_fnew_pnt :
1955*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_tnew_pt :
1956*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_fnew_pt :
1957*9880d681SAndroid Build Coastguard Worker    return true;
1958*9880d681SAndroid Build Coastguard Worker   }
1959*9880d681SAndroid Build Coastguard Worker   return false;
1960*9880d681SAndroid Build Coastguard Worker }
1961*9880d681SAndroid Build Coastguard Worker 
1962*9880d681SAndroid Build Coastguard Worker 
1963*9880d681SAndroid Build Coastguard Worker // Return true when ConsMI uses a register defined by ProdMI.
isDependent(const MachineInstr * ProdMI,const MachineInstr * ConsMI) const1964*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isDependent(const MachineInstr *ProdMI,
1965*9880d681SAndroid Build Coastguard Worker       const MachineInstr *ConsMI) const {
1966*9880d681SAndroid Build Coastguard Worker   const MCInstrDesc &ProdMCID = ProdMI->getDesc();
1967*9880d681SAndroid Build Coastguard Worker   if (!ProdMCID.getNumDefs())
1968*9880d681SAndroid Build Coastguard Worker     return false;
1969*9880d681SAndroid Build Coastguard Worker 
1970*9880d681SAndroid Build Coastguard Worker   auto &HRI = getRegisterInfo();
1971*9880d681SAndroid Build Coastguard Worker 
1972*9880d681SAndroid Build Coastguard Worker   SmallVector<unsigned, 4> DefsA;
1973*9880d681SAndroid Build Coastguard Worker   SmallVector<unsigned, 4> DefsB;
1974*9880d681SAndroid Build Coastguard Worker   SmallVector<unsigned, 8> UsesA;
1975*9880d681SAndroid Build Coastguard Worker   SmallVector<unsigned, 8> UsesB;
1976*9880d681SAndroid Build Coastguard Worker 
1977*9880d681SAndroid Build Coastguard Worker   parseOperands(ProdMI, DefsA, UsesA);
1978*9880d681SAndroid Build Coastguard Worker   parseOperands(ConsMI, DefsB, UsesB);
1979*9880d681SAndroid Build Coastguard Worker 
1980*9880d681SAndroid Build Coastguard Worker   for (auto &RegA : DefsA)
1981*9880d681SAndroid Build Coastguard Worker     for (auto &RegB : UsesB) {
1982*9880d681SAndroid Build Coastguard Worker       // True data dependency.
1983*9880d681SAndroid Build Coastguard Worker       if (RegA == RegB)
1984*9880d681SAndroid Build Coastguard Worker         return true;
1985*9880d681SAndroid Build Coastguard Worker 
1986*9880d681SAndroid Build Coastguard Worker       if (Hexagon::DoubleRegsRegClass.contains(RegA))
1987*9880d681SAndroid Build Coastguard Worker         for (MCSubRegIterator SubRegs(RegA, &HRI); SubRegs.isValid(); ++SubRegs)
1988*9880d681SAndroid Build Coastguard Worker           if (RegB == *SubRegs)
1989*9880d681SAndroid Build Coastguard Worker             return true;
1990*9880d681SAndroid Build Coastguard Worker 
1991*9880d681SAndroid Build Coastguard Worker       if (Hexagon::DoubleRegsRegClass.contains(RegB))
1992*9880d681SAndroid Build Coastguard Worker         for (MCSubRegIterator SubRegs(RegB, &HRI); SubRegs.isValid(); ++SubRegs)
1993*9880d681SAndroid Build Coastguard Worker           if (RegA == *SubRegs)
1994*9880d681SAndroid Build Coastguard Worker             return true;
1995*9880d681SAndroid Build Coastguard Worker     }
1996*9880d681SAndroid Build Coastguard Worker 
1997*9880d681SAndroid Build Coastguard Worker   return false;
1998*9880d681SAndroid Build Coastguard Worker }
1999*9880d681SAndroid Build Coastguard Worker 
2000*9880d681SAndroid Build Coastguard Worker 
2001*9880d681SAndroid Build Coastguard Worker // Returns true if the instruction is alread a .cur.
isDotCurInst(const MachineInstr * MI) const2002*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isDotCurInst(const MachineInstr* MI) const {
2003*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
2004*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vL32b_cur_pi:
2005*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vL32b_cur_ai:
2006*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vL32b_cur_pi_128B:
2007*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vL32b_cur_ai_128B:
2008*9880d681SAndroid Build Coastguard Worker     return true;
2009*9880d681SAndroid Build Coastguard Worker   }
2010*9880d681SAndroid Build Coastguard Worker   return false;
2011*9880d681SAndroid Build Coastguard Worker }
2012*9880d681SAndroid Build Coastguard Worker 
2013*9880d681SAndroid Build Coastguard Worker 
2014*9880d681SAndroid Build Coastguard Worker // Returns true, if any one of the operands is a dot new
2015*9880d681SAndroid Build Coastguard Worker // insn, whether it is predicated dot new or register dot new.
isDotNewInst(const MachineInstr * MI) const2016*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isDotNewInst(const MachineInstr* MI) const {
2017*9880d681SAndroid Build Coastguard Worker   if (isNewValueInst(MI) || (isPredicated(*MI) && isPredicatedNew(*MI)))
2018*9880d681SAndroid Build Coastguard Worker     return true;
2019*9880d681SAndroid Build Coastguard Worker 
2020*9880d681SAndroid Build Coastguard Worker   return false;
2021*9880d681SAndroid Build Coastguard Worker }
2022*9880d681SAndroid Build Coastguard Worker 
2023*9880d681SAndroid Build Coastguard Worker 
2024*9880d681SAndroid Build Coastguard Worker /// Symmetrical. See if these two instructions are fit for duplex pair.
isDuplexPair(const MachineInstr * MIa,const MachineInstr * MIb) const2025*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isDuplexPair(const MachineInstr *MIa,
2026*9880d681SAndroid Build Coastguard Worker       const MachineInstr *MIb) const {
2027*9880d681SAndroid Build Coastguard Worker   HexagonII::SubInstructionGroup MIaG = getDuplexCandidateGroup(MIa);
2028*9880d681SAndroid Build Coastguard Worker   HexagonII::SubInstructionGroup MIbG = getDuplexCandidateGroup(MIb);
2029*9880d681SAndroid Build Coastguard Worker   return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));
2030*9880d681SAndroid Build Coastguard Worker }
2031*9880d681SAndroid Build Coastguard Worker 
2032*9880d681SAndroid Build Coastguard Worker 
isEarlySourceInstr(const MachineInstr * MI) const2033*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isEarlySourceInstr(const MachineInstr *MI) const {
2034*9880d681SAndroid Build Coastguard Worker   if (!MI)
2035*9880d681SAndroid Build Coastguard Worker     return false;
2036*9880d681SAndroid Build Coastguard Worker 
2037*9880d681SAndroid Build Coastguard Worker   if (MI->mayLoad() || MI->mayStore() || MI->isCompare())
2038*9880d681SAndroid Build Coastguard Worker     return true;
2039*9880d681SAndroid Build Coastguard Worker 
2040*9880d681SAndroid Build Coastguard Worker   // Multiply
2041*9880d681SAndroid Build Coastguard Worker   unsigned SchedClass = MI->getDesc().getSchedClass();
2042*9880d681SAndroid Build Coastguard Worker   if (SchedClass == Hexagon::Sched::M_tc_3or4x_SLOT23)
2043*9880d681SAndroid Build Coastguard Worker     return true;
2044*9880d681SAndroid Build Coastguard Worker   return false;
2045*9880d681SAndroid Build Coastguard Worker }
2046*9880d681SAndroid Build Coastguard Worker 
2047*9880d681SAndroid Build Coastguard Worker 
isEndLoopN(unsigned Opcode) const2048*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isEndLoopN(unsigned Opcode) const {
2049*9880d681SAndroid Build Coastguard Worker   return (Opcode == Hexagon::ENDLOOP0 ||
2050*9880d681SAndroid Build Coastguard Worker           Opcode == Hexagon::ENDLOOP1);
2051*9880d681SAndroid Build Coastguard Worker }
2052*9880d681SAndroid Build Coastguard Worker 
2053*9880d681SAndroid Build Coastguard Worker 
isExpr(unsigned OpType) const2054*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isExpr(unsigned OpType) const {
2055*9880d681SAndroid Build Coastguard Worker   switch(OpType) {
2056*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_MachineBasicBlock:
2057*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_GlobalAddress:
2058*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_ExternalSymbol:
2059*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_JumpTableIndex:
2060*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_ConstantPoolIndex:
2061*9880d681SAndroid Build Coastguard Worker   case MachineOperand::MO_BlockAddress:
2062*9880d681SAndroid Build Coastguard Worker     return true;
2063*9880d681SAndroid Build Coastguard Worker   default:
2064*9880d681SAndroid Build Coastguard Worker     return false;
2065*9880d681SAndroid Build Coastguard Worker   }
2066*9880d681SAndroid Build Coastguard Worker }
2067*9880d681SAndroid Build Coastguard Worker 
2068*9880d681SAndroid Build Coastguard Worker 
isExtendable(const MachineInstr * MI) const2069*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isExtendable(const MachineInstr *MI) const {
2070*9880d681SAndroid Build Coastguard Worker   const MCInstrDesc &MID = MI->getDesc();
2071*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MID.TSFlags;
2072*9880d681SAndroid Build Coastguard Worker   if ((F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask)
2073*9880d681SAndroid Build Coastguard Worker     return true;
2074*9880d681SAndroid Build Coastguard Worker 
2075*9880d681SAndroid Build Coastguard Worker   // TODO: This is largely obsolete now. Will need to be removed
2076*9880d681SAndroid Build Coastguard Worker   // in consecutive patches.
2077*9880d681SAndroid Build Coastguard Worker   switch(MI->getOpcode()) {
2078*9880d681SAndroid Build Coastguard Worker     // TFR_FI Remains a special case.
2079*9880d681SAndroid Build Coastguard Worker     case Hexagon::TFR_FI:
2080*9880d681SAndroid Build Coastguard Worker       return true;
2081*9880d681SAndroid Build Coastguard Worker     default:
2082*9880d681SAndroid Build Coastguard Worker       return false;
2083*9880d681SAndroid Build Coastguard Worker   }
2084*9880d681SAndroid Build Coastguard Worker   return  false;
2085*9880d681SAndroid Build Coastguard Worker }
2086*9880d681SAndroid Build Coastguard Worker 
2087*9880d681SAndroid Build Coastguard Worker 
2088*9880d681SAndroid Build Coastguard Worker // This returns true in two cases:
2089*9880d681SAndroid Build Coastguard Worker // - The OP code itself indicates that this is an extended instruction.
2090*9880d681SAndroid Build Coastguard Worker // - One of MOs has been marked with HMOTF_ConstExtended flag.
isExtended(const MachineInstr * MI) const2091*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isExtended(const MachineInstr *MI) const {
2092*9880d681SAndroid Build Coastguard Worker   // First check if this is permanently extended op code.
2093*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI->getDesc().TSFlags;
2094*9880d681SAndroid Build Coastguard Worker   if ((F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask)
2095*9880d681SAndroid Build Coastguard Worker     return true;
2096*9880d681SAndroid Build Coastguard Worker   // Use MO operand flags to determine if one of MI's operands
2097*9880d681SAndroid Build Coastguard Worker   // has HMOTF_ConstExtended flag set.
2098*9880d681SAndroid Build Coastguard Worker   for (MachineInstr::const_mop_iterator I = MI->operands_begin(),
2099*9880d681SAndroid Build Coastguard Worker        E = MI->operands_end(); I != E; ++I) {
2100*9880d681SAndroid Build Coastguard Worker     if (I->getTargetFlags() && HexagonII::HMOTF_ConstExtended)
2101*9880d681SAndroid Build Coastguard Worker       return true;
2102*9880d681SAndroid Build Coastguard Worker   }
2103*9880d681SAndroid Build Coastguard Worker   return  false;
2104*9880d681SAndroid Build Coastguard Worker }
2105*9880d681SAndroid Build Coastguard Worker 
2106*9880d681SAndroid Build Coastguard Worker 
isFloat(const MachineInstr * MI) const2107*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isFloat(const MachineInstr *MI) const {
2108*9880d681SAndroid Build Coastguard Worker   unsigned Opcode = MI->getOpcode();
2109*9880d681SAndroid Build Coastguard Worker   const uint64_t F = get(Opcode).TSFlags;
2110*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::FPPos) & HexagonII::FPMask;
2111*9880d681SAndroid Build Coastguard Worker }
2112*9880d681SAndroid Build Coastguard Worker 
2113*9880d681SAndroid Build Coastguard Worker 
2114*9880d681SAndroid Build Coastguard Worker // No V60 HVX VMEM with A_INDIRECT.
isHVXMemWithAIndirect(const MachineInstr * I,const MachineInstr * J) const2115*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isHVXMemWithAIndirect(const MachineInstr *I,
2116*9880d681SAndroid Build Coastguard Worker       const MachineInstr *J) const {
2117*9880d681SAndroid Build Coastguard Worker   if (!isV60VectorInstruction(I))
2118*9880d681SAndroid Build Coastguard Worker     return false;
2119*9880d681SAndroid Build Coastguard Worker   if (!I->mayLoad() && !I->mayStore())
2120*9880d681SAndroid Build Coastguard Worker     return false;
2121*9880d681SAndroid Build Coastguard Worker   return J->isIndirectBranch() || isIndirectCall(J) || isIndirectL4Return(J);
2122*9880d681SAndroid Build Coastguard Worker }
2123*9880d681SAndroid Build Coastguard Worker 
2124*9880d681SAndroid Build Coastguard Worker 
isIndirectCall(const MachineInstr * MI) const2125*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isIndirectCall(const MachineInstr *MI) const {
2126*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
2127*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_callr :
2128*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_callrf :
2129*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_callrt :
2130*9880d681SAndroid Build Coastguard Worker     return true;
2131*9880d681SAndroid Build Coastguard Worker   }
2132*9880d681SAndroid Build Coastguard Worker   return false;
2133*9880d681SAndroid Build Coastguard Worker }
2134*9880d681SAndroid Build Coastguard Worker 
2135*9880d681SAndroid Build Coastguard Worker 
isIndirectL4Return(const MachineInstr * MI) const2136*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isIndirectL4Return(const MachineInstr *MI) const {
2137*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
2138*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return :
2139*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_t :
2140*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_f :
2141*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_fnew_pnt :
2142*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_fnew_pt :
2143*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_tnew_pnt :
2144*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_tnew_pt :
2145*9880d681SAndroid Build Coastguard Worker     return true;
2146*9880d681SAndroid Build Coastguard Worker   }
2147*9880d681SAndroid Build Coastguard Worker   return false;
2148*9880d681SAndroid Build Coastguard Worker }
2149*9880d681SAndroid Build Coastguard Worker 
2150*9880d681SAndroid Build Coastguard Worker 
isJumpR(const MachineInstr * MI) const2151*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isJumpR(const MachineInstr *MI) const {
2152*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
2153*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumpr :
2154*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumprt :
2155*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumprf :
2156*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumprtnewpt :
2157*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumprfnewpt  :
2158*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumprtnew :
2159*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumprfnew :
2160*9880d681SAndroid Build Coastguard Worker     return true;
2161*9880d681SAndroid Build Coastguard Worker   }
2162*9880d681SAndroid Build Coastguard Worker   return false;
2163*9880d681SAndroid Build Coastguard Worker }
2164*9880d681SAndroid Build Coastguard Worker 
2165*9880d681SAndroid Build Coastguard Worker 
2166*9880d681SAndroid Build Coastguard Worker // Return true if a given MI can accomodate given offset.
2167*9880d681SAndroid Build Coastguard Worker // Use abs estimate as oppose to the exact number.
2168*9880d681SAndroid Build Coastguard Worker // TODO: This will need to be changed to use MC level
2169*9880d681SAndroid Build Coastguard Worker // definition of instruction extendable field size.
isJumpWithinBranchRange(const MachineInstr * MI,unsigned offset) const2170*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isJumpWithinBranchRange(const MachineInstr *MI,
2171*9880d681SAndroid Build Coastguard Worker       unsigned offset) const {
2172*9880d681SAndroid Build Coastguard Worker   // This selection of jump instructions matches to that what
2173*9880d681SAndroid Build Coastguard Worker   // AnalyzeBranch can parse, plus NVJ.
2174*9880d681SAndroid Build Coastguard Worker   if (isNewValueJump(MI)) // r9:2
2175*9880d681SAndroid Build Coastguard Worker     return isInt<11>(offset);
2176*9880d681SAndroid Build Coastguard Worker 
2177*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
2178*9880d681SAndroid Build Coastguard Worker   // Still missing Jump to address condition on register value.
2179*9880d681SAndroid Build Coastguard Worker   default:
2180*9880d681SAndroid Build Coastguard Worker     return false;
2181*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jump: // bits<24> dst; // r22:2
2182*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_call:
2183*9880d681SAndroid Build Coastguard Worker   case Hexagon::CALLv3nr:
2184*9880d681SAndroid Build Coastguard Worker     return isInt<24>(offset);
2185*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumpt: //bits<17> dst; // r15:2
2186*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumpf:
2187*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumptnew:
2188*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumptnewpt:
2189*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumpfnew:
2190*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumpfnewpt:
2191*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_callt:
2192*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_callf:
2193*9880d681SAndroid Build Coastguard Worker     return isInt<17>(offset);
2194*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_loop0i:
2195*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_loop0iext:
2196*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_loop0r:
2197*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_loop0rext:
2198*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_loop1i:
2199*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_loop1iext:
2200*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_loop1r:
2201*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_loop1rext:
2202*9880d681SAndroid Build Coastguard Worker     return isInt<9>(offset);
2203*9880d681SAndroid Build Coastguard Worker   // TODO: Add all the compound branches here. Can we do this in Relation model?
2204*9880d681SAndroid Build Coastguard Worker   case Hexagon::J4_cmpeqi_tp0_jump_nt:
2205*9880d681SAndroid Build Coastguard Worker   case Hexagon::J4_cmpeqi_tp1_jump_nt:
2206*9880d681SAndroid Build Coastguard Worker     return isInt<11>(offset);
2207*9880d681SAndroid Build Coastguard Worker   }
2208*9880d681SAndroid Build Coastguard Worker }
2209*9880d681SAndroid Build Coastguard Worker 
2210*9880d681SAndroid Build Coastguard Worker 
isLateInstrFeedsEarlyInstr(const MachineInstr * LRMI,const MachineInstr * ESMI) const2211*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isLateInstrFeedsEarlyInstr(const MachineInstr *LRMI,
2212*9880d681SAndroid Build Coastguard Worker       const MachineInstr *ESMI) const {
2213*9880d681SAndroid Build Coastguard Worker   if (!LRMI || !ESMI)
2214*9880d681SAndroid Build Coastguard Worker     return false;
2215*9880d681SAndroid Build Coastguard Worker 
2216*9880d681SAndroid Build Coastguard Worker   bool isLate = isLateResultInstr(LRMI);
2217*9880d681SAndroid Build Coastguard Worker   bool isEarly = isEarlySourceInstr(ESMI);
2218*9880d681SAndroid Build Coastguard Worker 
2219*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "V60" <<  (isLate ? "-LR  " : " --  "));
2220*9880d681SAndroid Build Coastguard Worker   DEBUG(LRMI->dump());
2221*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "V60" <<  (isEarly ? "-ES  " : " --  "));
2222*9880d681SAndroid Build Coastguard Worker   DEBUG(ESMI->dump());
2223*9880d681SAndroid Build Coastguard Worker 
2224*9880d681SAndroid Build Coastguard Worker   if (isLate && isEarly) {
2225*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "++Is Late Result feeding Early Source\n");
2226*9880d681SAndroid Build Coastguard Worker     return true;
2227*9880d681SAndroid Build Coastguard Worker   }
2228*9880d681SAndroid Build Coastguard Worker 
2229*9880d681SAndroid Build Coastguard Worker   return false;
2230*9880d681SAndroid Build Coastguard Worker }
2231*9880d681SAndroid Build Coastguard Worker 
2232*9880d681SAndroid Build Coastguard Worker 
isLateResultInstr(const MachineInstr * MI) const2233*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isLateResultInstr(const MachineInstr *MI) const {
2234*9880d681SAndroid Build Coastguard Worker   if (!MI)
2235*9880d681SAndroid Build Coastguard Worker     return false;
2236*9880d681SAndroid Build Coastguard Worker 
2237*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
2238*9880d681SAndroid Build Coastguard Worker   case TargetOpcode::EXTRACT_SUBREG:
2239*9880d681SAndroid Build Coastguard Worker   case TargetOpcode::INSERT_SUBREG:
2240*9880d681SAndroid Build Coastguard Worker   case TargetOpcode::SUBREG_TO_REG:
2241*9880d681SAndroid Build Coastguard Worker   case TargetOpcode::REG_SEQUENCE:
2242*9880d681SAndroid Build Coastguard Worker   case TargetOpcode::IMPLICIT_DEF:
2243*9880d681SAndroid Build Coastguard Worker   case TargetOpcode::COPY:
2244*9880d681SAndroid Build Coastguard Worker   case TargetOpcode::INLINEASM:
2245*9880d681SAndroid Build Coastguard Worker   case TargetOpcode::PHI:
2246*9880d681SAndroid Build Coastguard Worker     return false;
2247*9880d681SAndroid Build Coastguard Worker   default:
2248*9880d681SAndroid Build Coastguard Worker     break;
2249*9880d681SAndroid Build Coastguard Worker   }
2250*9880d681SAndroid Build Coastguard Worker 
2251*9880d681SAndroid Build Coastguard Worker   unsigned SchedClass = MI->getDesc().getSchedClass();
2252*9880d681SAndroid Build Coastguard Worker 
2253*9880d681SAndroid Build Coastguard Worker   switch (SchedClass) {
2254*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::ALU32_2op_tc_1_SLOT0123:
2255*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::ALU32_3op_tc_1_SLOT0123:
2256*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::ALU32_ADDI_tc_1_SLOT0123:
2257*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::ALU64_tc_1_SLOT23:
2258*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::EXTENDER_tc_1_SLOT0123:
2259*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::S_2op_tc_1_SLOT23:
2260*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::S_3op_tc_1_SLOT23:
2261*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::V2LDST_tc_ld_SLOT01:
2262*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::V2LDST_tc_st_SLOT0:
2263*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::V2LDST_tc_st_SLOT01:
2264*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::V4LDST_tc_ld_SLOT01:
2265*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::V4LDST_tc_st_SLOT0:
2266*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::V4LDST_tc_st_SLOT01:
2267*9880d681SAndroid Build Coastguard Worker     return false;
2268*9880d681SAndroid Build Coastguard Worker   }
2269*9880d681SAndroid Build Coastguard Worker   return true;
2270*9880d681SAndroid Build Coastguard Worker }
2271*9880d681SAndroid Build Coastguard Worker 
2272*9880d681SAndroid Build Coastguard Worker 
isLateSourceInstr(const MachineInstr * MI) const2273*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isLateSourceInstr(const MachineInstr *MI) const {
2274*9880d681SAndroid Build Coastguard Worker   if (!MI)
2275*9880d681SAndroid Build Coastguard Worker     return false;
2276*9880d681SAndroid Build Coastguard Worker 
2277*9880d681SAndroid Build Coastguard Worker   // Instructions with iclass A_CVI_VX and attribute A_CVI_LATE uses a multiply
2278*9880d681SAndroid Build Coastguard Worker   // resource, but all operands can be received late like an ALU instruction.
2279*9880d681SAndroid Build Coastguard Worker   return MI->getDesc().getSchedClass() == Hexagon::Sched::CVI_VX_LATE;
2280*9880d681SAndroid Build Coastguard Worker }
2281*9880d681SAndroid Build Coastguard Worker 
2282*9880d681SAndroid Build Coastguard Worker 
isLoopN(const MachineInstr * MI) const2283*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isLoopN(const MachineInstr *MI) const {
2284*9880d681SAndroid Build Coastguard Worker   unsigned Opcode = MI->getOpcode();
2285*9880d681SAndroid Build Coastguard Worker   return Opcode == Hexagon::J2_loop0i    ||
2286*9880d681SAndroid Build Coastguard Worker          Opcode == Hexagon::J2_loop0r    ||
2287*9880d681SAndroid Build Coastguard Worker          Opcode == Hexagon::J2_loop0iext ||
2288*9880d681SAndroid Build Coastguard Worker          Opcode == Hexagon::J2_loop0rext ||
2289*9880d681SAndroid Build Coastguard Worker          Opcode == Hexagon::J2_loop1i    ||
2290*9880d681SAndroid Build Coastguard Worker          Opcode == Hexagon::J2_loop1r    ||
2291*9880d681SAndroid Build Coastguard Worker          Opcode == Hexagon::J2_loop1iext ||
2292*9880d681SAndroid Build Coastguard Worker          Opcode == Hexagon::J2_loop1rext;
2293*9880d681SAndroid Build Coastguard Worker }
2294*9880d681SAndroid Build Coastguard Worker 
2295*9880d681SAndroid Build Coastguard Worker 
isMemOp(const MachineInstr * MI) const2296*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isMemOp(const MachineInstr *MI) const {
2297*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
2298*9880d681SAndroid Build Coastguard Worker     default: return false;
2299*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_iadd_memopw_io :
2300*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_isub_memopw_io :
2301*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_add_memopw_io :
2302*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_sub_memopw_io :
2303*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_and_memopw_io :
2304*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_or_memopw_io :
2305*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_iadd_memoph_io :
2306*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_isub_memoph_io :
2307*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_add_memoph_io :
2308*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_sub_memoph_io :
2309*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_and_memoph_io :
2310*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_or_memoph_io :
2311*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_iadd_memopb_io :
2312*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_isub_memopb_io :
2313*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_add_memopb_io :
2314*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_sub_memopb_io :
2315*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_and_memopb_io :
2316*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_or_memopb_io :
2317*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_ior_memopb_io:
2318*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_ior_memoph_io:
2319*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_ior_memopw_io:
2320*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_iand_memopb_io:
2321*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_iand_memoph_io:
2322*9880d681SAndroid Build Coastguard Worker     case Hexagon::L4_iand_memopw_io:
2323*9880d681SAndroid Build Coastguard Worker     return true;
2324*9880d681SAndroid Build Coastguard Worker   }
2325*9880d681SAndroid Build Coastguard Worker   return false;
2326*9880d681SAndroid Build Coastguard Worker }
2327*9880d681SAndroid Build Coastguard Worker 
2328*9880d681SAndroid Build Coastguard Worker 
isNewValue(const MachineInstr * MI) const2329*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isNewValue(const MachineInstr* MI) const {
2330*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI->getDesc().TSFlags;
2331*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::NewValuePos) & HexagonII::NewValueMask;
2332*9880d681SAndroid Build Coastguard Worker }
2333*9880d681SAndroid Build Coastguard Worker 
2334*9880d681SAndroid Build Coastguard Worker 
isNewValue(unsigned Opcode) const2335*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isNewValue(unsigned Opcode) const {
2336*9880d681SAndroid Build Coastguard Worker   const uint64_t F = get(Opcode).TSFlags;
2337*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::NewValuePos) & HexagonII::NewValueMask;
2338*9880d681SAndroid Build Coastguard Worker }
2339*9880d681SAndroid Build Coastguard Worker 
2340*9880d681SAndroid Build Coastguard Worker 
isNewValueInst(const MachineInstr * MI) const2341*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isNewValueInst(const MachineInstr *MI) const {
2342*9880d681SAndroid Build Coastguard Worker   return isNewValueJump(MI) || isNewValueStore(MI);
2343*9880d681SAndroid Build Coastguard Worker }
2344*9880d681SAndroid Build Coastguard Worker 
2345*9880d681SAndroid Build Coastguard Worker 
isNewValueJump(const MachineInstr * MI) const2346*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isNewValueJump(const MachineInstr *MI) const {
2347*9880d681SAndroid Build Coastguard Worker   return isNewValue(MI) && MI->isBranch();
2348*9880d681SAndroid Build Coastguard Worker }
2349*9880d681SAndroid Build Coastguard Worker 
2350*9880d681SAndroid Build Coastguard Worker 
isNewValueJump(unsigned Opcode) const2351*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isNewValueJump(unsigned Opcode) const {
2352*9880d681SAndroid Build Coastguard Worker   return isNewValue(Opcode) && get(Opcode).isBranch() && isPredicated(Opcode);
2353*9880d681SAndroid Build Coastguard Worker }
2354*9880d681SAndroid Build Coastguard Worker 
2355*9880d681SAndroid Build Coastguard Worker 
isNewValueStore(const MachineInstr * MI) const2356*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const {
2357*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI->getDesc().TSFlags;
2358*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask;
2359*9880d681SAndroid Build Coastguard Worker }
2360*9880d681SAndroid Build Coastguard Worker 
2361*9880d681SAndroid Build Coastguard Worker 
isNewValueStore(unsigned Opcode) const2362*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isNewValueStore(unsigned Opcode) const {
2363*9880d681SAndroid Build Coastguard Worker   const uint64_t F = get(Opcode).TSFlags;
2364*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask;
2365*9880d681SAndroid Build Coastguard Worker }
2366*9880d681SAndroid Build Coastguard Worker 
2367*9880d681SAndroid Build Coastguard Worker 
2368*9880d681SAndroid Build Coastguard Worker // Returns true if a particular operand is extendable for an instruction.
isOperandExtended(const MachineInstr * MI,unsigned OperandNum) const2369*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isOperandExtended(const MachineInstr *MI,
2370*9880d681SAndroid Build Coastguard Worker     unsigned OperandNum) const {
2371*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI->getDesc().TSFlags;
2372*9880d681SAndroid Build Coastguard Worker   return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask)
2373*9880d681SAndroid Build Coastguard Worker           == OperandNum;
2374*9880d681SAndroid Build Coastguard Worker }
2375*9880d681SAndroid Build Coastguard Worker 
2376*9880d681SAndroid Build Coastguard Worker 
isPostIncrement(const MachineInstr * MI) const2377*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isPostIncrement(const MachineInstr* MI) const {
2378*9880d681SAndroid Build Coastguard Worker   return getAddrMode(MI) == HexagonII::PostInc;
2379*9880d681SAndroid Build Coastguard Worker }
2380*9880d681SAndroid Build Coastguard Worker 
2381*9880d681SAndroid Build Coastguard Worker 
isPredicatedNew(const MachineInstr & MI) const2382*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isPredicatedNew(const MachineInstr &MI) const {
2383*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI.getDesc().TSFlags;
2384*9880d681SAndroid Build Coastguard Worker   assert(isPredicated(MI));
2385*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask;
2386*9880d681SAndroid Build Coastguard Worker }
2387*9880d681SAndroid Build Coastguard Worker 
2388*9880d681SAndroid Build Coastguard Worker 
isPredicatedNew(unsigned Opcode) const2389*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isPredicatedNew(unsigned Opcode) const {
2390*9880d681SAndroid Build Coastguard Worker   const uint64_t F = get(Opcode).TSFlags;
2391*9880d681SAndroid Build Coastguard Worker   assert(isPredicated(Opcode));
2392*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask;
2393*9880d681SAndroid Build Coastguard Worker }
2394*9880d681SAndroid Build Coastguard Worker 
2395*9880d681SAndroid Build Coastguard Worker 
isPredicatedTrue(const MachineInstr & MI) const2396*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isPredicatedTrue(const MachineInstr &MI) const {
2397*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI.getDesc().TSFlags;
2398*9880d681SAndroid Build Coastguard Worker   return !((F >> HexagonII::PredicatedFalsePos) &
2399*9880d681SAndroid Build Coastguard Worker            HexagonII::PredicatedFalseMask);
2400*9880d681SAndroid Build Coastguard Worker }
2401*9880d681SAndroid Build Coastguard Worker 
2402*9880d681SAndroid Build Coastguard Worker 
isPredicatedTrue(unsigned Opcode) const2403*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isPredicatedTrue(unsigned Opcode) const {
2404*9880d681SAndroid Build Coastguard Worker   const uint64_t F = get(Opcode).TSFlags;
2405*9880d681SAndroid Build Coastguard Worker   // Make sure that the instruction is predicated.
2406*9880d681SAndroid Build Coastguard Worker   assert((F>> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);
2407*9880d681SAndroid Build Coastguard Worker   return !((F >> HexagonII::PredicatedFalsePos) &
2408*9880d681SAndroid Build Coastguard Worker            HexagonII::PredicatedFalseMask);
2409*9880d681SAndroid Build Coastguard Worker }
2410*9880d681SAndroid Build Coastguard Worker 
2411*9880d681SAndroid Build Coastguard Worker 
isPredicated(unsigned Opcode) const2412*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isPredicated(unsigned Opcode) const {
2413*9880d681SAndroid Build Coastguard Worker   const uint64_t F = get(Opcode).TSFlags;
2414*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask;
2415*9880d681SAndroid Build Coastguard Worker }
2416*9880d681SAndroid Build Coastguard Worker 
2417*9880d681SAndroid Build Coastguard Worker 
isPredicateLate(unsigned Opcode) const2418*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isPredicateLate(unsigned Opcode) const {
2419*9880d681SAndroid Build Coastguard Worker   const uint64_t F = get(Opcode).TSFlags;
2420*9880d681SAndroid Build Coastguard Worker   return ~(F >> HexagonII::PredicateLatePos) & HexagonII::PredicateLateMask;
2421*9880d681SAndroid Build Coastguard Worker }
2422*9880d681SAndroid Build Coastguard Worker 
2423*9880d681SAndroid Build Coastguard Worker 
isPredictedTaken(unsigned Opcode) const2424*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isPredictedTaken(unsigned Opcode) const {
2425*9880d681SAndroid Build Coastguard Worker   const uint64_t F = get(Opcode).TSFlags;
2426*9880d681SAndroid Build Coastguard Worker   assert(get(Opcode).isBranch() &&
2427*9880d681SAndroid Build Coastguard Worker          (isPredicatedNew(Opcode) || isNewValue(Opcode)));
2428*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::TakenPos) & HexagonII::TakenMask;
2429*9880d681SAndroid Build Coastguard Worker }
2430*9880d681SAndroid Build Coastguard Worker 
2431*9880d681SAndroid Build Coastguard Worker 
isSaveCalleeSavedRegsCall(const MachineInstr * MI) const2432*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isSaveCalleeSavedRegsCall(const MachineInstr *MI) const {
2433*9880d681SAndroid Build Coastguard Worker   return MI->getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4 ||
2434*9880d681SAndroid Build Coastguard Worker          MI->getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT ||
2435*9880d681SAndroid Build Coastguard Worker          MI->getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_PIC ||
2436*9880d681SAndroid Build Coastguard Worker          MI->getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC;
2437*9880d681SAndroid Build Coastguard Worker }
2438*9880d681SAndroid Build Coastguard Worker 
isSignExtendingLoad(const MachineInstr & MI) const2439*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isSignExtendingLoad(const MachineInstr &MI) const {
2440*9880d681SAndroid Build Coastguard Worker   switch (MI.getOpcode()) {
2441*9880d681SAndroid Build Coastguard Worker   // Byte
2442*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrb_io:
2443*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadrb_ur:
2444*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadrb_ap:
2445*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrb_pr:
2446*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrb_pbr:
2447*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrb_pi:
2448*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrb_pci:
2449*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrb_pcr:
2450*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbsw2_io:
2451*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadbsw2_ur:
2452*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadbsw2_ap:
2453*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbsw2_pr:
2454*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbsw2_pbr:
2455*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbsw2_pi:
2456*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbsw2_pci:
2457*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbsw2_pcr:
2458*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbsw4_io:
2459*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadbsw4_ur:
2460*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadbsw4_ap:
2461*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbsw4_pr:
2462*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbsw4_pbr:
2463*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbsw4_pi:
2464*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbsw4_pci:
2465*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbsw4_pcr:
2466*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadrb_rr:
2467*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrbt_io:
2468*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrbt_pi:
2469*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrbf_io:
2470*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrbf_pi:
2471*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrbtnew_io:
2472*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrbfnew_io:
2473*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrbt_rr:
2474*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrbf_rr:
2475*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrbtnew_rr:
2476*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrbfnew_rr:
2477*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrbtnew_pi:
2478*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrbfnew_pi:
2479*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrbt_abs:
2480*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrbf_abs:
2481*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrbtnew_abs:
2482*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrbfnew_abs:
2483*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrbgp:
2484*9880d681SAndroid Build Coastguard Worker   // Half
2485*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrh_io:
2486*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadrh_ur:
2487*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadrh_ap:
2488*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrh_pr:
2489*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrh_pbr:
2490*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrh_pi:
2491*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrh_pci:
2492*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrh_pcr:
2493*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadrh_rr:
2494*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrht_io:
2495*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrht_pi:
2496*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrhf_io:
2497*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrhf_pi:
2498*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrhtnew_io:
2499*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrhfnew_io:
2500*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrht_rr:
2501*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrhf_rr:
2502*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrhtnew_rr:
2503*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrhfnew_rr:
2504*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrhtnew_pi:
2505*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrhfnew_pi:
2506*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrht_abs:
2507*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrhf_abs:
2508*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrhtnew_abs:
2509*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrhfnew_abs:
2510*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrhgp:
2511*9880d681SAndroid Build Coastguard Worker     return true;
2512*9880d681SAndroid Build Coastguard Worker   default:
2513*9880d681SAndroid Build Coastguard Worker     return false;
2514*9880d681SAndroid Build Coastguard Worker   }
2515*9880d681SAndroid Build Coastguard Worker }
2516*9880d681SAndroid Build Coastguard Worker 
2517*9880d681SAndroid Build Coastguard Worker 
isSolo(const MachineInstr * MI) const2518*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isSolo(const MachineInstr* MI) const {
2519*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI->getDesc().TSFlags;
2520*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::SoloPos) & HexagonII::SoloMask;
2521*9880d681SAndroid Build Coastguard Worker }
2522*9880d681SAndroid Build Coastguard Worker 
2523*9880d681SAndroid Build Coastguard Worker 
isSpillPredRegOp(const MachineInstr * MI) const2524*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isSpillPredRegOp(const MachineInstr *MI) const {
2525*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
2526*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriw_pred :
2527*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriw_pred :
2528*9880d681SAndroid Build Coastguard Worker     return true;
2529*9880d681SAndroid Build Coastguard Worker   default:
2530*9880d681SAndroid Build Coastguard Worker     return false;
2531*9880d681SAndroid Build Coastguard Worker   }
2532*9880d681SAndroid Build Coastguard Worker }
2533*9880d681SAndroid Build Coastguard Worker 
2534*9880d681SAndroid Build Coastguard Worker 
isTailCall(const MachineInstr * MI) const2535*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isTailCall(const MachineInstr *MI) const {
2536*9880d681SAndroid Build Coastguard Worker   if (!MI->isBranch())
2537*9880d681SAndroid Build Coastguard Worker     return false;
2538*9880d681SAndroid Build Coastguard Worker 
2539*9880d681SAndroid Build Coastguard Worker   for (auto &Op : MI->operands())
2540*9880d681SAndroid Build Coastguard Worker     if (Op.isGlobal() || Op.isSymbol())
2541*9880d681SAndroid Build Coastguard Worker       return true;
2542*9880d681SAndroid Build Coastguard Worker   return false;
2543*9880d681SAndroid Build Coastguard Worker }
2544*9880d681SAndroid Build Coastguard Worker 
2545*9880d681SAndroid Build Coastguard Worker 
2546*9880d681SAndroid Build Coastguard Worker // Returns true when SU has a timing class TC1.
isTC1(const MachineInstr * MI) const2547*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isTC1(const MachineInstr *MI) const {
2548*9880d681SAndroid Build Coastguard Worker   unsigned SchedClass = MI->getDesc().getSchedClass();
2549*9880d681SAndroid Build Coastguard Worker   switch (SchedClass) {
2550*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::ALU32_2op_tc_1_SLOT0123:
2551*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::ALU32_3op_tc_1_SLOT0123:
2552*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::ALU32_ADDI_tc_1_SLOT0123:
2553*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::ALU64_tc_1_SLOT23:
2554*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::EXTENDER_tc_1_SLOT0123:
2555*9880d681SAndroid Build Coastguard Worker   //case Hexagon::Sched::M_tc_1_SLOT23:
2556*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::S_2op_tc_1_SLOT23:
2557*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::S_3op_tc_1_SLOT23:
2558*9880d681SAndroid Build Coastguard Worker     return true;
2559*9880d681SAndroid Build Coastguard Worker 
2560*9880d681SAndroid Build Coastguard Worker   default:
2561*9880d681SAndroid Build Coastguard Worker     return false;
2562*9880d681SAndroid Build Coastguard Worker   }
2563*9880d681SAndroid Build Coastguard Worker }
2564*9880d681SAndroid Build Coastguard Worker 
2565*9880d681SAndroid Build Coastguard Worker 
isTC2(const MachineInstr * MI) const2566*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isTC2(const MachineInstr *MI) const {
2567*9880d681SAndroid Build Coastguard Worker   unsigned SchedClass = MI->getDesc().getSchedClass();
2568*9880d681SAndroid Build Coastguard Worker   switch (SchedClass) {
2569*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::ALU32_3op_tc_2_SLOT0123:
2570*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::ALU64_tc_2_SLOT23:
2571*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::CR_tc_2_SLOT3:
2572*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::M_tc_2_SLOT23:
2573*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::S_2op_tc_2_SLOT23:
2574*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::S_3op_tc_2_SLOT23:
2575*9880d681SAndroid Build Coastguard Worker     return true;
2576*9880d681SAndroid Build Coastguard Worker 
2577*9880d681SAndroid Build Coastguard Worker   default:
2578*9880d681SAndroid Build Coastguard Worker     return false;
2579*9880d681SAndroid Build Coastguard Worker   }
2580*9880d681SAndroid Build Coastguard Worker }
2581*9880d681SAndroid Build Coastguard Worker 
2582*9880d681SAndroid Build Coastguard Worker 
isTC2Early(const MachineInstr * MI) const2583*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isTC2Early(const MachineInstr *MI) const {
2584*9880d681SAndroid Build Coastguard Worker   unsigned SchedClass = MI->getDesc().getSchedClass();
2585*9880d681SAndroid Build Coastguard Worker   switch (SchedClass) {
2586*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::ALU32_2op_tc_2early_SLOT0123:
2587*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::ALU32_3op_tc_2early_SLOT0123:
2588*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::ALU64_tc_2early_SLOT23:
2589*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::CR_tc_2early_SLOT23:
2590*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::CR_tc_2early_SLOT3:
2591*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::J_tc_2early_SLOT0123:
2592*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::J_tc_2early_SLOT2:
2593*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::J_tc_2early_SLOT23:
2594*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::S_2op_tc_2early_SLOT23:
2595*9880d681SAndroid Build Coastguard Worker   case Hexagon::Sched::S_3op_tc_2early_SLOT23:
2596*9880d681SAndroid Build Coastguard Worker     return true;
2597*9880d681SAndroid Build Coastguard Worker 
2598*9880d681SAndroid Build Coastguard Worker   default:
2599*9880d681SAndroid Build Coastguard Worker     return false;
2600*9880d681SAndroid Build Coastguard Worker   }
2601*9880d681SAndroid Build Coastguard Worker }
2602*9880d681SAndroid Build Coastguard Worker 
2603*9880d681SAndroid Build Coastguard Worker 
isTC4x(const MachineInstr * MI) const2604*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isTC4x(const MachineInstr *MI) const {
2605*9880d681SAndroid Build Coastguard Worker   if (!MI)
2606*9880d681SAndroid Build Coastguard Worker     return false;
2607*9880d681SAndroid Build Coastguard Worker 
2608*9880d681SAndroid Build Coastguard Worker   unsigned SchedClass = MI->getDesc().getSchedClass();
2609*9880d681SAndroid Build Coastguard Worker   return SchedClass == Hexagon::Sched::M_tc_3or4x_SLOT23;
2610*9880d681SAndroid Build Coastguard Worker }
2611*9880d681SAndroid Build Coastguard Worker 
2612*9880d681SAndroid Build Coastguard Worker 
isV60VectorInstruction(const MachineInstr * MI) const2613*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isV60VectorInstruction(const MachineInstr *MI) const {
2614*9880d681SAndroid Build Coastguard Worker   if (!MI)
2615*9880d681SAndroid Build Coastguard Worker     return false;
2616*9880d681SAndroid Build Coastguard Worker 
2617*9880d681SAndroid Build Coastguard Worker   const uint64_t V = getType(MI);
2618*9880d681SAndroid Build Coastguard Worker   return HexagonII::TypeCVI_FIRST <= V && V <= HexagonII::TypeCVI_LAST;
2619*9880d681SAndroid Build Coastguard Worker }
2620*9880d681SAndroid Build Coastguard Worker 
2621*9880d681SAndroid Build Coastguard Worker 
2622*9880d681SAndroid Build Coastguard Worker // Check if the Offset is a valid auto-inc imm by Load/Store Type.
2623*9880d681SAndroid Build Coastguard Worker //
isValidAutoIncImm(const EVT VT,const int Offset) const2624*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isValidAutoIncImm(const EVT VT, const int Offset) const {
2625*9880d681SAndroid Build Coastguard Worker   if (VT == MVT::v16i32 || VT == MVT::v8i64 ||
2626*9880d681SAndroid Build Coastguard Worker       VT == MVT::v32i16 || VT == MVT::v64i8) {
2627*9880d681SAndroid Build Coastguard Worker       return (Offset >= Hexagon_MEMV_AUTOINC_MIN &&
2628*9880d681SAndroid Build Coastguard Worker               Offset <= Hexagon_MEMV_AUTOINC_MAX &&
2629*9880d681SAndroid Build Coastguard Worker               (Offset & 0x3f) == 0);
2630*9880d681SAndroid Build Coastguard Worker   }
2631*9880d681SAndroid Build Coastguard Worker   // 128B
2632*9880d681SAndroid Build Coastguard Worker   if (VT == MVT::v32i32 || VT == MVT::v16i64 ||
2633*9880d681SAndroid Build Coastguard Worker       VT == MVT::v64i16 || VT == MVT::v128i8) {
2634*9880d681SAndroid Build Coastguard Worker       return (Offset >= Hexagon_MEMV_AUTOINC_MIN_128B &&
2635*9880d681SAndroid Build Coastguard Worker               Offset <= Hexagon_MEMV_AUTOINC_MAX_128B &&
2636*9880d681SAndroid Build Coastguard Worker               (Offset & 0x7f) == 0);
2637*9880d681SAndroid Build Coastguard Worker   }
2638*9880d681SAndroid Build Coastguard Worker   if (VT == MVT::i64) {
2639*9880d681SAndroid Build Coastguard Worker       return (Offset >= Hexagon_MEMD_AUTOINC_MIN &&
2640*9880d681SAndroid Build Coastguard Worker               Offset <= Hexagon_MEMD_AUTOINC_MAX &&
2641*9880d681SAndroid Build Coastguard Worker               (Offset & 0x7) == 0);
2642*9880d681SAndroid Build Coastguard Worker   }
2643*9880d681SAndroid Build Coastguard Worker   if (VT == MVT::i32) {
2644*9880d681SAndroid Build Coastguard Worker       return (Offset >= Hexagon_MEMW_AUTOINC_MIN &&
2645*9880d681SAndroid Build Coastguard Worker               Offset <= Hexagon_MEMW_AUTOINC_MAX &&
2646*9880d681SAndroid Build Coastguard Worker               (Offset & 0x3) == 0);
2647*9880d681SAndroid Build Coastguard Worker   }
2648*9880d681SAndroid Build Coastguard Worker   if (VT == MVT::i16) {
2649*9880d681SAndroid Build Coastguard Worker       return (Offset >= Hexagon_MEMH_AUTOINC_MIN &&
2650*9880d681SAndroid Build Coastguard Worker               Offset <= Hexagon_MEMH_AUTOINC_MAX &&
2651*9880d681SAndroid Build Coastguard Worker               (Offset & 0x1) == 0);
2652*9880d681SAndroid Build Coastguard Worker   }
2653*9880d681SAndroid Build Coastguard Worker   if (VT == MVT::i8) {
2654*9880d681SAndroid Build Coastguard Worker       return (Offset >= Hexagon_MEMB_AUTOINC_MIN &&
2655*9880d681SAndroid Build Coastguard Worker               Offset <= Hexagon_MEMB_AUTOINC_MAX);
2656*9880d681SAndroid Build Coastguard Worker   }
2657*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Not an auto-inc opc!");
2658*9880d681SAndroid Build Coastguard Worker }
2659*9880d681SAndroid Build Coastguard Worker 
2660*9880d681SAndroid Build Coastguard Worker 
isValidOffset(unsigned Opcode,int Offset,bool Extend) const2661*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset,
2662*9880d681SAndroid Build Coastguard Worker       bool Extend) const {
2663*9880d681SAndroid Build Coastguard Worker   // This function is to check whether the "Offset" is in the correct range of
2664*9880d681SAndroid Build Coastguard Worker   // the given "Opcode". If "Offset" is not in the correct range, "A2_addi" is
2665*9880d681SAndroid Build Coastguard Worker   // inserted to calculate the final address. Due to this reason, the function
2666*9880d681SAndroid Build Coastguard Worker   // assumes that the "Offset" has correct alignment.
2667*9880d681SAndroid Build Coastguard Worker   // We used to assert if the offset was not properly aligned, however,
2668*9880d681SAndroid Build Coastguard Worker   // there are cases where a misaligned pointer recast can cause this
2669*9880d681SAndroid Build Coastguard Worker   // problem, and we need to allow for it. The front end warns of such
2670*9880d681SAndroid Build Coastguard Worker   // misaligns with respect to load size.
2671*9880d681SAndroid Build Coastguard Worker 
2672*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
2673*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriq_pred_V6:
2674*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriq_pred_vec_V6:
2675*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriv_pseudo_V6:
2676*9880d681SAndroid Build Coastguard Worker   case Hexagon::STrivv_pseudo_V6:
2677*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriq_pred_V6:
2678*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriq_pred_vec_V6:
2679*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriv_pseudo_V6:
2680*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDrivv_pseudo_V6:
2681*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDrivv_indexed:
2682*9880d681SAndroid Build Coastguard Worker   case Hexagon::STrivv_indexed:
2683*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vL32b_ai:
2684*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vS32b_ai:
2685*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vL32Ub_ai:
2686*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vS32Ub_ai:
2687*9880d681SAndroid Build Coastguard Worker     return (Offset >= Hexagon_MEMV_OFFSET_MIN) &&
2688*9880d681SAndroid Build Coastguard Worker       (Offset <= Hexagon_MEMV_OFFSET_MAX);
2689*9880d681SAndroid Build Coastguard Worker 
2690*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriq_pred_V6_128B:
2691*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriq_pred_vec_V6_128B:
2692*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriv_pseudo_V6_128B:
2693*9880d681SAndroid Build Coastguard Worker   case Hexagon::STrivv_pseudo_V6_128B:
2694*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriq_pred_V6_128B:
2695*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriq_pred_vec_V6_128B:
2696*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriv_pseudo_V6_128B:
2697*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDrivv_pseudo_V6_128B:
2698*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDrivv_indexed_128B:
2699*9880d681SAndroid Build Coastguard Worker   case Hexagon::STrivv_indexed_128B:
2700*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vL32b_ai_128B:
2701*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vS32b_ai_128B:
2702*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vL32Ub_ai_128B:
2703*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vS32Ub_ai_128B:
2704*9880d681SAndroid Build Coastguard Worker     return (Offset >= Hexagon_MEMV_OFFSET_MIN_128B) &&
2705*9880d681SAndroid Build Coastguard Worker       (Offset <= Hexagon_MEMV_OFFSET_MAX_128B);
2706*9880d681SAndroid Build Coastguard Worker 
2707*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_loop0i:
2708*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_loop1i:
2709*9880d681SAndroid Build Coastguard Worker     return isUInt<10>(Offset);
2710*9880d681SAndroid Build Coastguard Worker   }
2711*9880d681SAndroid Build Coastguard Worker 
2712*9880d681SAndroid Build Coastguard Worker   if (Extend)
2713*9880d681SAndroid Build Coastguard Worker     return true;
2714*9880d681SAndroid Build Coastguard Worker 
2715*9880d681SAndroid Build Coastguard Worker   switch (Opcode) {
2716*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadri_io:
2717*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storeri_io:
2718*9880d681SAndroid Build Coastguard Worker     return (Offset >= Hexagon_MEMW_OFFSET_MIN) &&
2719*9880d681SAndroid Build Coastguard Worker       (Offset <= Hexagon_MEMW_OFFSET_MAX);
2720*9880d681SAndroid Build Coastguard Worker 
2721*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrd_io:
2722*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storerd_io:
2723*9880d681SAndroid Build Coastguard Worker     return (Offset >= Hexagon_MEMD_OFFSET_MIN) &&
2724*9880d681SAndroid Build Coastguard Worker       (Offset <= Hexagon_MEMD_OFFSET_MAX);
2725*9880d681SAndroid Build Coastguard Worker 
2726*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrh_io:
2727*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadruh_io:
2728*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storerh_io:
2729*9880d681SAndroid Build Coastguard Worker     return (Offset >= Hexagon_MEMH_OFFSET_MIN) &&
2730*9880d681SAndroid Build Coastguard Worker       (Offset <= Hexagon_MEMH_OFFSET_MAX);
2731*9880d681SAndroid Build Coastguard Worker 
2732*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrb_io:
2733*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrub_io:
2734*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storerb_io:
2735*9880d681SAndroid Build Coastguard Worker     return (Offset >= Hexagon_MEMB_OFFSET_MIN) &&
2736*9880d681SAndroid Build Coastguard Worker       (Offset <= Hexagon_MEMB_OFFSET_MAX);
2737*9880d681SAndroid Build Coastguard Worker 
2738*9880d681SAndroid Build Coastguard Worker   case Hexagon::A2_addi:
2739*9880d681SAndroid Build Coastguard Worker     return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&
2740*9880d681SAndroid Build Coastguard Worker       (Offset <= Hexagon_ADDI_OFFSET_MAX);
2741*9880d681SAndroid Build Coastguard Worker 
2742*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_iadd_memopw_io :
2743*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_isub_memopw_io :
2744*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_add_memopw_io :
2745*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_sub_memopw_io :
2746*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_and_memopw_io :
2747*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_or_memopw_io :
2748*9880d681SAndroid Build Coastguard Worker     return (0 <= Offset && Offset <= 255);
2749*9880d681SAndroid Build Coastguard Worker 
2750*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_iadd_memoph_io :
2751*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_isub_memoph_io :
2752*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_add_memoph_io :
2753*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_sub_memoph_io :
2754*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_and_memoph_io :
2755*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_or_memoph_io :
2756*9880d681SAndroid Build Coastguard Worker     return (0 <= Offset && Offset <= 127);
2757*9880d681SAndroid Build Coastguard Worker 
2758*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_iadd_memopb_io :
2759*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_isub_memopb_io :
2760*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_add_memopb_io :
2761*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_sub_memopb_io :
2762*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_and_memopb_io :
2763*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_or_memopb_io :
2764*9880d681SAndroid Build Coastguard Worker     return (0 <= Offset && Offset <= 63);
2765*9880d681SAndroid Build Coastguard Worker 
2766*9880d681SAndroid Build Coastguard Worker   // LDriw_xxx and STriw_xxx are pseudo operations, so it has to take offset of
2767*9880d681SAndroid Build Coastguard Worker   // any size. Later pass knows how to handle it.
2768*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriw_pred:
2769*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriw_pred:
2770*9880d681SAndroid Build Coastguard Worker   case Hexagon::STriw_mod:
2771*9880d681SAndroid Build Coastguard Worker   case Hexagon::LDriw_mod:
2772*9880d681SAndroid Build Coastguard Worker     return true;
2773*9880d681SAndroid Build Coastguard Worker 
2774*9880d681SAndroid Build Coastguard Worker   case Hexagon::TFR_FI:
2775*9880d681SAndroid Build Coastguard Worker   case Hexagon::TFR_FIA:
2776*9880d681SAndroid Build Coastguard Worker   case Hexagon::INLINEASM:
2777*9880d681SAndroid Build Coastguard Worker     return true;
2778*9880d681SAndroid Build Coastguard Worker 
2779*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrbt_io:
2780*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrbf_io:
2781*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrubt_io:
2782*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrubf_io:
2783*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_pstorerbt_io:
2784*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_pstorerbf_io:
2785*9880d681SAndroid Build Coastguard Worker   case Hexagon::S4_storeirb_io:
2786*9880d681SAndroid Build Coastguard Worker   case Hexagon::S4_storeirbt_io:
2787*9880d681SAndroid Build Coastguard Worker   case Hexagon::S4_storeirbf_io:
2788*9880d681SAndroid Build Coastguard Worker     return isUInt<6>(Offset);
2789*9880d681SAndroid Build Coastguard Worker 
2790*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrht_io:
2791*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrhf_io:
2792*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadruht_io:
2793*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadruhf_io:
2794*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_pstorerht_io:
2795*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_pstorerhf_io:
2796*9880d681SAndroid Build Coastguard Worker   case Hexagon::S4_storeirh_io:
2797*9880d681SAndroid Build Coastguard Worker   case Hexagon::S4_storeirht_io:
2798*9880d681SAndroid Build Coastguard Worker   case Hexagon::S4_storeirhf_io:
2799*9880d681SAndroid Build Coastguard Worker     return isShiftedUInt<6,1>(Offset);
2800*9880d681SAndroid Build Coastguard Worker 
2801*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrit_io:
2802*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrif_io:
2803*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_pstorerit_io:
2804*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_pstorerif_io:
2805*9880d681SAndroid Build Coastguard Worker   case Hexagon::S4_storeiri_io:
2806*9880d681SAndroid Build Coastguard Worker   case Hexagon::S4_storeirit_io:
2807*9880d681SAndroid Build Coastguard Worker   case Hexagon::S4_storeirif_io:
2808*9880d681SAndroid Build Coastguard Worker     return isShiftedUInt<6,2>(Offset);
2809*9880d681SAndroid Build Coastguard Worker 
2810*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrdt_io:
2811*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrdf_io:
2812*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_pstorerdt_io:
2813*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_pstorerdf_io:
2814*9880d681SAndroid Build Coastguard Worker     return isShiftedUInt<6,3>(Offset);
2815*9880d681SAndroid Build Coastguard Worker   } // switch
2816*9880d681SAndroid Build Coastguard Worker 
2817*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("No offset range is defined for this opcode. "
2818*9880d681SAndroid Build Coastguard Worker                    "Please define it in the above switch statement!");
2819*9880d681SAndroid Build Coastguard Worker }
2820*9880d681SAndroid Build Coastguard Worker 
2821*9880d681SAndroid Build Coastguard Worker 
isVecAcc(const MachineInstr * MI) const2822*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isVecAcc(const MachineInstr *MI) const {
2823*9880d681SAndroid Build Coastguard Worker   return MI && isV60VectorInstruction(MI) && isAccumulator(MI);
2824*9880d681SAndroid Build Coastguard Worker }
2825*9880d681SAndroid Build Coastguard Worker 
2826*9880d681SAndroid Build Coastguard Worker 
isVecALU(const MachineInstr * MI) const2827*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isVecALU(const MachineInstr *MI) const {
2828*9880d681SAndroid Build Coastguard Worker   if (!MI)
2829*9880d681SAndroid Build Coastguard Worker     return false;
2830*9880d681SAndroid Build Coastguard Worker   const uint64_t F = get(MI->getOpcode()).TSFlags;
2831*9880d681SAndroid Build Coastguard Worker   const uint64_t V = ((F >> HexagonII::TypePos) & HexagonII::TypeMask);
2832*9880d681SAndroid Build Coastguard Worker   return
2833*9880d681SAndroid Build Coastguard Worker     V == HexagonII::TypeCVI_VA         ||
2834*9880d681SAndroid Build Coastguard Worker     V == HexagonII::TypeCVI_VA_DV;
2835*9880d681SAndroid Build Coastguard Worker }
2836*9880d681SAndroid Build Coastguard Worker 
2837*9880d681SAndroid Build Coastguard Worker 
isVecUsableNextPacket(const MachineInstr * ProdMI,const MachineInstr * ConsMI) const2838*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isVecUsableNextPacket(const MachineInstr *ProdMI,
2839*9880d681SAndroid Build Coastguard Worker       const MachineInstr *ConsMI) const {
2840*9880d681SAndroid Build Coastguard Worker   if (EnableACCForwarding && isVecAcc(ProdMI) && isVecAcc(ConsMI))
2841*9880d681SAndroid Build Coastguard Worker     return true;
2842*9880d681SAndroid Build Coastguard Worker 
2843*9880d681SAndroid Build Coastguard Worker   if (EnableALUForwarding && (isVecALU(ConsMI) || isLateSourceInstr(ConsMI)))
2844*9880d681SAndroid Build Coastguard Worker     return true;
2845*9880d681SAndroid Build Coastguard Worker 
2846*9880d681SAndroid Build Coastguard Worker   if (mayBeNewStore(ConsMI))
2847*9880d681SAndroid Build Coastguard Worker     return true;
2848*9880d681SAndroid Build Coastguard Worker 
2849*9880d681SAndroid Build Coastguard Worker   return false;
2850*9880d681SAndroid Build Coastguard Worker }
2851*9880d681SAndroid Build Coastguard Worker 
isZeroExtendingLoad(const MachineInstr & MI) const2852*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::isZeroExtendingLoad(const MachineInstr &MI) const {
2853*9880d681SAndroid Build Coastguard Worker   switch (MI.getOpcode()) {
2854*9880d681SAndroid Build Coastguard Worker   // Byte
2855*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrub_io:
2856*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadrub_ur:
2857*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadrub_ap:
2858*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrub_pr:
2859*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrub_pbr:
2860*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrub_pi:
2861*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrub_pci:
2862*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrub_pcr:
2863*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbzw2_io:
2864*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadbzw2_ur:
2865*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadbzw2_ap:
2866*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbzw2_pr:
2867*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbzw2_pbr:
2868*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbzw2_pi:
2869*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbzw2_pci:
2870*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbzw2_pcr:
2871*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbzw4_io:
2872*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadbzw4_ur:
2873*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadbzw4_ap:
2874*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbzw4_pr:
2875*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbzw4_pbr:
2876*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbzw4_pi:
2877*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbzw4_pci:
2878*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadbzw4_pcr:
2879*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadrub_rr:
2880*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrubt_io:
2881*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrubt_pi:
2882*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrubf_io:
2883*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrubf_pi:
2884*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrubtnew_io:
2885*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrubfnew_io:
2886*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrubt_rr:
2887*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrubf_rr:
2888*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrubtnew_rr:
2889*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrubfnew_rr:
2890*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrubtnew_pi:
2891*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadrubfnew_pi:
2892*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrubt_abs:
2893*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrubf_abs:
2894*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrubtnew_abs:
2895*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadrubfnew_abs:
2896*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrubgp:
2897*9880d681SAndroid Build Coastguard Worker   // Half
2898*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadruh_io:
2899*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadruh_ur:
2900*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadruh_ap:
2901*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadruh_pr:
2902*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadruh_pbr:
2903*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadruh_pi:
2904*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadruh_pci:
2905*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadruh_pcr:
2906*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_loadruh_rr:
2907*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadruht_io:
2908*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadruht_pi:
2909*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadruhf_io:
2910*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadruhf_pi:
2911*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadruhtnew_io:
2912*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadruhfnew_io:
2913*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadruht_rr:
2914*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadruhf_rr:
2915*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadruhtnew_rr:
2916*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadruhfnew_rr:
2917*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadruhtnew_pi:
2918*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_ploadruhfnew_pi:
2919*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadruht_abs:
2920*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadruhf_abs:
2921*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadruhtnew_abs:
2922*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_ploadruhfnew_abs:
2923*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadruhgp:
2924*9880d681SAndroid Build Coastguard Worker     return true;
2925*9880d681SAndroid Build Coastguard Worker   default:
2926*9880d681SAndroid Build Coastguard Worker     return false;
2927*9880d681SAndroid Build Coastguard Worker   }
2928*9880d681SAndroid Build Coastguard Worker }
2929*9880d681SAndroid Build Coastguard Worker 
2930*9880d681SAndroid Build Coastguard Worker 
2931*9880d681SAndroid Build Coastguard Worker // Add latency to instruction.
addLatencyToSchedule(const MachineInstr * MI1,const MachineInstr * MI2) const2932*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::addLatencyToSchedule(const MachineInstr *MI1,
2933*9880d681SAndroid Build Coastguard Worker       const MachineInstr *MI2) const {
2934*9880d681SAndroid Build Coastguard Worker   if (isV60VectorInstruction(MI1) && isV60VectorInstruction(MI2))
2935*9880d681SAndroid Build Coastguard Worker     if (!isVecUsableNextPacket(MI1, MI2))
2936*9880d681SAndroid Build Coastguard Worker       return true;
2937*9880d681SAndroid Build Coastguard Worker   return false;
2938*9880d681SAndroid Build Coastguard Worker }
2939*9880d681SAndroid Build Coastguard Worker 
2940*9880d681SAndroid Build Coastguard Worker 
2941*9880d681SAndroid Build Coastguard Worker /// \brief Get the base register and byte offset of a load/store instr.
getMemOpBaseRegImmOfs(MachineInstr & LdSt,unsigned & BaseReg,int64_t & Offset,const TargetRegisterInfo * TRI) const2942*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::getMemOpBaseRegImmOfs(MachineInstr &LdSt,
2943*9880d681SAndroid Build Coastguard Worker       unsigned &BaseReg, int64_t &Offset, const TargetRegisterInfo *TRI)
2944*9880d681SAndroid Build Coastguard Worker       const {
2945*9880d681SAndroid Build Coastguard Worker   unsigned AccessSize = 0;
2946*9880d681SAndroid Build Coastguard Worker   int OffsetVal = 0;
2947*9880d681SAndroid Build Coastguard Worker   BaseReg = getBaseAndOffset(&LdSt, OffsetVal, AccessSize);
2948*9880d681SAndroid Build Coastguard Worker   Offset = OffsetVal;
2949*9880d681SAndroid Build Coastguard Worker   return BaseReg != 0;
2950*9880d681SAndroid Build Coastguard Worker }
2951*9880d681SAndroid Build Coastguard Worker 
2952*9880d681SAndroid Build Coastguard Worker 
2953*9880d681SAndroid Build Coastguard Worker /// \brief Can these instructions execute at the same time in a bundle.
canExecuteInBundle(const MachineInstr * First,const MachineInstr * Second) const2954*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::canExecuteInBundle(const MachineInstr *First,
2955*9880d681SAndroid Build Coastguard Worker       const MachineInstr *Second) const {
2956*9880d681SAndroid Build Coastguard Worker   if (DisableNVSchedule)
2957*9880d681SAndroid Build Coastguard Worker     return false;
2958*9880d681SAndroid Build Coastguard Worker   if (mayBeNewStore(Second)) {
2959*9880d681SAndroid Build Coastguard Worker     // Make sure the definition of the first instruction is the value being
2960*9880d681SAndroid Build Coastguard Worker     // stored.
2961*9880d681SAndroid Build Coastguard Worker     const MachineOperand &Stored =
2962*9880d681SAndroid Build Coastguard Worker       Second->getOperand(Second->getNumOperands() - 1);
2963*9880d681SAndroid Build Coastguard Worker     if (!Stored.isReg())
2964*9880d681SAndroid Build Coastguard Worker       return false;
2965*9880d681SAndroid Build Coastguard Worker     for (unsigned i = 0, e = First->getNumOperands(); i < e; ++i) {
2966*9880d681SAndroid Build Coastguard Worker       const MachineOperand &Op = First->getOperand(i);
2967*9880d681SAndroid Build Coastguard Worker       if (Op.isReg() && Op.isDef() && Op.getReg() == Stored.getReg())
2968*9880d681SAndroid Build Coastguard Worker         return true;
2969*9880d681SAndroid Build Coastguard Worker     }
2970*9880d681SAndroid Build Coastguard Worker   }
2971*9880d681SAndroid Build Coastguard Worker   return false;
2972*9880d681SAndroid Build Coastguard Worker }
2973*9880d681SAndroid Build Coastguard Worker 
2974*9880d681SAndroid Build Coastguard Worker 
hasEHLabel(const MachineBasicBlock * B) const2975*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::hasEHLabel(const MachineBasicBlock *B) const {
2976*9880d681SAndroid Build Coastguard Worker   for (auto &I : *B)
2977*9880d681SAndroid Build Coastguard Worker     if (I.isEHLabel())
2978*9880d681SAndroid Build Coastguard Worker       return true;
2979*9880d681SAndroid Build Coastguard Worker   return false;
2980*9880d681SAndroid Build Coastguard Worker }
2981*9880d681SAndroid Build Coastguard Worker 
2982*9880d681SAndroid Build Coastguard Worker 
2983*9880d681SAndroid Build Coastguard Worker // Returns true if an instruction can be converted into a non-extended
2984*9880d681SAndroid Build Coastguard Worker // equivalent instruction.
hasNonExtEquivalent(const MachineInstr * MI) const2985*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::hasNonExtEquivalent(const MachineInstr *MI) const {
2986*9880d681SAndroid Build Coastguard Worker   short NonExtOpcode;
2987*9880d681SAndroid Build Coastguard Worker   // Check if the instruction has a register form that uses register in place
2988*9880d681SAndroid Build Coastguard Worker   // of the extended operand, if so return that as the non-extended form.
2989*9880d681SAndroid Build Coastguard Worker   if (Hexagon::getRegForm(MI->getOpcode()) >= 0)
2990*9880d681SAndroid Build Coastguard Worker     return true;
2991*9880d681SAndroid Build Coastguard Worker 
2992*9880d681SAndroid Build Coastguard Worker   if (MI->getDesc().mayLoad() || MI->getDesc().mayStore()) {
2993*9880d681SAndroid Build Coastguard Worker     // Check addressing mode and retrieve non-ext equivalent instruction.
2994*9880d681SAndroid Build Coastguard Worker 
2995*9880d681SAndroid Build Coastguard Worker     switch (getAddrMode(MI)) {
2996*9880d681SAndroid Build Coastguard Worker     case HexagonII::Absolute :
2997*9880d681SAndroid Build Coastguard Worker       // Load/store with absolute addressing mode can be converted into
2998*9880d681SAndroid Build Coastguard Worker       // base+offset mode.
2999*9880d681SAndroid Build Coastguard Worker       NonExtOpcode = Hexagon::getBaseWithImmOffset(MI->getOpcode());
3000*9880d681SAndroid Build Coastguard Worker       break;
3001*9880d681SAndroid Build Coastguard Worker     case HexagonII::BaseImmOffset :
3002*9880d681SAndroid Build Coastguard Worker       // Load/store with base+offset addressing mode can be converted into
3003*9880d681SAndroid Build Coastguard Worker       // base+register offset addressing mode. However left shift operand should
3004*9880d681SAndroid Build Coastguard Worker       // be set to 0.
3005*9880d681SAndroid Build Coastguard Worker       NonExtOpcode = Hexagon::getBaseWithRegOffset(MI->getOpcode());
3006*9880d681SAndroid Build Coastguard Worker       break;
3007*9880d681SAndroid Build Coastguard Worker     case HexagonII::BaseLongOffset:
3008*9880d681SAndroid Build Coastguard Worker       NonExtOpcode = Hexagon::getRegShlForm(MI->getOpcode());
3009*9880d681SAndroid Build Coastguard Worker       break;
3010*9880d681SAndroid Build Coastguard Worker     default:
3011*9880d681SAndroid Build Coastguard Worker       return false;
3012*9880d681SAndroid Build Coastguard Worker     }
3013*9880d681SAndroid Build Coastguard Worker     if (NonExtOpcode < 0)
3014*9880d681SAndroid Build Coastguard Worker       return false;
3015*9880d681SAndroid Build Coastguard Worker     return true;
3016*9880d681SAndroid Build Coastguard Worker   }
3017*9880d681SAndroid Build Coastguard Worker   return false;
3018*9880d681SAndroid Build Coastguard Worker }
3019*9880d681SAndroid Build Coastguard Worker 
3020*9880d681SAndroid Build Coastguard Worker 
hasPseudoInstrPair(const MachineInstr * MI) const3021*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::hasPseudoInstrPair(const MachineInstr *MI) const {
3022*9880d681SAndroid Build Coastguard Worker   return Hexagon::getRealHWInstr(MI->getOpcode(),
3023*9880d681SAndroid Build Coastguard Worker                                  Hexagon::InstrType_Pseudo) >= 0;
3024*9880d681SAndroid Build Coastguard Worker }
3025*9880d681SAndroid Build Coastguard Worker 
3026*9880d681SAndroid Build Coastguard Worker 
hasUncondBranch(const MachineBasicBlock * B) const3027*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::hasUncondBranch(const MachineBasicBlock *B)
3028*9880d681SAndroid Build Coastguard Worker       const {
3029*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::const_iterator I = B->getFirstTerminator(), E = B->end();
3030*9880d681SAndroid Build Coastguard Worker   while (I != E) {
3031*9880d681SAndroid Build Coastguard Worker     if (I->isBarrier())
3032*9880d681SAndroid Build Coastguard Worker       return true;
3033*9880d681SAndroid Build Coastguard Worker     ++I;
3034*9880d681SAndroid Build Coastguard Worker   }
3035*9880d681SAndroid Build Coastguard Worker   return false;
3036*9880d681SAndroid Build Coastguard Worker }
3037*9880d681SAndroid Build Coastguard Worker 
3038*9880d681SAndroid Build Coastguard Worker 
3039*9880d681SAndroid Build Coastguard Worker // Returns true, if a LD insn can be promoted to a cur load.
mayBeCurLoad(const MachineInstr * MI) const3040*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::mayBeCurLoad(const MachineInstr *MI) const {
3041*9880d681SAndroid Build Coastguard Worker   auto &HST = MI->getParent()->getParent()->getSubtarget<HexagonSubtarget>();
3042*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI->getDesc().TSFlags;
3043*9880d681SAndroid Build Coastguard Worker   return ((F >> HexagonII::mayCVLoadPos) & HexagonII::mayCVLoadMask) &&
3044*9880d681SAndroid Build Coastguard Worker          HST.hasV60TOps();
3045*9880d681SAndroid Build Coastguard Worker }
3046*9880d681SAndroid Build Coastguard Worker 
3047*9880d681SAndroid Build Coastguard Worker 
3048*9880d681SAndroid Build Coastguard Worker // Returns true, if a ST insn can be promoted to a new-value store.
mayBeNewStore(const MachineInstr * MI) const3049*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::mayBeNewStore(const MachineInstr *MI) const {
3050*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI->getDesc().TSFlags;
3051*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::mayNVStorePos) & HexagonII::mayNVStoreMask;
3052*9880d681SAndroid Build Coastguard Worker }
3053*9880d681SAndroid Build Coastguard Worker 
3054*9880d681SAndroid Build Coastguard Worker 
producesStall(const MachineInstr * ProdMI,const MachineInstr * ConsMI) const3055*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::producesStall(const MachineInstr *ProdMI,
3056*9880d681SAndroid Build Coastguard Worker       const MachineInstr *ConsMI) const {
3057*9880d681SAndroid Build Coastguard Worker   // There is no stall when ProdMI is not a V60 vector.
3058*9880d681SAndroid Build Coastguard Worker   if (!isV60VectorInstruction(ProdMI))
3059*9880d681SAndroid Build Coastguard Worker     return false;
3060*9880d681SAndroid Build Coastguard Worker 
3061*9880d681SAndroid Build Coastguard Worker   // There is no stall when ProdMI and ConsMI are not dependent.
3062*9880d681SAndroid Build Coastguard Worker   if (!isDependent(ProdMI, ConsMI))
3063*9880d681SAndroid Build Coastguard Worker     return false;
3064*9880d681SAndroid Build Coastguard Worker 
3065*9880d681SAndroid Build Coastguard Worker   // When Forward Scheduling is enabled, there is no stall if ProdMI and ConsMI
3066*9880d681SAndroid Build Coastguard Worker   // are scheduled in consecutive packets.
3067*9880d681SAndroid Build Coastguard Worker   if (isVecUsableNextPacket(ProdMI, ConsMI))
3068*9880d681SAndroid Build Coastguard Worker     return false;
3069*9880d681SAndroid Build Coastguard Worker 
3070*9880d681SAndroid Build Coastguard Worker   return true;
3071*9880d681SAndroid Build Coastguard Worker }
3072*9880d681SAndroid Build Coastguard Worker 
3073*9880d681SAndroid Build Coastguard Worker 
producesStall(const MachineInstr * MI,MachineBasicBlock::const_instr_iterator BII) const3074*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::producesStall(const MachineInstr *MI,
3075*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock::const_instr_iterator BII) const {
3076*9880d681SAndroid Build Coastguard Worker   // There is no stall when I is not a V60 vector.
3077*9880d681SAndroid Build Coastguard Worker   if (!isV60VectorInstruction(MI))
3078*9880d681SAndroid Build Coastguard Worker     return false;
3079*9880d681SAndroid Build Coastguard Worker 
3080*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::const_instr_iterator MII = BII;
3081*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::const_instr_iterator MIE = MII->getParent()->instr_end();
3082*9880d681SAndroid Build Coastguard Worker 
3083*9880d681SAndroid Build Coastguard Worker   if (!(*MII).isBundle()) {
3084*9880d681SAndroid Build Coastguard Worker     const MachineInstr *J = &*MII;
3085*9880d681SAndroid Build Coastguard Worker     if (!isV60VectorInstruction(J))
3086*9880d681SAndroid Build Coastguard Worker       return false;
3087*9880d681SAndroid Build Coastguard Worker     else if (isVecUsableNextPacket(J, MI))
3088*9880d681SAndroid Build Coastguard Worker       return false;
3089*9880d681SAndroid Build Coastguard Worker     return true;
3090*9880d681SAndroid Build Coastguard Worker   }
3091*9880d681SAndroid Build Coastguard Worker 
3092*9880d681SAndroid Build Coastguard Worker   for (++MII; MII != MIE && MII->isInsideBundle(); ++MII) {
3093*9880d681SAndroid Build Coastguard Worker     const MachineInstr *J = &*MII;
3094*9880d681SAndroid Build Coastguard Worker     if (producesStall(J, MI))
3095*9880d681SAndroid Build Coastguard Worker       return true;
3096*9880d681SAndroid Build Coastguard Worker   }
3097*9880d681SAndroid Build Coastguard Worker   return false;
3098*9880d681SAndroid Build Coastguard Worker }
3099*9880d681SAndroid Build Coastguard Worker 
3100*9880d681SAndroid Build Coastguard Worker 
predCanBeUsedAsDotNew(const MachineInstr * MI,unsigned PredReg) const3101*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::predCanBeUsedAsDotNew(const MachineInstr *MI,
3102*9880d681SAndroid Build Coastguard Worker       unsigned PredReg) const {
3103*9880d681SAndroid Build Coastguard Worker   for (unsigned opNum = 0; opNum < MI->getNumOperands(); opNum++) {
3104*9880d681SAndroid Build Coastguard Worker     const MachineOperand &MO = MI->getOperand(opNum);
3105*9880d681SAndroid Build Coastguard Worker     if (MO.isReg() && MO.isDef() && MO.isImplicit() && (MO.getReg() == PredReg))
3106*9880d681SAndroid Build Coastguard Worker       return false; // Predicate register must be explicitly defined.
3107*9880d681SAndroid Build Coastguard Worker   }
3108*9880d681SAndroid Build Coastguard Worker 
3109*9880d681SAndroid Build Coastguard Worker   // Hexagon Programmer's Reference says that decbin, memw_locked, and
3110*9880d681SAndroid Build Coastguard Worker   // memd_locked cannot be used as .new as well,
3111*9880d681SAndroid Build Coastguard Worker   // but we don't seem to have these instructions defined.
3112*9880d681SAndroid Build Coastguard Worker   return MI->getOpcode() != Hexagon::A4_tlbmatch;
3113*9880d681SAndroid Build Coastguard Worker }
3114*9880d681SAndroid Build Coastguard Worker 
3115*9880d681SAndroid Build Coastguard Worker 
PredOpcodeHasJMP_c(unsigned Opcode) const3116*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::PredOpcodeHasJMP_c(unsigned Opcode) const {
3117*9880d681SAndroid Build Coastguard Worker   return (Opcode == Hexagon::J2_jumpt)      ||
3118*9880d681SAndroid Build Coastguard Worker          (Opcode == Hexagon::J2_jumpf)      ||
3119*9880d681SAndroid Build Coastguard Worker          (Opcode == Hexagon::J2_jumptnew)   ||
3120*9880d681SAndroid Build Coastguard Worker          (Opcode == Hexagon::J2_jumpfnew)   ||
3121*9880d681SAndroid Build Coastguard Worker          (Opcode == Hexagon::J2_jumptnewpt) ||
3122*9880d681SAndroid Build Coastguard Worker          (Opcode == Hexagon::J2_jumpfnewpt);
3123*9880d681SAndroid Build Coastguard Worker }
3124*9880d681SAndroid Build Coastguard Worker 
3125*9880d681SAndroid Build Coastguard Worker 
predOpcodeHasNot(ArrayRef<MachineOperand> Cond) const3126*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::predOpcodeHasNot(ArrayRef<MachineOperand> Cond) const {
3127*9880d681SAndroid Build Coastguard Worker   if (Cond.empty() || !isPredicated(Cond[0].getImm()))
3128*9880d681SAndroid Build Coastguard Worker     return false;
3129*9880d681SAndroid Build Coastguard Worker   return !isPredicatedTrue(Cond[0].getImm());
3130*9880d681SAndroid Build Coastguard Worker }
3131*9880d681SAndroid Build Coastguard Worker 
3132*9880d681SAndroid Build Coastguard Worker 
getAbsoluteForm(const MachineInstr * MI) const3133*9880d681SAndroid Build Coastguard Worker short HexagonInstrInfo::getAbsoluteForm(const MachineInstr *MI) const {
3134*9880d681SAndroid Build Coastguard Worker   return Hexagon::getAbsoluteForm(MI->getOpcode());
3135*9880d681SAndroid Build Coastguard Worker }
3136*9880d681SAndroid Build Coastguard Worker 
3137*9880d681SAndroid Build Coastguard Worker 
getAddrMode(const MachineInstr * MI) const3138*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::getAddrMode(const MachineInstr* MI) const {
3139*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI->getDesc().TSFlags;
3140*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::AddrModePos) & HexagonII::AddrModeMask;
3141*9880d681SAndroid Build Coastguard Worker }
3142*9880d681SAndroid Build Coastguard Worker 
3143*9880d681SAndroid Build Coastguard Worker 
3144*9880d681SAndroid Build Coastguard Worker // Returns the base register in a memory access (load/store). The offset is
3145*9880d681SAndroid Build Coastguard Worker // returned in Offset and the access size is returned in AccessSize.
getBaseAndOffset(const MachineInstr * MI,int & Offset,unsigned & AccessSize) const3146*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::getBaseAndOffset(const MachineInstr *MI,
3147*9880d681SAndroid Build Coastguard Worker       int &Offset, unsigned &AccessSize) const {
3148*9880d681SAndroid Build Coastguard Worker   // Return if it is not a base+offset type instruction or a MemOp.
3149*9880d681SAndroid Build Coastguard Worker   if (getAddrMode(MI) != HexagonII::BaseImmOffset &&
3150*9880d681SAndroid Build Coastguard Worker       getAddrMode(MI) != HexagonII::BaseLongOffset &&
3151*9880d681SAndroid Build Coastguard Worker       !isMemOp(MI) && !isPostIncrement(MI))
3152*9880d681SAndroid Build Coastguard Worker     return 0;
3153*9880d681SAndroid Build Coastguard Worker 
3154*9880d681SAndroid Build Coastguard Worker   // Since it is a memory access instruction, getMemAccessSize() should never
3155*9880d681SAndroid Build Coastguard Worker   // return 0.
3156*9880d681SAndroid Build Coastguard Worker   assert (getMemAccessSize(MI) &&
3157*9880d681SAndroid Build Coastguard Worker           "BaseImmOffset or BaseLongOffset or MemOp without accessSize");
3158*9880d681SAndroid Build Coastguard Worker 
3159*9880d681SAndroid Build Coastguard Worker   // Return Values of getMemAccessSize() are
3160*9880d681SAndroid Build Coastguard Worker   // 0 - Checked in the assert above.
3161*9880d681SAndroid Build Coastguard Worker   // 1, 2, 3, 4 & 7, 8 - The statement below is correct for all these.
3162*9880d681SAndroid Build Coastguard Worker   // MemAccessSize is represented as 1+log2(N) where N is size in bits.
3163*9880d681SAndroid Build Coastguard Worker   AccessSize = (1U << (getMemAccessSize(MI) - 1));
3164*9880d681SAndroid Build Coastguard Worker 
3165*9880d681SAndroid Build Coastguard Worker   unsigned basePos = 0, offsetPos = 0;
3166*9880d681SAndroid Build Coastguard Worker   if (!getBaseAndOffsetPosition(MI, basePos, offsetPos))
3167*9880d681SAndroid Build Coastguard Worker     return 0;
3168*9880d681SAndroid Build Coastguard Worker 
3169*9880d681SAndroid Build Coastguard Worker   // Post increment updates its EA after the mem access,
3170*9880d681SAndroid Build Coastguard Worker   // so we need to treat its offset as zero.
3171*9880d681SAndroid Build Coastguard Worker   if (isPostIncrement(MI))
3172*9880d681SAndroid Build Coastguard Worker     Offset = 0;
3173*9880d681SAndroid Build Coastguard Worker   else {
3174*9880d681SAndroid Build Coastguard Worker     Offset = MI->getOperand(offsetPos).getImm();
3175*9880d681SAndroid Build Coastguard Worker   }
3176*9880d681SAndroid Build Coastguard Worker 
3177*9880d681SAndroid Build Coastguard Worker   return MI->getOperand(basePos).getReg();
3178*9880d681SAndroid Build Coastguard Worker }
3179*9880d681SAndroid Build Coastguard Worker 
3180*9880d681SAndroid Build Coastguard Worker 
3181*9880d681SAndroid Build Coastguard Worker /// Return the position of the base and offset operands for this instruction.
getBaseAndOffsetPosition(const MachineInstr * MI,unsigned & BasePos,unsigned & OffsetPos) const3182*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::getBaseAndOffsetPosition(const MachineInstr *MI,
3183*9880d681SAndroid Build Coastguard Worker       unsigned &BasePos, unsigned &OffsetPos) const {
3184*9880d681SAndroid Build Coastguard Worker   // Deal with memops first.
3185*9880d681SAndroid Build Coastguard Worker   if (isMemOp(MI)) {
3186*9880d681SAndroid Build Coastguard Worker     assert (MI->getOperand(0).isReg() && MI->getOperand(1).isImm() &&
3187*9880d681SAndroid Build Coastguard Worker             "Bad Memop.");
3188*9880d681SAndroid Build Coastguard Worker     BasePos = 0;
3189*9880d681SAndroid Build Coastguard Worker     OffsetPos = 1;
3190*9880d681SAndroid Build Coastguard Worker   } else if (MI->mayStore()) {
3191*9880d681SAndroid Build Coastguard Worker     BasePos = 0;
3192*9880d681SAndroid Build Coastguard Worker     OffsetPos = 1;
3193*9880d681SAndroid Build Coastguard Worker   } else if (MI->mayLoad()) {
3194*9880d681SAndroid Build Coastguard Worker     BasePos = 1;
3195*9880d681SAndroid Build Coastguard Worker     OffsetPos = 2;
3196*9880d681SAndroid Build Coastguard Worker   } else
3197*9880d681SAndroid Build Coastguard Worker     return false;
3198*9880d681SAndroid Build Coastguard Worker 
3199*9880d681SAndroid Build Coastguard Worker   if (isPredicated(*MI)) {
3200*9880d681SAndroid Build Coastguard Worker     BasePos++;
3201*9880d681SAndroid Build Coastguard Worker     OffsetPos++;
3202*9880d681SAndroid Build Coastguard Worker   }
3203*9880d681SAndroid Build Coastguard Worker   if (isPostIncrement(MI)) {
3204*9880d681SAndroid Build Coastguard Worker     BasePos++;
3205*9880d681SAndroid Build Coastguard Worker     OffsetPos++;
3206*9880d681SAndroid Build Coastguard Worker   }
3207*9880d681SAndroid Build Coastguard Worker 
3208*9880d681SAndroid Build Coastguard Worker   if (!MI->getOperand(BasePos).isReg() || !MI->getOperand(OffsetPos).isImm())
3209*9880d681SAndroid Build Coastguard Worker     return false;
3210*9880d681SAndroid Build Coastguard Worker 
3211*9880d681SAndroid Build Coastguard Worker   return true;
3212*9880d681SAndroid Build Coastguard Worker }
3213*9880d681SAndroid Build Coastguard Worker 
3214*9880d681SAndroid Build Coastguard Worker 
3215*9880d681SAndroid Build Coastguard Worker // Inserts branching instructions in reverse order of their occurence.
3216*9880d681SAndroid Build Coastguard Worker // e.g. jump_t t1 (i1)
3217*9880d681SAndroid Build Coastguard Worker // jump t2        (i2)
3218*9880d681SAndroid Build Coastguard Worker // Jumpers = {i2, i1}
getBranchingInstrs(MachineBasicBlock & MBB) const3219*9880d681SAndroid Build Coastguard Worker SmallVector<MachineInstr*, 2> HexagonInstrInfo::getBranchingInstrs(
3220*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock& MBB) const {
3221*9880d681SAndroid Build Coastguard Worker   SmallVector<MachineInstr*, 2> Jumpers;
3222*9880d681SAndroid Build Coastguard Worker   // If the block has no terminators, it just falls into the block after it.
3223*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::instr_iterator I = MBB.instr_end();
3224*9880d681SAndroid Build Coastguard Worker   if (I == MBB.instr_begin())
3225*9880d681SAndroid Build Coastguard Worker     return Jumpers;
3226*9880d681SAndroid Build Coastguard Worker 
3227*9880d681SAndroid Build Coastguard Worker   // A basic block may looks like this:
3228*9880d681SAndroid Build Coastguard Worker   //
3229*9880d681SAndroid Build Coastguard Worker   //  [   insn
3230*9880d681SAndroid Build Coastguard Worker   //     EH_LABEL
3231*9880d681SAndroid Build Coastguard Worker   //      insn
3232*9880d681SAndroid Build Coastguard Worker   //      insn
3233*9880d681SAndroid Build Coastguard Worker   //      insn
3234*9880d681SAndroid Build Coastguard Worker   //     EH_LABEL
3235*9880d681SAndroid Build Coastguard Worker   //      insn     ]
3236*9880d681SAndroid Build Coastguard Worker   //
3237*9880d681SAndroid Build Coastguard Worker   // It has two succs but does not have a terminator
3238*9880d681SAndroid Build Coastguard Worker   // Don't know how to handle it.
3239*9880d681SAndroid Build Coastguard Worker   do {
3240*9880d681SAndroid Build Coastguard Worker     --I;
3241*9880d681SAndroid Build Coastguard Worker     if (I->isEHLabel())
3242*9880d681SAndroid Build Coastguard Worker       return Jumpers;
3243*9880d681SAndroid Build Coastguard Worker   } while (I != MBB.instr_begin());
3244*9880d681SAndroid Build Coastguard Worker 
3245*9880d681SAndroid Build Coastguard Worker   I = MBB.instr_end();
3246*9880d681SAndroid Build Coastguard Worker   --I;
3247*9880d681SAndroid Build Coastguard Worker 
3248*9880d681SAndroid Build Coastguard Worker   while (I->isDebugValue()) {
3249*9880d681SAndroid Build Coastguard Worker     if (I == MBB.instr_begin())
3250*9880d681SAndroid Build Coastguard Worker       return Jumpers;
3251*9880d681SAndroid Build Coastguard Worker     --I;
3252*9880d681SAndroid Build Coastguard Worker   }
3253*9880d681SAndroid Build Coastguard Worker   if (!isUnpredicatedTerminator(*I))
3254*9880d681SAndroid Build Coastguard Worker     return Jumpers;
3255*9880d681SAndroid Build Coastguard Worker 
3256*9880d681SAndroid Build Coastguard Worker   // Get the last instruction in the block.
3257*9880d681SAndroid Build Coastguard Worker   MachineInstr *LastInst = &*I;
3258*9880d681SAndroid Build Coastguard Worker   Jumpers.push_back(LastInst);
3259*9880d681SAndroid Build Coastguard Worker   MachineInstr *SecondLastInst = nullptr;
3260*9880d681SAndroid Build Coastguard Worker   // Find one more terminator if present.
3261*9880d681SAndroid Build Coastguard Worker   do {
3262*9880d681SAndroid Build Coastguard Worker     if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
3263*9880d681SAndroid Build Coastguard Worker       if (!SecondLastInst) {
3264*9880d681SAndroid Build Coastguard Worker         SecondLastInst = &*I;
3265*9880d681SAndroid Build Coastguard Worker         Jumpers.push_back(SecondLastInst);
3266*9880d681SAndroid Build Coastguard Worker       } else // This is a third branch.
3267*9880d681SAndroid Build Coastguard Worker         return Jumpers;
3268*9880d681SAndroid Build Coastguard Worker     }
3269*9880d681SAndroid Build Coastguard Worker     if (I == MBB.instr_begin())
3270*9880d681SAndroid Build Coastguard Worker       break;
3271*9880d681SAndroid Build Coastguard Worker     --I;
3272*9880d681SAndroid Build Coastguard Worker   } while (true);
3273*9880d681SAndroid Build Coastguard Worker   return Jumpers;
3274*9880d681SAndroid Build Coastguard Worker }
3275*9880d681SAndroid Build Coastguard Worker 
3276*9880d681SAndroid Build Coastguard Worker 
getBaseWithLongOffset(short Opcode) const3277*9880d681SAndroid Build Coastguard Worker short HexagonInstrInfo::getBaseWithLongOffset(short Opcode) const {
3278*9880d681SAndroid Build Coastguard Worker   if (Opcode < 0)
3279*9880d681SAndroid Build Coastguard Worker     return -1;
3280*9880d681SAndroid Build Coastguard Worker   return Hexagon::getBaseWithLongOffset(Opcode);
3281*9880d681SAndroid Build Coastguard Worker }
3282*9880d681SAndroid Build Coastguard Worker 
3283*9880d681SAndroid Build Coastguard Worker 
getBaseWithLongOffset(const MachineInstr * MI) const3284*9880d681SAndroid Build Coastguard Worker short HexagonInstrInfo::getBaseWithLongOffset(const MachineInstr *MI) const {
3285*9880d681SAndroid Build Coastguard Worker   return Hexagon::getBaseWithLongOffset(MI->getOpcode());
3286*9880d681SAndroid Build Coastguard Worker }
3287*9880d681SAndroid Build Coastguard Worker 
3288*9880d681SAndroid Build Coastguard Worker 
getBaseWithRegOffset(const MachineInstr * MI) const3289*9880d681SAndroid Build Coastguard Worker short HexagonInstrInfo::getBaseWithRegOffset(const MachineInstr *MI) const {
3290*9880d681SAndroid Build Coastguard Worker   return Hexagon::getBaseWithRegOffset(MI->getOpcode());
3291*9880d681SAndroid Build Coastguard Worker }
3292*9880d681SAndroid Build Coastguard Worker 
3293*9880d681SAndroid Build Coastguard Worker 
3294*9880d681SAndroid Build Coastguard Worker // Returns Operand Index for the constant extended instruction.
getCExtOpNum(const MachineInstr * MI) const3295*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::getCExtOpNum(const MachineInstr *MI) const {
3296*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI->getDesc().TSFlags;
3297*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask;
3298*9880d681SAndroid Build Coastguard Worker }
3299*9880d681SAndroid Build Coastguard Worker 
3300*9880d681SAndroid Build Coastguard Worker // See if instruction could potentially be a duplex candidate.
3301*9880d681SAndroid Build Coastguard Worker // If so, return its group. Zero otherwise.
getCompoundCandidateGroup(const MachineInstr * MI) const3302*9880d681SAndroid Build Coastguard Worker HexagonII::CompoundGroup HexagonInstrInfo::getCompoundCandidateGroup(
3303*9880d681SAndroid Build Coastguard Worker       const MachineInstr *MI) const {
3304*9880d681SAndroid Build Coastguard Worker   unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
3305*9880d681SAndroid Build Coastguard Worker 
3306*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
3307*9880d681SAndroid Build Coastguard Worker   default:
3308*9880d681SAndroid Build Coastguard Worker     return HexagonII::HCG_None;
3309*9880d681SAndroid Build Coastguard Worker   //
3310*9880d681SAndroid Build Coastguard Worker   // Compound pairs.
3311*9880d681SAndroid Build Coastguard Worker   // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
3312*9880d681SAndroid Build Coastguard Worker   // "Rd16=#U6 ; jump #r9:2"
3313*9880d681SAndroid Build Coastguard Worker   // "Rd16=Rs16 ; jump #r9:2"
3314*9880d681SAndroid Build Coastguard Worker   //
3315*9880d681SAndroid Build Coastguard Worker   case Hexagon::C2_cmpeq:
3316*9880d681SAndroid Build Coastguard Worker   case Hexagon::C2_cmpgt:
3317*9880d681SAndroid Build Coastguard Worker   case Hexagon::C2_cmpgtu:
3318*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3319*9880d681SAndroid Build Coastguard Worker     Src1Reg = MI->getOperand(1).getReg();
3320*9880d681SAndroid Build Coastguard Worker     Src2Reg = MI->getOperand(2).getReg();
3321*9880d681SAndroid Build Coastguard Worker     if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3322*9880d681SAndroid Build Coastguard Worker         (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3323*9880d681SAndroid Build Coastguard Worker         isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg))
3324*9880d681SAndroid Build Coastguard Worker       return HexagonII::HCG_A;
3325*9880d681SAndroid Build Coastguard Worker     break;
3326*9880d681SAndroid Build Coastguard Worker   case Hexagon::C2_cmpeqi:
3327*9880d681SAndroid Build Coastguard Worker   case Hexagon::C2_cmpgti:
3328*9880d681SAndroid Build Coastguard Worker   case Hexagon::C2_cmpgtui:
3329*9880d681SAndroid Build Coastguard Worker     // P0 = cmp.eq(Rs,#u2)
3330*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3331*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(1).getReg();
3332*9880d681SAndroid Build Coastguard Worker     if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3333*9880d681SAndroid Build Coastguard Worker         (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3334*9880d681SAndroid Build Coastguard Worker         isIntRegForSubInst(SrcReg) && MI->getOperand(2).isImm() &&
3335*9880d681SAndroid Build Coastguard Worker         ((isUInt<5>(MI->getOperand(2).getImm())) ||
3336*9880d681SAndroid Build Coastguard Worker          (MI->getOperand(2).getImm() == -1)))
3337*9880d681SAndroid Build Coastguard Worker       return HexagonII::HCG_A;
3338*9880d681SAndroid Build Coastguard Worker     break;
3339*9880d681SAndroid Build Coastguard Worker   case Hexagon::A2_tfr:
3340*9880d681SAndroid Build Coastguard Worker     // Rd = Rs
3341*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3342*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(1).getReg();
3343*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
3344*9880d681SAndroid Build Coastguard Worker       return HexagonII::HCG_A;
3345*9880d681SAndroid Build Coastguard Worker     break;
3346*9880d681SAndroid Build Coastguard Worker   case Hexagon::A2_tfrsi:
3347*9880d681SAndroid Build Coastguard Worker     // Rd = #u6
3348*9880d681SAndroid Build Coastguard Worker     // Do not test for #u6 size since the const is getting extended
3349*9880d681SAndroid Build Coastguard Worker     // regardless and compound could be formed.
3350*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3351*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(DstReg))
3352*9880d681SAndroid Build Coastguard Worker       return HexagonII::HCG_A;
3353*9880d681SAndroid Build Coastguard Worker     break;
3354*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_tstbit_i:
3355*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3356*9880d681SAndroid Build Coastguard Worker     Src1Reg = MI->getOperand(1).getReg();
3357*9880d681SAndroid Build Coastguard Worker     if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3358*9880d681SAndroid Build Coastguard Worker         (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3359*9880d681SAndroid Build Coastguard Worker         MI->getOperand(2).isImm() &&
3360*9880d681SAndroid Build Coastguard Worker         isIntRegForSubInst(Src1Reg) && (MI->getOperand(2).getImm() == 0))
3361*9880d681SAndroid Build Coastguard Worker       return HexagonII::HCG_A;
3362*9880d681SAndroid Build Coastguard Worker     break;
3363*9880d681SAndroid Build Coastguard Worker   // The fact that .new form is used pretty much guarantees
3364*9880d681SAndroid Build Coastguard Worker   // that predicate register will match. Nevertheless,
3365*9880d681SAndroid Build Coastguard Worker   // there could be some false positives without additional
3366*9880d681SAndroid Build Coastguard Worker   // checking.
3367*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumptnew:
3368*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumpfnew:
3369*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumptnewpt:
3370*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumpfnewpt:
3371*9880d681SAndroid Build Coastguard Worker     Src1Reg = MI->getOperand(0).getReg();
3372*9880d681SAndroid Build Coastguard Worker     if (Hexagon::PredRegsRegClass.contains(Src1Reg) &&
3373*9880d681SAndroid Build Coastguard Worker         (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg))
3374*9880d681SAndroid Build Coastguard Worker       return HexagonII::HCG_B;
3375*9880d681SAndroid Build Coastguard Worker     break;
3376*9880d681SAndroid Build Coastguard Worker   // Transfer and jump:
3377*9880d681SAndroid Build Coastguard Worker   // Rd=#U6 ; jump #r9:2
3378*9880d681SAndroid Build Coastguard Worker   // Rd=Rs ; jump #r9:2
3379*9880d681SAndroid Build Coastguard Worker   // Do not test for jump range here.
3380*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jump:
3381*9880d681SAndroid Build Coastguard Worker   case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
3382*9880d681SAndroid Build Coastguard Worker     return HexagonII::HCG_C;
3383*9880d681SAndroid Build Coastguard Worker     break;
3384*9880d681SAndroid Build Coastguard Worker   }
3385*9880d681SAndroid Build Coastguard Worker 
3386*9880d681SAndroid Build Coastguard Worker   return HexagonII::HCG_None;
3387*9880d681SAndroid Build Coastguard Worker }
3388*9880d681SAndroid Build Coastguard Worker 
3389*9880d681SAndroid Build Coastguard Worker 
3390*9880d681SAndroid Build Coastguard Worker // Returns -1 when there is no opcode found.
getCompoundOpcode(const MachineInstr * GA,const MachineInstr * GB) const3391*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::getCompoundOpcode(const MachineInstr *GA,
3392*9880d681SAndroid Build Coastguard Worker       const MachineInstr *GB) const {
3393*9880d681SAndroid Build Coastguard Worker   assert(getCompoundCandidateGroup(GA) == HexagonII::HCG_A);
3394*9880d681SAndroid Build Coastguard Worker   assert(getCompoundCandidateGroup(GB) == HexagonII::HCG_B);
3395*9880d681SAndroid Build Coastguard Worker   if ((GA->getOpcode() != Hexagon::C2_cmpeqi) ||
3396*9880d681SAndroid Build Coastguard Worker       (GB->getOpcode() != Hexagon::J2_jumptnew))
3397*9880d681SAndroid Build Coastguard Worker     return -1;
3398*9880d681SAndroid Build Coastguard Worker   unsigned DestReg = GA->getOperand(0).getReg();
3399*9880d681SAndroid Build Coastguard Worker   if (!GB->readsRegister(DestReg))
3400*9880d681SAndroid Build Coastguard Worker     return -1;
3401*9880d681SAndroid Build Coastguard Worker   if (DestReg == Hexagon::P0)
3402*9880d681SAndroid Build Coastguard Worker     return Hexagon::J4_cmpeqi_tp0_jump_nt;
3403*9880d681SAndroid Build Coastguard Worker   if (DestReg == Hexagon::P1)
3404*9880d681SAndroid Build Coastguard Worker     return Hexagon::J4_cmpeqi_tp1_jump_nt;
3405*9880d681SAndroid Build Coastguard Worker   return -1;
3406*9880d681SAndroid Build Coastguard Worker }
3407*9880d681SAndroid Build Coastguard Worker 
3408*9880d681SAndroid Build Coastguard Worker 
getCondOpcode(int Opc,bool invertPredicate) const3409*9880d681SAndroid Build Coastguard Worker int HexagonInstrInfo::getCondOpcode(int Opc, bool invertPredicate) const {
3410*9880d681SAndroid Build Coastguard Worker   enum Hexagon::PredSense inPredSense;
3411*9880d681SAndroid Build Coastguard Worker   inPredSense = invertPredicate ? Hexagon::PredSense_false :
3412*9880d681SAndroid Build Coastguard Worker                                   Hexagon::PredSense_true;
3413*9880d681SAndroid Build Coastguard Worker   int CondOpcode = Hexagon::getPredOpcode(Opc, inPredSense);
3414*9880d681SAndroid Build Coastguard Worker   if (CondOpcode >= 0) // Valid Conditional opcode/instruction
3415*9880d681SAndroid Build Coastguard Worker     return CondOpcode;
3416*9880d681SAndroid Build Coastguard Worker 
3417*9880d681SAndroid Build Coastguard Worker   // This switch case will be removed once all the instructions have been
3418*9880d681SAndroid Build Coastguard Worker   // modified to use relation maps.
3419*9880d681SAndroid Build Coastguard Worker   switch(Opc) {
3420*9880d681SAndroid Build Coastguard Worker   case Hexagon::TFRI_f:
3421*9880d681SAndroid Build Coastguard Worker     return !invertPredicate ? Hexagon::TFRI_cPt_f :
3422*9880d681SAndroid Build Coastguard Worker                               Hexagon::TFRI_cNotPt_f;
3423*9880d681SAndroid Build Coastguard Worker   }
3424*9880d681SAndroid Build Coastguard Worker 
3425*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Unexpected predicable instruction");
3426*9880d681SAndroid Build Coastguard Worker }
3427*9880d681SAndroid Build Coastguard Worker 
3428*9880d681SAndroid Build Coastguard Worker 
3429*9880d681SAndroid Build Coastguard Worker // Return the cur value instruction for a given store.
getDotCurOp(const MachineInstr * MI) const3430*9880d681SAndroid Build Coastguard Worker int HexagonInstrInfo::getDotCurOp(const MachineInstr* MI) const {
3431*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
3432*9880d681SAndroid Build Coastguard Worker   default: llvm_unreachable("Unknown .cur type");
3433*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vL32b_pi:
3434*9880d681SAndroid Build Coastguard Worker     return Hexagon::V6_vL32b_cur_pi;
3435*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vL32b_ai:
3436*9880d681SAndroid Build Coastguard Worker     return Hexagon::V6_vL32b_cur_ai;
3437*9880d681SAndroid Build Coastguard Worker   //128B
3438*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vL32b_pi_128B:
3439*9880d681SAndroid Build Coastguard Worker     return Hexagon::V6_vL32b_cur_pi_128B;
3440*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vL32b_ai_128B:
3441*9880d681SAndroid Build Coastguard Worker     return Hexagon::V6_vL32b_cur_ai_128B;
3442*9880d681SAndroid Build Coastguard Worker   }
3443*9880d681SAndroid Build Coastguard Worker   return 0;
3444*9880d681SAndroid Build Coastguard Worker }
3445*9880d681SAndroid Build Coastguard Worker 
3446*9880d681SAndroid Build Coastguard Worker 
3447*9880d681SAndroid Build Coastguard Worker 
3448*9880d681SAndroid Build Coastguard Worker // The diagram below shows the steps involved in the conversion of a predicated
3449*9880d681SAndroid Build Coastguard Worker // store instruction to its .new predicated new-value form.
3450*9880d681SAndroid Build Coastguard Worker //
3451*9880d681SAndroid Build Coastguard Worker //               p.new NV store [ if(p0.new)memw(R0+#0)=R2.new ]
3452*9880d681SAndroid Build Coastguard Worker //                ^           ^
3453*9880d681SAndroid Build Coastguard Worker //               /             \ (not OK. it will cause new-value store to be
3454*9880d681SAndroid Build Coastguard Worker //              /               X conditional on p0.new while R2 producer is
3455*9880d681SAndroid Build Coastguard Worker //             /                 \ on p0)
3456*9880d681SAndroid Build Coastguard Worker //            /                   \.
3457*9880d681SAndroid Build Coastguard Worker //     p.new store                 p.old NV store
3458*9880d681SAndroid Build Coastguard Worker // [if(p0.new)memw(R0+#0)=R2]    [if(p0)memw(R0+#0)=R2.new]
3459*9880d681SAndroid Build Coastguard Worker //            ^                  ^
3460*9880d681SAndroid Build Coastguard Worker //             \                /
3461*9880d681SAndroid Build Coastguard Worker //              \              /
3462*9880d681SAndroid Build Coastguard Worker //               \            /
3463*9880d681SAndroid Build Coastguard Worker //                 p.old store
3464*9880d681SAndroid Build Coastguard Worker //             [if (p0)memw(R0+#0)=R2]
3465*9880d681SAndroid Build Coastguard Worker //
3466*9880d681SAndroid Build Coastguard Worker //
3467*9880d681SAndroid Build Coastguard Worker // The following set of instructions further explains the scenario where
3468*9880d681SAndroid Build Coastguard Worker // conditional new-value store becomes invalid when promoted to .new predicate
3469*9880d681SAndroid Build Coastguard Worker // form.
3470*9880d681SAndroid Build Coastguard Worker //
3471*9880d681SAndroid Build Coastguard Worker // { 1) if (p0) r0 = add(r1, r2)
3472*9880d681SAndroid Build Coastguard Worker //   2) p0 = cmp.eq(r3, #0) }
3473*9880d681SAndroid Build Coastguard Worker //
3474*9880d681SAndroid Build Coastguard Worker //   3) if (p0) memb(r1+#0) = r0  --> this instruction can't be grouped with
3475*9880d681SAndroid Build Coastguard Worker // the first two instructions because in instr 1, r0 is conditional on old value
3476*9880d681SAndroid Build Coastguard Worker // of p0 but its use in instr 3 is conditional on p0 modified by instr 2 which
3477*9880d681SAndroid Build Coastguard Worker // is not valid for new-value stores.
3478*9880d681SAndroid Build Coastguard Worker // Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded
3479*9880d681SAndroid Build Coastguard Worker // from the "Conditional Store" list. Because a predicated new value store
3480*9880d681SAndroid Build Coastguard Worker // would NOT be promoted to a double dot new store. See diagram below:
3481*9880d681SAndroid Build Coastguard Worker // This function returns yes for those stores that are predicated but not
3482*9880d681SAndroid Build Coastguard Worker // yet promoted to predicate dot new instructions.
3483*9880d681SAndroid Build Coastguard Worker //
3484*9880d681SAndroid Build Coastguard Worker //                          +---------------------+
3485*9880d681SAndroid Build Coastguard Worker //                    /-----| if (p0) memw(..)=r0 |---------\~
3486*9880d681SAndroid Build Coastguard Worker //                   ||     +---------------------+         ||
3487*9880d681SAndroid Build Coastguard Worker //          promote  ||       /\       /\                   ||  promote
3488*9880d681SAndroid Build Coastguard Worker //                   ||      /||\     /||\                  ||
3489*9880d681SAndroid Build Coastguard Worker //                  \||/    demote     ||                  \||/
3490*9880d681SAndroid Build Coastguard Worker //                   \/       ||       ||                   \/
3491*9880d681SAndroid Build Coastguard Worker //       +-------------------------+   ||   +-------------------------+
3492*9880d681SAndroid Build Coastguard Worker //       | if (p0.new) memw(..)=r0 |   ||   | if (p0) memw(..)=r0.new |
3493*9880d681SAndroid Build Coastguard Worker //       +-------------------------+   ||   +-------------------------+
3494*9880d681SAndroid Build Coastguard Worker //                        ||           ||         ||
3495*9880d681SAndroid Build Coastguard Worker //                        ||         demote      \||/
3496*9880d681SAndroid Build Coastguard Worker //                      promote        ||         \/ NOT possible
3497*9880d681SAndroid Build Coastguard Worker //                        ||           ||         /\~
3498*9880d681SAndroid Build Coastguard Worker //                       \||/          ||        /||\~
3499*9880d681SAndroid Build Coastguard Worker //                        \/           ||         ||
3500*9880d681SAndroid Build Coastguard Worker //                      +-----------------------------+
3501*9880d681SAndroid Build Coastguard Worker //                      | if (p0.new) memw(..)=r0.new |
3502*9880d681SAndroid Build Coastguard Worker //                      +-----------------------------+
3503*9880d681SAndroid Build Coastguard Worker //                           Double Dot New Store
3504*9880d681SAndroid Build Coastguard Worker //
3505*9880d681SAndroid Build Coastguard Worker // Returns the most basic instruction for the .new predicated instructions and
3506*9880d681SAndroid Build Coastguard Worker // new-value stores.
3507*9880d681SAndroid Build Coastguard Worker // For example, all of the following instructions will be converted back to the
3508*9880d681SAndroid Build Coastguard Worker // same instruction:
3509*9880d681SAndroid Build Coastguard Worker // 1) if (p0.new) memw(R0+#0) = R1.new  --->
3510*9880d681SAndroid Build Coastguard Worker // 2) if (p0) memw(R0+#0)= R1.new      -------> if (p0) memw(R0+#0) = R1
3511*9880d681SAndroid Build Coastguard Worker // 3) if (p0.new) memw(R0+#0) = R1      --->
3512*9880d681SAndroid Build Coastguard Worker //
3513*9880d681SAndroid Build Coastguard Worker // To understand the translation of instruction 1 to its original form, consider
3514*9880d681SAndroid Build Coastguard Worker // a packet with 3 instructions.
3515*9880d681SAndroid Build Coastguard Worker // { p0 = cmp.eq(R0,R1)
3516*9880d681SAndroid Build Coastguard Worker //   if (p0.new) R2 = add(R3, R4)
3517*9880d681SAndroid Build Coastguard Worker //   R5 = add (R3, R1)
3518*9880d681SAndroid Build Coastguard Worker // }
3519*9880d681SAndroid Build Coastguard Worker // if (p0) memw(R5+#0) = R2 <--- trying to include it in the previous packet
3520*9880d681SAndroid Build Coastguard Worker //
3521*9880d681SAndroid Build Coastguard Worker // This instruction can be part of the previous packet only if both p0 and R2
3522*9880d681SAndroid Build Coastguard Worker // are promoted to .new values. This promotion happens in steps, first
3523*9880d681SAndroid Build Coastguard Worker // predicate register is promoted to .new and in the next iteration R2 is
3524*9880d681SAndroid Build Coastguard Worker // promoted. Therefore, in case of dependence check failure (due to R5) during
3525*9880d681SAndroid Build Coastguard Worker // next iteration, it should be converted back to its most basic form.
3526*9880d681SAndroid Build Coastguard Worker 
3527*9880d681SAndroid Build Coastguard Worker 
3528*9880d681SAndroid Build Coastguard Worker // Return the new value instruction for a given store.
getDotNewOp(const MachineInstr * MI) const3529*9880d681SAndroid Build Coastguard Worker int HexagonInstrInfo::getDotNewOp(const MachineInstr* MI) const {
3530*9880d681SAndroid Build Coastguard Worker   int NVOpcode = Hexagon::getNewValueOpcode(MI->getOpcode());
3531*9880d681SAndroid Build Coastguard Worker   if (NVOpcode >= 0) // Valid new-value store instruction.
3532*9880d681SAndroid Build Coastguard Worker     return NVOpcode;
3533*9880d681SAndroid Build Coastguard Worker 
3534*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
3535*9880d681SAndroid Build Coastguard Worker   default: llvm_unreachable("Unknown .new type");
3536*9880d681SAndroid Build Coastguard Worker   case Hexagon::S4_storerb_ur:
3537*9880d681SAndroid Build Coastguard Worker     return Hexagon::S4_storerbnew_ur;
3538*9880d681SAndroid Build Coastguard Worker 
3539*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storerb_pci:
3540*9880d681SAndroid Build Coastguard Worker     return Hexagon::S2_storerb_pci;
3541*9880d681SAndroid Build Coastguard Worker 
3542*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storeri_pci:
3543*9880d681SAndroid Build Coastguard Worker     return Hexagon::S2_storeri_pci;
3544*9880d681SAndroid Build Coastguard Worker 
3545*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storerh_pci:
3546*9880d681SAndroid Build Coastguard Worker     return Hexagon::S2_storerh_pci;
3547*9880d681SAndroid Build Coastguard Worker 
3548*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storerd_pci:
3549*9880d681SAndroid Build Coastguard Worker     return Hexagon::S2_storerd_pci;
3550*9880d681SAndroid Build Coastguard Worker 
3551*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storerf_pci:
3552*9880d681SAndroid Build Coastguard Worker     return Hexagon::S2_storerf_pci;
3553*9880d681SAndroid Build Coastguard Worker 
3554*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vS32b_ai:
3555*9880d681SAndroid Build Coastguard Worker     return Hexagon::V6_vS32b_new_ai;
3556*9880d681SAndroid Build Coastguard Worker 
3557*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vS32b_pi:
3558*9880d681SAndroid Build Coastguard Worker     return Hexagon::V6_vS32b_new_pi;
3559*9880d681SAndroid Build Coastguard Worker 
3560*9880d681SAndroid Build Coastguard Worker   // 128B
3561*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vS32b_ai_128B:
3562*9880d681SAndroid Build Coastguard Worker     return Hexagon::V6_vS32b_new_ai_128B;
3563*9880d681SAndroid Build Coastguard Worker 
3564*9880d681SAndroid Build Coastguard Worker   case Hexagon::V6_vS32b_pi_128B:
3565*9880d681SAndroid Build Coastguard Worker     return Hexagon::V6_vS32b_new_pi_128B;
3566*9880d681SAndroid Build Coastguard Worker   }
3567*9880d681SAndroid Build Coastguard Worker   return 0;
3568*9880d681SAndroid Build Coastguard Worker }
3569*9880d681SAndroid Build Coastguard Worker 
3570*9880d681SAndroid Build Coastguard Worker 
3571*9880d681SAndroid Build Coastguard Worker // Returns the opcode to use when converting MI, which is a conditional jump,
3572*9880d681SAndroid Build Coastguard Worker // into a conditional instruction which uses the .new value of the predicate.
3573*9880d681SAndroid Build Coastguard Worker // We also use branch probabilities to add a hint to the jump.
getDotNewPredJumpOp(const MachineInstr * MI,const MachineBranchProbabilityInfo * MBPI) const3574*9880d681SAndroid Build Coastguard Worker int HexagonInstrInfo::getDotNewPredJumpOp(const MachineInstr *MI,
3575*9880d681SAndroid Build Coastguard Worker       const MachineBranchProbabilityInfo *MBPI) const {
3576*9880d681SAndroid Build Coastguard Worker   // We assume that block can have at most two successors.
3577*9880d681SAndroid Build Coastguard Worker   bool taken = false;
3578*9880d681SAndroid Build Coastguard Worker   const MachineBasicBlock *Src = MI->getParent();
3579*9880d681SAndroid Build Coastguard Worker   const MachineOperand *BrTarget = &MI->getOperand(1);
3580*9880d681SAndroid Build Coastguard Worker   const MachineBasicBlock *Dst = BrTarget->getMBB();
3581*9880d681SAndroid Build Coastguard Worker 
3582*9880d681SAndroid Build Coastguard Worker   const BranchProbability Prediction = MBPI->getEdgeProbability(Src, Dst);
3583*9880d681SAndroid Build Coastguard Worker   if (Prediction >= BranchProbability(1,2))
3584*9880d681SAndroid Build Coastguard Worker     taken = true;
3585*9880d681SAndroid Build Coastguard Worker 
3586*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
3587*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumpt:
3588*9880d681SAndroid Build Coastguard Worker     return taken ? Hexagon::J2_jumptnewpt : Hexagon::J2_jumptnew;
3589*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumpf:
3590*9880d681SAndroid Build Coastguard Worker     return taken ? Hexagon::J2_jumpfnewpt : Hexagon::J2_jumpfnew;
3591*9880d681SAndroid Build Coastguard Worker 
3592*9880d681SAndroid Build Coastguard Worker   default:
3593*9880d681SAndroid Build Coastguard Worker     llvm_unreachable("Unexpected jump instruction.");
3594*9880d681SAndroid Build Coastguard Worker   }
3595*9880d681SAndroid Build Coastguard Worker }
3596*9880d681SAndroid Build Coastguard Worker 
3597*9880d681SAndroid Build Coastguard Worker 
3598*9880d681SAndroid Build Coastguard Worker // Return .new predicate version for an instruction.
getDotNewPredOp(const MachineInstr * MI,const MachineBranchProbabilityInfo * MBPI) const3599*9880d681SAndroid Build Coastguard Worker int HexagonInstrInfo::getDotNewPredOp(const MachineInstr *MI,
3600*9880d681SAndroid Build Coastguard Worker       const MachineBranchProbabilityInfo *MBPI) const {
3601*9880d681SAndroid Build Coastguard Worker   int NewOpcode = Hexagon::getPredNewOpcode(MI->getOpcode());
3602*9880d681SAndroid Build Coastguard Worker   if (NewOpcode >= 0) // Valid predicate new instruction
3603*9880d681SAndroid Build Coastguard Worker     return NewOpcode;
3604*9880d681SAndroid Build Coastguard Worker 
3605*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
3606*9880d681SAndroid Build Coastguard Worker   // Condtional Jumps
3607*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumpt:
3608*9880d681SAndroid Build Coastguard Worker   case Hexagon::J2_jumpf:
3609*9880d681SAndroid Build Coastguard Worker     return getDotNewPredJumpOp(MI, MBPI);
3610*9880d681SAndroid Build Coastguard Worker 
3611*9880d681SAndroid Build Coastguard Worker   default:
3612*9880d681SAndroid Build Coastguard Worker     assert(0 && "Unknown .new type");
3613*9880d681SAndroid Build Coastguard Worker   }
3614*9880d681SAndroid Build Coastguard Worker   return 0;
3615*9880d681SAndroid Build Coastguard Worker }
3616*9880d681SAndroid Build Coastguard Worker 
3617*9880d681SAndroid Build Coastguard Worker 
getDotOldOp(const int opc) const3618*9880d681SAndroid Build Coastguard Worker int HexagonInstrInfo::getDotOldOp(const int opc) const {
3619*9880d681SAndroid Build Coastguard Worker   int NewOp = opc;
3620*9880d681SAndroid Build Coastguard Worker   if (isPredicated(NewOp) && isPredicatedNew(NewOp)) { // Get predicate old form
3621*9880d681SAndroid Build Coastguard Worker     NewOp = Hexagon::getPredOldOpcode(NewOp);
3622*9880d681SAndroid Build Coastguard Worker     assert(NewOp >= 0 &&
3623*9880d681SAndroid Build Coastguard Worker            "Couldn't change predicate new instruction to its old form.");
3624*9880d681SAndroid Build Coastguard Worker   }
3625*9880d681SAndroid Build Coastguard Worker 
3626*9880d681SAndroid Build Coastguard Worker   if (isNewValueStore(NewOp)) { // Convert into non-new-value format
3627*9880d681SAndroid Build Coastguard Worker     NewOp = Hexagon::getNonNVStore(NewOp);
3628*9880d681SAndroid Build Coastguard Worker     assert(NewOp >= 0 && "Couldn't change new-value store to its old form.");
3629*9880d681SAndroid Build Coastguard Worker   }
3630*9880d681SAndroid Build Coastguard Worker   return NewOp;
3631*9880d681SAndroid Build Coastguard Worker }
3632*9880d681SAndroid Build Coastguard Worker 
3633*9880d681SAndroid Build Coastguard Worker 
3634*9880d681SAndroid Build Coastguard Worker // See if instruction could potentially be a duplex candidate.
3635*9880d681SAndroid Build Coastguard Worker // If so, return its group. Zero otherwise.
getDuplexCandidateGroup(const MachineInstr * MI) const3636*9880d681SAndroid Build Coastguard Worker HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup(
3637*9880d681SAndroid Build Coastguard Worker       const MachineInstr *MI) const {
3638*9880d681SAndroid Build Coastguard Worker   unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
3639*9880d681SAndroid Build Coastguard Worker   auto &HRI = getRegisterInfo();
3640*9880d681SAndroid Build Coastguard Worker 
3641*9880d681SAndroid Build Coastguard Worker   switch (MI->getOpcode()) {
3642*9880d681SAndroid Build Coastguard Worker   default:
3643*9880d681SAndroid Build Coastguard Worker     return HexagonII::HSIG_None;
3644*9880d681SAndroid Build Coastguard Worker   //
3645*9880d681SAndroid Build Coastguard Worker   // Group L1:
3646*9880d681SAndroid Build Coastguard Worker   //
3647*9880d681SAndroid Build Coastguard Worker   // Rd = memw(Rs+#u4:2)
3648*9880d681SAndroid Build Coastguard Worker   // Rd = memub(Rs+#u4:0)
3649*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadri_io:
3650*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3651*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(1).getReg();
3652*9880d681SAndroid Build Coastguard Worker     // Special case this one from Group L2.
3653*9880d681SAndroid Build Coastguard Worker     // Rd = memw(r29+#u5:2)
3654*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(DstReg)) {
3655*9880d681SAndroid Build Coastguard Worker       if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
3656*9880d681SAndroid Build Coastguard Worker           HRI.getStackRegister() == SrcReg &&
3657*9880d681SAndroid Build Coastguard Worker           MI->getOperand(2).isImm() &&
3658*9880d681SAndroid Build Coastguard Worker           isShiftedUInt<5,2>(MI->getOperand(2).getImm()))
3659*9880d681SAndroid Build Coastguard Worker         return HexagonII::HSIG_L2;
3660*9880d681SAndroid Build Coastguard Worker       // Rd = memw(Rs+#u4:2)
3661*9880d681SAndroid Build Coastguard Worker       if (isIntRegForSubInst(SrcReg) &&
3662*9880d681SAndroid Build Coastguard Worker           (MI->getOperand(2).isImm() &&
3663*9880d681SAndroid Build Coastguard Worker           isShiftedUInt<4,2>(MI->getOperand(2).getImm())))
3664*9880d681SAndroid Build Coastguard Worker         return HexagonII::HSIG_L1;
3665*9880d681SAndroid Build Coastguard Worker     }
3666*9880d681SAndroid Build Coastguard Worker     break;
3667*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrub_io:
3668*9880d681SAndroid Build Coastguard Worker     // Rd = memub(Rs+#u4:0)
3669*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3670*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(1).getReg();
3671*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
3672*9880d681SAndroid Build Coastguard Worker         MI->getOperand(2).isImm() && isUInt<4>(MI->getOperand(2).getImm()))
3673*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_L1;
3674*9880d681SAndroid Build Coastguard Worker     break;
3675*9880d681SAndroid Build Coastguard Worker   //
3676*9880d681SAndroid Build Coastguard Worker   // Group L2:
3677*9880d681SAndroid Build Coastguard Worker   //
3678*9880d681SAndroid Build Coastguard Worker   // Rd = memh/memuh(Rs+#u3:1)
3679*9880d681SAndroid Build Coastguard Worker   // Rd = memb(Rs+#u3:0)
3680*9880d681SAndroid Build Coastguard Worker   // Rd = memw(r29+#u5:2) - Handled above.
3681*9880d681SAndroid Build Coastguard Worker   // Rdd = memd(r29+#u5:3)
3682*9880d681SAndroid Build Coastguard Worker   // deallocframe
3683*9880d681SAndroid Build Coastguard Worker   // [if ([!]p0[.new])] dealloc_return
3684*9880d681SAndroid Build Coastguard Worker   // [if ([!]p0[.new])] jumpr r31
3685*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrh_io:
3686*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadruh_io:
3687*9880d681SAndroid Build Coastguard Worker     // Rd = memh/memuh(Rs+#u3:1)
3688*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3689*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(1).getReg();
3690*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
3691*9880d681SAndroid Build Coastguard Worker         MI->getOperand(2).isImm() &&
3692*9880d681SAndroid Build Coastguard Worker         isShiftedUInt<3,1>(MI->getOperand(2).getImm()))
3693*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_L2;
3694*9880d681SAndroid Build Coastguard Worker     break;
3695*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrb_io:
3696*9880d681SAndroid Build Coastguard Worker     // Rd = memb(Rs+#u3:0)
3697*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3698*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(1).getReg();
3699*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
3700*9880d681SAndroid Build Coastguard Worker         MI->getOperand(2).isImm() &&
3701*9880d681SAndroid Build Coastguard Worker         isUInt<3>(MI->getOperand(2).getImm()))
3702*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_L2;
3703*9880d681SAndroid Build Coastguard Worker     break;
3704*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_loadrd_io:
3705*9880d681SAndroid Build Coastguard Worker     // Rdd = memd(r29+#u5:3)
3706*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3707*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(1).getReg();
3708*9880d681SAndroid Build Coastguard Worker     if (isDblRegForSubInst(DstReg, HRI) &&
3709*9880d681SAndroid Build Coastguard Worker         Hexagon::IntRegsRegClass.contains(SrcReg) &&
3710*9880d681SAndroid Build Coastguard Worker         HRI.getStackRegister() == SrcReg &&
3711*9880d681SAndroid Build Coastguard Worker         MI->getOperand(2).isImm() &&
3712*9880d681SAndroid Build Coastguard Worker         isShiftedUInt<5,3>(MI->getOperand(2).getImm()))
3713*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_L2;
3714*9880d681SAndroid Build Coastguard Worker     break;
3715*9880d681SAndroid Build Coastguard Worker   // dealloc_return is not documented in Hexagon Manual, but marked
3716*9880d681SAndroid Build Coastguard Worker   // with A_SUBINSN attribute in iset_v4classic.py.
3717*9880d681SAndroid Build Coastguard Worker   case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
3718*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return:
3719*9880d681SAndroid Build Coastguard Worker   case Hexagon::L2_deallocframe:
3720*9880d681SAndroid Build Coastguard Worker     return HexagonII::HSIG_L2;
3721*9880d681SAndroid Build Coastguard Worker   case Hexagon::EH_RETURN_JMPR:
3722*9880d681SAndroid Build Coastguard Worker   case Hexagon::JMPret :
3723*9880d681SAndroid Build Coastguard Worker     // jumpr r31
3724*9880d681SAndroid Build Coastguard Worker     // Actual form JMPR %PC<imp-def>, %R31<imp-use>, %R0<imp-use,internal>.
3725*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3726*9880d681SAndroid Build Coastguard Worker     if (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg))
3727*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_L2;
3728*9880d681SAndroid Build Coastguard Worker     break;
3729*9880d681SAndroid Build Coastguard Worker   case Hexagon::JMPrett:
3730*9880d681SAndroid Build Coastguard Worker   case Hexagon::JMPretf:
3731*9880d681SAndroid Build Coastguard Worker   case Hexagon::JMPrettnewpt:
3732*9880d681SAndroid Build Coastguard Worker   case Hexagon::JMPretfnewpt :
3733*9880d681SAndroid Build Coastguard Worker   case Hexagon::JMPrettnew :
3734*9880d681SAndroid Build Coastguard Worker   case Hexagon::JMPretfnew :
3735*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(1).getReg();
3736*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(0).getReg();
3737*9880d681SAndroid Build Coastguard Worker     // [if ([!]p0[.new])] jumpr r31
3738*9880d681SAndroid Build Coastguard Worker     if ((Hexagon::PredRegsRegClass.contains(SrcReg) &&
3739*9880d681SAndroid Build Coastguard Worker         (Hexagon::P0 == SrcReg)) &&
3740*9880d681SAndroid Build Coastguard Worker         (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg)))
3741*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_L2;
3742*9880d681SAndroid Build Coastguard Worker      break;
3743*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_t :
3744*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_f :
3745*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_tnew_pnt :
3746*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_fnew_pnt :
3747*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_tnew_pt :
3748*9880d681SAndroid Build Coastguard Worker   case Hexagon::L4_return_fnew_pt :
3749*9880d681SAndroid Build Coastguard Worker     // [if ([!]p0[.new])] dealloc_return
3750*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(0).getReg();
3751*9880d681SAndroid Build Coastguard Worker     if (Hexagon::PredRegsRegClass.contains(SrcReg) && (Hexagon::P0 == SrcReg))
3752*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_L2;
3753*9880d681SAndroid Build Coastguard Worker     break;
3754*9880d681SAndroid Build Coastguard Worker   //
3755*9880d681SAndroid Build Coastguard Worker   // Group S1:
3756*9880d681SAndroid Build Coastguard Worker   //
3757*9880d681SAndroid Build Coastguard Worker   // memw(Rs+#u4:2) = Rt
3758*9880d681SAndroid Build Coastguard Worker   // memb(Rs+#u4:0) = Rt
3759*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storeri_io:
3760*9880d681SAndroid Build Coastguard Worker     // Special case this one from Group S2.
3761*9880d681SAndroid Build Coastguard Worker     // memw(r29+#u5:2) = Rt
3762*9880d681SAndroid Build Coastguard Worker     Src1Reg = MI->getOperand(0).getReg();
3763*9880d681SAndroid Build Coastguard Worker     Src2Reg = MI->getOperand(2).getReg();
3764*9880d681SAndroid Build Coastguard Worker     if (Hexagon::IntRegsRegClass.contains(Src1Reg) &&
3765*9880d681SAndroid Build Coastguard Worker         isIntRegForSubInst(Src2Reg) &&
3766*9880d681SAndroid Build Coastguard Worker         HRI.getStackRegister() == Src1Reg && MI->getOperand(1).isImm() &&
3767*9880d681SAndroid Build Coastguard Worker         isShiftedUInt<5,2>(MI->getOperand(1).getImm()))
3768*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_S2;
3769*9880d681SAndroid Build Coastguard Worker     // memw(Rs+#u4:2) = Rt
3770*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
3771*9880d681SAndroid Build Coastguard Worker         MI->getOperand(1).isImm() &&
3772*9880d681SAndroid Build Coastguard Worker         isShiftedUInt<4,2>(MI->getOperand(1).getImm()))
3773*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_S1;
3774*9880d681SAndroid Build Coastguard Worker     break;
3775*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storerb_io:
3776*9880d681SAndroid Build Coastguard Worker     // memb(Rs+#u4:0) = Rt
3777*9880d681SAndroid Build Coastguard Worker     Src1Reg = MI->getOperand(0).getReg();
3778*9880d681SAndroid Build Coastguard Worker     Src2Reg = MI->getOperand(2).getReg();
3779*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
3780*9880d681SAndroid Build Coastguard Worker         MI->getOperand(1).isImm() && isUInt<4>(MI->getOperand(1).getImm()))
3781*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_S1;
3782*9880d681SAndroid Build Coastguard Worker     break;
3783*9880d681SAndroid Build Coastguard Worker   //
3784*9880d681SAndroid Build Coastguard Worker   // Group S2:
3785*9880d681SAndroid Build Coastguard Worker   //
3786*9880d681SAndroid Build Coastguard Worker   // memh(Rs+#u3:1) = Rt
3787*9880d681SAndroid Build Coastguard Worker   // memw(r29+#u5:2) = Rt
3788*9880d681SAndroid Build Coastguard Worker   // memd(r29+#s6:3) = Rtt
3789*9880d681SAndroid Build Coastguard Worker   // memw(Rs+#u4:2) = #U1
3790*9880d681SAndroid Build Coastguard Worker   // memb(Rs+#u4) = #U1
3791*9880d681SAndroid Build Coastguard Worker   // allocframe(#u5:3)
3792*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storerh_io:
3793*9880d681SAndroid Build Coastguard Worker     // memh(Rs+#u3:1) = Rt
3794*9880d681SAndroid Build Coastguard Worker     Src1Reg = MI->getOperand(0).getReg();
3795*9880d681SAndroid Build Coastguard Worker     Src2Reg = MI->getOperand(2).getReg();
3796*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
3797*9880d681SAndroid Build Coastguard Worker         MI->getOperand(1).isImm() &&
3798*9880d681SAndroid Build Coastguard Worker         isShiftedUInt<3,1>(MI->getOperand(1).getImm()))
3799*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_S1;
3800*9880d681SAndroid Build Coastguard Worker     break;
3801*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_storerd_io:
3802*9880d681SAndroid Build Coastguard Worker     // memd(r29+#s6:3) = Rtt
3803*9880d681SAndroid Build Coastguard Worker     Src1Reg = MI->getOperand(0).getReg();
3804*9880d681SAndroid Build Coastguard Worker     Src2Reg = MI->getOperand(2).getReg();
3805*9880d681SAndroid Build Coastguard Worker     if (isDblRegForSubInst(Src2Reg, HRI) &&
3806*9880d681SAndroid Build Coastguard Worker         Hexagon::IntRegsRegClass.contains(Src1Reg) &&
3807*9880d681SAndroid Build Coastguard Worker         HRI.getStackRegister() == Src1Reg && MI->getOperand(1).isImm() &&
3808*9880d681SAndroid Build Coastguard Worker         isShiftedInt<6,3>(MI->getOperand(1).getImm()))
3809*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_S2;
3810*9880d681SAndroid Build Coastguard Worker     break;
3811*9880d681SAndroid Build Coastguard Worker   case Hexagon::S4_storeiri_io:
3812*9880d681SAndroid Build Coastguard Worker     // memw(Rs+#u4:2) = #U1
3813*9880d681SAndroid Build Coastguard Worker     Src1Reg = MI->getOperand(0).getReg();
3814*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(Src1Reg) && MI->getOperand(1).isImm() &&
3815*9880d681SAndroid Build Coastguard Worker         isShiftedUInt<4,2>(MI->getOperand(1).getImm()) &&
3816*9880d681SAndroid Build Coastguard Worker         MI->getOperand(2).isImm() && isUInt<1>(MI->getOperand(2).getImm()))
3817*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_S2;
3818*9880d681SAndroid Build Coastguard Worker     break;
3819*9880d681SAndroid Build Coastguard Worker   case Hexagon::S4_storeirb_io:
3820*9880d681SAndroid Build Coastguard Worker     // memb(Rs+#u4) = #U1
3821*9880d681SAndroid Build Coastguard Worker     Src1Reg = MI->getOperand(0).getReg();
3822*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(Src1Reg) &&
3823*9880d681SAndroid Build Coastguard Worker         MI->getOperand(1).isImm() && isUInt<4>(MI->getOperand(1).getImm()) &&
3824*9880d681SAndroid Build Coastguard Worker         MI->getOperand(2).isImm() && isUInt<1>(MI->getOperand(2).getImm()))
3825*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_S2;
3826*9880d681SAndroid Build Coastguard Worker     break;
3827*9880d681SAndroid Build Coastguard Worker   case Hexagon::S2_allocframe:
3828*9880d681SAndroid Build Coastguard Worker     if (MI->getOperand(0).isImm() &&
3829*9880d681SAndroid Build Coastguard Worker         isShiftedUInt<5,3>(MI->getOperand(0).getImm()))
3830*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_S1;
3831*9880d681SAndroid Build Coastguard Worker     break;
3832*9880d681SAndroid Build Coastguard Worker   //
3833*9880d681SAndroid Build Coastguard Worker   // Group A:
3834*9880d681SAndroid Build Coastguard Worker   //
3835*9880d681SAndroid Build Coastguard Worker   // Rx = add(Rx,#s7)
3836*9880d681SAndroid Build Coastguard Worker   // Rd = Rs
3837*9880d681SAndroid Build Coastguard Worker   // Rd = #u6
3838*9880d681SAndroid Build Coastguard Worker   // Rd = #-1
3839*9880d681SAndroid Build Coastguard Worker   // if ([!]P0[.new]) Rd = #0
3840*9880d681SAndroid Build Coastguard Worker   // Rd = add(r29,#u6:2)
3841*9880d681SAndroid Build Coastguard Worker   // Rx = add(Rx,Rs)
3842*9880d681SAndroid Build Coastguard Worker   // P0 = cmp.eq(Rs,#u2)
3843*9880d681SAndroid Build Coastguard Worker   // Rdd = combine(#0,Rs)
3844*9880d681SAndroid Build Coastguard Worker   // Rdd = combine(Rs,#0)
3845*9880d681SAndroid Build Coastguard Worker   // Rdd = combine(#u2,#U2)
3846*9880d681SAndroid Build Coastguard Worker   // Rd = add(Rs,#1)
3847*9880d681SAndroid Build Coastguard Worker   // Rd = add(Rs,#-1)
3848*9880d681SAndroid Build Coastguard Worker   // Rd = sxth/sxtb/zxtb/zxth(Rs)
3849*9880d681SAndroid Build Coastguard Worker   // Rd = and(Rs,#1)
3850*9880d681SAndroid Build Coastguard Worker   case Hexagon::A2_addi:
3851*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3852*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(1).getReg();
3853*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(DstReg)) {
3854*9880d681SAndroid Build Coastguard Worker       // Rd = add(r29,#u6:2)
3855*9880d681SAndroid Build Coastguard Worker       if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
3856*9880d681SAndroid Build Coastguard Worker         HRI.getStackRegister() == SrcReg && MI->getOperand(2).isImm() &&
3857*9880d681SAndroid Build Coastguard Worker         isShiftedUInt<6,2>(MI->getOperand(2).getImm()))
3858*9880d681SAndroid Build Coastguard Worker         return HexagonII::HSIG_A;
3859*9880d681SAndroid Build Coastguard Worker       // Rx = add(Rx,#s7)
3860*9880d681SAndroid Build Coastguard Worker       if ((DstReg == SrcReg) && MI->getOperand(2).isImm() &&
3861*9880d681SAndroid Build Coastguard Worker           isInt<7>(MI->getOperand(2).getImm()))
3862*9880d681SAndroid Build Coastguard Worker         return HexagonII::HSIG_A;
3863*9880d681SAndroid Build Coastguard Worker       // Rd = add(Rs,#1)
3864*9880d681SAndroid Build Coastguard Worker       // Rd = add(Rs,#-1)
3865*9880d681SAndroid Build Coastguard Worker       if (isIntRegForSubInst(SrcReg) && MI->getOperand(2).isImm() &&
3866*9880d681SAndroid Build Coastguard Worker           ((MI->getOperand(2).getImm() == 1) ||
3867*9880d681SAndroid Build Coastguard Worker           (MI->getOperand(2).getImm() == -1)))
3868*9880d681SAndroid Build Coastguard Worker         return HexagonII::HSIG_A;
3869*9880d681SAndroid Build Coastguard Worker     }
3870*9880d681SAndroid Build Coastguard Worker     break;
3871*9880d681SAndroid Build Coastguard Worker   case Hexagon::A2_add:
3872*9880d681SAndroid Build Coastguard Worker     // Rx = add(Rx,Rs)
3873*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3874*9880d681SAndroid Build Coastguard Worker     Src1Reg = MI->getOperand(1).getReg();
3875*9880d681SAndroid Build Coastguard Worker     Src2Reg = MI->getOperand(2).getReg();
3876*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&
3877*9880d681SAndroid Build Coastguard Worker         isIntRegForSubInst(Src2Reg))
3878*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_A;
3879*9880d681SAndroid Build Coastguard Worker     break;
3880*9880d681SAndroid Build Coastguard Worker   case Hexagon::A2_andir:
3881*9880d681SAndroid Build Coastguard Worker     // Same as zxtb.
3882*9880d681SAndroid Build Coastguard Worker     // Rd16=and(Rs16,#255)
3883*9880d681SAndroid Build Coastguard Worker     // Rd16=and(Rs16,#1)
3884*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3885*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(1).getReg();
3886*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
3887*9880d681SAndroid Build Coastguard Worker         MI->getOperand(2).isImm() &&
3888*9880d681SAndroid Build Coastguard Worker         ((MI->getOperand(2).getImm() == 1) ||
3889*9880d681SAndroid Build Coastguard Worker         (MI->getOperand(2).getImm() == 255)))
3890*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_A;
3891*9880d681SAndroid Build Coastguard Worker     break;
3892*9880d681SAndroid Build Coastguard Worker   case Hexagon::A2_tfr:
3893*9880d681SAndroid Build Coastguard Worker     // Rd = Rs
3894*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3895*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(1).getReg();
3896*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
3897*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_A;
3898*9880d681SAndroid Build Coastguard Worker     break;
3899*9880d681SAndroid Build Coastguard Worker   case Hexagon::A2_tfrsi:
3900*9880d681SAndroid Build Coastguard Worker     // Rd = #u6
3901*9880d681SAndroid Build Coastguard Worker     // Do not test for #u6 size since the const is getting extended
3902*9880d681SAndroid Build Coastguard Worker     // regardless and compound could be formed.
3903*9880d681SAndroid Build Coastguard Worker     // Rd = #-1
3904*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3905*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(DstReg))
3906*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_A;
3907*9880d681SAndroid Build Coastguard Worker     break;
3908*9880d681SAndroid Build Coastguard Worker   case Hexagon::C2_cmoveit:
3909*9880d681SAndroid Build Coastguard Worker   case Hexagon::C2_cmovenewit:
3910*9880d681SAndroid Build Coastguard Worker   case Hexagon::C2_cmoveif:
3911*9880d681SAndroid Build Coastguard Worker   case Hexagon::C2_cmovenewif:
3912*9880d681SAndroid Build Coastguard Worker     // if ([!]P0[.new]) Rd = #0
3913*9880d681SAndroid Build Coastguard Worker     // Actual form:
3914*9880d681SAndroid Build Coastguard Worker     // %R16<def> = C2_cmovenewit %P0<internal>, 0, %R16<imp-use,undef>;
3915*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3916*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(1).getReg();
3917*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(DstReg) &&
3918*9880d681SAndroid Build Coastguard Worker         Hexagon::PredRegsRegClass.contains(SrcReg) && Hexagon::P0 == SrcReg &&
3919*9880d681SAndroid Build Coastguard Worker         MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0)
3920*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_A;
3921*9880d681SAndroid Build Coastguard Worker     break;
3922*9880d681SAndroid Build Coastguard Worker   case Hexagon::C2_cmpeqi:
3923*9880d681SAndroid Build Coastguard Worker     // P0 = cmp.eq(Rs,#u2)
3924*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3925*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(1).getReg();
3926*9880d681SAndroid Build Coastguard Worker     if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3927*9880d681SAndroid Build Coastguard Worker         Hexagon::P0 == DstReg && isIntRegForSubInst(SrcReg) &&
3928*9880d681SAndroid Build Coastguard Worker         MI->getOperand(2).isImm() && isUInt<2>(MI->getOperand(2).getImm()))
3929*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_A;
3930*9880d681SAndroid Build Coastguard Worker     break;
3931*9880d681SAndroid Build Coastguard Worker   case Hexagon::A2_combineii:
3932*9880d681SAndroid Build Coastguard Worker   case Hexagon::A4_combineii:
3933*9880d681SAndroid Build Coastguard Worker     // Rdd = combine(#u2,#U2)
3934*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3935*9880d681SAndroid Build Coastguard Worker     if (isDblRegForSubInst(DstReg, HRI) &&
3936*9880d681SAndroid Build Coastguard Worker         ((MI->getOperand(1).isImm() && isUInt<2>(MI->getOperand(1).getImm())) ||
3937*9880d681SAndroid Build Coastguard Worker         (MI->getOperand(1).isGlobal() &&
3938*9880d681SAndroid Build Coastguard Worker         isUInt<2>(MI->getOperand(1).getOffset()))) &&
3939*9880d681SAndroid Build Coastguard Worker         ((MI->getOperand(2).isImm() && isUInt<2>(MI->getOperand(2).getImm())) ||
3940*9880d681SAndroid Build Coastguard Worker         (MI->getOperand(2).isGlobal() &&
3941*9880d681SAndroid Build Coastguard Worker         isUInt<2>(MI->getOperand(2).getOffset()))))
3942*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_A;
3943*9880d681SAndroid Build Coastguard Worker     break;
3944*9880d681SAndroid Build Coastguard Worker   case Hexagon::A4_combineri:
3945*9880d681SAndroid Build Coastguard Worker     // Rdd = combine(Rs,#0)
3946*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3947*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(1).getReg();
3948*9880d681SAndroid Build Coastguard Worker     if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&
3949*9880d681SAndroid Build Coastguard Worker         ((MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0) ||
3950*9880d681SAndroid Build Coastguard Worker         (MI->getOperand(2).isGlobal() && MI->getOperand(2).getOffset() == 0)))
3951*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_A;
3952*9880d681SAndroid Build Coastguard Worker     break;
3953*9880d681SAndroid Build Coastguard Worker   case Hexagon::A4_combineir:
3954*9880d681SAndroid Build Coastguard Worker     // Rdd = combine(#0,Rs)
3955*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3956*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(2).getReg();
3957*9880d681SAndroid Build Coastguard Worker     if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&
3958*9880d681SAndroid Build Coastguard Worker         ((MI->getOperand(1).isImm() && MI->getOperand(1).getImm() == 0) ||
3959*9880d681SAndroid Build Coastguard Worker         (MI->getOperand(1).isGlobal() && MI->getOperand(1).getOffset() == 0)))
3960*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_A;
3961*9880d681SAndroid Build Coastguard Worker     break;
3962*9880d681SAndroid Build Coastguard Worker   case Hexagon::A2_sxtb:
3963*9880d681SAndroid Build Coastguard Worker   case Hexagon::A2_sxth:
3964*9880d681SAndroid Build Coastguard Worker   case Hexagon::A2_zxtb:
3965*9880d681SAndroid Build Coastguard Worker   case Hexagon::A2_zxth:
3966*9880d681SAndroid Build Coastguard Worker     // Rd = sxth/sxtb/zxtb/zxth(Rs)
3967*9880d681SAndroid Build Coastguard Worker     DstReg = MI->getOperand(0).getReg();
3968*9880d681SAndroid Build Coastguard Worker     SrcReg = MI->getOperand(1).getReg();
3969*9880d681SAndroid Build Coastguard Worker     if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
3970*9880d681SAndroid Build Coastguard Worker       return HexagonII::HSIG_A;
3971*9880d681SAndroid Build Coastguard Worker     break;
3972*9880d681SAndroid Build Coastguard Worker   }
3973*9880d681SAndroid Build Coastguard Worker 
3974*9880d681SAndroid Build Coastguard Worker   return HexagonII::HSIG_None;
3975*9880d681SAndroid Build Coastguard Worker }
3976*9880d681SAndroid Build Coastguard Worker 
3977*9880d681SAndroid Build Coastguard Worker 
getEquivalentHWInstr(const MachineInstr * MI) const3978*9880d681SAndroid Build Coastguard Worker short HexagonInstrInfo::getEquivalentHWInstr(const MachineInstr *MI) const {
3979*9880d681SAndroid Build Coastguard Worker   return Hexagon::getRealHWInstr(MI->getOpcode(), Hexagon::InstrType_Real);
3980*9880d681SAndroid Build Coastguard Worker }
3981*9880d681SAndroid Build Coastguard Worker 
3982*9880d681SAndroid Build Coastguard Worker 
3983*9880d681SAndroid Build Coastguard Worker // Return first non-debug instruction in the basic block.
getFirstNonDbgInst(MachineBasicBlock * BB) const3984*9880d681SAndroid Build Coastguard Worker MachineInstr *HexagonInstrInfo::getFirstNonDbgInst(MachineBasicBlock *BB)
3985*9880d681SAndroid Build Coastguard Worker       const {
3986*9880d681SAndroid Build Coastguard Worker   for (auto MII = BB->instr_begin(), End = BB->instr_end(); MII != End; MII++) {
3987*9880d681SAndroid Build Coastguard Worker     MachineInstr *MI = &*MII;
3988*9880d681SAndroid Build Coastguard Worker     if (MI->isDebugValue())
3989*9880d681SAndroid Build Coastguard Worker       continue;
3990*9880d681SAndroid Build Coastguard Worker     return MI;
3991*9880d681SAndroid Build Coastguard Worker   }
3992*9880d681SAndroid Build Coastguard Worker   return nullptr;
3993*9880d681SAndroid Build Coastguard Worker }
3994*9880d681SAndroid Build Coastguard Worker 
3995*9880d681SAndroid Build Coastguard Worker 
getInstrTimingClassLatency(const InstrItineraryData * ItinData,const MachineInstr * MI) const3996*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::getInstrTimingClassLatency(
3997*9880d681SAndroid Build Coastguard Worker       const InstrItineraryData *ItinData, const MachineInstr *MI) const {
3998*9880d681SAndroid Build Coastguard Worker   // Default to one cycle for no itinerary. However, an "empty" itinerary may
3999*9880d681SAndroid Build Coastguard Worker   // still have a MinLatency property, which getStageLatency checks.
4000*9880d681SAndroid Build Coastguard Worker   if (!ItinData)
4001*9880d681SAndroid Build Coastguard Worker     return getInstrLatency(ItinData, *MI);
4002*9880d681SAndroid Build Coastguard Worker 
4003*9880d681SAndroid Build Coastguard Worker   // Get the latency embedded in the itinerary. If we're not using timing class
4004*9880d681SAndroid Build Coastguard Worker   // latencies or if we using BSB scheduling, then restrict the maximum latency
4005*9880d681SAndroid Build Coastguard Worker   // to 1 (that is, either 0 or 1).
4006*9880d681SAndroid Build Coastguard Worker   if (MI->isTransient())
4007*9880d681SAndroid Build Coastguard Worker     return 0;
4008*9880d681SAndroid Build Coastguard Worker   unsigned Latency = ItinData->getStageLatency(MI->getDesc().getSchedClass());
4009*9880d681SAndroid Build Coastguard Worker   if (!EnableTimingClassLatency ||
4010*9880d681SAndroid Build Coastguard Worker       MI->getParent()->getParent()->getSubtarget<HexagonSubtarget>().
4011*9880d681SAndroid Build Coastguard Worker       useBSBScheduling())
4012*9880d681SAndroid Build Coastguard Worker     if (Latency > 1)
4013*9880d681SAndroid Build Coastguard Worker       Latency = 1;
4014*9880d681SAndroid Build Coastguard Worker   return Latency;
4015*9880d681SAndroid Build Coastguard Worker }
4016*9880d681SAndroid Build Coastguard Worker 
4017*9880d681SAndroid Build Coastguard Worker 
4018*9880d681SAndroid Build Coastguard Worker // inverts the predication logic.
4019*9880d681SAndroid Build Coastguard Worker // p -> NotP
4020*9880d681SAndroid Build Coastguard Worker // NotP -> P
getInvertedPredSense(SmallVectorImpl<MachineOperand> & Cond) const4021*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::getInvertedPredSense(
4022*9880d681SAndroid Build Coastguard Worker       SmallVectorImpl<MachineOperand> &Cond) const {
4023*9880d681SAndroid Build Coastguard Worker   if (Cond.empty())
4024*9880d681SAndroid Build Coastguard Worker     return false;
4025*9880d681SAndroid Build Coastguard Worker   unsigned Opc = getInvertedPredicatedOpcode(Cond[0].getImm());
4026*9880d681SAndroid Build Coastguard Worker   Cond[0].setImm(Opc);
4027*9880d681SAndroid Build Coastguard Worker   return true;
4028*9880d681SAndroid Build Coastguard Worker }
4029*9880d681SAndroid Build Coastguard Worker 
4030*9880d681SAndroid Build Coastguard Worker 
getInvertedPredicatedOpcode(const int Opc) const4031*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const {
4032*9880d681SAndroid Build Coastguard Worker   int InvPredOpcode;
4033*9880d681SAndroid Build Coastguard Worker   InvPredOpcode = isPredicatedTrue(Opc) ? Hexagon::getFalsePredOpcode(Opc)
4034*9880d681SAndroid Build Coastguard Worker                                         : Hexagon::getTruePredOpcode(Opc);
4035*9880d681SAndroid Build Coastguard Worker   if (InvPredOpcode >= 0) // Valid instruction with the inverted predicate.
4036*9880d681SAndroid Build Coastguard Worker     return InvPredOpcode;
4037*9880d681SAndroid Build Coastguard Worker 
4038*9880d681SAndroid Build Coastguard Worker   llvm_unreachable("Unexpected predicated instruction");
4039*9880d681SAndroid Build Coastguard Worker }
4040*9880d681SAndroid Build Coastguard Worker 
4041*9880d681SAndroid Build Coastguard Worker 
4042*9880d681SAndroid Build Coastguard Worker // Returns the max value that doesn't need to be extended.
getMaxValue(const MachineInstr * MI) const4043*9880d681SAndroid Build Coastguard Worker int HexagonInstrInfo::getMaxValue(const MachineInstr *MI) const {
4044*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI->getDesc().TSFlags;
4045*9880d681SAndroid Build Coastguard Worker   unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
4046*9880d681SAndroid Build Coastguard Worker                     & HexagonII::ExtentSignedMask;
4047*9880d681SAndroid Build Coastguard Worker   unsigned bits =  (F >> HexagonII::ExtentBitsPos)
4048*9880d681SAndroid Build Coastguard Worker                     & HexagonII::ExtentBitsMask;
4049*9880d681SAndroid Build Coastguard Worker 
4050*9880d681SAndroid Build Coastguard Worker   if (isSigned) // if value is signed
4051*9880d681SAndroid Build Coastguard Worker     return ~(-1U << (bits - 1));
4052*9880d681SAndroid Build Coastguard Worker   else
4053*9880d681SAndroid Build Coastguard Worker     return ~(-1U << bits);
4054*9880d681SAndroid Build Coastguard Worker }
4055*9880d681SAndroid Build Coastguard Worker 
4056*9880d681SAndroid Build Coastguard Worker 
getMemAccessSize(const MachineInstr * MI) const4057*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::getMemAccessSize(const MachineInstr* MI) const {
4058*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI->getDesc().TSFlags;
4059*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::MemAccessSizePos) & HexagonII::MemAccesSizeMask;
4060*9880d681SAndroid Build Coastguard Worker }
4061*9880d681SAndroid Build Coastguard Worker 
4062*9880d681SAndroid Build Coastguard Worker 
4063*9880d681SAndroid Build Coastguard Worker // Returns the min value that doesn't need to be extended.
getMinValue(const MachineInstr * MI) const4064*9880d681SAndroid Build Coastguard Worker int HexagonInstrInfo::getMinValue(const MachineInstr *MI) const {
4065*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI->getDesc().TSFlags;
4066*9880d681SAndroid Build Coastguard Worker   unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
4067*9880d681SAndroid Build Coastguard Worker                     & HexagonII::ExtentSignedMask;
4068*9880d681SAndroid Build Coastguard Worker   unsigned bits =  (F >> HexagonII::ExtentBitsPos)
4069*9880d681SAndroid Build Coastguard Worker                     & HexagonII::ExtentBitsMask;
4070*9880d681SAndroid Build Coastguard Worker 
4071*9880d681SAndroid Build Coastguard Worker   if (isSigned) // if value is signed
4072*9880d681SAndroid Build Coastguard Worker     return -1U << (bits - 1);
4073*9880d681SAndroid Build Coastguard Worker   else
4074*9880d681SAndroid Build Coastguard Worker     return 0;
4075*9880d681SAndroid Build Coastguard Worker }
4076*9880d681SAndroid Build Coastguard Worker 
4077*9880d681SAndroid Build Coastguard Worker 
4078*9880d681SAndroid Build Coastguard Worker // Returns opcode of the non-extended equivalent instruction.
getNonExtOpcode(const MachineInstr * MI) const4079*9880d681SAndroid Build Coastguard Worker short HexagonInstrInfo::getNonExtOpcode(const MachineInstr *MI) const {
4080*9880d681SAndroid Build Coastguard Worker   // Check if the instruction has a register form that uses register in place
4081*9880d681SAndroid Build Coastguard Worker   // of the extended operand, if so return that as the non-extended form.
4082*9880d681SAndroid Build Coastguard Worker   short NonExtOpcode = Hexagon::getRegForm(MI->getOpcode());
4083*9880d681SAndroid Build Coastguard Worker     if (NonExtOpcode >= 0)
4084*9880d681SAndroid Build Coastguard Worker       return NonExtOpcode;
4085*9880d681SAndroid Build Coastguard Worker 
4086*9880d681SAndroid Build Coastguard Worker   if (MI->getDesc().mayLoad() || MI->getDesc().mayStore()) {
4087*9880d681SAndroid Build Coastguard Worker     // Check addressing mode and retrieve non-ext equivalent instruction.
4088*9880d681SAndroid Build Coastguard Worker     switch (getAddrMode(MI)) {
4089*9880d681SAndroid Build Coastguard Worker     case HexagonII::Absolute :
4090*9880d681SAndroid Build Coastguard Worker       return Hexagon::getBaseWithImmOffset(MI->getOpcode());
4091*9880d681SAndroid Build Coastguard Worker     case HexagonII::BaseImmOffset :
4092*9880d681SAndroid Build Coastguard Worker       return Hexagon::getBaseWithRegOffset(MI->getOpcode());
4093*9880d681SAndroid Build Coastguard Worker     case HexagonII::BaseLongOffset:
4094*9880d681SAndroid Build Coastguard Worker       return Hexagon::getRegShlForm(MI->getOpcode());
4095*9880d681SAndroid Build Coastguard Worker 
4096*9880d681SAndroid Build Coastguard Worker     default:
4097*9880d681SAndroid Build Coastguard Worker       return -1;
4098*9880d681SAndroid Build Coastguard Worker     }
4099*9880d681SAndroid Build Coastguard Worker   }
4100*9880d681SAndroid Build Coastguard Worker   return -1;
4101*9880d681SAndroid Build Coastguard Worker }
4102*9880d681SAndroid Build Coastguard Worker 
4103*9880d681SAndroid Build Coastguard Worker 
getPredReg(ArrayRef<MachineOperand> Cond,unsigned & PredReg,unsigned & PredRegPos,unsigned & PredRegFlags) const4104*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::getPredReg(ArrayRef<MachineOperand> Cond,
4105*9880d681SAndroid Build Coastguard Worker       unsigned &PredReg, unsigned &PredRegPos, unsigned &PredRegFlags) const {
4106*9880d681SAndroid Build Coastguard Worker   if (Cond.empty())
4107*9880d681SAndroid Build Coastguard Worker     return false;
4108*9880d681SAndroid Build Coastguard Worker   assert(Cond.size() == 2);
4109*9880d681SAndroid Build Coastguard Worker   if (isNewValueJump(Cond[0].getImm()) || Cond[1].isMBB()) {
4110*9880d681SAndroid Build Coastguard Worker      DEBUG(dbgs() << "No predregs for new-value jumps/endloop");
4111*9880d681SAndroid Build Coastguard Worker      return false;
4112*9880d681SAndroid Build Coastguard Worker   }
4113*9880d681SAndroid Build Coastguard Worker   PredReg = Cond[1].getReg();
4114*9880d681SAndroid Build Coastguard Worker   PredRegPos = 1;
4115*9880d681SAndroid Build Coastguard Worker   // See IfConversion.cpp why we add RegState::Implicit | RegState::Undef
4116*9880d681SAndroid Build Coastguard Worker   PredRegFlags = 0;
4117*9880d681SAndroid Build Coastguard Worker   if (Cond[1].isImplicit())
4118*9880d681SAndroid Build Coastguard Worker     PredRegFlags = RegState::Implicit;
4119*9880d681SAndroid Build Coastguard Worker   if (Cond[1].isUndef())
4120*9880d681SAndroid Build Coastguard Worker     PredRegFlags |= RegState::Undef;
4121*9880d681SAndroid Build Coastguard Worker   return true;
4122*9880d681SAndroid Build Coastguard Worker }
4123*9880d681SAndroid Build Coastguard Worker 
4124*9880d681SAndroid Build Coastguard Worker 
getPseudoInstrPair(const MachineInstr * MI) const4125*9880d681SAndroid Build Coastguard Worker short HexagonInstrInfo::getPseudoInstrPair(const MachineInstr *MI) const {
4126*9880d681SAndroid Build Coastguard Worker   return Hexagon::getRealHWInstr(MI->getOpcode(), Hexagon::InstrType_Pseudo);
4127*9880d681SAndroid Build Coastguard Worker }
4128*9880d681SAndroid Build Coastguard Worker 
4129*9880d681SAndroid Build Coastguard Worker 
getRegForm(const MachineInstr * MI) const4130*9880d681SAndroid Build Coastguard Worker short HexagonInstrInfo::getRegForm(const MachineInstr *MI) const {
4131*9880d681SAndroid Build Coastguard Worker   return Hexagon::getRegForm(MI->getOpcode());
4132*9880d681SAndroid Build Coastguard Worker }
4133*9880d681SAndroid Build Coastguard Worker 
4134*9880d681SAndroid Build Coastguard Worker 
4135*9880d681SAndroid Build Coastguard Worker // Return the number of bytes required to encode the instruction.
4136*9880d681SAndroid Build Coastguard Worker // Hexagon instructions are fixed length, 4 bytes, unless they
4137*9880d681SAndroid Build Coastguard Worker // use a constant extender, which requires another 4 bytes.
4138*9880d681SAndroid Build Coastguard Worker // For debug instructions and prolog labels, return 0.
getSize(const MachineInstr * MI) const4139*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::getSize(const MachineInstr *MI) const {
4140*9880d681SAndroid Build Coastguard Worker   if (MI->isDebugValue() || MI->isPosition())
4141*9880d681SAndroid Build Coastguard Worker     return 0;
4142*9880d681SAndroid Build Coastguard Worker 
4143*9880d681SAndroid Build Coastguard Worker   unsigned Size = MI->getDesc().getSize();
4144*9880d681SAndroid Build Coastguard Worker   if (!Size)
4145*9880d681SAndroid Build Coastguard Worker     // Assume the default insn size in case it cannot be determined
4146*9880d681SAndroid Build Coastguard Worker     // for whatever reason.
4147*9880d681SAndroid Build Coastguard Worker     Size = HEXAGON_INSTR_SIZE;
4148*9880d681SAndroid Build Coastguard Worker 
4149*9880d681SAndroid Build Coastguard Worker   if (isConstExtended(MI) || isExtended(MI))
4150*9880d681SAndroid Build Coastguard Worker     Size += HEXAGON_INSTR_SIZE;
4151*9880d681SAndroid Build Coastguard Worker 
4152*9880d681SAndroid Build Coastguard Worker   // Try and compute number of instructions in asm.
4153*9880d681SAndroid Build Coastguard Worker   if (BranchRelaxAsmLarge && MI->getOpcode() == Hexagon::INLINEASM) {
4154*9880d681SAndroid Build Coastguard Worker     const MachineBasicBlock &MBB = *MI->getParent();
4155*9880d681SAndroid Build Coastguard Worker     const MachineFunction *MF = MBB.getParent();
4156*9880d681SAndroid Build Coastguard Worker     const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo();
4157*9880d681SAndroid Build Coastguard Worker 
4158*9880d681SAndroid Build Coastguard Worker     // Count the number of register definitions to find the asm string.
4159*9880d681SAndroid Build Coastguard Worker     unsigned NumDefs = 0;
4160*9880d681SAndroid Build Coastguard Worker     for (; MI->getOperand(NumDefs).isReg() && MI->getOperand(NumDefs).isDef();
4161*9880d681SAndroid Build Coastguard Worker          ++NumDefs)
4162*9880d681SAndroid Build Coastguard Worker       assert(NumDefs != MI->getNumOperands()-2 && "No asm string?");
4163*9880d681SAndroid Build Coastguard Worker 
4164*9880d681SAndroid Build Coastguard Worker     assert(MI->getOperand(NumDefs).isSymbol() && "No asm string?");
4165*9880d681SAndroid Build Coastguard Worker     // Disassemble the AsmStr and approximate number of instructions.
4166*9880d681SAndroid Build Coastguard Worker     const char *AsmStr = MI->getOperand(NumDefs).getSymbolName();
4167*9880d681SAndroid Build Coastguard Worker     Size = getInlineAsmLength(AsmStr, *MAI);
4168*9880d681SAndroid Build Coastguard Worker   }
4169*9880d681SAndroid Build Coastguard Worker 
4170*9880d681SAndroid Build Coastguard Worker   return Size;
4171*9880d681SAndroid Build Coastguard Worker }
4172*9880d681SAndroid Build Coastguard Worker 
4173*9880d681SAndroid Build Coastguard Worker 
getType(const MachineInstr * MI) const4174*9880d681SAndroid Build Coastguard Worker uint64_t HexagonInstrInfo::getType(const MachineInstr* MI) const {
4175*9880d681SAndroid Build Coastguard Worker   const uint64_t F = MI->getDesc().TSFlags;
4176*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::TypePos) & HexagonII::TypeMask;
4177*9880d681SAndroid Build Coastguard Worker }
4178*9880d681SAndroid Build Coastguard Worker 
4179*9880d681SAndroid Build Coastguard Worker 
getUnits(const MachineInstr * MI) const4180*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::getUnits(const MachineInstr* MI) const {
4181*9880d681SAndroid Build Coastguard Worker   const TargetSubtargetInfo &ST = MI->getParent()->getParent()->getSubtarget();
4182*9880d681SAndroid Build Coastguard Worker   const InstrItineraryData &II = *ST.getInstrItineraryData();
4183*9880d681SAndroid Build Coastguard Worker   const InstrStage &IS = *II.beginStage(MI->getDesc().getSchedClass());
4184*9880d681SAndroid Build Coastguard Worker 
4185*9880d681SAndroid Build Coastguard Worker   return IS.getUnits();
4186*9880d681SAndroid Build Coastguard Worker }
4187*9880d681SAndroid Build Coastguard Worker 
4188*9880d681SAndroid Build Coastguard Worker 
getValidSubTargets(const unsigned Opcode) const4189*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::getValidSubTargets(const unsigned Opcode) const {
4190*9880d681SAndroid Build Coastguard Worker   const uint64_t F = get(Opcode).TSFlags;
4191*9880d681SAndroid Build Coastguard Worker   return (F >> HexagonII::validSubTargetPos) & HexagonII::validSubTargetMask;
4192*9880d681SAndroid Build Coastguard Worker }
4193*9880d681SAndroid Build Coastguard Worker 
4194*9880d681SAndroid Build Coastguard Worker 
4195*9880d681SAndroid Build Coastguard Worker // Calculate size of the basic block without debug instructions.
nonDbgBBSize(const MachineBasicBlock * BB) const4196*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::nonDbgBBSize(const MachineBasicBlock *BB) const {
4197*9880d681SAndroid Build Coastguard Worker   return nonDbgMICount(BB->instr_begin(), BB->instr_end());
4198*9880d681SAndroid Build Coastguard Worker }
4199*9880d681SAndroid Build Coastguard Worker 
4200*9880d681SAndroid Build Coastguard Worker 
nonDbgBundleSize(MachineBasicBlock::const_iterator BundleHead) const4201*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::nonDbgBundleSize(
4202*9880d681SAndroid Build Coastguard Worker       MachineBasicBlock::const_iterator BundleHead) const {
4203*9880d681SAndroid Build Coastguard Worker   assert(BundleHead->isBundle() && "Not a bundle header");
4204*9880d681SAndroid Build Coastguard Worker   auto MII = BundleHead.getInstrIterator();
4205*9880d681SAndroid Build Coastguard Worker   // Skip the bundle header.
4206*9880d681SAndroid Build Coastguard Worker   return nonDbgMICount(++MII, getBundleEnd(*BundleHead));
4207*9880d681SAndroid Build Coastguard Worker }
4208*9880d681SAndroid Build Coastguard Worker 
4209*9880d681SAndroid Build Coastguard Worker 
4210*9880d681SAndroid Build Coastguard Worker /// immediateExtend - Changes the instruction in place to one using an immediate
4211*9880d681SAndroid Build Coastguard Worker /// extender.
immediateExtend(MachineInstr * MI) const4212*9880d681SAndroid Build Coastguard Worker void HexagonInstrInfo::immediateExtend(MachineInstr *MI) const {
4213*9880d681SAndroid Build Coastguard Worker   assert((isExtendable(MI)||isConstExtended(MI)) &&
4214*9880d681SAndroid Build Coastguard Worker                                "Instruction must be extendable");
4215*9880d681SAndroid Build Coastguard Worker   // Find which operand is extendable.
4216*9880d681SAndroid Build Coastguard Worker   short ExtOpNum = getCExtOpNum(MI);
4217*9880d681SAndroid Build Coastguard Worker   MachineOperand &MO = MI->getOperand(ExtOpNum);
4218*9880d681SAndroid Build Coastguard Worker   // This needs to be something we understand.
4219*9880d681SAndroid Build Coastguard Worker   assert((MO.isMBB() || MO.isImm()) &&
4220*9880d681SAndroid Build Coastguard Worker          "Branch with unknown extendable field type");
4221*9880d681SAndroid Build Coastguard Worker   // Mark given operand as extended.
4222*9880d681SAndroid Build Coastguard Worker   MO.addTargetFlag(HexagonII::HMOTF_ConstExtended);
4223*9880d681SAndroid Build Coastguard Worker }
4224*9880d681SAndroid Build Coastguard Worker 
4225*9880d681SAndroid Build Coastguard Worker 
invertAndChangeJumpTarget(MachineInstr * MI,MachineBasicBlock * NewTarget) const4226*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::invertAndChangeJumpTarget(
4227*9880d681SAndroid Build Coastguard Worker       MachineInstr* MI, MachineBasicBlock* NewTarget) const {
4228*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "\n[invertAndChangeJumpTarget] to BB#"
4229*9880d681SAndroid Build Coastguard Worker                << NewTarget->getNumber(); MI->dump(););
4230*9880d681SAndroid Build Coastguard Worker   assert(MI->isBranch());
4231*9880d681SAndroid Build Coastguard Worker   unsigned NewOpcode = getInvertedPredicatedOpcode(MI->getOpcode());
4232*9880d681SAndroid Build Coastguard Worker   int TargetPos = MI->getNumOperands() - 1;
4233*9880d681SAndroid Build Coastguard Worker   // In general branch target is the last operand,
4234*9880d681SAndroid Build Coastguard Worker   // but some implicit defs added at the end might change it.
4235*9880d681SAndroid Build Coastguard Worker   while ((TargetPos > -1) && !MI->getOperand(TargetPos).isMBB())
4236*9880d681SAndroid Build Coastguard Worker     --TargetPos;
4237*9880d681SAndroid Build Coastguard Worker   assert((TargetPos >= 0) && MI->getOperand(TargetPos).isMBB());
4238*9880d681SAndroid Build Coastguard Worker   MI->getOperand(TargetPos).setMBB(NewTarget);
4239*9880d681SAndroid Build Coastguard Worker   if (EnableBranchPrediction && isPredicatedNew(*MI)) {
4240*9880d681SAndroid Build Coastguard Worker     NewOpcode = reversePrediction(NewOpcode);
4241*9880d681SAndroid Build Coastguard Worker   }
4242*9880d681SAndroid Build Coastguard Worker   MI->setDesc(get(NewOpcode));
4243*9880d681SAndroid Build Coastguard Worker   return true;
4244*9880d681SAndroid Build Coastguard Worker }
4245*9880d681SAndroid Build Coastguard Worker 
4246*9880d681SAndroid Build Coastguard Worker 
genAllInsnTimingClasses(MachineFunction & MF) const4247*9880d681SAndroid Build Coastguard Worker void HexagonInstrInfo::genAllInsnTimingClasses(MachineFunction &MF) const {
4248*9880d681SAndroid Build Coastguard Worker   /* +++ The code below is used to generate complete set of Hexagon Insn +++ */
4249*9880d681SAndroid Build Coastguard Worker   MachineFunction::iterator A = MF.begin();
4250*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock &B = *A;
4251*9880d681SAndroid Build Coastguard Worker   MachineBasicBlock::iterator I = B.begin();
4252*9880d681SAndroid Build Coastguard Worker   MachineInstr *MI = &*I;
4253*9880d681SAndroid Build Coastguard Worker   DebugLoc DL = MI->getDebugLoc();
4254*9880d681SAndroid Build Coastguard Worker   MachineInstr *NewMI;
4255*9880d681SAndroid Build Coastguard Worker 
4256*9880d681SAndroid Build Coastguard Worker   for (unsigned insn = TargetOpcode::GENERIC_OP_END+1;
4257*9880d681SAndroid Build Coastguard Worker        insn < Hexagon::INSTRUCTION_LIST_END; ++insn) {
4258*9880d681SAndroid Build Coastguard Worker     NewMI = BuildMI(B, MI, DL, get(insn));
4259*9880d681SAndroid Build Coastguard Worker     DEBUG(dbgs() << "\n" << getName(NewMI->getOpcode()) <<
4260*9880d681SAndroid Build Coastguard Worker           "  Class: " << NewMI->getDesc().getSchedClass());
4261*9880d681SAndroid Build Coastguard Worker     NewMI->eraseFromParent();
4262*9880d681SAndroid Build Coastguard Worker   }
4263*9880d681SAndroid Build Coastguard Worker   /* --- The code above is used to generate complete set of Hexagon Insn --- */
4264*9880d681SAndroid Build Coastguard Worker }
4265*9880d681SAndroid Build Coastguard Worker 
4266*9880d681SAndroid Build Coastguard Worker 
4267*9880d681SAndroid Build Coastguard Worker // inverts the predication logic.
4268*9880d681SAndroid Build Coastguard Worker // p -> NotP
4269*9880d681SAndroid Build Coastguard Worker // NotP -> P
reversePredSense(MachineInstr * MI) const4270*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::reversePredSense(MachineInstr* MI) const {
4271*9880d681SAndroid Build Coastguard Worker   DEBUG(dbgs() << "\nTrying to reverse pred. sense of:"; MI->dump());
4272*9880d681SAndroid Build Coastguard Worker   MI->setDesc(get(getInvertedPredicatedOpcode(MI->getOpcode())));
4273*9880d681SAndroid Build Coastguard Worker   return true;
4274*9880d681SAndroid Build Coastguard Worker }
4275*9880d681SAndroid Build Coastguard Worker 
4276*9880d681SAndroid Build Coastguard Worker 
4277*9880d681SAndroid Build Coastguard Worker // Reverse the branch prediction.
reversePrediction(unsigned Opcode) const4278*9880d681SAndroid Build Coastguard Worker unsigned HexagonInstrInfo::reversePrediction(unsigned Opcode) const {
4279*9880d681SAndroid Build Coastguard Worker   int PredRevOpcode = -1;
4280*9880d681SAndroid Build Coastguard Worker   if (isPredictedTaken(Opcode))
4281*9880d681SAndroid Build Coastguard Worker     PredRevOpcode = Hexagon::notTakenBranchPrediction(Opcode);
4282*9880d681SAndroid Build Coastguard Worker   else
4283*9880d681SAndroid Build Coastguard Worker     PredRevOpcode = Hexagon::takenBranchPrediction(Opcode);
4284*9880d681SAndroid Build Coastguard Worker   assert(PredRevOpcode > 0);
4285*9880d681SAndroid Build Coastguard Worker   return PredRevOpcode;
4286*9880d681SAndroid Build Coastguard Worker }
4287*9880d681SAndroid Build Coastguard Worker 
4288*9880d681SAndroid Build Coastguard Worker 
4289*9880d681SAndroid Build Coastguard Worker // TODO: Add more rigorous validation.
validateBranchCond(const ArrayRef<MachineOperand> & Cond) const4290*9880d681SAndroid Build Coastguard Worker bool HexagonInstrInfo::validateBranchCond(const ArrayRef<MachineOperand> &Cond)
4291*9880d681SAndroid Build Coastguard Worker       const {
4292*9880d681SAndroid Build Coastguard Worker   return Cond.empty() || (Cond[0].isImm() && (Cond.size() != 1));
4293*9880d681SAndroid Build Coastguard Worker }
4294*9880d681SAndroid Build Coastguard Worker 
4295*9880d681SAndroid Build Coastguard Worker 
xformRegToImmOffset(const MachineInstr * MI) const4296*9880d681SAndroid Build Coastguard Worker short HexagonInstrInfo::xformRegToImmOffset(const MachineInstr *MI) const {
4297*9880d681SAndroid Build Coastguard Worker   return Hexagon::xformRegToImmOffset(MI->getOpcode());
4298*9880d681SAndroid Build Coastguard Worker }
4299