blob: 96b1397c9db4432fcb8b0528b5f1322830792c72 [file] [log] [blame]
Jia Liub22310f2012-02-18 12:03:15 +00001//===-- HexagonInstrInfo.cpp - Hexagon Instruction Information ------------===//
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains the Hexagon implementation of the TargetInstrInfo class.
11//
12//===----------------------------------------------------------------------===//
13
Tony Linthicum1213a7a2011-12-12 21:14:40 +000014#include "HexagonInstrInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000015#include "Hexagon.h"
Craig Topperb25fda92012-03-17 18:46:09 +000016#include "HexagonRegisterInfo.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000017#include "HexagonSubtarget.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000018#include "llvm/ADT/STLExtras.h"
19#include "llvm/ADT/SmallVector.h"
Benjamin Kramerae87d7b2012-02-06 10:19:29 +000020#include "llvm/CodeGen/DFAPacketizer.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000021#include "llvm/CodeGen/MachineFrameInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000022#include "llvm/CodeGen/MachineInstrBuilder.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000023#include "llvm/CodeGen/MachineMemOperand.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000024#include "llvm/CodeGen/MachineRegisterInfo.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000025#include "llvm/CodeGen/PseudoSourceValue.h"
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +000026#include "llvm/MC/MCAsmInfo.h"
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +000027#include "llvm/Support/CommandLine.h"
Jyotsna Verma5ed51812013-05-01 21:37:34 +000028#include "llvm/Support/Debug.h"
Benjamin Kramerae87d7b2012-02-06 10:19:29 +000029#include "llvm/Support/MathExtras.h"
Reid Kleckner1c76f1552013-05-03 00:54:56 +000030#include "llvm/Support/raw_ostream.h"
Krzysztof Parzyszekaa935752015-11-24 15:11:13 +000031#include <cctype>
Tony Linthicum1213a7a2011-12-12 21:14:40 +000032
Tony Linthicum1213a7a2011-12-12 21:14:40 +000033using namespace llvm;
34
Chandler Carruthe96dd892014-04-21 22:55:11 +000035#define DEBUG_TYPE "hexagon-instrinfo"
36
Chandler Carruthd174b722014-04-22 02:03:14 +000037#define GET_INSTRINFO_CTOR_DTOR
38#define GET_INSTRMAP_INFO
39#include "HexagonGenInstrInfo.inc"
40#include "HexagonGenDFAPacketizer.inc"
41
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +000042using namespace llvm;
43
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +000044cl::opt<bool> ScheduleInlineAsm("hexagon-sched-inline-asm", cl::Hidden,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +000045 cl::init(false), cl::desc("Do not consider inline-asm a scheduling/"
46 "packetization boundary."));
47
48static cl::opt<bool> EnableBranchPrediction("hexagon-enable-branch-prediction",
49 cl::Hidden, cl::init(true), cl::desc("Enable branch prediction"));
50
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +000051static cl::opt<bool> DisableNVSchedule("disable-hexagon-nv-schedule",
52 cl::Hidden, cl::ZeroOrMore, cl::init(false),
53 cl::desc("Disable schedule adjustment for new value stores."));
54
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +000055static cl::opt<bool> EnableTimingClassLatency(
56 "enable-timing-class-latency", cl::Hidden, cl::init(false),
57 cl::desc("Enable timing class latency"));
58
59static cl::opt<bool> EnableALUForwarding(
60 "enable-alu-forwarding", cl::Hidden, cl::init(true),
61 cl::desc("Enable vec alu forwarding"));
62
63static cl::opt<bool> EnableACCForwarding(
64 "enable-acc-forwarding", cl::Hidden, cl::init(true),
65 cl::desc("Enable vec acc forwarding"));
66
67static cl::opt<bool> BranchRelaxAsmLarge("branch-relax-asm-large",
68 cl::init(true), cl::Hidden, cl::ZeroOrMore, cl::desc("branch relax asm"));
69
Tony Linthicum1213a7a2011-12-12 21:14:40 +000070///
71/// Constants for Hexagon instructions.
72///
Krzysztof Parzyszek6bd42682016-05-05 21:58:02 +000073const int Hexagon_MEMV_OFFSET_MAX_128B = 896; // #s4: -8*128...7*128
74const int Hexagon_MEMV_OFFSET_MIN_128B = -1024; // #s4
75const int Hexagon_MEMV_OFFSET_MAX = 448; // #s4: -8*64...7*64
76const int Hexagon_MEMV_OFFSET_MIN = -512; // #s4
Tony Linthicum1213a7a2011-12-12 21:14:40 +000077const int Hexagon_MEMW_OFFSET_MAX = 4095;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +000078const int Hexagon_MEMW_OFFSET_MIN = -4096;
Tony Linthicum1213a7a2011-12-12 21:14:40 +000079const int Hexagon_MEMD_OFFSET_MAX = 8191;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +000080const int Hexagon_MEMD_OFFSET_MIN = -8192;
Tony Linthicum1213a7a2011-12-12 21:14:40 +000081const int Hexagon_MEMH_OFFSET_MAX = 2047;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +000082const int Hexagon_MEMH_OFFSET_MIN = -2048;
Tony Linthicum1213a7a2011-12-12 21:14:40 +000083const int Hexagon_MEMB_OFFSET_MAX = 1023;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +000084const int Hexagon_MEMB_OFFSET_MIN = -1024;
Tony Linthicum1213a7a2011-12-12 21:14:40 +000085const int Hexagon_ADDI_OFFSET_MAX = 32767;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +000086const int Hexagon_ADDI_OFFSET_MIN = -32768;
Tony Linthicum1213a7a2011-12-12 21:14:40 +000087const int Hexagon_MEMD_AUTOINC_MAX = 56;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +000088const int Hexagon_MEMD_AUTOINC_MIN = -64;
Tony Linthicum1213a7a2011-12-12 21:14:40 +000089const int Hexagon_MEMW_AUTOINC_MAX = 28;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +000090const int Hexagon_MEMW_AUTOINC_MIN = -32;
Tony Linthicum1213a7a2011-12-12 21:14:40 +000091const int Hexagon_MEMH_AUTOINC_MAX = 14;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +000092const int Hexagon_MEMH_AUTOINC_MIN = -16;
Tony Linthicum1213a7a2011-12-12 21:14:40 +000093const int Hexagon_MEMB_AUTOINC_MAX = 7;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +000094const int Hexagon_MEMB_AUTOINC_MIN = -8;
Krzysztof Parzyszek6bd42682016-05-05 21:58:02 +000095const int Hexagon_MEMV_AUTOINC_MAX = 192; // #s3
96const int Hexagon_MEMV_AUTOINC_MIN = -256; // #s3
97const int Hexagon_MEMV_AUTOINC_MAX_128B = 384; // #s3
98const int Hexagon_MEMV_AUTOINC_MIN_128B = -512; // #s3
Tony Linthicum1213a7a2011-12-12 21:14:40 +000099
Juergen Ributzkad12ccbd2013-11-19 00:57:56 +0000100// Pin the vtable to this file.
101void HexagonInstrInfo::anchor() {}
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000102
103HexagonInstrInfo::HexagonInstrInfo(HexagonSubtarget &ST)
Eric Christopherc4d31402015-03-10 23:45:55 +0000104 : HexagonGenInstrInfo(Hexagon::ADJCALLSTACKDOWN, Hexagon::ADJCALLSTACKUP),
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000105 RI() {}
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000106
107
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000108static bool isIntRegForSubInst(unsigned Reg) {
109 return (Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||
110 (Reg >= Hexagon::R16 && Reg <= Hexagon::R23);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000111}
112
113
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000114static bool isDblRegForSubInst(unsigned Reg, const HexagonRegisterInfo &HRI) {
115 return isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::subreg_loreg)) &&
116 isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::subreg_hireg));
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000117}
118
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000119
120/// Calculate number of instructions excluding the debug instructions.
121static unsigned nonDbgMICount(MachineBasicBlock::const_instr_iterator MIB,
122 MachineBasicBlock::const_instr_iterator MIE) {
123 unsigned Count = 0;
124 for (; MIB != MIE; ++MIB) {
125 if (!MIB->isDebugValue())
126 ++Count;
127 }
128 return Count;
129}
130
131
132/// Find the hardware loop instruction used to set-up the specified loop.
133/// On Hexagon, we have two instructions used to set-up the hardware loop
134/// (LOOP0, LOOP1) with corresponding endloop (ENDLOOP0, ENDLOOP1) instructions
135/// to indicate the end of a loop.
136static MachineInstr *findLoopInstr(MachineBasicBlock *BB, int EndLoopOp,
137 SmallPtrSet<MachineBasicBlock *, 8> &Visited) {
Brendon Cahoondf43e682015-05-08 16:16:29 +0000138 int LOOPi;
139 int LOOPr;
140 if (EndLoopOp == Hexagon::ENDLOOP0) {
141 LOOPi = Hexagon::J2_loop0i;
142 LOOPr = Hexagon::J2_loop0r;
143 } else { // EndLoopOp == Hexagon::EndLOOP1
144 LOOPi = Hexagon::J2_loop1i;
145 LOOPr = Hexagon::J2_loop1r;
146 }
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000147
Brendon Cahoondf43e682015-05-08 16:16:29 +0000148 // The loop set-up instruction will be in a predecessor block
149 for (MachineBasicBlock::pred_iterator PB = BB->pred_begin(),
150 PE = BB->pred_end(); PB != PE; ++PB) {
151 // If this has been visited, already skip it.
152 if (!Visited.insert(*PB).second)
153 continue;
154 if (*PB == BB)
155 continue;
156 for (MachineBasicBlock::reverse_instr_iterator I = (*PB)->instr_rbegin(),
157 E = (*PB)->instr_rend(); I != E; ++I) {
158 int Opc = I->getOpcode();
159 if (Opc == LOOPi || Opc == LOOPr)
160 return &*I;
161 // We've reached a different loop, which means the loop0 has been removed.
162 if (Opc == EndLoopOp)
163 return 0;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000164 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000165 // Check the predecessors for the LOOP instruction.
166 MachineInstr *loop = findLoopInstr(*PB, EndLoopOp, Visited);
167 if (loop)
168 return loop;
169 }
170 return 0;
171}
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000172
Brendon Cahoondf43e682015-05-08 16:16:29 +0000173
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000174/// Gather register def/uses from MI.
175/// This treats possible (predicated) defs as actually happening ones
176/// (conservatively).
177static inline void parseOperands(const MachineInstr *MI,
178 SmallVector<unsigned, 4> &Defs, SmallVector<unsigned, 8> &Uses) {
179 Defs.clear();
180 Uses.clear();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000181
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000182 for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
183 const MachineOperand &MO = MI->getOperand(i);
Brendon Cahoondf43e682015-05-08 16:16:29 +0000184
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000185 if (!MO.isReg())
186 continue;
Brendon Cahoondf43e682015-05-08 16:16:29 +0000187
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000188 unsigned Reg = MO.getReg();
189 if (!Reg)
190 continue;
191
192 if (MO.isUse())
193 Uses.push_back(MO.getReg());
194
195 if (MO.isDef())
196 Defs.push_back(MO.getReg());
197 }
198}
199
200
201// Position dependent, so check twice for swap.
202static bool isDuplexPairMatch(unsigned Ga, unsigned Gb) {
203 switch (Ga) {
204 case HexagonII::HSIG_None:
205 default:
206 return false;
207 case HexagonII::HSIG_L1:
208 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_A);
209 case HexagonII::HSIG_L2:
210 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
211 Gb == HexagonII::HSIG_A);
212 case HexagonII::HSIG_S1:
213 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
214 Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_A);
215 case HexagonII::HSIG_S2:
216 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
217 Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_S2 ||
218 Gb == HexagonII::HSIG_A);
219 case HexagonII::HSIG_A:
220 return (Gb == HexagonII::HSIG_A);
221 case HexagonII::HSIG_Compound:
222 return (Gb == HexagonII::HSIG_Compound);
223 }
224 return false;
225}
226
227
228
229/// isLoadFromStackSlot - If the specified machine instruction is a direct
230/// load from a stack slot, return the virtual or physical register number of
231/// the destination along with the FrameIndex of the loaded stack slot. If
232/// not, return 0. This predicate must return 0 if the instruction has
233/// any side effects other than loading from the stack slot.
234unsigned HexagonInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
235 int &FrameIndex) const {
236 switch (MI->getOpcode()) {
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +0000237 default:
238 break;
239 case Hexagon::L2_loadrb_io:
240 case Hexagon::L2_loadrub_io:
241 case Hexagon::L2_loadrh_io:
242 case Hexagon::L2_loadruh_io:
243 case Hexagon::L2_loadri_io:
244 case Hexagon::L2_loadrd_io:
245 case Hexagon::V6_vL32b_ai:
246 case Hexagon::V6_vL32b_ai_128B:
247 case Hexagon::V6_vL32Ub_ai:
248 case Hexagon::V6_vL32Ub_ai_128B:
249 case Hexagon::LDriw_pred:
250 case Hexagon::LDriw_mod:
251 case Hexagon::LDriq_pred_V6:
252 case Hexagon::LDriq_pred_vec_V6:
253 case Hexagon::LDriv_pseudo_V6:
254 case Hexagon::LDrivv_pseudo_V6:
255 case Hexagon::LDriq_pred_V6_128B:
256 case Hexagon::LDriq_pred_vec_V6_128B:
257 case Hexagon::LDriv_pseudo_V6_128B:
258 case Hexagon::LDrivv_pseudo_V6_128B: {
259 const MachineOperand OpFI = MI->getOperand(1);
260 if (!OpFI.isFI())
261 return 0;
262 const MachineOperand OpOff = MI->getOperand(2);
263 if (!OpOff.isImm() || OpOff.getImm() != 0)
264 return 0;
265 FrameIndex = OpFI.getIndex();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000266 return MI->getOperand(0).getReg();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000267 }
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +0000268
269 case Hexagon::L2_ploadrbt_io:
270 case Hexagon::L2_ploadrbf_io:
271 case Hexagon::L2_ploadrubt_io:
272 case Hexagon::L2_ploadrubf_io:
273 case Hexagon::L2_ploadrht_io:
274 case Hexagon::L2_ploadrhf_io:
275 case Hexagon::L2_ploadruht_io:
276 case Hexagon::L2_ploadruhf_io:
277 case Hexagon::L2_ploadrit_io:
278 case Hexagon::L2_ploadrif_io:
279 case Hexagon::L2_ploadrdt_io:
280 case Hexagon::L2_ploadrdf_io: {
281 const MachineOperand OpFI = MI->getOperand(2);
282 if (!OpFI.isFI())
283 return 0;
284 const MachineOperand OpOff = MI->getOperand(3);
285 if (!OpOff.isImm() || OpOff.getImm() != 0)
286 return 0;
287 FrameIndex = OpFI.getIndex();
288 return MI->getOperand(0).getReg();
289 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000290 }
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +0000291
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000292 return 0;
293}
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000294
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000295
296/// isStoreToStackSlot - If the specified machine instruction is a direct
297/// store to a stack slot, return the virtual or physical register number of
298/// the source reg along with the FrameIndex of the loaded stack slot. If
299/// not, return 0. This predicate must return 0 if the instruction has
300/// any side effects other than storing to the stack slot.
301unsigned HexagonInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
302 int &FrameIndex) const {
303 switch (MI->getOpcode()) {
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +0000304 default:
305 break;
306 case Hexagon::S2_storerb_io:
307 case Hexagon::S2_storerh_io:
308 case Hexagon::S2_storeri_io:
309 case Hexagon::S2_storerd_io:
310 case Hexagon::V6_vS32b_ai:
311 case Hexagon::V6_vS32b_ai_128B:
312 case Hexagon::V6_vS32Ub_ai:
313 case Hexagon::V6_vS32Ub_ai_128B:
314 case Hexagon::STriw_pred:
315 case Hexagon::STriw_mod:
316 case Hexagon::STriq_pred_V6:
317 case Hexagon::STriq_pred_vec_V6:
318 case Hexagon::STriv_pseudo_V6:
319 case Hexagon::STrivv_pseudo_V6:
320 case Hexagon::STriq_pred_V6_128B:
321 case Hexagon::STriq_pred_vec_V6_128B:
322 case Hexagon::STriv_pseudo_V6_128B:
323 case Hexagon::STrivv_pseudo_V6_128B: {
324 const MachineOperand &OpFI = MI->getOperand(0);
325 if (!OpFI.isFI())
326 return 0;
327 const MachineOperand &OpOff = MI->getOperand(1);
328 if (!OpOff.isImm() || OpOff.getImm() != 0)
329 return 0;
330 FrameIndex = OpFI.getIndex();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000331 return MI->getOperand(2).getReg();
332 }
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +0000333
334 case Hexagon::S2_pstorerbt_io:
335 case Hexagon::S2_pstorerbf_io:
336 case Hexagon::S2_pstorerht_io:
337 case Hexagon::S2_pstorerhf_io:
338 case Hexagon::S2_pstorerit_io:
339 case Hexagon::S2_pstorerif_io:
340 case Hexagon::S2_pstorerdt_io:
341 case Hexagon::S2_pstorerdf_io: {
342 const MachineOperand &OpFI = MI->getOperand(1);
343 if (!OpFI.isFI())
344 return 0;
345 const MachineOperand &OpOff = MI->getOperand(2);
346 if (!OpOff.isImm() || OpOff.getImm() != 0)
347 return 0;
348 FrameIndex = OpFI.getIndex();
349 return MI->getOperand(3).getReg();
350 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000351 }
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +0000352
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000353 return 0;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000354}
355
356
Brendon Cahoondf43e682015-05-08 16:16:29 +0000357/// This function can analyze one/two way branching only and should (mostly) be
358/// called by target independent side.
359/// First entry is always the opcode of the branching instruction, except when
360/// the Cond vector is supposed to be empty, e.g., when AnalyzeBranch fails, a
361/// BB with only unconditional jump. Subsequent entries depend upon the opcode,
362/// e.g. Jump_c p will have
363/// Cond[0] = Jump_c
364/// Cond[1] = p
365/// HW-loop ENDLOOP:
366/// Cond[0] = ENDLOOP
367/// Cond[1] = MBB
368/// New value jump:
369/// Cond[0] = Hexagon::CMPEQri_f_Jumpnv_t_V4 -- specific opcode
370/// Cond[1] = R
371/// Cond[2] = Imm
Brendon Cahoondf43e682015-05-08 16:16:29 +0000372///
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000373bool HexagonInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB,
374 MachineBasicBlock *&TBB,
Brendon Cahoondf43e682015-05-08 16:16:29 +0000375 MachineBasicBlock *&FBB,
376 SmallVectorImpl<MachineOperand> &Cond,
377 bool AllowModify) const {
Craig Topper062a2ba2014-04-25 05:30:21 +0000378 TBB = nullptr;
379 FBB = nullptr;
Brendon Cahoondf43e682015-05-08 16:16:29 +0000380 Cond.clear();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000381
382 // If the block has no terminators, it just falls into the block after it.
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000383 MachineBasicBlock::instr_iterator I = MBB.instr_end();
384 if (I == MBB.instr_begin())
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000385 return false;
386
387 // A basic block may looks like this:
388 //
389 // [ insn
390 // EH_LABEL
391 // insn
392 // insn
393 // insn
394 // EH_LABEL
395 // insn ]
396 //
397 // It has two succs but does not have a terminator
398 // Don't know how to handle it.
399 do {
400 --I;
401 if (I->isEHLabel())
Brendon Cahoondf43e682015-05-08 16:16:29 +0000402 // Don't analyze EH branches.
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000403 return true;
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000404 } while (I != MBB.instr_begin());
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000405
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000406 I = MBB.instr_end();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000407 --I;
408
409 while (I->isDebugValue()) {
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000410 if (I == MBB.instr_begin())
411 return false;
412 --I;
413 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000414
Colin LeMahieu7b1799c2015-03-09 22:05:21 +0000415 bool JumpToBlock = I->getOpcode() == Hexagon::J2_jump &&
416 I->getOperand(0).isMBB();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000417 // Delete the J2_jump if it's equivalent to a fall-through.
Colin LeMahieu7b1799c2015-03-09 22:05:21 +0000418 if (AllowModify && JumpToBlock &&
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000419 MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
420 DEBUG(dbgs()<< "\nErasing the jump to successor block\n";);
421 I->eraseFromParent();
422 I = MBB.instr_end();
423 if (I == MBB.instr_begin())
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000424 return false;
425 --I;
426 }
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +0000427 if (!isUnpredicatedTerminator(*I))
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000428 return false;
429
430 // Get the last instruction in the block.
Duncan P. N. Exon Smitha72c6e22015-10-20 00:46:39 +0000431 MachineInstr *LastInst = &*I;
Craig Topper062a2ba2014-04-25 05:30:21 +0000432 MachineInstr *SecondLastInst = nullptr;
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000433 // Find one more terminator if present.
Duncan P. N. Exon Smitha72c6e22015-10-20 00:46:39 +0000434 for (;;) {
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +0000435 if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000436 if (!SecondLastInst)
Duncan P. N. Exon Smitha72c6e22015-10-20 00:46:39 +0000437 SecondLastInst = &*I;
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000438 else
439 // This is a third branch.
440 return true;
441 }
442 if (I == MBB.instr_begin())
443 break;
444 --I;
Duncan P. N. Exon Smitha72c6e22015-10-20 00:46:39 +0000445 }
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000446
447 int LastOpcode = LastInst->getOpcode();
Colin LeMahieu7b1799c2015-03-09 22:05:21 +0000448 int SecLastOpcode = SecondLastInst ? SecondLastInst->getOpcode() : 0;
449 // If the branch target is not a basic block, it could be a tail call.
450 // (It is, if the target is a function.)
451 if (LastOpcode == Hexagon::J2_jump && !LastInst->getOperand(0).isMBB())
452 return true;
453 if (SecLastOpcode == Hexagon::J2_jump &&
454 !SecondLastInst->getOperand(0).isMBB())
455 return true;
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000456
457 bool LastOpcodeHasJMP_c = PredOpcodeHasJMP_c(LastOpcode);
Brendon Cahoondf43e682015-05-08 16:16:29 +0000458 bool LastOpcodeHasNVJump = isNewValueJump(LastInst);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000459
Krzysztof Parzyszekb28ae102016-01-14 15:05:27 +0000460 if (LastOpcodeHasJMP_c && !LastInst->getOperand(1).isMBB())
461 return true;
462
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000463 // If there is only one terminator instruction, process it.
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000464 if (LastInst && !SecondLastInst) {
Colin LeMahieudb0b13c2014-12-10 21:24:10 +0000465 if (LastOpcode == Hexagon::J2_jump) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000466 TBB = LastInst->getOperand(0).getMBB();
467 return false;
468 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000469 if (isEndLoopN(LastOpcode)) {
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000470 TBB = LastInst->getOperand(0).getMBB();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000471 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000472 Cond.push_back(LastInst->getOperand(0));
473 return false;
474 }
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000475 if (LastOpcodeHasJMP_c) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000476 TBB = LastInst->getOperand(1).getMBB();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000477 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000478 Cond.push_back(LastInst->getOperand(0));
479 return false;
480 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000481 // Only supporting rr/ri versions of new-value jumps.
482 if (LastOpcodeHasNVJump && (LastInst->getNumExplicitOperands() == 3)) {
483 TBB = LastInst->getOperand(2).getMBB();
484 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
485 Cond.push_back(LastInst->getOperand(0));
486 Cond.push_back(LastInst->getOperand(1));
487 return false;
488 }
489 DEBUG(dbgs() << "\nCant analyze BB#" << MBB.getNumber()
490 << " with one jump\n";);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000491 // Otherwise, don't know what this is.
492 return true;
493 }
494
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000495 bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
Brendon Cahoondf43e682015-05-08 16:16:29 +0000496 bool SecLastOpcodeHasNVJump = isNewValueJump(SecondLastInst);
Colin LeMahieudb0b13c2014-12-10 21:24:10 +0000497 if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) {
Krzysztof Parzyszekb28ae102016-01-14 15:05:27 +0000498 if (!SecondLastInst->getOperand(1).isMBB())
499 return true;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000500 TBB = SecondLastInst->getOperand(1).getMBB();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000501 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000502 Cond.push_back(SecondLastInst->getOperand(0));
503 FBB = LastInst->getOperand(0).getMBB();
504 return false;
505 }
506
Brendon Cahoondf43e682015-05-08 16:16:29 +0000507 // Only supporting rr/ri versions of new-value jumps.
508 if (SecLastOpcodeHasNVJump &&
509 (SecondLastInst->getNumExplicitOperands() == 3) &&
510 (LastOpcode == Hexagon::J2_jump)) {
511 TBB = SecondLastInst->getOperand(2).getMBB();
512 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
513 Cond.push_back(SecondLastInst->getOperand(0));
514 Cond.push_back(SecondLastInst->getOperand(1));
515 FBB = LastInst->getOperand(0).getMBB();
516 return false;
517 }
518
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000519 // If the block ends with two Hexagon:JMPs, handle it. The second one is not
520 // executed, so remove it.
Colin LeMahieudb0b13c2014-12-10 21:24:10 +0000521 if (SecLastOpcode == Hexagon::J2_jump && LastOpcode == Hexagon::J2_jump) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000522 TBB = SecondLastInst->getOperand(0).getMBB();
Duncan P. N. Exon Smithc5b668d2016-02-22 20:49:58 +0000523 I = LastInst->getIterator();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000524 if (AllowModify)
525 I->eraseFromParent();
526 return false;
527 }
528
Brendon Cahoondf43e682015-05-08 16:16:29 +0000529 // If the block ends with an ENDLOOP, and J2_jump, handle it.
530 if (isEndLoopN(SecLastOpcode) && LastOpcode == Hexagon::J2_jump) {
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000531 TBB = SecondLastInst->getOperand(0).getMBB();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000532 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000533 Cond.push_back(SecondLastInst->getOperand(0));
534 FBB = LastInst->getOperand(0).getMBB();
535 return false;
536 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000537 DEBUG(dbgs() << "\nCant analyze BB#" << MBB.getNumber()
538 << " with two jumps";);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000539 // Otherwise, can't handle this.
540 return true;
541}
542
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000543
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000544unsigned HexagonInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
Brendon Cahoondf43e682015-05-08 16:16:29 +0000545 DEBUG(dbgs() << "\nRemoving branches out of BB#" << MBB.getNumber());
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000546 MachineBasicBlock::iterator I = MBB.end();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000547 unsigned Count = 0;
548 while (I != MBB.begin()) {
549 --I;
550 if (I->isDebugValue())
551 continue;
552 // Only removing branches from end of MBB.
553 if (!I->isBranch())
554 return Count;
555 if (Count && (I->getOpcode() == Hexagon::J2_jump))
556 llvm_unreachable("Malformed basic block: unconditional branch not last");
557 MBB.erase(&MBB.back());
558 I = MBB.end();
559 ++Count;
Krzysztof Parzyszek78cc36f2015-03-18 15:56:43 +0000560 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000561 return Count;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000562}
563
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000564unsigned HexagonInstrInfo::InsertBranch(MachineBasicBlock &MBB,
Benjamin Kramerbdc49562016-06-12 15:39:02 +0000565 MachineBasicBlock *TBB,
566 MachineBasicBlock *FBB,
567 ArrayRef<MachineOperand> Cond,
568 const DebugLoc &DL) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000569 unsigned BOpc = Hexagon::J2_jump;
570 unsigned BccOpc = Hexagon::J2_jumpt;
571 assert(validateBranchCond(Cond) && "Invalid branching condition");
572 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
573
574 // Check if ReverseBranchCondition has asked to reverse this branch
575 // If we want to reverse the branch an odd number of times, we want
576 // J2_jumpf.
577 if (!Cond.empty() && Cond[0].isImm())
578 BccOpc = Cond[0].getImm();
579
580 if (!FBB) {
581 if (Cond.empty()) {
582 // Due to a bug in TailMerging/CFG Optimization, we need to add a
583 // special case handling of a predicated jump followed by an
584 // unconditional jump. If not, Tail Merging and CFG Optimization go
585 // into an infinite loop.
586 MachineBasicBlock *NewTBB, *NewFBB;
587 SmallVector<MachineOperand, 4> Cond;
588 MachineInstr *Term = MBB.getFirstTerminator();
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +0000589 if (Term != MBB.end() && isPredicated(*Term) &&
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000590 !AnalyzeBranch(MBB, NewTBB, NewFBB, Cond, false)) {
591 MachineBasicBlock *NextBB = &*++MBB.getIterator();
592 if (NewTBB == NextBB) {
593 ReverseBranchCondition(Cond);
594 RemoveBranch(MBB);
595 return InsertBranch(MBB, TBB, nullptr, Cond, DL);
596 }
597 }
598 BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);
599 } else if (isEndLoopN(Cond[0].getImm())) {
600 int EndLoopOp = Cond[0].getImm();
601 assert(Cond[1].isMBB());
602 // Since we're adding an ENDLOOP, there better be a LOOP instruction.
603 // Check for it, and change the BB target if needed.
604 SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
605 MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, VisitedBBs);
606 assert(Loop != 0 && "Inserting an ENDLOOP without a LOOP");
607 Loop->getOperand(0).setMBB(TBB);
608 // Add the ENDLOOP after the finding the LOOP0.
609 BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
610 } else if (isNewValueJump(Cond[0].getImm())) {
611 assert((Cond.size() == 3) && "Only supporting rr/ri version of nvjump");
612 // New value jump
613 // (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset)
614 // (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset)
615 unsigned Flags1 = getUndefRegState(Cond[1].isUndef());
616 DEBUG(dbgs() << "\nInserting NVJump for BB#" << MBB.getNumber(););
617 if (Cond[2].isReg()) {
618 unsigned Flags2 = getUndefRegState(Cond[2].isUndef());
619 BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).
620 addReg(Cond[2].getReg(), Flags2).addMBB(TBB);
621 } else if(Cond[2].isImm()) {
622 BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).
623 addImm(Cond[2].getImm()).addMBB(TBB);
624 } else
625 llvm_unreachable("Invalid condition for branching");
626 } else {
627 assert((Cond.size() == 2) && "Malformed cond vector");
628 const MachineOperand &RO = Cond[1];
629 unsigned Flags = getUndefRegState(RO.isUndef());
630 BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);
631 }
632 return 1;
Krzysztof Parzyszekcfe285e2013-02-11 20:04:29 +0000633 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000634 assert((!Cond.empty()) &&
635 "Cond. cannot be empty when multiple branchings are required");
636 assert((!isNewValueJump(Cond[0].getImm())) &&
637 "NV-jump cannot be inserted with another branch");
638 // Special case for hardware loops. The condition is a basic block.
639 if (isEndLoopN(Cond[0].getImm())) {
640 int EndLoopOp = Cond[0].getImm();
641 assert(Cond[1].isMBB());
642 // Since we're adding an ENDLOOP, there better be a LOOP instruction.
643 // Check for it, and change the BB target if needed.
644 SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
645 MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, VisitedBBs);
646 assert(Loop != 0 && "Inserting an ENDLOOP without a LOOP");
647 Loop->getOperand(0).setMBB(TBB);
648 // Add the ENDLOOP after the finding the LOOP0.
649 BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
650 } else {
651 const MachineOperand &RO = Cond[1];
652 unsigned Flags = getUndefRegState(RO.isUndef());
653 BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);
Krzysztof Parzyszekcfe285e2013-02-11 20:04:29 +0000654 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000655 BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB);
Krzysztof Parzyszekcfe285e2013-02-11 20:04:29 +0000656
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000657 return 2;
658}
659
660
661bool HexagonInstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,
662 unsigned NumCycles, unsigned ExtraPredCycles,
663 BranchProbability Probability) const {
664 return nonDbgBBSize(&MBB) <= 3;
665}
666
667
668bool HexagonInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB,
669 unsigned NumTCycles, unsigned ExtraTCycles, MachineBasicBlock &FMBB,
670 unsigned NumFCycles, unsigned ExtraFCycles, BranchProbability Probability)
671 const {
672 return nonDbgBBSize(&TMBB) <= 3 && nonDbgBBSize(&FMBB) <= 3;
673}
674
675
676bool HexagonInstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock &MBB,
677 unsigned NumInstrs, BranchProbability Probability) const {
678 return NumInstrs <= 4;
Krzysztof Parzyszekcfe285e2013-02-11 20:04:29 +0000679}
680
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000681void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
Benjamin Kramerbdc49562016-06-12 15:39:02 +0000682 MachineBasicBlock::iterator I,
683 const DebugLoc &DL, unsigned DestReg,
684 unsigned SrcReg, bool KillSrc) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000685 auto &HRI = getRegisterInfo();
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000686 unsigned KillFlag = getKillRegState(KillSrc);
687
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000688 if (Hexagon::IntRegsRegClass.contains(SrcReg, DestReg)) {
Krzysztof Parzyszek3d6fc832016-06-02 14:33:08 +0000689 BuildMI(MBB, I, DL, get(Hexagon::A2_tfr), DestReg)
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000690 .addReg(SrcReg, KillFlag);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000691 return;
692 }
693 if (Hexagon::DoubleRegsRegClass.contains(SrcReg, DestReg)) {
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000694 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrp), DestReg)
695 .addReg(SrcReg, KillFlag);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000696 return;
697 }
698 if (Hexagon::PredRegsRegClass.contains(SrcReg, DestReg)) {
699 // Map Pd = Ps to Pd = or(Ps, Ps).
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000700 BuildMI(MBB, I, DL, get(Hexagon::C2_or), DestReg)
701 .addReg(SrcReg).addReg(SrcReg, KillFlag);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000702 return;
703 }
Colin LeMahieu402f7722014-12-19 18:56:10 +0000704 if (Hexagon::CtrRegsRegClass.contains(DestReg) &&
Sirish Pande8bb97452012-05-12 05:54:15 +0000705 Hexagon::IntRegsRegClass.contains(SrcReg)) {
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000706 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg)
707 .addReg(SrcReg, KillFlag);
708 return;
709 }
710 if (Hexagon::IntRegsRegClass.contains(DestReg) &&
711 Hexagon::CtrRegsRegClass.contains(SrcReg)) {
712 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrcrr), DestReg)
713 .addReg(SrcReg, KillFlag);
714 return;
715 }
716 if (Hexagon::ModRegsRegClass.contains(DestReg) &&
717 Hexagon::IntRegsRegClass.contains(SrcReg)) {
718 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg)
719 .addReg(SrcReg, KillFlag);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000720 return;
Sirish Pande30804c22012-02-15 18:52:27 +0000721 }
Anshuman Dasguptae96f8042013-02-13 22:56:34 +0000722 if (Hexagon::PredRegsRegClass.contains(SrcReg) &&
723 Hexagon::IntRegsRegClass.contains(DestReg)) {
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000724 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg)
725 .addReg(SrcReg, KillFlag);
Anshuman Dasguptae96f8042013-02-13 22:56:34 +0000726 return;
727 }
728 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
729 Hexagon::PredRegsRegClass.contains(DestReg)) {
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000730 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrrp), DestReg)
731 .addReg(SrcReg, KillFlag);
Anshuman Dasguptae96f8042013-02-13 22:56:34 +0000732 return;
733 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000734 if (Hexagon::PredRegsRegClass.contains(SrcReg) &&
735 Hexagon::IntRegsRegClass.contains(DestReg)) {
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000736 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg)
737 .addReg(SrcReg, KillFlag);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000738 return;
739 }
740 if (Hexagon::VectorRegsRegClass.contains(SrcReg, DestReg)) {
741 BuildMI(MBB, I, DL, get(Hexagon::V6_vassign), DestReg).
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000742 addReg(SrcReg, KillFlag);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000743 return;
744 }
745 if (Hexagon::VecDblRegsRegClass.contains(SrcReg, DestReg)) {
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000746 BuildMI(MBB, I, DL, get(Hexagon::V6_vcombine), DestReg)
747 .addReg(HRI.getSubReg(SrcReg, Hexagon::subreg_hireg), KillFlag)
748 .addReg(HRI.getSubReg(SrcReg, Hexagon::subreg_loreg), KillFlag);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000749 return;
750 }
751 if (Hexagon::VecPredRegsRegClass.contains(SrcReg, DestReg)) {
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000752 BuildMI(MBB, I, DL, get(Hexagon::V6_pred_and), DestReg)
753 .addReg(SrcReg)
754 .addReg(SrcReg, KillFlag);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000755 return;
756 }
757 if (Hexagon::VecPredRegsRegClass.contains(SrcReg) &&
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000758 Hexagon::VectorRegsRegClass.contains(DestReg)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000759 llvm_unreachable("Unimplemented pred to vec");
760 return;
761 }
762 if (Hexagon::VecPredRegsRegClass.contains(DestReg) &&
763 Hexagon::VectorRegsRegClass.contains(SrcReg)) {
764 llvm_unreachable("Unimplemented vec to pred");
765 return;
766 }
767 if (Hexagon::VecPredRegs128BRegClass.contains(SrcReg, DestReg)) {
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000768 unsigned DstHi = HRI.getSubReg(DestReg, Hexagon::subreg_hireg);
769 BuildMI(MBB, I, DL, get(Hexagon::V6_pred_and), DstHi)
770 .addReg(HRI.getSubReg(SrcReg, Hexagon::subreg_hireg), KillFlag);
771 unsigned DstLo = HRI.getSubReg(DestReg, Hexagon::subreg_loreg);
772 BuildMI(MBB, I, DL, get(Hexagon::V6_pred_and), DstLo)
773 .addReg(HRI.getSubReg(SrcReg, Hexagon::subreg_loreg), KillFlag);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000774 return;
775 }
Sirish Pande30804c22012-02-15 18:52:27 +0000776
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000777#ifndef NDEBUG
778 // Show the invalid registers to ease debugging.
779 dbgs() << "Invalid registers for copy in BB#" << MBB.getNumber()
780 << ": " << PrintReg(DestReg, &HRI)
781 << " = " << PrintReg(SrcReg, &HRI) << '\n';
782#endif
Sirish Pande30804c22012-02-15 18:52:27 +0000783 llvm_unreachable("Unimplemented");
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000784}
785
786
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000787void HexagonInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
788 MachineBasicBlock::iterator I, unsigned SrcReg, bool isKill, int FI,
789 const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000790 DebugLoc DL = MBB.findDebugLoc(I);
791 MachineFunction &MF = *MBB.getParent();
792 MachineFrameInfo &MFI = *MF.getFrameInfo();
793 unsigned Align = MFI.getObjectAlignment(FI);
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000794 unsigned KillFlag = getKillRegState(isKill);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000795
Alex Lorenze40c8a22015-08-11 23:09:45 +0000796 MachineMemOperand *MMO = MF.getMachineMemOperand(
797 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
798 MFI.getObjectSize(FI), Align);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000799
Craig Topperc7242e02012-04-20 07:30:17 +0000800 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {
Colin LeMahieubda31b42014-12-29 20:44:51 +0000801 BuildMI(MBB, I, DL, get(Hexagon::S2_storeri_io))
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000802 .addFrameIndex(FI).addImm(0)
803 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
Craig Topperc7242e02012-04-20 07:30:17 +0000804 } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {
Colin LeMahieubda31b42014-12-29 20:44:51 +0000805 BuildMI(MBB, I, DL, get(Hexagon::S2_storerd_io))
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000806 .addFrameIndex(FI).addImm(0)
807 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
Craig Topperc7242e02012-04-20 07:30:17 +0000808 } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000809 BuildMI(MBB, I, DL, get(Hexagon::STriw_pred))
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000810 .addFrameIndex(FI).addImm(0)
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000811 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000812 } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {
813 BuildMI(MBB, I, DL, get(Hexagon::STriw_mod))
814 .addFrameIndex(FI).addImm(0)
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000815 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
816 } else if (Hexagon::VecPredRegs128BRegClass.hasSubClassEq(RC)) {
817 BuildMI(MBB, I, DL, get(Hexagon::STriq_pred_V6_128B))
818 .addFrameIndex(FI).addImm(0)
819 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
820 } else if (Hexagon::VecPredRegsRegClass.hasSubClassEq(RC)) {
821 BuildMI(MBB, I, DL, get(Hexagon::STriq_pred_V6))
822 .addFrameIndex(FI).addImm(0)
823 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
824 } else if (Hexagon::VectorRegs128BRegClass.hasSubClassEq(RC)) {
825 DEBUG(dbgs() << "++Generating 128B vector spill");
826 BuildMI(MBB, I, DL, get(Hexagon::STriv_pseudo_V6_128B))
827 .addFrameIndex(FI).addImm(0)
828 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
829 } else if (Hexagon::VectorRegsRegClass.hasSubClassEq(RC)) {
830 DEBUG(dbgs() << "++Generating vector spill");
831 BuildMI(MBB, I, DL, get(Hexagon::STriv_pseudo_V6))
832 .addFrameIndex(FI).addImm(0)
833 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
834 } else if (Hexagon::VecDblRegsRegClass.hasSubClassEq(RC)) {
835 DEBUG(dbgs() << "++Generating double vector spill");
836 BuildMI(MBB, I, DL, get(Hexagon::STrivv_pseudo_V6))
837 .addFrameIndex(FI).addImm(0)
838 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
839 } else if (Hexagon::VecDblRegs128BRegClass.hasSubClassEq(RC)) {
840 DEBUG(dbgs() << "++Generating 128B double vector spill");
841 BuildMI(MBB, I, DL, get(Hexagon::STrivv_pseudo_V6_128B))
842 .addFrameIndex(FI).addImm(0)
843 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000844 } else {
Craig Toppere55c5562012-02-07 02:50:20 +0000845 llvm_unreachable("Unimplemented");
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000846 }
847}
848
849
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000850void HexagonInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
851 MachineBasicBlock::iterator I, unsigned DestReg, int FI,
852 const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000853 DebugLoc DL = MBB.findDebugLoc(I);
854 MachineFunction &MF = *MBB.getParent();
855 MachineFrameInfo &MFI = *MF.getFrameInfo();
856 unsigned Align = MFI.getObjectAlignment(FI);
857
Alex Lorenze40c8a22015-08-11 23:09:45 +0000858 MachineMemOperand *MMO = MF.getMachineMemOperand(
859 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
860 MFI.getObjectSize(FI), Align);
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000861
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000862 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {
Colin LeMahieu026e88d2014-12-23 20:02:16 +0000863 BuildMI(MBB, I, DL, get(Hexagon::L2_loadri_io), DestReg)
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000864 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000865 } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {
Colin LeMahieu947cd702014-12-23 20:44:59 +0000866 BuildMI(MBB, I, DL, get(Hexagon::L2_loadrd_io), DestReg)
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000867 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000868 } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000869 BuildMI(MBB, I, DL, get(Hexagon::LDriw_pred), DestReg)
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000870 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
871 } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {
872 BuildMI(MBB, I, DL, get(Hexagon::LDriw_mod), DestReg)
873 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000874 } else if (Hexagon::VecPredRegs128BRegClass.hasSubClassEq(RC)) {
875 BuildMI(MBB, I, DL, get(Hexagon::LDriq_pred_V6_128B), DestReg)
876 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
877 } else if (Hexagon::VecPredRegsRegClass.hasSubClassEq(RC)) {
878 BuildMI(MBB, I, DL, get(Hexagon::LDriq_pred_V6), DestReg)
879 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
880 } else if (Hexagon::VecDblRegs128BRegClass.hasSubClassEq(RC)) {
881 DEBUG(dbgs() << "++Generating 128B double vector restore");
882 BuildMI(MBB, I, DL, get(Hexagon::LDrivv_pseudo_V6_128B), DestReg)
883 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
884 } else if (Hexagon::VectorRegs128BRegClass.hasSubClassEq(RC)) {
885 DEBUG(dbgs() << "++Generating 128B vector restore");
886 BuildMI(MBB, I, DL, get(Hexagon::LDriv_pseudo_V6_128B), DestReg)
887 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
888 } else if (Hexagon::VectorRegsRegClass.hasSubClassEq(RC)) {
889 DEBUG(dbgs() << "++Generating vector restore");
890 BuildMI(MBB, I, DL, get(Hexagon::LDriv_pseudo_V6), DestReg)
891 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
892 } else if (Hexagon::VecDblRegsRegClass.hasSubClassEq(RC)) {
893 DEBUG(dbgs() << "++Generating double vector restore");
894 BuildMI(MBB, I, DL, get(Hexagon::LDrivv_pseudo_V6), DestReg)
895 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000896 } else {
Craig Toppere55c5562012-02-07 02:50:20 +0000897 llvm_unreachable("Can't store this register to stack slot");
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000898 }
899}
900
901
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000902/// expandPostRAPseudo - This function is called for all pseudo instructions
903/// that remain after register allocation. Many pseudo instructions are
904/// created to help register allocation. This is the place to convert them
905/// into real instructions. The target can edit MI in place, or it can insert
906/// new instructions and erase MI. The function should return true if
907/// anything was changed.
908bool HexagonInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI)
909 const {
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +0000910 const HexagonRegisterInfo &HRI = getRegisterInfo();
Krzysztof Parzyszek42113342015-03-19 16:33:08 +0000911 MachineRegisterInfo &MRI = MI->getParent()->getParent()->getRegInfo();
Krzysztof Parzyszek36ccfa52015-03-18 19:07:53 +0000912 MachineBasicBlock &MBB = *MI->getParent();
913 DebugLoc DL = MI->getDebugLoc();
Colin LeMahieu7b1799c2015-03-09 22:05:21 +0000914 unsigned Opc = MI->getOpcode();
Krzysztof Parzyszek195dc8d2015-11-26 04:33:11 +0000915 const unsigned VecOffset = 1;
916 bool Is128B = false;
Colin LeMahieu7b1799c2015-03-09 22:05:21 +0000917
918 switch (Opc) {
Krzysztof Parzyszek3d6fc832016-06-02 14:33:08 +0000919 case TargetOpcode::COPY: {
920 MachineOperand &MD = MI->getOperand(0);
921 MachineOperand &MS = MI->getOperand(1);
922 if (MD.getReg() != MS.getReg() && !MS.isUndef()) {
923 copyPhysReg(MBB, MI, DL, MD.getReg(), MS.getReg(), MS.isKill());
924 std::prev(MI)->copyImplicitOps(*MBB.getParent(), *MI);
925 }
926 MBB.erase(MI);
927 return true;
928 }
Krzysztof Parzyszek4fa2a9f2015-04-22 16:43:53 +0000929 case Hexagon::ALIGNA:
930 BuildMI(MBB, MI, DL, get(Hexagon::A2_andir), MI->getOperand(0).getReg())
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +0000931 .addReg(HRI.getFrameRegister())
Krzysztof Parzyszek4fa2a9f2015-04-22 16:43:53 +0000932 .addImm(-MI->getOperand(1).getImm());
933 MBB.erase(MI);
934 return true;
Krzysztof Parzyszek4eb6d4d2015-11-26 16:54:33 +0000935 case Hexagon::HEXAGON_V6_vassignp_128B:
936 case Hexagon::HEXAGON_V6_vassignp: {
937 unsigned SrcReg = MI->getOperand(1).getReg();
938 unsigned DstReg = MI->getOperand(0).getReg();
939 if (SrcReg != DstReg)
940 copyPhysReg(MBB, MI, DL, DstReg, SrcReg, MI->getOperand(1).isKill());
941 MBB.erase(MI);
942 return true;
943 }
944 case Hexagon::HEXAGON_V6_lo_128B:
945 case Hexagon::HEXAGON_V6_lo: {
946 unsigned SrcReg = MI->getOperand(1).getReg();
947 unsigned DstReg = MI->getOperand(0).getReg();
948 unsigned SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::subreg_loreg);
949 copyPhysReg(MBB, MI, DL, DstReg, SrcSubLo, MI->getOperand(1).isKill());
950 MBB.erase(MI);
951 MRI.clearKillFlags(SrcSubLo);
952 return true;
953 }
954 case Hexagon::HEXAGON_V6_hi_128B:
955 case Hexagon::HEXAGON_V6_hi: {
956 unsigned SrcReg = MI->getOperand(1).getReg();
957 unsigned DstReg = MI->getOperand(0).getReg();
958 unsigned SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::subreg_hireg);
959 copyPhysReg(MBB, MI, DL, DstReg, SrcSubHi, MI->getOperand(1).isKill());
960 MBB.erase(MI);
961 MRI.clearKillFlags(SrcSubHi);
962 return true;
963 }
Krzysztof Parzyszek195dc8d2015-11-26 04:33:11 +0000964 case Hexagon::STrivv_indexed_128B:
965 Is128B = true;
966 case Hexagon::STrivv_indexed: {
967 unsigned SrcReg = MI->getOperand(2).getReg();
968 unsigned SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::subreg_hireg);
969 unsigned SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::subreg_loreg);
970 unsigned NewOpcd = Is128B ? Hexagon::V6_vS32b_ai_128B
971 : Hexagon::V6_vS32b_ai;
972 unsigned Offset = Is128B ? VecOffset << 7 : VecOffset << 6;
973 MachineInstr *MI1New = BuildMI(MBB, MI, DL, get(NewOpcd))
974 .addOperand(MI->getOperand(0))
975 .addImm(MI->getOperand(1).getImm())
976 .addReg(SrcSubLo)
977 .setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
978 MI1New->getOperand(0).setIsKill(false);
979 BuildMI(MBB, MI, DL, get(NewOpcd))
980 .addOperand(MI->getOperand(0))
981 // The Vectors are indexed in multiples of vector size.
982 .addImm(MI->getOperand(1).getImm()+Offset)
983 .addReg(SrcSubHi)
984 .setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
985 MBB.erase(MI);
986 return true;
987 }
988 case Hexagon::LDrivv_pseudo_V6_128B:
989 case Hexagon::LDrivv_indexed_128B:
990 Is128B = true;
991 case Hexagon::LDrivv_pseudo_V6:
992 case Hexagon::LDrivv_indexed: {
993 unsigned NewOpcd = Is128B ? Hexagon::V6_vL32b_ai_128B
994 : Hexagon::V6_vL32b_ai;
995 unsigned DstReg = MI->getOperand(0).getReg();
996 unsigned Offset = Is128B ? VecOffset << 7 : VecOffset << 6;
997 MachineInstr *MI1New =
998 BuildMI(MBB, MI, DL, get(NewOpcd),
999 HRI.getSubReg(DstReg, Hexagon::subreg_loreg))
1000 .addOperand(MI->getOperand(1))
1001 .addImm(MI->getOperand(2).getImm());
1002 MI1New->getOperand(1).setIsKill(false);
1003 BuildMI(MBB, MI, DL, get(NewOpcd),
1004 HRI.getSubReg(DstReg, Hexagon::subreg_hireg))
1005 .addOperand(MI->getOperand(1))
1006 // The Vectors are indexed in multiples of vector size.
1007 .addImm(MI->getOperand(2).getImm() + Offset)
1008 .setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
1009 MBB.erase(MI);
1010 return true;
1011 }
1012 case Hexagon::LDriv_pseudo_V6_128B:
1013 Is128B = true;
1014 case Hexagon::LDriv_pseudo_V6: {
1015 unsigned DstReg = MI->getOperand(0).getReg();
1016 unsigned NewOpc = Is128B ? Hexagon::V6_vL32b_ai_128B
1017 : Hexagon::V6_vL32b_ai;
1018 int32_t Off = MI->getOperand(2).getImm();
Krzysztof Parzyszek195dc8d2015-11-26 04:33:11 +00001019 BuildMI(MBB, MI, DL, get(NewOpc), DstReg)
1020 .addOperand(MI->getOperand(1))
Krzysztof Parzyszek96cfc3812016-06-10 15:43:18 +00001021 .addImm(Off)
Krzysztof Parzyszek195dc8d2015-11-26 04:33:11 +00001022 .setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
1023 MBB.erase(MI);
1024 return true;
1025 }
1026 case Hexagon::STriv_pseudo_V6_128B:
1027 Is128B = true;
1028 case Hexagon::STriv_pseudo_V6: {
1029 unsigned NewOpc = Is128B ? Hexagon::V6_vS32b_ai_128B
1030 : Hexagon::V6_vS32b_ai;
1031 int32_t Off = MI->getOperand(1).getImm();
Krzysztof Parzyszek195dc8d2015-11-26 04:33:11 +00001032 BuildMI(MBB, MI, DL, get(NewOpc))
1033 .addOperand(MI->getOperand(0))
Krzysztof Parzyszek96cfc3812016-06-10 15:43:18 +00001034 .addImm(Off)
Krzysztof Parzyszek195dc8d2015-11-26 04:33:11 +00001035 .addOperand(MI->getOperand(2))
1036 .setMemRefs(MI->memoperands_begin(), MI->memoperands_end());
1037 MBB.erase(MI);
1038 return true;
1039 }
Krzysztof Parzyszek36ccfa52015-03-18 19:07:53 +00001040 case Hexagon::TFR_PdTrue: {
1041 unsigned Reg = MI->getOperand(0).getReg();
1042 BuildMI(MBB, MI, DL, get(Hexagon::C2_orn), Reg)
1043 .addReg(Reg, RegState::Undef)
1044 .addReg(Reg, RegState::Undef);
1045 MBB.erase(MI);
1046 return true;
1047 }
1048 case Hexagon::TFR_PdFalse: {
1049 unsigned Reg = MI->getOperand(0).getReg();
1050 BuildMI(MBB, MI, DL, get(Hexagon::C2_andn), Reg)
1051 .addReg(Reg, RegState::Undef)
1052 .addReg(Reg, RegState::Undef);
1053 MBB.erase(MI);
1054 return true;
1055 }
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001056 case Hexagon::VMULW: {
1057 // Expand a 64-bit vector multiply into 2 32-bit scalar multiplies.
1058 unsigned DstReg = MI->getOperand(0).getReg();
1059 unsigned Src1Reg = MI->getOperand(1).getReg();
1060 unsigned Src2Reg = MI->getOperand(2).getReg();
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00001061 unsigned Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::subreg_hireg);
1062 unsigned Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::subreg_loreg);
1063 unsigned Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::subreg_hireg);
1064 unsigned Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::subreg_loreg);
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001065 BuildMI(MBB, MI, MI->getDebugLoc(), get(Hexagon::M2_mpyi),
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00001066 HRI.getSubReg(DstReg, Hexagon::subreg_hireg)).addReg(Src1SubHi)
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001067 .addReg(Src2SubHi);
1068 BuildMI(MBB, MI, MI->getDebugLoc(), get(Hexagon::M2_mpyi),
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00001069 HRI.getSubReg(DstReg, Hexagon::subreg_loreg)).addReg(Src1SubLo)
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001070 .addReg(Src2SubLo);
1071 MBB.erase(MI);
1072 MRI.clearKillFlags(Src1SubHi);
1073 MRI.clearKillFlags(Src1SubLo);
1074 MRI.clearKillFlags(Src2SubHi);
1075 MRI.clearKillFlags(Src2SubLo);
1076 return true;
1077 }
1078 case Hexagon::VMULW_ACC: {
1079 // Expand 64-bit vector multiply with addition into 2 scalar multiplies.
1080 unsigned DstReg = MI->getOperand(0).getReg();
1081 unsigned Src1Reg = MI->getOperand(1).getReg();
1082 unsigned Src2Reg = MI->getOperand(2).getReg();
1083 unsigned Src3Reg = MI->getOperand(3).getReg();
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00001084 unsigned Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::subreg_hireg);
1085 unsigned Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::subreg_loreg);
1086 unsigned Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::subreg_hireg);
1087 unsigned Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::subreg_loreg);
1088 unsigned Src3SubHi = HRI.getSubReg(Src3Reg, Hexagon::subreg_hireg);
1089 unsigned Src3SubLo = HRI.getSubReg(Src3Reg, Hexagon::subreg_loreg);
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001090 BuildMI(MBB, MI, MI->getDebugLoc(), get(Hexagon::M2_maci),
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00001091 HRI.getSubReg(DstReg, Hexagon::subreg_hireg)).addReg(Src1SubHi)
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001092 .addReg(Src2SubHi).addReg(Src3SubHi);
1093 BuildMI(MBB, MI, MI->getDebugLoc(), get(Hexagon::M2_maci),
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00001094 HRI.getSubReg(DstReg, Hexagon::subreg_loreg)).addReg(Src1SubLo)
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001095 .addReg(Src2SubLo).addReg(Src3SubLo);
1096 MBB.erase(MI);
1097 MRI.clearKillFlags(Src1SubHi);
1098 MRI.clearKillFlags(Src1SubLo);
1099 MRI.clearKillFlags(Src2SubHi);
1100 MRI.clearKillFlags(Src2SubLo);
1101 MRI.clearKillFlags(Src3SubHi);
1102 MRI.clearKillFlags(Src3SubLo);
1103 return true;
1104 }
Krzysztof Parzyszek237b9612016-01-14 15:37:16 +00001105 case Hexagon::Insert4: {
1106 unsigned DstReg = MI->getOperand(0).getReg();
1107 unsigned Src1Reg = MI->getOperand(1).getReg();
1108 unsigned Src2Reg = MI->getOperand(2).getReg();
1109 unsigned Src3Reg = MI->getOperand(3).getReg();
1110 unsigned Src4Reg = MI->getOperand(4).getReg();
1111 unsigned Src1RegIsKill = getKillRegState(MI->getOperand(1).isKill());
1112 unsigned Src2RegIsKill = getKillRegState(MI->getOperand(2).isKill());
1113 unsigned Src3RegIsKill = getKillRegState(MI->getOperand(3).isKill());
1114 unsigned Src4RegIsKill = getKillRegState(MI->getOperand(4).isKill());
1115 unsigned DstSubHi = HRI.getSubReg(DstReg, Hexagon::subreg_hireg);
1116 unsigned DstSubLo = HRI.getSubReg(DstReg, Hexagon::subreg_loreg);
1117 BuildMI(MBB, MI, MI->getDebugLoc(), get(Hexagon::S2_insert),
1118 HRI.getSubReg(DstReg, Hexagon::subreg_loreg)).addReg(DstSubLo)
1119 .addReg(Src1Reg, Src1RegIsKill).addImm(16).addImm(0);
1120 BuildMI(MBB, MI, MI->getDebugLoc(), get(Hexagon::S2_insert),
1121 HRI.getSubReg(DstReg, Hexagon::subreg_loreg)).addReg(DstSubLo)
1122 .addReg(Src2Reg, Src2RegIsKill).addImm(16).addImm(16);
1123 BuildMI(MBB, MI, MI->getDebugLoc(), get(Hexagon::S2_insert),
1124 HRI.getSubReg(DstReg, Hexagon::subreg_hireg)).addReg(DstSubHi)
1125 .addReg(Src3Reg, Src3RegIsKill).addImm(16).addImm(0);
1126 BuildMI(MBB, MI, MI->getDebugLoc(), get(Hexagon::S2_insert),
1127 HRI.getSubReg(DstReg, Hexagon::subreg_hireg)).addReg(DstSubHi)
1128 .addReg(Src4Reg, Src4RegIsKill).addImm(16).addImm(16);
1129 MBB.erase(MI);
1130 MRI.clearKillFlags(DstReg);
1131 MRI.clearKillFlags(DstSubHi);
1132 MRI.clearKillFlags(DstSubLo);
1133 return true;
1134 }
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00001135 case Hexagon::MUX64_rr: {
1136 const MachineOperand &Op0 = MI->getOperand(0);
1137 const MachineOperand &Op1 = MI->getOperand(1);
1138 const MachineOperand &Op2 = MI->getOperand(2);
1139 const MachineOperand &Op3 = MI->getOperand(3);
1140 unsigned Rd = Op0.getReg();
1141 unsigned Pu = Op1.getReg();
1142 unsigned Rs = Op2.getReg();
1143 unsigned Rt = Op3.getReg();
1144 DebugLoc DL = MI->getDebugLoc();
1145 unsigned K1 = getKillRegState(Op1.isKill());
1146 unsigned K2 = getKillRegState(Op2.isKill());
1147 unsigned K3 = getKillRegState(Op3.isKill());
1148 if (Rd != Rs)
1149 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpt), Rd)
1150 .addReg(Pu, (Rd == Rt) ? K1 : 0)
1151 .addReg(Rs, K2);
1152 if (Rd != Rt)
1153 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpf), Rd)
1154 .addReg(Pu, K1)
1155 .addReg(Rt, K3);
1156 MBB.erase(MI);
1157 return true;
1158 }
Krzysztof Parzyszek4afed552016-05-12 19:16:02 +00001159 case Hexagon::VSelectPseudo_V6: {
1160 const MachineOperand &Op0 = MI->getOperand(0);
1161 const MachineOperand &Op1 = MI->getOperand(1);
1162 const MachineOperand &Op2 = MI->getOperand(2);
1163 const MachineOperand &Op3 = MI->getOperand(3);
1164 BuildMI(MBB, MI, DL, get(Hexagon::V6_vcmov))
1165 .addOperand(Op0)
1166 .addOperand(Op1)
1167 .addOperand(Op2);
1168 BuildMI(MBB, MI, DL, get(Hexagon::V6_vncmov))
1169 .addOperand(Op0)
1170 .addOperand(Op1)
1171 .addOperand(Op3);
1172 MBB.erase(MI);
1173 return true;
1174 }
1175 case Hexagon::VSelectDblPseudo_V6: {
1176 MachineOperand &Op0 = MI->getOperand(0);
1177 MachineOperand &Op1 = MI->getOperand(1);
1178 MachineOperand &Op2 = MI->getOperand(2);
1179 MachineOperand &Op3 = MI->getOperand(3);
1180 unsigned SrcLo = HRI.getSubReg(Op2.getReg(), Hexagon::subreg_loreg);
1181 unsigned SrcHi = HRI.getSubReg(Op2.getReg(), Hexagon::subreg_hireg);
1182 BuildMI(MBB, MI, DL, get(Hexagon::V6_vccombine))
1183 .addOperand(Op0)
1184 .addOperand(Op1)
1185 .addReg(SrcHi)
1186 .addReg(SrcLo);
1187 SrcLo = HRI.getSubReg(Op3.getReg(), Hexagon::subreg_loreg);
1188 SrcHi = HRI.getSubReg(Op3.getReg(), Hexagon::subreg_hireg);
1189 BuildMI(MBB, MI, DL, get(Hexagon::V6_vnccombine))
1190 .addOperand(Op0)
1191 .addOperand(Op1)
1192 .addReg(SrcHi)
1193 .addReg(SrcLo);
1194 MBB.erase(MI);
1195 return true;
1196 }
Colin LeMahieu7b1799c2015-03-09 22:05:21 +00001197 case Hexagon::TCRETURNi:
1198 MI->setDesc(get(Hexagon::J2_jump));
1199 return true;
1200 case Hexagon::TCRETURNr:
1201 MI->setDesc(get(Hexagon::J2_jumpr));
1202 return true;
Krzysztof Parzyszek70a134d2015-11-25 21:40:03 +00001203 case Hexagon::TFRI_f:
1204 case Hexagon::TFRI_cPt_f:
1205 case Hexagon::TFRI_cNotPt_f: {
1206 unsigned Opx = (Opc == Hexagon::TFRI_f) ? 1 : 2;
1207 APFloat FVal = MI->getOperand(Opx).getFPImm()->getValueAPF();
1208 APInt IVal = FVal.bitcastToAPInt();
1209 MI->RemoveOperand(Opx);
1210 unsigned NewOpc = (Opc == Hexagon::TFRI_f) ? Hexagon::A2_tfrsi :
1211 (Opc == Hexagon::TFRI_cPt_f) ? Hexagon::C2_cmoveit :
1212 Hexagon::C2_cmoveif;
1213 MI->setDesc(get(NewOpc));
1214 MI->addOperand(MachineOperand::CreateImm(IVal.getZExtValue()));
1215 return true;
1216 }
Colin LeMahieu7b1799c2015-03-09 22:05:21 +00001217 }
1218
1219 return false;
1220}
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001221
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001222
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001223// We indicate that we want to reverse the branch by
1224// inserting the reversed branching opcode.
1225bool HexagonInstrInfo::ReverseBranchCondition(
1226 SmallVectorImpl<MachineOperand> &Cond) const {
1227 if (Cond.empty())
Jyotsna Vermaf1214a82013-03-05 18:51:42 +00001228 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001229 assert(Cond[0].isImm() && "First entry in the cond vector not imm-val");
1230 unsigned opcode = Cond[0].getImm();
1231 //unsigned temp;
1232 assert(get(opcode).isBranch() && "Should be a branching condition.");
1233 if (isEndLoopN(opcode))
Jyotsna Vermaf1214a82013-03-05 18:51:42 +00001234 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001235 unsigned NewOpcode = getInvertedPredicatedOpcode(opcode);
1236 Cond[0].setImm(NewOpcode);
Jyotsna Vermaf1214a82013-03-05 18:51:42 +00001237 return false;
1238}
1239
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001240
1241void HexagonInstrInfo::insertNoop(MachineBasicBlock &MBB,
1242 MachineBasicBlock::iterator MI) const {
1243 DebugLoc DL;
1244 BuildMI(MBB, MI, DL, get(Hexagon::A2_nop));
1245}
1246
1247
1248// Returns true if an instruction is predicated irrespective of the predicate
1249// sense. For example, all of the following will return true.
1250// if (p0) R1 = add(R2, R3)
1251// if (!p0) R1 = add(R2, R3)
1252// if (p0.new) R1 = add(R2, R3)
1253// if (!p0.new) R1 = add(R2, R3)
1254// Note: New-value stores are not included here as in the current
1255// implementation, we don't need to check their predicate sense.
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001256bool HexagonInstrInfo::isPredicated(const MachineInstr &MI) const {
1257 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001258 return (F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask;
Brendon Cahoondf43e682015-05-08 16:16:29 +00001259}
1260
Krzysztof Parzyszek0a04ac22016-05-16 16:56:10 +00001261
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001262bool HexagonInstrInfo::PredicateInstruction(
1263 MachineInstr &MI, ArrayRef<MachineOperand> Cond) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001264 if (Cond.empty() || isNewValueJump(Cond[0].getImm()) ||
1265 isEndLoopN(Cond[0].getImm())) {
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001266 DEBUG(dbgs() << "\nCannot predicate:"; MI.dump(););
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001267 return false;
1268 }
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001269 int Opc = MI.getOpcode();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001270 assert (isPredicable(MI) && "Expected predicable instruction");
1271 bool invertJump = predOpcodeHasNot(Cond);
1272
1273 // We have to predicate MI "in place", i.e. after this function returns,
1274 // MI will need to be transformed into a predicated form. To avoid com-
1275 // plicated manipulations with the operands (handling tied operands,
1276 // etc.), build a new temporary instruction, then overwrite MI with it.
1277
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001278 MachineBasicBlock &B = *MI.getParent();
1279 DebugLoc DL = MI.getDebugLoc();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001280 unsigned PredOpc = getCondOpcode(Opc, invertJump);
1281 MachineInstrBuilder T = BuildMI(B, MI, DL, get(PredOpc));
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001282 unsigned NOp = 0, NumOps = MI.getNumOperands();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001283 while (NOp < NumOps) {
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001284 MachineOperand &Op = MI.getOperand(NOp);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001285 if (!Op.isReg() || !Op.isDef() || Op.isImplicit())
1286 break;
1287 T.addOperand(Op);
1288 NOp++;
1289 }
1290
1291 unsigned PredReg, PredRegPos, PredRegFlags;
1292 bool GotPredReg = getPredReg(Cond, PredReg, PredRegPos, PredRegFlags);
1293 (void)GotPredReg;
1294 assert(GotPredReg);
1295 T.addReg(PredReg, PredRegFlags);
1296 while (NOp < NumOps)
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001297 T.addOperand(MI.getOperand(NOp++));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001298
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001299 MI.setDesc(get(PredOpc));
1300 while (unsigned n = MI.getNumOperands())
1301 MI.RemoveOperand(n-1);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001302 for (unsigned i = 0, n = T->getNumOperands(); i < n; ++i)
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001303 MI.addOperand(T->getOperand(i));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001304
Duncan P. N. Exon Smithc5b668d2016-02-22 20:49:58 +00001305 MachineBasicBlock::instr_iterator TI = T->getIterator();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001306 B.erase(TI);
1307
1308 MachineRegisterInfo &MRI = B.getParent()->getRegInfo();
1309 MRI.clearKillFlags(PredReg);
1310 return true;
Brendon Cahoondf43e682015-05-08 16:16:29 +00001311}
1312
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001313
1314bool HexagonInstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
1315 ArrayRef<MachineOperand> Pred2) const {
1316 // TODO: Fix this
1317 return false;
1318}
1319
Krzysztof Parzyszek0a04ac22016-05-16 16:56:10 +00001320
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001321bool HexagonInstrInfo::DefinesPredicate(
1322 MachineInstr &MI, std::vector<MachineOperand> &Pred) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001323 auto &HRI = getRegisterInfo();
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001324 for (unsigned oper = 0; oper < MI.getNumOperands(); ++oper) {
1325 MachineOperand MO = MI.getOperand(oper);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001326 if (MO.isReg() && MO.isDef()) {
1327 const TargetRegisterClass* RC = HRI.getMinimalPhysRegClass(MO.getReg());
1328 if (RC == &Hexagon::PredRegsRegClass) {
1329 Pred.push_back(MO);
1330 return true;
1331 }
1332 }
1333 }
1334 return false;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +00001335}
Andrew Trickd06df962012-02-01 22:13:57 +00001336
Krzysztof Parzyszek0a04ac22016-05-16 16:56:10 +00001337
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001338bool HexagonInstrInfo::isPredicable(MachineInstr &MI) const {
Krzysztof Parzyszek0a04ac22016-05-16 16:56:10 +00001339 return MI.getDesc().isPredicable();
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001340}
1341
Jyotsna Verma84c47102013-05-06 18:49:23 +00001342
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001343bool HexagonInstrInfo::isSchedulingBoundary(const MachineInstr *MI,
1344 const MachineBasicBlock *MBB, const MachineFunction &MF) const {
1345 // Debug info is never a scheduling boundary. It's necessary to be explicit
1346 // due to the special treatment of IT instructions below, otherwise a
1347 // dbg_value followed by an IT will result in the IT instruction being
1348 // considered a scheduling hazard, which is wrong. It should be the actual
1349 // instruction preceding the dbg_value instruction(s), just like it is
1350 // when debug info is not present.
1351 if (MI->isDebugValue())
Brendon Cahoondf43e682015-05-08 16:16:29 +00001352 return false;
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001353
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001354 // Throwing call is a boundary.
1355 if (MI->isCall()) {
1356 // If any of the block's successors is a landing pad, this could be a
1357 // throwing call.
1358 for (auto I : MBB->successors())
1359 if (I->isEHPad())
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001360 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001361 }
1362
1363 // Don't mess around with no return calls.
1364 if (MI->getOpcode() == Hexagon::CALLv3nr)
1365 return true;
1366
1367 // Terminators and labels can't be scheduled around.
1368 if (MI->getDesc().isTerminator() || MI->isPosition())
1369 return true;
1370
1371 if (MI->isInlineAsm() && !ScheduleInlineAsm)
1372 return true;
1373
1374 return false;
1375}
1376
1377
1378/// Measure the specified inline asm to determine an approximation of its
1379/// length.
1380/// Comments (which run till the next SeparatorString or newline) do not
1381/// count as an instruction.
1382/// Any other non-whitespace text is considered an instruction, with
1383/// multiple instructions separated by SeparatorString or newlines.
1384/// Variable-length instructions are not handled here; this function
1385/// may be overloaded in the target code to do that.
1386/// Hexagon counts the number of ##'s and adjust for that many
1387/// constant exenders.
1388unsigned HexagonInstrInfo::getInlineAsmLength(const char *Str,
1389 const MCAsmInfo &MAI) const {
1390 StringRef AStr(Str);
1391 // Count the number of instructions in the asm.
1392 bool atInsnStart = true;
1393 unsigned Length = 0;
1394 for (; *Str; ++Str) {
1395 if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
1396 strlen(MAI.getSeparatorString())) == 0)
1397 atInsnStart = true;
1398 if (atInsnStart && !std::isspace(static_cast<unsigned char>(*Str))) {
1399 Length += MAI.getMaxInstLength();
1400 atInsnStart = false;
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001401 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001402 if (atInsnStart && strncmp(Str, MAI.getCommentString(),
1403 strlen(MAI.getCommentString())) == 0)
1404 atInsnStart = false;
1405 }
1406
1407 // Add to size number of constant extenders seen * 4.
1408 StringRef Occ("##");
1409 Length += AStr.count(Occ)*4;
1410 return Length;
1411}
1412
1413
1414ScheduleHazardRecognizer*
1415HexagonInstrInfo::CreateTargetPostRAHazardRecognizer(
1416 const InstrItineraryData *II, const ScheduleDAG *DAG) const {
1417 return TargetInstrInfo::CreateTargetPostRAHazardRecognizer(II, DAG);
1418}
1419
1420
1421/// \brief For a comparison instruction, return the source registers in
1422/// \p SrcReg and \p SrcReg2 if having two register operands, and the value it
1423/// compares against in CmpValue. Return true if the comparison instruction
1424/// can be analyzed.
1425bool HexagonInstrInfo::analyzeCompare(const MachineInstr *MI,
1426 unsigned &SrcReg, unsigned &SrcReg2, int &Mask, int &Value) const {
1427 unsigned Opc = MI->getOpcode();
1428
1429 // Set mask and the first source register.
1430 switch (Opc) {
1431 case Hexagon::C2_cmpeq:
1432 case Hexagon::C2_cmpeqp:
1433 case Hexagon::C2_cmpgt:
1434 case Hexagon::C2_cmpgtp:
1435 case Hexagon::C2_cmpgtu:
1436 case Hexagon::C2_cmpgtup:
1437 case Hexagon::C4_cmpneq:
1438 case Hexagon::C4_cmplte:
1439 case Hexagon::C4_cmplteu:
1440 case Hexagon::C2_cmpeqi:
1441 case Hexagon::C2_cmpgti:
1442 case Hexagon::C2_cmpgtui:
1443 case Hexagon::C4_cmpneqi:
1444 case Hexagon::C4_cmplteui:
1445 case Hexagon::C4_cmpltei:
1446 SrcReg = MI->getOperand(1).getReg();
1447 Mask = ~0;
1448 break;
1449 case Hexagon::A4_cmpbeq:
1450 case Hexagon::A4_cmpbgt:
1451 case Hexagon::A4_cmpbgtu:
1452 case Hexagon::A4_cmpbeqi:
1453 case Hexagon::A4_cmpbgti:
1454 case Hexagon::A4_cmpbgtui:
1455 SrcReg = MI->getOperand(1).getReg();
1456 Mask = 0xFF;
1457 break;
1458 case Hexagon::A4_cmpheq:
1459 case Hexagon::A4_cmphgt:
1460 case Hexagon::A4_cmphgtu:
1461 case Hexagon::A4_cmpheqi:
1462 case Hexagon::A4_cmphgti:
1463 case Hexagon::A4_cmphgtui:
1464 SrcReg = MI->getOperand(1).getReg();
1465 Mask = 0xFFFF;
1466 break;
1467 }
1468
1469 // Set the value/second source register.
1470 switch (Opc) {
1471 case Hexagon::C2_cmpeq:
1472 case Hexagon::C2_cmpeqp:
1473 case Hexagon::C2_cmpgt:
1474 case Hexagon::C2_cmpgtp:
1475 case Hexagon::C2_cmpgtu:
1476 case Hexagon::C2_cmpgtup:
1477 case Hexagon::A4_cmpbeq:
1478 case Hexagon::A4_cmpbgt:
1479 case Hexagon::A4_cmpbgtu:
1480 case Hexagon::A4_cmpheq:
1481 case Hexagon::A4_cmphgt:
1482 case Hexagon::A4_cmphgtu:
1483 case Hexagon::C4_cmpneq:
1484 case Hexagon::C4_cmplte:
1485 case Hexagon::C4_cmplteu:
1486 SrcReg2 = MI->getOperand(2).getReg();
1487 return true;
1488
1489 case Hexagon::C2_cmpeqi:
1490 case Hexagon::C2_cmpgtui:
1491 case Hexagon::C2_cmpgti:
1492 case Hexagon::C4_cmpneqi:
1493 case Hexagon::C4_cmplteui:
1494 case Hexagon::C4_cmpltei:
1495 case Hexagon::A4_cmpbeqi:
1496 case Hexagon::A4_cmpbgti:
1497 case Hexagon::A4_cmpbgtui:
1498 case Hexagon::A4_cmpheqi:
1499 case Hexagon::A4_cmphgti:
1500 case Hexagon::A4_cmphgtui:
1501 SrcReg2 = 0;
1502 Value = MI->getOperand(2).getImm();
1503 return true;
1504 }
1505
1506 return false;
1507}
1508
1509
1510unsigned HexagonInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
1511 const MachineInstr *MI, unsigned *PredCost) const {
1512 return getInstrTimingClassLatency(ItinData, MI);
1513}
1514
1515
1516DFAPacketizer *HexagonInstrInfo::CreateTargetScheduleState(
1517 const TargetSubtargetInfo &STI) const {
1518 const InstrItineraryData *II = STI.getInstrItineraryData();
1519 return static_cast<const HexagonSubtarget&>(STI).createDFAPacketizer(II);
1520}
1521
1522
1523// Inspired by this pair:
1524// %R13<def> = L2_loadri_io %R29, 136; mem:LD4[FixedStack0]
1525// S2_storeri_io %R29, 132, %R1<kill>; flags: mem:ST4[FixedStack1]
1526// Currently AA considers the addresses in these instructions to be aliasing.
1527bool HexagonInstrInfo::areMemAccessesTriviallyDisjoint(MachineInstr *MIa,
1528 MachineInstr *MIb, AliasAnalysis *AA) const {
1529 int OffsetA = 0, OffsetB = 0;
1530 unsigned SizeA = 0, SizeB = 0;
1531
1532 if (MIa->hasUnmodeledSideEffects() || MIb->hasUnmodeledSideEffects() ||
Krzysztof Parzyszekf2a4f8f2016-06-15 21:05:04 +00001533 MIa->hasOrderedMemoryRef() || MIb->hasOrderedMemoryRef())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001534 return false;
1535
1536 // Instructions that are pure loads, not loads and stores like memops are not
1537 // dependent.
1538 if (MIa->mayLoad() && !isMemOp(MIa) && MIb->mayLoad() && !isMemOp(MIb))
1539 return true;
1540
1541 // Get base, offset, and access size in MIa.
1542 unsigned BaseRegA = getBaseAndOffset(MIa, OffsetA, SizeA);
1543 if (!BaseRegA || !SizeA)
1544 return false;
1545
1546 // Get base, offset, and access size in MIb.
1547 unsigned BaseRegB = getBaseAndOffset(MIb, OffsetB, SizeB);
1548 if (!BaseRegB || !SizeB)
1549 return false;
1550
1551 if (BaseRegA != BaseRegB)
1552 return false;
1553
1554 // This is a mem access with the same base register and known offsets from it.
1555 // Reason about it.
1556 if (OffsetA > OffsetB) {
1557 uint64_t offDiff = (uint64_t)((int64_t)OffsetA - (int64_t)OffsetB);
1558 return (SizeB <= offDiff);
1559 } else if (OffsetA < OffsetB) {
1560 uint64_t offDiff = (uint64_t)((int64_t)OffsetB - (int64_t)OffsetA);
1561 return (SizeA <= offDiff);
1562 }
1563
1564 return false;
1565}
1566
1567
1568unsigned HexagonInstrInfo::createVR(MachineFunction* MF, MVT VT) const {
1569 MachineRegisterInfo &MRI = MF->getRegInfo();
1570 const TargetRegisterClass *TRC;
1571 if (VT == MVT::i1) {
1572 TRC = &Hexagon::PredRegsRegClass;
1573 } else if (VT == MVT::i32 || VT == MVT::f32) {
1574 TRC = &Hexagon::IntRegsRegClass;
1575 } else if (VT == MVT::i64 || VT == MVT::f64) {
1576 TRC = &Hexagon::DoubleRegsRegClass;
1577 } else {
1578 llvm_unreachable("Cannot handle this register class");
1579 }
1580
1581 unsigned NewReg = MRI.createVirtualRegister(TRC);
1582 return NewReg;
1583}
1584
1585
1586bool HexagonInstrInfo::isAbsoluteSet(const MachineInstr* MI) const {
1587 return (getAddrMode(MI) == HexagonII::AbsoluteSet);
1588}
1589
1590
1591bool HexagonInstrInfo::isAccumulator(const MachineInstr *MI) const {
1592 const uint64_t F = MI->getDesc().TSFlags;
1593 return((F >> HexagonII::AccumulatorPos) & HexagonII::AccumulatorMask);
1594}
1595
1596
1597bool HexagonInstrInfo::isComplex(const MachineInstr *MI) const {
1598 const MachineFunction *MF = MI->getParent()->getParent();
1599 const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
1600 const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
1601
1602 if (!(isTC1(MI))
1603 && !(QII->isTC2Early(MI))
1604 && !(MI->getDesc().mayLoad())
1605 && !(MI->getDesc().mayStore())
1606 && (MI->getDesc().getOpcode() != Hexagon::S2_allocframe)
1607 && (MI->getDesc().getOpcode() != Hexagon::L2_deallocframe)
1608 && !(QII->isMemOp(MI))
1609 && !(MI->isBranch())
1610 && !(MI->isReturn())
1611 && !MI->isCall())
1612 return true;
1613
1614 return false;
1615}
1616
1617
Sanjay Patele4b9f502015-12-07 19:21:39 +00001618// Return true if the instruction is a compund branch instruction.
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001619bool HexagonInstrInfo::isCompoundBranchInstr(const MachineInstr *MI) const {
1620 return (getType(MI) == HexagonII::TypeCOMPOUND && MI->isBranch());
1621}
1622
1623
1624bool HexagonInstrInfo::isCondInst(const MachineInstr *MI) const {
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001625 return (MI->isBranch() && isPredicated(*MI)) ||
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001626 isConditionalTransfer(MI) ||
1627 isConditionalALU32(MI) ||
1628 isConditionalLoad(MI) ||
1629 // Predicated stores which don't have a .new on any operands.
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001630 (MI->mayStore() && isPredicated(*MI) && !isNewValueStore(MI) &&
1631 !isPredicatedNew(*MI));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001632}
1633
1634
1635bool HexagonInstrInfo::isConditionalALU32(const MachineInstr* MI) const {
1636 switch (MI->getOpcode()) {
1637 case Hexagon::A2_paddf:
1638 case Hexagon::A2_paddfnew:
1639 case Hexagon::A2_paddif:
1640 case Hexagon::A2_paddifnew:
1641 case Hexagon::A2_paddit:
1642 case Hexagon::A2_padditnew:
1643 case Hexagon::A2_paddt:
1644 case Hexagon::A2_paddtnew:
1645 case Hexagon::A2_pandf:
1646 case Hexagon::A2_pandfnew:
1647 case Hexagon::A2_pandt:
1648 case Hexagon::A2_pandtnew:
1649 case Hexagon::A2_porf:
1650 case Hexagon::A2_porfnew:
1651 case Hexagon::A2_port:
1652 case Hexagon::A2_portnew:
1653 case Hexagon::A2_psubf:
1654 case Hexagon::A2_psubfnew:
1655 case Hexagon::A2_psubt:
1656 case Hexagon::A2_psubtnew:
1657 case Hexagon::A2_pxorf:
1658 case Hexagon::A2_pxorfnew:
1659 case Hexagon::A2_pxort:
1660 case Hexagon::A2_pxortnew:
1661 case Hexagon::A4_paslhf:
1662 case Hexagon::A4_paslhfnew:
1663 case Hexagon::A4_paslht:
1664 case Hexagon::A4_paslhtnew:
1665 case Hexagon::A4_pasrhf:
1666 case Hexagon::A4_pasrhfnew:
1667 case Hexagon::A4_pasrht:
1668 case Hexagon::A4_pasrhtnew:
1669 case Hexagon::A4_psxtbf:
1670 case Hexagon::A4_psxtbfnew:
1671 case Hexagon::A4_psxtbt:
1672 case Hexagon::A4_psxtbtnew:
1673 case Hexagon::A4_psxthf:
1674 case Hexagon::A4_psxthfnew:
1675 case Hexagon::A4_psxtht:
1676 case Hexagon::A4_psxthtnew:
1677 case Hexagon::A4_pzxtbf:
1678 case Hexagon::A4_pzxtbfnew:
1679 case Hexagon::A4_pzxtbt:
1680 case Hexagon::A4_pzxtbtnew:
1681 case Hexagon::A4_pzxthf:
1682 case Hexagon::A4_pzxthfnew:
1683 case Hexagon::A4_pzxtht:
1684 case Hexagon::A4_pzxthtnew:
1685 case Hexagon::C2_ccombinewf:
1686 case Hexagon::C2_ccombinewt:
1687 return true;
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001688 }
1689 return false;
1690}
1691
1692
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001693// FIXME - Function name and it's functionality don't match.
1694// It should be renamed to hasPredNewOpcode()
1695bool HexagonInstrInfo::isConditionalLoad(const MachineInstr* MI) const {
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001696 if (!MI->getDesc().mayLoad() || !isPredicated(*MI))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001697 return false;
1698
1699 int PNewOpcode = Hexagon::getPredNewOpcode(MI->getOpcode());
1700 // Instruction with valid predicated-new opcode can be promoted to .new.
1701 return PNewOpcode >= 0;
1702}
1703
1704
1705// Returns true if an instruction is a conditional store.
1706//
1707// Note: It doesn't include conditional new-value stores as they can't be
1708// converted to .new predicate.
1709bool HexagonInstrInfo::isConditionalStore(const MachineInstr* MI) const {
1710 switch (MI->getOpcode()) {
1711 default: return false;
1712 case Hexagon::S4_storeirbt_io:
1713 case Hexagon::S4_storeirbf_io:
1714 case Hexagon::S4_pstorerbt_rr:
1715 case Hexagon::S4_pstorerbf_rr:
1716 case Hexagon::S2_pstorerbt_io:
1717 case Hexagon::S2_pstorerbf_io:
1718 case Hexagon::S2_pstorerbt_pi:
1719 case Hexagon::S2_pstorerbf_pi:
1720 case Hexagon::S2_pstorerdt_io:
1721 case Hexagon::S2_pstorerdf_io:
1722 case Hexagon::S4_pstorerdt_rr:
1723 case Hexagon::S4_pstorerdf_rr:
1724 case Hexagon::S2_pstorerdt_pi:
1725 case Hexagon::S2_pstorerdf_pi:
1726 case Hexagon::S2_pstorerht_io:
1727 case Hexagon::S2_pstorerhf_io:
1728 case Hexagon::S4_storeirht_io:
1729 case Hexagon::S4_storeirhf_io:
1730 case Hexagon::S4_pstorerht_rr:
1731 case Hexagon::S4_pstorerhf_rr:
1732 case Hexagon::S2_pstorerht_pi:
1733 case Hexagon::S2_pstorerhf_pi:
1734 case Hexagon::S2_pstorerit_io:
1735 case Hexagon::S2_pstorerif_io:
1736 case Hexagon::S4_storeirit_io:
1737 case Hexagon::S4_storeirif_io:
1738 case Hexagon::S4_pstorerit_rr:
1739 case Hexagon::S4_pstorerif_rr:
1740 case Hexagon::S2_pstorerit_pi:
1741 case Hexagon::S2_pstorerif_pi:
1742
1743 // V4 global address store before promoting to dot new.
1744 case Hexagon::S4_pstorerdt_abs:
1745 case Hexagon::S4_pstorerdf_abs:
1746 case Hexagon::S4_pstorerbt_abs:
1747 case Hexagon::S4_pstorerbf_abs:
1748 case Hexagon::S4_pstorerht_abs:
1749 case Hexagon::S4_pstorerhf_abs:
1750 case Hexagon::S4_pstorerit_abs:
1751 case Hexagon::S4_pstorerif_abs:
1752 return true;
1753
1754 // Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded
1755 // from the "Conditional Store" list. Because a predicated new value store
1756 // would NOT be promoted to a double dot new store.
1757 // This function returns yes for those stores that are predicated but not
1758 // yet promoted to predicate dot new instructions.
1759 }
1760}
1761
1762
1763bool HexagonInstrInfo::isConditionalTransfer(const MachineInstr *MI) const {
1764 switch (MI->getOpcode()) {
1765 case Hexagon::A2_tfrt:
1766 case Hexagon::A2_tfrf:
1767 case Hexagon::C2_cmoveit:
1768 case Hexagon::C2_cmoveif:
1769 case Hexagon::A2_tfrtnew:
1770 case Hexagon::A2_tfrfnew:
1771 case Hexagon::C2_cmovenewit:
1772 case Hexagon::C2_cmovenewif:
1773 case Hexagon::A2_tfrpt:
1774 case Hexagon::A2_tfrpf:
1775 return true;
1776
1777 default:
1778 return false;
1779 }
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001780 return false;
1781}
1782
1783
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001784// TODO: In order to have isExtendable for fpimm/f32Ext, we need to handle
1785// isFPImm and later getFPImm as well.
1786bool HexagonInstrInfo::isConstExtended(const MachineInstr *MI) const {
1787 const uint64_t F = MI->getDesc().TSFlags;
1788 unsigned isExtended = (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
1789 if (isExtended) // Instruction must be extended.
Krzysztof Parzyszekc6f19332015-03-19 15:18:57 +00001790 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001791
1792 unsigned isExtendable =
1793 (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;
1794 if (!isExtendable)
1795 return false;
1796
1797 if (MI->isCall())
1798 return false;
1799
1800 short ExtOpNum = getCExtOpNum(MI);
1801 const MachineOperand &MO = MI->getOperand(ExtOpNum);
1802 // Use MO operand flags to determine if MO
1803 // has the HMOTF_ConstExtended flag set.
1804 if (MO.getTargetFlags() && HexagonII::HMOTF_ConstExtended)
Brendon Cahoondf43e682015-05-08 16:16:29 +00001805 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001806 // If this is a Machine BB address we are talking about, and it is
1807 // not marked as extended, say so.
1808 if (MO.isMBB())
1809 return false;
1810
1811 // We could be using an instruction with an extendable immediate and shoehorn
1812 // a global address into it. If it is a global address it will be constant
1813 // extended. We do this for COMBINE.
1814 // We currently only handle isGlobal() because it is the only kind of
1815 // object we are going to end up with here for now.
1816 // In the future we probably should add isSymbol(), etc.
1817 if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress() ||
1818 MO.isJTI() || MO.isCPI())
1819 return true;
1820
1821 // If the extendable operand is not 'Immediate' type, the instruction should
1822 // have 'isExtended' flag set.
1823 assert(MO.isImm() && "Extendable operand must be Immediate type");
1824
1825 int MinValue = getMinValue(MI);
1826 int MaxValue = getMaxValue(MI);
1827 int ImmValue = MO.getImm();
1828
1829 return (ImmValue < MinValue || ImmValue > MaxValue);
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001830}
1831
1832
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001833bool HexagonInstrInfo::isDeallocRet(const MachineInstr *MI) const {
1834 switch (MI->getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001835 case Hexagon::L4_return :
1836 case Hexagon::L4_return_t :
1837 case Hexagon::L4_return_f :
1838 case Hexagon::L4_return_tnew_pnt :
1839 case Hexagon::L4_return_fnew_pnt :
1840 case Hexagon::L4_return_tnew_pt :
1841 case Hexagon::L4_return_fnew_pt :
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001842 return true;
1843 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001844 return false;
1845}
1846
1847
1848// Return true when ConsMI uses a register defined by ProdMI.
1849bool HexagonInstrInfo::isDependent(const MachineInstr *ProdMI,
1850 const MachineInstr *ConsMI) const {
1851 const MCInstrDesc &ProdMCID = ProdMI->getDesc();
1852 if (!ProdMCID.getNumDefs())
1853 return false;
1854
1855 auto &HRI = getRegisterInfo();
1856
1857 SmallVector<unsigned, 4> DefsA;
1858 SmallVector<unsigned, 4> DefsB;
1859 SmallVector<unsigned, 8> UsesA;
1860 SmallVector<unsigned, 8> UsesB;
1861
1862 parseOperands(ProdMI, DefsA, UsesA);
1863 parseOperands(ConsMI, DefsB, UsesB);
1864
1865 for (auto &RegA : DefsA)
1866 for (auto &RegB : UsesB) {
1867 // True data dependency.
1868 if (RegA == RegB)
1869 return true;
1870
1871 if (Hexagon::DoubleRegsRegClass.contains(RegA))
1872 for (MCSubRegIterator SubRegs(RegA, &HRI); SubRegs.isValid(); ++SubRegs)
1873 if (RegB == *SubRegs)
1874 return true;
1875
1876 if (Hexagon::DoubleRegsRegClass.contains(RegB))
1877 for (MCSubRegIterator SubRegs(RegB, &HRI); SubRegs.isValid(); ++SubRegs)
1878 if (RegA == *SubRegs)
1879 return true;
1880 }
1881
1882 return false;
1883}
1884
1885
1886// Returns true if the instruction is alread a .cur.
1887bool HexagonInstrInfo::isDotCurInst(const MachineInstr* MI) const {
1888 switch (MI->getOpcode()) {
1889 case Hexagon::V6_vL32b_cur_pi:
1890 case Hexagon::V6_vL32b_cur_ai:
1891 case Hexagon::V6_vL32b_cur_pi_128B:
1892 case Hexagon::V6_vL32b_cur_ai_128B:
1893 return true;
1894 }
1895 return false;
1896}
1897
1898
1899// Returns true, if any one of the operands is a dot new
1900// insn, whether it is predicated dot new or register dot new.
1901bool HexagonInstrInfo::isDotNewInst(const MachineInstr* MI) const {
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001902 if (isNewValueInst(MI) || (isPredicated(*MI) && isPredicatedNew(*MI)))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001903 return true;
1904
1905 return false;
1906}
1907
1908
1909/// Symmetrical. See if these two instructions are fit for duplex pair.
1910bool HexagonInstrInfo::isDuplexPair(const MachineInstr *MIa,
1911 const MachineInstr *MIb) const {
1912 HexagonII::SubInstructionGroup MIaG = getDuplexCandidateGroup(MIa);
1913 HexagonII::SubInstructionGroup MIbG = getDuplexCandidateGroup(MIb);
1914 return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));
1915}
1916
1917
Krzysztof Parzyszek5e6f2bd2015-12-14 21:32:25 +00001918bool HexagonInstrInfo::isEarlySourceInstr(const MachineInstr *MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001919 if (!MI)
1920 return false;
1921
1922 if (MI->mayLoad() || MI->mayStore() || MI->isCompare())
1923 return true;
1924
1925 // Multiply
1926 unsigned SchedClass = MI->getDesc().getSchedClass();
1927 if (SchedClass == Hexagon::Sched::M_tc_3or4x_SLOT23)
1928 return true;
1929 return false;
1930}
1931
1932
1933bool HexagonInstrInfo::isEndLoopN(unsigned Opcode) const {
1934 return (Opcode == Hexagon::ENDLOOP0 ||
1935 Opcode == Hexagon::ENDLOOP1);
1936}
1937
1938
1939bool HexagonInstrInfo::isExpr(unsigned OpType) const {
1940 switch(OpType) {
1941 case MachineOperand::MO_MachineBasicBlock:
1942 case MachineOperand::MO_GlobalAddress:
1943 case MachineOperand::MO_ExternalSymbol:
1944 case MachineOperand::MO_JumpTableIndex:
1945 case MachineOperand::MO_ConstantPoolIndex:
1946 case MachineOperand::MO_BlockAddress:
1947 return true;
1948 default:
1949 return false;
1950 }
1951}
1952
1953
1954bool HexagonInstrInfo::isExtendable(const MachineInstr *MI) const {
1955 const MCInstrDesc &MID = MI->getDesc();
1956 const uint64_t F = MID.TSFlags;
1957 if ((F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask)
1958 return true;
1959
1960 // TODO: This is largely obsolete now. Will need to be removed
1961 // in consecutive patches.
1962 switch(MI->getOpcode()) {
1963 // TFR_FI Remains a special case.
1964 case Hexagon::TFR_FI:
1965 return true;
1966 default:
1967 return false;
1968 }
1969 return false;
1970}
1971
1972
1973// This returns true in two cases:
1974// - The OP code itself indicates that this is an extended instruction.
1975// - One of MOs has been marked with HMOTF_ConstExtended flag.
1976bool HexagonInstrInfo::isExtended(const MachineInstr *MI) const {
1977 // First check if this is permanently extended op code.
1978 const uint64_t F = MI->getDesc().TSFlags;
1979 if ((F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask)
1980 return true;
1981 // Use MO operand flags to determine if one of MI's operands
1982 // has HMOTF_ConstExtended flag set.
1983 for (MachineInstr::const_mop_iterator I = MI->operands_begin(),
1984 E = MI->operands_end(); I != E; ++I) {
1985 if (I->getTargetFlags() && HexagonII::HMOTF_ConstExtended)
1986 return true;
1987 }
1988 return false;
1989}
1990
1991
Krzysztof Parzyszek5e6f2bd2015-12-14 21:32:25 +00001992bool HexagonInstrInfo::isFloat(const MachineInstr *MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001993 unsigned Opcode = MI->getOpcode();
1994 const uint64_t F = get(Opcode).TSFlags;
1995 return (F >> HexagonII::FPPos) & HexagonII::FPMask;
1996}
1997
1998
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00001999// No V60 HVX VMEM with A_INDIRECT.
2000bool HexagonInstrInfo::isHVXMemWithAIndirect(const MachineInstr *I,
2001 const MachineInstr *J) const {
2002 if (!isV60VectorInstruction(I))
2003 return false;
2004 if (!I->mayLoad() && !I->mayStore())
2005 return false;
2006 return J->isIndirectBranch() || isIndirectCall(J) || isIndirectL4Return(J);
2007}
2008
2009
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002010bool HexagonInstrInfo::isIndirectCall(const MachineInstr *MI) const {
2011 switch (MI->getOpcode()) {
2012 case Hexagon::J2_callr :
2013 case Hexagon::J2_callrf :
2014 case Hexagon::J2_callrt :
2015 return true;
2016 }
2017 return false;
2018}
2019
2020
2021bool HexagonInstrInfo::isIndirectL4Return(const MachineInstr *MI) const {
2022 switch (MI->getOpcode()) {
2023 case Hexagon::L4_return :
2024 case Hexagon::L4_return_t :
2025 case Hexagon::L4_return_f :
2026 case Hexagon::L4_return_fnew_pnt :
2027 case Hexagon::L4_return_fnew_pt :
2028 case Hexagon::L4_return_tnew_pnt :
2029 case Hexagon::L4_return_tnew_pt :
2030 return true;
2031 }
2032 return false;
2033}
2034
2035
2036bool HexagonInstrInfo::isJumpR(const MachineInstr *MI) const {
2037 switch (MI->getOpcode()) {
2038 case Hexagon::J2_jumpr :
2039 case Hexagon::J2_jumprt :
2040 case Hexagon::J2_jumprf :
2041 case Hexagon::J2_jumprtnewpt :
2042 case Hexagon::J2_jumprfnewpt :
2043 case Hexagon::J2_jumprtnew :
2044 case Hexagon::J2_jumprfnew :
2045 return true;
2046 }
2047 return false;
2048}
2049
2050
2051// Return true if a given MI can accomodate given offset.
2052// Use abs estimate as oppose to the exact number.
2053// TODO: This will need to be changed to use MC level
2054// definition of instruction extendable field size.
2055bool HexagonInstrInfo::isJumpWithinBranchRange(const MachineInstr *MI,
2056 unsigned offset) const {
2057 // This selection of jump instructions matches to that what
2058 // AnalyzeBranch can parse, plus NVJ.
2059 if (isNewValueJump(MI)) // r9:2
2060 return isInt<11>(offset);
2061
2062 switch (MI->getOpcode()) {
2063 // Still missing Jump to address condition on register value.
2064 default:
2065 return false;
2066 case Hexagon::J2_jump: // bits<24> dst; // r22:2
2067 case Hexagon::J2_call:
2068 case Hexagon::CALLv3nr:
2069 return isInt<24>(offset);
2070 case Hexagon::J2_jumpt: //bits<17> dst; // r15:2
2071 case Hexagon::J2_jumpf:
2072 case Hexagon::J2_jumptnew:
2073 case Hexagon::J2_jumptnewpt:
2074 case Hexagon::J2_jumpfnew:
2075 case Hexagon::J2_jumpfnewpt:
2076 case Hexagon::J2_callt:
2077 case Hexagon::J2_callf:
2078 return isInt<17>(offset);
2079 case Hexagon::J2_loop0i:
2080 case Hexagon::J2_loop0iext:
2081 case Hexagon::J2_loop0r:
2082 case Hexagon::J2_loop0rext:
2083 case Hexagon::J2_loop1i:
2084 case Hexagon::J2_loop1iext:
2085 case Hexagon::J2_loop1r:
2086 case Hexagon::J2_loop1rext:
2087 return isInt<9>(offset);
2088 // TODO: Add all the compound branches here. Can we do this in Relation model?
2089 case Hexagon::J4_cmpeqi_tp0_jump_nt:
2090 case Hexagon::J4_cmpeqi_tp1_jump_nt:
2091 return isInt<11>(offset);
2092 }
2093}
2094
2095
Krzysztof Parzyszek5e6f2bd2015-12-14 21:32:25 +00002096bool HexagonInstrInfo::isLateInstrFeedsEarlyInstr(const MachineInstr *LRMI,
2097 const MachineInstr *ESMI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002098 if (!LRMI || !ESMI)
2099 return false;
2100
2101 bool isLate = isLateResultInstr(LRMI);
2102 bool isEarly = isEarlySourceInstr(ESMI);
2103
2104 DEBUG(dbgs() << "V60" << (isLate ? "-LR " : " -- "));
2105 DEBUG(LRMI->dump());
2106 DEBUG(dbgs() << "V60" << (isEarly ? "-ES " : " -- "));
2107 DEBUG(ESMI->dump());
2108
2109 if (isLate && isEarly) {
2110 DEBUG(dbgs() << "++Is Late Result feeding Early Source\n");
2111 return true;
2112 }
2113
2114 return false;
2115}
2116
2117
Krzysztof Parzyszek5e6f2bd2015-12-14 21:32:25 +00002118bool HexagonInstrInfo::isLateResultInstr(const MachineInstr *MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002119 if (!MI)
2120 return false;
2121
2122 switch (MI->getOpcode()) {
2123 case TargetOpcode::EXTRACT_SUBREG:
2124 case TargetOpcode::INSERT_SUBREG:
2125 case TargetOpcode::SUBREG_TO_REG:
2126 case TargetOpcode::REG_SEQUENCE:
2127 case TargetOpcode::IMPLICIT_DEF:
2128 case TargetOpcode::COPY:
2129 case TargetOpcode::INLINEASM:
2130 case TargetOpcode::PHI:
2131 return false;
2132 default:
2133 break;
2134 }
2135
2136 unsigned SchedClass = MI->getDesc().getSchedClass();
2137
2138 switch (SchedClass) {
2139 case Hexagon::Sched::ALU32_2op_tc_1_SLOT0123:
2140 case Hexagon::Sched::ALU32_3op_tc_1_SLOT0123:
2141 case Hexagon::Sched::ALU32_ADDI_tc_1_SLOT0123:
2142 case Hexagon::Sched::ALU64_tc_1_SLOT23:
2143 case Hexagon::Sched::EXTENDER_tc_1_SLOT0123:
2144 case Hexagon::Sched::S_2op_tc_1_SLOT23:
2145 case Hexagon::Sched::S_3op_tc_1_SLOT23:
2146 case Hexagon::Sched::V2LDST_tc_ld_SLOT01:
2147 case Hexagon::Sched::V2LDST_tc_st_SLOT0:
2148 case Hexagon::Sched::V2LDST_tc_st_SLOT01:
2149 case Hexagon::Sched::V4LDST_tc_ld_SLOT01:
2150 case Hexagon::Sched::V4LDST_tc_st_SLOT0:
2151 case Hexagon::Sched::V4LDST_tc_st_SLOT01:
2152 return false;
2153 }
2154 return true;
2155}
2156
2157
2158bool HexagonInstrInfo::isLateSourceInstr(const MachineInstr *MI) const {
2159 if (!MI)
2160 return false;
2161
2162 // Instructions with iclass A_CVI_VX and attribute A_CVI_LATE uses a multiply
2163 // resource, but all operands can be received late like an ALU instruction.
2164 return MI->getDesc().getSchedClass() == Hexagon::Sched::CVI_VX_LATE;
2165}
2166
2167
Krzysztof Parzyszek5e6f2bd2015-12-14 21:32:25 +00002168bool HexagonInstrInfo::isLoopN(const MachineInstr *MI) const {
2169 unsigned Opcode = MI->getOpcode();
2170 return Opcode == Hexagon::J2_loop0i ||
2171 Opcode == Hexagon::J2_loop0r ||
2172 Opcode == Hexagon::J2_loop0iext ||
2173 Opcode == Hexagon::J2_loop0rext ||
2174 Opcode == Hexagon::J2_loop1i ||
2175 Opcode == Hexagon::J2_loop1r ||
2176 Opcode == Hexagon::J2_loop1iext ||
2177 Opcode == Hexagon::J2_loop1rext;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002178}
2179
2180
2181bool HexagonInstrInfo::isMemOp(const MachineInstr *MI) const {
2182 switch (MI->getOpcode()) {
2183 default: return false;
2184 case Hexagon::L4_iadd_memopw_io :
2185 case Hexagon::L4_isub_memopw_io :
2186 case Hexagon::L4_add_memopw_io :
2187 case Hexagon::L4_sub_memopw_io :
2188 case Hexagon::L4_and_memopw_io :
2189 case Hexagon::L4_or_memopw_io :
2190 case Hexagon::L4_iadd_memoph_io :
2191 case Hexagon::L4_isub_memoph_io :
2192 case Hexagon::L4_add_memoph_io :
2193 case Hexagon::L4_sub_memoph_io :
2194 case Hexagon::L4_and_memoph_io :
2195 case Hexagon::L4_or_memoph_io :
2196 case Hexagon::L4_iadd_memopb_io :
2197 case Hexagon::L4_isub_memopb_io :
2198 case Hexagon::L4_add_memopb_io :
2199 case Hexagon::L4_sub_memopb_io :
2200 case Hexagon::L4_and_memopb_io :
2201 case Hexagon::L4_or_memopb_io :
2202 case Hexagon::L4_ior_memopb_io:
2203 case Hexagon::L4_ior_memoph_io:
2204 case Hexagon::L4_ior_memopw_io:
2205 case Hexagon::L4_iand_memopb_io:
2206 case Hexagon::L4_iand_memoph_io:
2207 case Hexagon::L4_iand_memopw_io:
2208 return true;
2209 }
2210 return false;
2211}
2212
2213
2214bool HexagonInstrInfo::isNewValue(const MachineInstr* MI) const {
2215 const uint64_t F = MI->getDesc().TSFlags;
2216 return (F >> HexagonII::NewValuePos) & HexagonII::NewValueMask;
2217}
2218
2219
2220bool HexagonInstrInfo::isNewValue(unsigned Opcode) const {
2221 const uint64_t F = get(Opcode).TSFlags;
2222 return (F >> HexagonII::NewValuePos) & HexagonII::NewValueMask;
2223}
2224
2225
2226bool HexagonInstrInfo::isNewValueInst(const MachineInstr *MI) const {
2227 return isNewValueJump(MI) || isNewValueStore(MI);
2228}
2229
2230
2231bool HexagonInstrInfo::isNewValueJump(const MachineInstr *MI) const {
2232 return isNewValue(MI) && MI->isBranch();
2233}
2234
2235
2236bool HexagonInstrInfo::isNewValueJump(unsigned Opcode) const {
2237 return isNewValue(Opcode) && get(Opcode).isBranch() && isPredicated(Opcode);
2238}
2239
2240
2241bool HexagonInstrInfo::isNewValueStore(const MachineInstr *MI) const {
2242 const uint64_t F = MI->getDesc().TSFlags;
2243 return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask;
2244}
2245
2246
2247bool HexagonInstrInfo::isNewValueStore(unsigned Opcode) const {
2248 const uint64_t F = get(Opcode).TSFlags;
2249 return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask;
2250}
2251
2252
2253// Returns true if a particular operand is extendable for an instruction.
2254bool HexagonInstrInfo::isOperandExtended(const MachineInstr *MI,
2255 unsigned OperandNum) const {
2256 const uint64_t F = MI->getDesc().TSFlags;
2257 return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask)
2258 == OperandNum;
2259}
2260
2261
2262bool HexagonInstrInfo::isPostIncrement(const MachineInstr* MI) const {
2263 return getAddrMode(MI) == HexagonII::PostInc;
2264}
2265
2266
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00002267bool HexagonInstrInfo::isPredicatedNew(const MachineInstr &MI) const {
2268 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002269 assert(isPredicated(MI));
2270 return (F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask;
2271}
2272
2273
2274bool HexagonInstrInfo::isPredicatedNew(unsigned Opcode) const {
2275 const uint64_t F = get(Opcode).TSFlags;
2276 assert(isPredicated(Opcode));
2277 return (F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask;
2278}
2279
2280
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00002281bool HexagonInstrInfo::isPredicatedTrue(const MachineInstr &MI) const {
2282 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002283 return !((F >> HexagonII::PredicatedFalsePos) &
2284 HexagonII::PredicatedFalseMask);
2285}
2286
2287
2288bool HexagonInstrInfo::isPredicatedTrue(unsigned Opcode) const {
2289 const uint64_t F = get(Opcode).TSFlags;
2290 // Make sure that the instruction is predicated.
2291 assert((F>> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);
2292 return !((F >> HexagonII::PredicatedFalsePos) &
2293 HexagonII::PredicatedFalseMask);
2294}
2295
2296
2297bool HexagonInstrInfo::isPredicated(unsigned Opcode) const {
2298 const uint64_t F = get(Opcode).TSFlags;
2299 return (F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask;
2300}
2301
2302
2303bool HexagonInstrInfo::isPredicateLate(unsigned Opcode) const {
2304 const uint64_t F = get(Opcode).TSFlags;
2305 return ~(F >> HexagonII::PredicateLatePos) & HexagonII::PredicateLateMask;
2306}
2307
2308
2309bool HexagonInstrInfo::isPredictedTaken(unsigned Opcode) const {
2310 const uint64_t F = get(Opcode).TSFlags;
2311 assert(get(Opcode).isBranch() &&
2312 (isPredicatedNew(Opcode) || isNewValue(Opcode)));
2313 return (F >> HexagonII::TakenPos) & HexagonII::TakenMask;
2314}
2315
2316
2317bool HexagonInstrInfo::isSaveCalleeSavedRegsCall(const MachineInstr *MI) const {
2318 return MI->getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4 ||
Krzysztof Parzyszek181fdbd2016-03-24 19:18:48 +00002319 MI->getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT ||
2320 MI->getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_PIC ||
2321 MI->getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002322}
2323
2324
Krzysztof Parzyszekfd02aad2016-02-12 18:37:23 +00002325bool HexagonInstrInfo::isSignExtendingLoad(const MachineInstr* MI) const {
2326 switch (MI->getOpcode()) {
2327 // Byte
2328 case Hexagon::L2_loadrb_io:
2329 case Hexagon::L4_loadrb_ur:
2330 case Hexagon::L4_loadrb_ap:
2331 case Hexagon::L2_loadrb_pr:
2332 case Hexagon::L2_loadrb_pbr:
2333 case Hexagon::L2_loadrb_pi:
2334 case Hexagon::L2_loadrb_pci:
2335 case Hexagon::L2_loadrb_pcr:
2336 case Hexagon::L2_loadbsw2_io:
2337 case Hexagon::L4_loadbsw2_ur:
2338 case Hexagon::L4_loadbsw2_ap:
2339 case Hexagon::L2_loadbsw2_pr:
2340 case Hexagon::L2_loadbsw2_pbr:
2341 case Hexagon::L2_loadbsw2_pi:
2342 case Hexagon::L2_loadbsw2_pci:
2343 case Hexagon::L2_loadbsw2_pcr:
2344 case Hexagon::L2_loadbsw4_io:
2345 case Hexagon::L4_loadbsw4_ur:
2346 case Hexagon::L4_loadbsw4_ap:
2347 case Hexagon::L2_loadbsw4_pr:
2348 case Hexagon::L2_loadbsw4_pbr:
2349 case Hexagon::L2_loadbsw4_pi:
2350 case Hexagon::L2_loadbsw4_pci:
2351 case Hexagon::L2_loadbsw4_pcr:
2352 case Hexagon::L4_loadrb_rr:
2353 case Hexagon::L2_ploadrbt_io:
2354 case Hexagon::L2_ploadrbt_pi:
2355 case Hexagon::L2_ploadrbf_io:
2356 case Hexagon::L2_ploadrbf_pi:
2357 case Hexagon::L2_ploadrbtnew_io:
2358 case Hexagon::L2_ploadrbfnew_io:
2359 case Hexagon::L4_ploadrbt_rr:
2360 case Hexagon::L4_ploadrbf_rr:
2361 case Hexagon::L4_ploadrbtnew_rr:
2362 case Hexagon::L4_ploadrbfnew_rr:
2363 case Hexagon::L2_ploadrbtnew_pi:
2364 case Hexagon::L2_ploadrbfnew_pi:
2365 case Hexagon::L4_ploadrbt_abs:
2366 case Hexagon::L4_ploadrbf_abs:
2367 case Hexagon::L4_ploadrbtnew_abs:
2368 case Hexagon::L4_ploadrbfnew_abs:
2369 case Hexagon::L2_loadrbgp:
2370 // Half
2371 case Hexagon::L2_loadrh_io:
2372 case Hexagon::L4_loadrh_ur:
2373 case Hexagon::L4_loadrh_ap:
2374 case Hexagon::L2_loadrh_pr:
2375 case Hexagon::L2_loadrh_pbr:
2376 case Hexagon::L2_loadrh_pi:
2377 case Hexagon::L2_loadrh_pci:
2378 case Hexagon::L2_loadrh_pcr:
2379 case Hexagon::L4_loadrh_rr:
2380 case Hexagon::L2_ploadrht_io:
2381 case Hexagon::L2_ploadrht_pi:
2382 case Hexagon::L2_ploadrhf_io:
2383 case Hexagon::L2_ploadrhf_pi:
2384 case Hexagon::L2_ploadrhtnew_io:
2385 case Hexagon::L2_ploadrhfnew_io:
2386 case Hexagon::L4_ploadrht_rr:
2387 case Hexagon::L4_ploadrhf_rr:
2388 case Hexagon::L4_ploadrhtnew_rr:
2389 case Hexagon::L4_ploadrhfnew_rr:
2390 case Hexagon::L2_ploadrhtnew_pi:
2391 case Hexagon::L2_ploadrhfnew_pi:
2392 case Hexagon::L4_ploadrht_abs:
2393 case Hexagon::L4_ploadrhf_abs:
2394 case Hexagon::L4_ploadrhtnew_abs:
2395 case Hexagon::L4_ploadrhfnew_abs:
2396 case Hexagon::L2_loadrhgp:
2397 return true;
2398 default:
2399 return false;
2400 }
2401}
2402
2403
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002404bool HexagonInstrInfo::isSolo(const MachineInstr* MI) const {
2405 const uint64_t F = MI->getDesc().TSFlags;
2406 return (F >> HexagonII::SoloPos) & HexagonII::SoloMask;
2407}
2408
2409
2410bool HexagonInstrInfo::isSpillPredRegOp(const MachineInstr *MI) const {
2411 switch (MI->getOpcode()) {
2412 case Hexagon::STriw_pred :
2413 case Hexagon::LDriw_pred :
2414 return true;
2415 default:
2416 return false;
2417 }
2418}
2419
2420
2421// Returns true when SU has a timing class TC1.
2422bool HexagonInstrInfo::isTC1(const MachineInstr *MI) const {
2423 unsigned SchedClass = MI->getDesc().getSchedClass();
2424 switch (SchedClass) {
2425 case Hexagon::Sched::ALU32_2op_tc_1_SLOT0123:
2426 case Hexagon::Sched::ALU32_3op_tc_1_SLOT0123:
2427 case Hexagon::Sched::ALU32_ADDI_tc_1_SLOT0123:
2428 case Hexagon::Sched::ALU64_tc_1_SLOT23:
2429 case Hexagon::Sched::EXTENDER_tc_1_SLOT0123:
2430 //case Hexagon::Sched::M_tc_1_SLOT23:
2431 case Hexagon::Sched::S_2op_tc_1_SLOT23:
2432 case Hexagon::Sched::S_3op_tc_1_SLOT23:
2433 return true;
2434
2435 default:
2436 return false;
2437 }
2438}
2439
2440
2441bool HexagonInstrInfo::isTC2(const MachineInstr *MI) const {
2442 unsigned SchedClass = MI->getDesc().getSchedClass();
2443 switch (SchedClass) {
2444 case Hexagon::Sched::ALU32_3op_tc_2_SLOT0123:
2445 case Hexagon::Sched::ALU64_tc_2_SLOT23:
2446 case Hexagon::Sched::CR_tc_2_SLOT3:
2447 case Hexagon::Sched::M_tc_2_SLOT23:
2448 case Hexagon::Sched::S_2op_tc_2_SLOT23:
2449 case Hexagon::Sched::S_3op_tc_2_SLOT23:
2450 return true;
2451
2452 default:
2453 return false;
2454 }
2455}
2456
2457
2458bool HexagonInstrInfo::isTC2Early(const MachineInstr *MI) const {
2459 unsigned SchedClass = MI->getDesc().getSchedClass();
2460 switch (SchedClass) {
2461 case Hexagon::Sched::ALU32_2op_tc_2early_SLOT0123:
2462 case Hexagon::Sched::ALU32_3op_tc_2early_SLOT0123:
2463 case Hexagon::Sched::ALU64_tc_2early_SLOT23:
2464 case Hexagon::Sched::CR_tc_2early_SLOT23:
2465 case Hexagon::Sched::CR_tc_2early_SLOT3:
2466 case Hexagon::Sched::J_tc_2early_SLOT0123:
2467 case Hexagon::Sched::J_tc_2early_SLOT2:
2468 case Hexagon::Sched::J_tc_2early_SLOT23:
2469 case Hexagon::Sched::S_2op_tc_2early_SLOT23:
2470 case Hexagon::Sched::S_3op_tc_2early_SLOT23:
2471 return true;
2472
2473 default:
2474 return false;
2475 }
2476}
2477
2478
2479bool HexagonInstrInfo::isTC4x(const MachineInstr *MI) const {
2480 if (!MI)
2481 return false;
2482
2483 unsigned SchedClass = MI->getDesc().getSchedClass();
2484 return SchedClass == Hexagon::Sched::M_tc_3or4x_SLOT23;
2485}
2486
2487
2488bool HexagonInstrInfo::isV60VectorInstruction(const MachineInstr *MI) const {
2489 if (!MI)
2490 return false;
2491
2492 const uint64_t V = getType(MI);
2493 return HexagonII::TypeCVI_FIRST <= V && V <= HexagonII::TypeCVI_LAST;
2494}
2495
2496
2497// Check if the Offset is a valid auto-inc imm by Load/Store Type.
2498//
2499bool HexagonInstrInfo::isValidAutoIncImm(const EVT VT, const int Offset) const {
2500 if (VT == MVT::v16i32 || VT == MVT::v8i64 ||
2501 VT == MVT::v32i16 || VT == MVT::v64i8) {
2502 return (Offset >= Hexagon_MEMV_AUTOINC_MIN &&
2503 Offset <= Hexagon_MEMV_AUTOINC_MAX &&
2504 (Offset & 0x3f) == 0);
2505 }
2506 // 128B
2507 if (VT == MVT::v32i32 || VT == MVT::v16i64 ||
2508 VT == MVT::v64i16 || VT == MVT::v128i8) {
2509 return (Offset >= Hexagon_MEMV_AUTOINC_MIN_128B &&
2510 Offset <= Hexagon_MEMV_AUTOINC_MAX_128B &&
2511 (Offset & 0x7f) == 0);
2512 }
2513 if (VT == MVT::i64) {
2514 return (Offset >= Hexagon_MEMD_AUTOINC_MIN &&
2515 Offset <= Hexagon_MEMD_AUTOINC_MAX &&
2516 (Offset & 0x7) == 0);
2517 }
2518 if (VT == MVT::i32) {
2519 return (Offset >= Hexagon_MEMW_AUTOINC_MIN &&
2520 Offset <= Hexagon_MEMW_AUTOINC_MAX &&
2521 (Offset & 0x3) == 0);
2522 }
2523 if (VT == MVT::i16) {
2524 return (Offset >= Hexagon_MEMH_AUTOINC_MIN &&
2525 Offset <= Hexagon_MEMH_AUTOINC_MAX &&
2526 (Offset & 0x1) == 0);
2527 }
2528 if (VT == MVT::i8) {
2529 return (Offset >= Hexagon_MEMB_AUTOINC_MIN &&
2530 Offset <= Hexagon_MEMB_AUTOINC_MAX);
2531 }
2532 llvm_unreachable("Not an auto-inc opc!");
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002533}
2534
2535
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002536bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset,
2537 bool Extend) const {
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002538 // This function is to check whether the "Offset" is in the correct range of
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002539 // the given "Opcode". If "Offset" is not in the correct range, "A2_addi" is
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002540 // inserted to calculate the final address. Due to this reason, the function
2541 // assumes that the "Offset" has correct alignment.
Jyotsna Vermaec613662013-03-14 19:08:03 +00002542 // We used to assert if the offset was not properly aligned, however,
2543 // there are cases where a misaligned pointer recast can cause this
2544 // problem, and we need to allow for it. The front end warns of such
2545 // misaligns with respect to load size.
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002546
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002547 switch (Opcode) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002548 case Hexagon::STriq_pred_V6:
2549 case Hexagon::STriq_pred_vec_V6:
2550 case Hexagon::STriv_pseudo_V6:
2551 case Hexagon::STrivv_pseudo_V6:
2552 case Hexagon::LDriq_pred_V6:
2553 case Hexagon::LDriq_pred_vec_V6:
2554 case Hexagon::LDriv_pseudo_V6:
2555 case Hexagon::LDrivv_pseudo_V6:
2556 case Hexagon::LDrivv_indexed:
2557 case Hexagon::STrivv_indexed:
2558 case Hexagon::V6_vL32b_ai:
2559 case Hexagon::V6_vS32b_ai:
2560 case Hexagon::V6_vL32Ub_ai:
2561 case Hexagon::V6_vS32Ub_ai:
2562 return (Offset >= Hexagon_MEMV_OFFSET_MIN) &&
2563 (Offset <= Hexagon_MEMV_OFFSET_MAX);
2564
2565 case Hexagon::STriq_pred_V6_128B:
2566 case Hexagon::STriq_pred_vec_V6_128B:
2567 case Hexagon::STriv_pseudo_V6_128B:
2568 case Hexagon::STrivv_pseudo_V6_128B:
2569 case Hexagon::LDriq_pred_V6_128B:
2570 case Hexagon::LDriq_pred_vec_V6_128B:
2571 case Hexagon::LDriv_pseudo_V6_128B:
2572 case Hexagon::LDrivv_pseudo_V6_128B:
2573 case Hexagon::LDrivv_indexed_128B:
2574 case Hexagon::STrivv_indexed_128B:
2575 case Hexagon::V6_vL32b_ai_128B:
2576 case Hexagon::V6_vS32b_ai_128B:
2577 case Hexagon::V6_vL32Ub_ai_128B:
2578 case Hexagon::V6_vS32Ub_ai_128B:
2579 return (Offset >= Hexagon_MEMV_OFFSET_MIN_128B) &&
2580 (Offset <= Hexagon_MEMV_OFFSET_MAX_128B);
2581
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002582 case Hexagon::J2_loop0i:
2583 case Hexagon::J2_loop1i:
2584 return isUInt<10>(Offset);
2585 }
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002586
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002587 if (Extend)
2588 return true;
2589
2590 switch (Opcode) {
Colin LeMahieu026e88d2014-12-23 20:02:16 +00002591 case Hexagon::L2_loadri_io:
Colin LeMahieubda31b42014-12-29 20:44:51 +00002592 case Hexagon::S2_storeri_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002593 return (Offset >= Hexagon_MEMW_OFFSET_MIN) &&
2594 (Offset <= Hexagon_MEMW_OFFSET_MAX);
2595
Colin LeMahieu947cd702014-12-23 20:44:59 +00002596 case Hexagon::L2_loadrd_io:
Colin LeMahieubda31b42014-12-29 20:44:51 +00002597 case Hexagon::S2_storerd_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002598 return (Offset >= Hexagon_MEMD_OFFSET_MIN) &&
2599 (Offset <= Hexagon_MEMD_OFFSET_MAX);
2600
Colin LeMahieu8e39cad2014-12-23 17:25:57 +00002601 case Hexagon::L2_loadrh_io:
Colin LeMahieua9386d22014-12-23 16:42:57 +00002602 case Hexagon::L2_loadruh_io:
Colin LeMahieubda31b42014-12-29 20:44:51 +00002603 case Hexagon::S2_storerh_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002604 return (Offset >= Hexagon_MEMH_OFFSET_MIN) &&
2605 (Offset <= Hexagon_MEMH_OFFSET_MAX);
2606
Colin LeMahieu4b1eac42014-12-22 21:40:43 +00002607 case Hexagon::L2_loadrb_io:
Colin LeMahieuaf1e5de2014-12-22 21:20:03 +00002608 case Hexagon::L2_loadrub_io:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002609 case Hexagon::S2_storerb_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002610 return (Offset >= Hexagon_MEMB_OFFSET_MIN) &&
2611 (Offset <= Hexagon_MEMB_OFFSET_MAX);
2612
Colin LeMahieuf297dbe2015-02-05 17:49:13 +00002613 case Hexagon::A2_addi:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002614 return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&
2615 (Offset <= Hexagon_ADDI_OFFSET_MAX);
2616
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002617 case Hexagon::L4_iadd_memopw_io :
2618 case Hexagon::L4_isub_memopw_io :
2619 case Hexagon::L4_add_memopw_io :
2620 case Hexagon::L4_sub_memopw_io :
2621 case Hexagon::L4_and_memopw_io :
2622 case Hexagon::L4_or_memopw_io :
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002623 return (0 <= Offset && Offset <= 255);
2624
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002625 case Hexagon::L4_iadd_memoph_io :
2626 case Hexagon::L4_isub_memoph_io :
2627 case Hexagon::L4_add_memoph_io :
2628 case Hexagon::L4_sub_memoph_io :
2629 case Hexagon::L4_and_memoph_io :
2630 case Hexagon::L4_or_memoph_io :
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002631 return (0 <= Offset && Offset <= 127);
2632
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002633 case Hexagon::L4_iadd_memopb_io :
2634 case Hexagon::L4_isub_memopb_io :
2635 case Hexagon::L4_add_memopb_io :
2636 case Hexagon::L4_sub_memopb_io :
2637 case Hexagon::L4_and_memopb_io :
2638 case Hexagon::L4_or_memopb_io :
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002639 return (0 <= Offset && Offset <= 63);
2640
Krzysztof Parzyszekfd02aad2016-02-12 18:37:23 +00002641 // LDriw_xxx and STriw_xxx are pseudo operations, so it has to take offset of
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002642 // any size. Later pass knows how to handle it.
2643 case Hexagon::STriw_pred:
2644 case Hexagon::LDriw_pred:
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +00002645 case Hexagon::STriw_mod:
2646 case Hexagon::LDriw_mod:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002647 return true;
2648
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002649 case Hexagon::TFR_FI:
2650 case Hexagon::TFR_FIA:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002651 case Hexagon::INLINEASM:
2652 return true;
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00002653
2654 case Hexagon::L2_ploadrbt_io:
2655 case Hexagon::L2_ploadrbf_io:
2656 case Hexagon::L2_ploadrubt_io:
2657 case Hexagon::L2_ploadrubf_io:
2658 case Hexagon::S2_pstorerbt_io:
2659 case Hexagon::S2_pstorerbf_io:
2660 case Hexagon::S4_storeirb_io:
2661 case Hexagon::S4_storeirbt_io:
2662 case Hexagon::S4_storeirbf_io:
2663 return isUInt<6>(Offset);
2664
2665 case Hexagon::L2_ploadrht_io:
2666 case Hexagon::L2_ploadrhf_io:
2667 case Hexagon::L2_ploadruht_io:
2668 case Hexagon::L2_ploadruhf_io:
2669 case Hexagon::S2_pstorerht_io:
2670 case Hexagon::S2_pstorerhf_io:
2671 case Hexagon::S4_storeirh_io:
2672 case Hexagon::S4_storeirht_io:
2673 case Hexagon::S4_storeirhf_io:
2674 return isShiftedUInt<6,1>(Offset);
2675
2676 case Hexagon::L2_ploadrit_io:
2677 case Hexagon::L2_ploadrif_io:
2678 case Hexagon::S2_pstorerit_io:
2679 case Hexagon::S2_pstorerif_io:
2680 case Hexagon::S4_storeiri_io:
2681 case Hexagon::S4_storeirit_io:
2682 case Hexagon::S4_storeirif_io:
2683 return isShiftedUInt<6,2>(Offset);
2684
2685 case Hexagon::L2_ploadrdt_io:
2686 case Hexagon::L2_ploadrdf_io:
2687 case Hexagon::S2_pstorerdt_io:
2688 case Hexagon::S2_pstorerdf_io:
2689 return isShiftedUInt<6,3>(Offset);
2690 } // switch
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002691
Benjamin Kramerb6684012011-12-27 11:41:05 +00002692 llvm_unreachable("No offset range is defined for this opcode. "
2693 "Please define it in the above switch statement!");
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002694}
2695
2696
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002697bool HexagonInstrInfo::isVecAcc(const MachineInstr *MI) const {
2698 return MI && isV60VectorInstruction(MI) && isAccumulator(MI);
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002699}
2700
2701
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002702bool HexagonInstrInfo::isVecALU(const MachineInstr *MI) const {
2703 if (!MI)
Andrew Trickd06df962012-02-01 22:13:57 +00002704 return false;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002705 const uint64_t F = get(MI->getOpcode()).TSFlags;
2706 const uint64_t V = ((F >> HexagonII::TypePos) & HexagonII::TypeMask);
2707 return
2708 V == HexagonII::TypeCVI_VA ||
2709 V == HexagonII::TypeCVI_VA_DV;
2710}
Andrew Trickd06df962012-02-01 22:13:57 +00002711
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002712
2713bool HexagonInstrInfo::isVecUsableNextPacket(const MachineInstr *ProdMI,
2714 const MachineInstr *ConsMI) const {
2715 if (EnableACCForwarding && isVecAcc(ProdMI) && isVecAcc(ConsMI))
2716 return true;
2717
2718 if (EnableALUForwarding && (isVecALU(ConsMI) || isLateSourceInstr(ConsMI)))
2719 return true;
2720
2721 if (mayBeNewStore(ConsMI))
Andrew Trickd06df962012-02-01 22:13:57 +00002722 return true;
2723
2724 return false;
2725}
Jyotsna Verma84256432013-03-01 17:37:13 +00002726
Jyotsna Verma84256432013-03-01 17:37:13 +00002727
Krzysztof Parzyszekfd02aad2016-02-12 18:37:23 +00002728bool HexagonInstrInfo::isZeroExtendingLoad(const MachineInstr* MI) const {
2729 switch (MI->getOpcode()) {
2730 // Byte
2731 case Hexagon::L2_loadrub_io:
2732 case Hexagon::L4_loadrub_ur:
2733 case Hexagon::L4_loadrub_ap:
2734 case Hexagon::L2_loadrub_pr:
2735 case Hexagon::L2_loadrub_pbr:
2736 case Hexagon::L2_loadrub_pi:
2737 case Hexagon::L2_loadrub_pci:
2738 case Hexagon::L2_loadrub_pcr:
2739 case Hexagon::L2_loadbzw2_io:
2740 case Hexagon::L4_loadbzw2_ur:
2741 case Hexagon::L4_loadbzw2_ap:
2742 case Hexagon::L2_loadbzw2_pr:
2743 case Hexagon::L2_loadbzw2_pbr:
2744 case Hexagon::L2_loadbzw2_pi:
2745 case Hexagon::L2_loadbzw2_pci:
2746 case Hexagon::L2_loadbzw2_pcr:
2747 case Hexagon::L2_loadbzw4_io:
2748 case Hexagon::L4_loadbzw4_ur:
2749 case Hexagon::L4_loadbzw4_ap:
2750 case Hexagon::L2_loadbzw4_pr:
2751 case Hexagon::L2_loadbzw4_pbr:
2752 case Hexagon::L2_loadbzw4_pi:
2753 case Hexagon::L2_loadbzw4_pci:
2754 case Hexagon::L2_loadbzw4_pcr:
2755 case Hexagon::L4_loadrub_rr:
2756 case Hexagon::L2_ploadrubt_io:
2757 case Hexagon::L2_ploadrubt_pi:
2758 case Hexagon::L2_ploadrubf_io:
2759 case Hexagon::L2_ploadrubf_pi:
2760 case Hexagon::L2_ploadrubtnew_io:
2761 case Hexagon::L2_ploadrubfnew_io:
2762 case Hexagon::L4_ploadrubt_rr:
2763 case Hexagon::L4_ploadrubf_rr:
2764 case Hexagon::L4_ploadrubtnew_rr:
2765 case Hexagon::L4_ploadrubfnew_rr:
2766 case Hexagon::L2_ploadrubtnew_pi:
2767 case Hexagon::L2_ploadrubfnew_pi:
2768 case Hexagon::L4_ploadrubt_abs:
2769 case Hexagon::L4_ploadrubf_abs:
2770 case Hexagon::L4_ploadrubtnew_abs:
2771 case Hexagon::L4_ploadrubfnew_abs:
2772 case Hexagon::L2_loadrubgp:
2773 // Half
2774 case Hexagon::L2_loadruh_io:
2775 case Hexagon::L4_loadruh_ur:
2776 case Hexagon::L4_loadruh_ap:
2777 case Hexagon::L2_loadruh_pr:
2778 case Hexagon::L2_loadruh_pbr:
2779 case Hexagon::L2_loadruh_pi:
2780 case Hexagon::L2_loadruh_pci:
2781 case Hexagon::L2_loadruh_pcr:
2782 case Hexagon::L4_loadruh_rr:
2783 case Hexagon::L2_ploadruht_io:
2784 case Hexagon::L2_ploadruht_pi:
2785 case Hexagon::L2_ploadruhf_io:
2786 case Hexagon::L2_ploadruhf_pi:
2787 case Hexagon::L2_ploadruhtnew_io:
2788 case Hexagon::L2_ploadruhfnew_io:
2789 case Hexagon::L4_ploadruht_rr:
2790 case Hexagon::L4_ploadruhf_rr:
2791 case Hexagon::L4_ploadruhtnew_rr:
2792 case Hexagon::L4_ploadruhfnew_rr:
2793 case Hexagon::L2_ploadruhtnew_pi:
2794 case Hexagon::L2_ploadruhfnew_pi:
2795 case Hexagon::L4_ploadruht_abs:
2796 case Hexagon::L4_ploadruhf_abs:
2797 case Hexagon::L4_ploadruhtnew_abs:
2798 case Hexagon::L4_ploadruhfnew_abs:
2799 case Hexagon::L2_loadruhgp:
2800 return true;
2801 default:
2802 return false;
2803 }
2804}
2805
2806
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00002807/// \brief Can these instructions execute at the same time in a bundle.
2808bool HexagonInstrInfo::canExecuteInBundle(const MachineInstr *First,
2809 const MachineInstr *Second) const {
2810 if (DisableNVSchedule)
2811 return false;
2812 if (mayBeNewStore(Second)) {
2813 // Make sure the definition of the first instruction is the value being
2814 // stored.
2815 const MachineOperand &Stored =
2816 Second->getOperand(Second->getNumOperands() - 1);
2817 if (!Stored.isReg())
2818 return false;
2819 for (unsigned i = 0, e = First->getNumOperands(); i < e; ++i) {
2820 const MachineOperand &Op = First->getOperand(i);
2821 if (Op.isReg() && Op.isDef() && Op.getReg() == Stored.getReg())
2822 return true;
2823 }
2824 }
2825 return false;
2826}
2827
2828
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002829bool HexagonInstrInfo::hasEHLabel(const MachineBasicBlock *B) const {
2830 for (auto &I : *B)
2831 if (I.isEHLabel())
2832 return true;
2833 return false;
Jyotsna Verma84256432013-03-01 17:37:13 +00002834}
2835
Jyotsna Verma84256432013-03-01 17:37:13 +00002836
2837// Returns true if an instruction can be converted into a non-extended
2838// equivalent instruction.
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002839bool HexagonInstrInfo::hasNonExtEquivalent(const MachineInstr *MI) const {
Jyotsna Verma84256432013-03-01 17:37:13 +00002840 short NonExtOpcode;
2841 // Check if the instruction has a register form that uses register in place
2842 // of the extended operand, if so return that as the non-extended form.
2843 if (Hexagon::getRegForm(MI->getOpcode()) >= 0)
2844 return true;
2845
2846 if (MI->getDesc().mayLoad() || MI->getDesc().mayStore()) {
Alp Tokercb402912014-01-24 17:20:08 +00002847 // Check addressing mode and retrieve non-ext equivalent instruction.
Jyotsna Verma84256432013-03-01 17:37:13 +00002848
2849 switch (getAddrMode(MI)) {
2850 case HexagonII::Absolute :
2851 // Load/store with absolute addressing mode can be converted into
2852 // base+offset mode.
Krzysztof Parzyszek02579052015-10-20 19:21:05 +00002853 NonExtOpcode = Hexagon::getBaseWithImmOffset(MI->getOpcode());
Jyotsna Verma84256432013-03-01 17:37:13 +00002854 break;
2855 case HexagonII::BaseImmOffset :
2856 // Load/store with base+offset addressing mode can be converted into
2857 // base+register offset addressing mode. However left shift operand should
2858 // be set to 0.
2859 NonExtOpcode = Hexagon::getBaseWithRegOffset(MI->getOpcode());
2860 break;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002861 case HexagonII::BaseLongOffset:
2862 NonExtOpcode = Hexagon::getRegShlForm(MI->getOpcode());
2863 break;
Jyotsna Verma84256432013-03-01 17:37:13 +00002864 default:
2865 return false;
2866 }
2867 if (NonExtOpcode < 0)
2868 return false;
2869 return true;
2870 }
2871 return false;
2872}
2873
Jyotsna Verma84256432013-03-01 17:37:13 +00002874
Krzysztof Parzyszek5e6f2bd2015-12-14 21:32:25 +00002875bool HexagonInstrInfo::hasPseudoInstrPair(const MachineInstr *MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002876 return Hexagon::getRealHWInstr(MI->getOpcode(),
2877 Hexagon::InstrType_Pseudo) >= 0;
2878}
2879
2880
2881bool HexagonInstrInfo::hasUncondBranch(const MachineBasicBlock *B)
2882 const {
2883 MachineBasicBlock::const_iterator I = B->getFirstTerminator(), E = B->end();
2884 while (I != E) {
2885 if (I->isBarrier())
2886 return true;
2887 ++I;
2888 }
2889 return false;
2890}
2891
2892
2893// Returns true, if a LD insn can be promoted to a cur load.
2894bool HexagonInstrInfo::mayBeCurLoad(const MachineInstr *MI) const {
2895 auto &HST = MI->getParent()->getParent()->getSubtarget<HexagonSubtarget>();
2896 const uint64_t F = MI->getDesc().TSFlags;
2897 return ((F >> HexagonII::mayCVLoadPos) & HexagonII::mayCVLoadMask) &&
2898 HST.hasV60TOps();
2899}
2900
2901
2902// Returns true, if a ST insn can be promoted to a new-value store.
2903bool HexagonInstrInfo::mayBeNewStore(const MachineInstr *MI) const {
2904 const uint64_t F = MI->getDesc().TSFlags;
2905 return (F >> HexagonII::mayNVStorePos) & HexagonII::mayNVStoreMask;
2906}
2907
2908
2909bool HexagonInstrInfo::producesStall(const MachineInstr *ProdMI,
2910 const MachineInstr *ConsMI) const {
2911 // There is no stall when ProdMI is not a V60 vector.
2912 if (!isV60VectorInstruction(ProdMI))
2913 return false;
2914
2915 // There is no stall when ProdMI and ConsMI are not dependent.
2916 if (!isDependent(ProdMI, ConsMI))
2917 return false;
2918
2919 // When Forward Scheduling is enabled, there is no stall if ProdMI and ConsMI
2920 // are scheduled in consecutive packets.
2921 if (isVecUsableNextPacket(ProdMI, ConsMI))
2922 return false;
2923
2924 return true;
2925}
2926
2927
2928bool HexagonInstrInfo::producesStall(const MachineInstr *MI,
2929 MachineBasicBlock::const_instr_iterator BII) const {
2930 // There is no stall when I is not a V60 vector.
2931 if (!isV60VectorInstruction(MI))
2932 return false;
2933
2934 MachineBasicBlock::const_instr_iterator MII = BII;
2935 MachineBasicBlock::const_instr_iterator MIE = MII->getParent()->instr_end();
2936
2937 if (!(*MII).isBundle()) {
2938 const MachineInstr *J = &*MII;
2939 if (!isV60VectorInstruction(J))
2940 return false;
2941 else if (isVecUsableNextPacket(J, MI))
2942 return false;
2943 return true;
2944 }
2945
2946 for (++MII; MII != MIE && MII->isInsideBundle(); ++MII) {
2947 const MachineInstr *J = &*MII;
2948 if (producesStall(J, MI))
2949 return true;
2950 }
2951 return false;
2952}
2953
2954
Krzysztof Parzyszek5e6f2bd2015-12-14 21:32:25 +00002955bool HexagonInstrInfo::predCanBeUsedAsDotNew(const MachineInstr *MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002956 unsigned PredReg) const {
2957 for (unsigned opNum = 0; opNum < MI->getNumOperands(); opNum++) {
Krzysztof Parzyszek5e6f2bd2015-12-14 21:32:25 +00002958 const MachineOperand &MO = MI->getOperand(opNum);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002959 if (MO.isReg() && MO.isDef() && MO.isImplicit() && (MO.getReg() == PredReg))
2960 return false; // Predicate register must be explicitly defined.
2961 }
2962
2963 // Hexagon Programmer's Reference says that decbin, memw_locked, and
2964 // memd_locked cannot be used as .new as well,
2965 // but we don't seem to have these instructions defined.
2966 return MI->getOpcode() != Hexagon::A4_tlbmatch;
2967}
2968
2969
2970bool HexagonInstrInfo::PredOpcodeHasJMP_c(unsigned Opcode) const {
2971 return (Opcode == Hexagon::J2_jumpt) ||
2972 (Opcode == Hexagon::J2_jumpf) ||
2973 (Opcode == Hexagon::J2_jumptnew) ||
2974 (Opcode == Hexagon::J2_jumpfnew) ||
2975 (Opcode == Hexagon::J2_jumptnewpt) ||
2976 (Opcode == Hexagon::J2_jumpfnewpt);
2977}
2978
2979
2980bool HexagonInstrInfo::predOpcodeHasNot(ArrayRef<MachineOperand> Cond) const {
2981 if (Cond.empty() || !isPredicated(Cond[0].getImm()))
2982 return false;
2983 return !isPredicatedTrue(Cond[0].getImm());
2984}
2985
2986
Krzysztof Parzyszekf5cbac92016-04-29 15:49:13 +00002987short HexagonInstrInfo::getAbsoluteForm(const MachineInstr *MI) const {
2988 return Hexagon::getAbsoluteForm(MI->getOpcode());
2989}
2990
2991
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002992unsigned HexagonInstrInfo::getAddrMode(const MachineInstr* MI) const {
2993 const uint64_t F = MI->getDesc().TSFlags;
2994 return (F >> HexagonII::AddrModePos) & HexagonII::AddrModeMask;
2995}
2996
2997
2998// Returns the base register in a memory access (load/store). The offset is
2999// returned in Offset and the access size is returned in AccessSize.
3000unsigned HexagonInstrInfo::getBaseAndOffset(const MachineInstr *MI,
3001 int &Offset, unsigned &AccessSize) const {
3002 // Return if it is not a base+offset type instruction or a MemOp.
3003 if (getAddrMode(MI) != HexagonII::BaseImmOffset &&
3004 getAddrMode(MI) != HexagonII::BaseLongOffset &&
3005 !isMemOp(MI) && !isPostIncrement(MI))
3006 return 0;
3007
3008 // Since it is a memory access instruction, getMemAccessSize() should never
3009 // return 0.
3010 assert (getMemAccessSize(MI) &&
3011 "BaseImmOffset or BaseLongOffset or MemOp without accessSize");
3012
3013 // Return Values of getMemAccessSize() are
3014 // 0 - Checked in the assert above.
3015 // 1, 2, 3, 4 & 7, 8 - The statement below is correct for all these.
3016 // MemAccessSize is represented as 1+log2(N) where N is size in bits.
3017 AccessSize = (1U << (getMemAccessSize(MI) - 1));
3018
3019 unsigned basePos = 0, offsetPos = 0;
3020 if (!getBaseAndOffsetPosition(MI, basePos, offsetPos))
3021 return 0;
3022
3023 // Post increment updates its EA after the mem access,
3024 // so we need to treat its offset as zero.
3025 if (isPostIncrement(MI))
3026 Offset = 0;
3027 else {
3028 Offset = MI->getOperand(offsetPos).getImm();
3029 }
3030
3031 return MI->getOperand(basePos).getReg();
3032}
3033
3034
3035/// Return the position of the base and offset operands for this instruction.
3036bool HexagonInstrInfo::getBaseAndOffsetPosition(const MachineInstr *MI,
3037 unsigned &BasePos, unsigned &OffsetPos) const {
3038 // Deal with memops first.
3039 if (isMemOp(MI)) {
3040 assert (MI->getOperand(0).isReg() && MI->getOperand(1).isImm() &&
3041 "Bad Memop.");
3042 BasePos = 0;
3043 OffsetPos = 1;
3044 } else if (MI->mayStore()) {
3045 BasePos = 0;
3046 OffsetPos = 1;
3047 } else if (MI->mayLoad()) {
3048 BasePos = 1;
3049 OffsetPos = 2;
3050 } else
3051 return false;
3052
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00003053 if (isPredicated(*MI)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003054 BasePos++;
3055 OffsetPos++;
3056 }
3057 if (isPostIncrement(MI)) {
3058 BasePos++;
3059 OffsetPos++;
3060 }
3061
3062 if (!MI->getOperand(BasePos).isReg() || !MI->getOperand(OffsetPos).isImm())
3063 return false;
3064
3065 return true;
3066}
3067
3068
3069// Inserts branching instructions in reverse order of their occurence.
3070// e.g. jump_t t1 (i1)
3071// jump t2 (i2)
3072// Jumpers = {i2, i1}
3073SmallVector<MachineInstr*, 2> HexagonInstrInfo::getBranchingInstrs(
3074 MachineBasicBlock& MBB) const {
3075 SmallVector<MachineInstr*, 2> Jumpers;
3076 // If the block has no terminators, it just falls into the block after it.
3077 MachineBasicBlock::instr_iterator I = MBB.instr_end();
3078 if (I == MBB.instr_begin())
3079 return Jumpers;
3080
3081 // A basic block may looks like this:
3082 //
3083 // [ insn
3084 // EH_LABEL
3085 // insn
3086 // insn
3087 // insn
3088 // EH_LABEL
3089 // insn ]
3090 //
3091 // It has two succs but does not have a terminator
3092 // Don't know how to handle it.
3093 do {
3094 --I;
3095 if (I->isEHLabel())
3096 return Jumpers;
3097 } while (I != MBB.instr_begin());
3098
3099 I = MBB.instr_end();
3100 --I;
3101
3102 while (I->isDebugValue()) {
3103 if (I == MBB.instr_begin())
3104 return Jumpers;
3105 --I;
3106 }
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00003107 if (!isUnpredicatedTerminator(*I))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003108 return Jumpers;
3109
3110 // Get the last instruction in the block.
3111 MachineInstr *LastInst = &*I;
3112 Jumpers.push_back(LastInst);
3113 MachineInstr *SecondLastInst = nullptr;
3114 // Find one more terminator if present.
3115 do {
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00003116 if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003117 if (!SecondLastInst) {
3118 SecondLastInst = &*I;
3119 Jumpers.push_back(SecondLastInst);
3120 } else // This is a third branch.
3121 return Jumpers;
3122 }
3123 if (I == MBB.instr_begin())
3124 break;
3125 --I;
3126 } while (true);
3127 return Jumpers;
3128}
3129
3130
Krzysztof Parzyszekf5cbac92016-04-29 15:49:13 +00003131short HexagonInstrInfo::getBaseWithLongOffset(short Opcode) const {
3132 if (Opcode < 0)
3133 return -1;
3134 return Hexagon::getBaseWithLongOffset(Opcode);
3135}
3136
3137
3138short HexagonInstrInfo::getBaseWithLongOffset(const MachineInstr *MI) const {
3139 return Hexagon::getBaseWithLongOffset(MI->getOpcode());
3140}
3141
3142
3143short HexagonInstrInfo::getBaseWithRegOffset(const MachineInstr *MI) const {
3144 return Hexagon::getBaseWithRegOffset(MI->getOpcode());
3145}
3146
3147
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003148// Returns Operand Index for the constant extended instruction.
3149unsigned HexagonInstrInfo::getCExtOpNum(const MachineInstr *MI) const {
3150 const uint64_t F = MI->getDesc().TSFlags;
3151 return (F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask;
3152}
3153
3154// See if instruction could potentially be a duplex candidate.
3155// If so, return its group. Zero otherwise.
3156HexagonII::CompoundGroup HexagonInstrInfo::getCompoundCandidateGroup(
3157 const MachineInstr *MI) const {
3158 unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
3159
3160 switch (MI->getOpcode()) {
3161 default:
3162 return HexagonII::HCG_None;
3163 //
3164 // Compound pairs.
3165 // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
3166 // "Rd16=#U6 ; jump #r9:2"
3167 // "Rd16=Rs16 ; jump #r9:2"
3168 //
3169 case Hexagon::C2_cmpeq:
3170 case Hexagon::C2_cmpgt:
3171 case Hexagon::C2_cmpgtu:
3172 DstReg = MI->getOperand(0).getReg();
3173 Src1Reg = MI->getOperand(1).getReg();
3174 Src2Reg = MI->getOperand(2).getReg();
3175 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3176 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3177 isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg))
3178 return HexagonII::HCG_A;
3179 break;
3180 case Hexagon::C2_cmpeqi:
3181 case Hexagon::C2_cmpgti:
3182 case Hexagon::C2_cmpgtui:
3183 // P0 = cmp.eq(Rs,#u2)
3184 DstReg = MI->getOperand(0).getReg();
3185 SrcReg = MI->getOperand(1).getReg();
3186 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3187 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3188 isIntRegForSubInst(SrcReg) && MI->getOperand(2).isImm() &&
3189 ((isUInt<5>(MI->getOperand(2).getImm())) ||
3190 (MI->getOperand(2).getImm() == -1)))
3191 return HexagonII::HCG_A;
3192 break;
3193 case Hexagon::A2_tfr:
3194 // Rd = Rs
3195 DstReg = MI->getOperand(0).getReg();
3196 SrcReg = MI->getOperand(1).getReg();
3197 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
3198 return HexagonII::HCG_A;
3199 break;
3200 case Hexagon::A2_tfrsi:
3201 // Rd = #u6
3202 // Do not test for #u6 size since the const is getting extended
3203 // regardless and compound could be formed.
3204 DstReg = MI->getOperand(0).getReg();
3205 if (isIntRegForSubInst(DstReg))
3206 return HexagonII::HCG_A;
3207 break;
3208 case Hexagon::S2_tstbit_i:
3209 DstReg = MI->getOperand(0).getReg();
3210 Src1Reg = MI->getOperand(1).getReg();
3211 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3212 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3213 MI->getOperand(2).isImm() &&
3214 isIntRegForSubInst(Src1Reg) && (MI->getOperand(2).getImm() == 0))
3215 return HexagonII::HCG_A;
3216 break;
3217 // The fact that .new form is used pretty much guarantees
3218 // that predicate register will match. Nevertheless,
3219 // there could be some false positives without additional
3220 // checking.
3221 case Hexagon::J2_jumptnew:
3222 case Hexagon::J2_jumpfnew:
3223 case Hexagon::J2_jumptnewpt:
3224 case Hexagon::J2_jumpfnewpt:
3225 Src1Reg = MI->getOperand(0).getReg();
3226 if (Hexagon::PredRegsRegClass.contains(Src1Reg) &&
3227 (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg))
3228 return HexagonII::HCG_B;
3229 break;
3230 // Transfer and jump:
3231 // Rd=#U6 ; jump #r9:2
3232 // Rd=Rs ; jump #r9:2
3233 // Do not test for jump range here.
3234 case Hexagon::J2_jump:
3235 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
3236 return HexagonII::HCG_C;
3237 break;
3238 }
3239
3240 return HexagonII::HCG_None;
3241}
3242
3243
3244// Returns -1 when there is no opcode found.
3245unsigned HexagonInstrInfo::getCompoundOpcode(const MachineInstr *GA,
3246 const MachineInstr *GB) const {
3247 assert(getCompoundCandidateGroup(GA) == HexagonII::HCG_A);
3248 assert(getCompoundCandidateGroup(GB) == HexagonII::HCG_B);
3249 if ((GA->getOpcode() != Hexagon::C2_cmpeqi) ||
3250 (GB->getOpcode() != Hexagon::J2_jumptnew))
3251 return -1;
3252 unsigned DestReg = GA->getOperand(0).getReg();
3253 if (!GB->readsRegister(DestReg))
3254 return -1;
3255 if (DestReg == Hexagon::P0)
3256 return Hexagon::J4_cmpeqi_tp0_jump_nt;
3257 if (DestReg == Hexagon::P1)
3258 return Hexagon::J4_cmpeqi_tp1_jump_nt;
3259 return -1;
3260}
3261
3262
3263int HexagonInstrInfo::getCondOpcode(int Opc, bool invertPredicate) const {
3264 enum Hexagon::PredSense inPredSense;
3265 inPredSense = invertPredicate ? Hexagon::PredSense_false :
3266 Hexagon::PredSense_true;
3267 int CondOpcode = Hexagon::getPredOpcode(Opc, inPredSense);
3268 if (CondOpcode >= 0) // Valid Conditional opcode/instruction
3269 return CondOpcode;
3270
3271 // This switch case will be removed once all the instructions have been
3272 // modified to use relation maps.
3273 switch(Opc) {
3274 case Hexagon::TFRI_f:
3275 return !invertPredicate ? Hexagon::TFRI_cPt_f :
3276 Hexagon::TFRI_cNotPt_f;
3277 }
3278
3279 llvm_unreachable("Unexpected predicable instruction");
3280}
3281
3282
3283// Return the cur value instruction for a given store.
3284int HexagonInstrInfo::getDotCurOp(const MachineInstr* MI) const {
3285 switch (MI->getOpcode()) {
3286 default: llvm_unreachable("Unknown .cur type");
3287 case Hexagon::V6_vL32b_pi:
3288 return Hexagon::V6_vL32b_cur_pi;
3289 case Hexagon::V6_vL32b_ai:
3290 return Hexagon::V6_vL32b_cur_ai;
3291 //128B
3292 case Hexagon::V6_vL32b_pi_128B:
3293 return Hexagon::V6_vL32b_cur_pi_128B;
3294 case Hexagon::V6_vL32b_ai_128B:
3295 return Hexagon::V6_vL32b_cur_ai_128B;
3296 }
3297 return 0;
3298}
3299
3300
3301
3302// The diagram below shows the steps involved in the conversion of a predicated
3303// store instruction to its .new predicated new-value form.
3304//
3305// p.new NV store [ if(p0.new)memw(R0+#0)=R2.new ]
3306// ^ ^
3307// / \ (not OK. it will cause new-value store to be
3308// / X conditional on p0.new while R2 producer is
3309// / \ on p0)
3310// / \.
3311// p.new store p.old NV store
3312// [if(p0.new)memw(R0+#0)=R2] [if(p0)memw(R0+#0)=R2.new]
3313// ^ ^
3314// \ /
3315// \ /
3316// \ /
3317// p.old store
3318// [if (p0)memw(R0+#0)=R2]
3319//
3320//
3321// The following set of instructions further explains the scenario where
3322// conditional new-value store becomes invalid when promoted to .new predicate
3323// form.
3324//
3325// { 1) if (p0) r0 = add(r1, r2)
3326// 2) p0 = cmp.eq(r3, #0) }
3327//
3328// 3) if (p0) memb(r1+#0) = r0 --> this instruction can't be grouped with
3329// the first two instructions because in instr 1, r0 is conditional on old value
3330// of p0 but its use in instr 3 is conditional on p0 modified by instr 2 which
3331// is not valid for new-value stores.
3332// Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded
3333// from the "Conditional Store" list. Because a predicated new value store
3334// would NOT be promoted to a double dot new store. See diagram below:
3335// This function returns yes for those stores that are predicated but not
3336// yet promoted to predicate dot new instructions.
3337//
3338// +---------------------+
3339// /-----| if (p0) memw(..)=r0 |---------\~
3340// || +---------------------+ ||
3341// promote || /\ /\ || promote
3342// || /||\ /||\ ||
3343// \||/ demote || \||/
3344// \/ || || \/
3345// +-------------------------+ || +-------------------------+
3346// | if (p0.new) memw(..)=r0 | || | if (p0) memw(..)=r0.new |
3347// +-------------------------+ || +-------------------------+
3348// || || ||
3349// || demote \||/
3350// promote || \/ NOT possible
3351// || || /\~
3352// \||/ || /||\~
3353// \/ || ||
3354// +-----------------------------+
3355// | if (p0.new) memw(..)=r0.new |
3356// +-----------------------------+
3357// Double Dot New Store
3358//
3359// Returns the most basic instruction for the .new predicated instructions and
3360// new-value stores.
3361// For example, all of the following instructions will be converted back to the
3362// same instruction:
3363// 1) if (p0.new) memw(R0+#0) = R1.new --->
3364// 2) if (p0) memw(R0+#0)= R1.new -------> if (p0) memw(R0+#0) = R1
3365// 3) if (p0.new) memw(R0+#0) = R1 --->
3366//
3367// To understand the translation of instruction 1 to its original form, consider
3368// a packet with 3 instructions.
3369// { p0 = cmp.eq(R0,R1)
3370// if (p0.new) R2 = add(R3, R4)
3371// R5 = add (R3, R1)
3372// }
3373// if (p0) memw(R5+#0) = R2 <--- trying to include it in the previous packet
3374//
3375// This instruction can be part of the previous packet only if both p0 and R2
3376// are promoted to .new values. This promotion happens in steps, first
3377// predicate register is promoted to .new and in the next iteration R2 is
3378// promoted. Therefore, in case of dependence check failure (due to R5) during
3379// next iteration, it should be converted back to its most basic form.
3380
3381
3382// Return the new value instruction for a given store.
3383int HexagonInstrInfo::getDotNewOp(const MachineInstr* MI) const {
3384 int NVOpcode = Hexagon::getNewValueOpcode(MI->getOpcode());
3385 if (NVOpcode >= 0) // Valid new-value store instruction.
3386 return NVOpcode;
3387
3388 switch (MI->getOpcode()) {
3389 default: llvm_unreachable("Unknown .new type");
3390 case Hexagon::S4_storerb_ur:
3391 return Hexagon::S4_storerbnew_ur;
3392
3393 case Hexagon::S2_storerb_pci:
3394 return Hexagon::S2_storerb_pci;
3395
3396 case Hexagon::S2_storeri_pci:
3397 return Hexagon::S2_storeri_pci;
3398
3399 case Hexagon::S2_storerh_pci:
3400 return Hexagon::S2_storerh_pci;
3401
3402 case Hexagon::S2_storerd_pci:
3403 return Hexagon::S2_storerd_pci;
3404
3405 case Hexagon::S2_storerf_pci:
3406 return Hexagon::S2_storerf_pci;
3407
3408 case Hexagon::V6_vS32b_ai:
3409 return Hexagon::V6_vS32b_new_ai;
3410
3411 case Hexagon::V6_vS32b_pi:
3412 return Hexagon::V6_vS32b_new_pi;
3413
3414 // 128B
3415 case Hexagon::V6_vS32b_ai_128B:
3416 return Hexagon::V6_vS32b_new_ai_128B;
3417
3418 case Hexagon::V6_vS32b_pi_128B:
3419 return Hexagon::V6_vS32b_new_pi_128B;
3420 }
3421 return 0;
3422}
3423
Krzysztof Parzyszek0a04ac22016-05-16 16:56:10 +00003424
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003425// Returns the opcode to use when converting MI, which is a conditional jump,
3426// into a conditional instruction which uses the .new value of the predicate.
3427// We also use branch probabilities to add a hint to the jump.
Krzysztof Parzyszek5e6f2bd2015-12-14 21:32:25 +00003428int HexagonInstrInfo::getDotNewPredJumpOp(const MachineInstr *MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003429 const MachineBranchProbabilityInfo *MBPI) const {
3430 // We assume that block can have at most two successors.
3431 bool taken = false;
Krzysztof Parzyszek5e6f2bd2015-12-14 21:32:25 +00003432 const MachineBasicBlock *Src = MI->getParent();
3433 const MachineOperand *BrTarget = &MI->getOperand(1);
3434 const MachineBasicBlock *Dst = BrTarget->getMBB();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003435
3436 const BranchProbability Prediction = MBPI->getEdgeProbability(Src, Dst);
3437 if (Prediction >= BranchProbability(1,2))
3438 taken = true;
3439
3440 switch (MI->getOpcode()) {
3441 case Hexagon::J2_jumpt:
3442 return taken ? Hexagon::J2_jumptnewpt : Hexagon::J2_jumptnew;
3443 case Hexagon::J2_jumpf:
3444 return taken ? Hexagon::J2_jumpfnewpt : Hexagon::J2_jumpfnew;
3445
3446 default:
3447 llvm_unreachable("Unexpected jump instruction.");
3448 }
3449}
3450
3451
3452// Return .new predicate version for an instruction.
Krzysztof Parzyszek5e6f2bd2015-12-14 21:32:25 +00003453int HexagonInstrInfo::getDotNewPredOp(const MachineInstr *MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003454 const MachineBranchProbabilityInfo *MBPI) const {
3455 int NewOpcode = Hexagon::getPredNewOpcode(MI->getOpcode());
3456 if (NewOpcode >= 0) // Valid predicate new instruction
3457 return NewOpcode;
3458
3459 switch (MI->getOpcode()) {
3460 // Condtional Jumps
3461 case Hexagon::J2_jumpt:
3462 case Hexagon::J2_jumpf:
3463 return getDotNewPredJumpOp(MI, MBPI);
3464
3465 default:
3466 assert(0 && "Unknown .new type");
3467 }
3468 return 0;
3469}
3470
3471
3472int HexagonInstrInfo::getDotOldOp(const int opc) const {
3473 int NewOp = opc;
3474 if (isPredicated(NewOp) && isPredicatedNew(NewOp)) { // Get predicate old form
3475 NewOp = Hexagon::getPredOldOpcode(NewOp);
3476 assert(NewOp >= 0 &&
3477 "Couldn't change predicate new instruction to its old form.");
3478 }
3479
3480 if (isNewValueStore(NewOp)) { // Convert into non-new-value format
3481 NewOp = Hexagon::getNonNVStore(NewOp);
3482 assert(NewOp >= 0 && "Couldn't change new-value store to its old form.");
3483 }
3484 return NewOp;
3485}
3486
3487
3488// See if instruction could potentially be a duplex candidate.
3489// If so, return its group. Zero otherwise.
3490HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup(
3491 const MachineInstr *MI) const {
3492 unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
3493 auto &HRI = getRegisterInfo();
3494
3495 switch (MI->getOpcode()) {
3496 default:
3497 return HexagonII::HSIG_None;
3498 //
3499 // Group L1:
3500 //
3501 // Rd = memw(Rs+#u4:2)
3502 // Rd = memub(Rs+#u4:0)
3503 case Hexagon::L2_loadri_io:
3504 DstReg = MI->getOperand(0).getReg();
3505 SrcReg = MI->getOperand(1).getReg();
3506 // Special case this one from Group L2.
3507 // Rd = memw(r29+#u5:2)
3508 if (isIntRegForSubInst(DstReg)) {
3509 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
3510 HRI.getStackRegister() == SrcReg &&
3511 MI->getOperand(2).isImm() &&
3512 isShiftedUInt<5,2>(MI->getOperand(2).getImm()))
3513 return HexagonII::HSIG_L2;
3514 // Rd = memw(Rs+#u4:2)
3515 if (isIntRegForSubInst(SrcReg) &&
3516 (MI->getOperand(2).isImm() &&
3517 isShiftedUInt<4,2>(MI->getOperand(2).getImm())))
3518 return HexagonII::HSIG_L1;
3519 }
3520 break;
3521 case Hexagon::L2_loadrub_io:
3522 // Rd = memub(Rs+#u4:0)
3523 DstReg = MI->getOperand(0).getReg();
3524 SrcReg = MI->getOperand(1).getReg();
3525 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
3526 MI->getOperand(2).isImm() && isUInt<4>(MI->getOperand(2).getImm()))
3527 return HexagonII::HSIG_L1;
3528 break;
3529 //
3530 // Group L2:
3531 //
3532 // Rd = memh/memuh(Rs+#u3:1)
3533 // Rd = memb(Rs+#u3:0)
3534 // Rd = memw(r29+#u5:2) - Handled above.
3535 // Rdd = memd(r29+#u5:3)
3536 // deallocframe
3537 // [if ([!]p0[.new])] dealloc_return
3538 // [if ([!]p0[.new])] jumpr r31
3539 case Hexagon::L2_loadrh_io:
3540 case Hexagon::L2_loadruh_io:
3541 // Rd = memh/memuh(Rs+#u3:1)
3542 DstReg = MI->getOperand(0).getReg();
3543 SrcReg = MI->getOperand(1).getReg();
3544 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
3545 MI->getOperand(2).isImm() &&
3546 isShiftedUInt<3,1>(MI->getOperand(2).getImm()))
3547 return HexagonII::HSIG_L2;
3548 break;
3549 case Hexagon::L2_loadrb_io:
3550 // Rd = memb(Rs+#u3:0)
3551 DstReg = MI->getOperand(0).getReg();
3552 SrcReg = MI->getOperand(1).getReg();
3553 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
3554 MI->getOperand(2).isImm() &&
3555 isUInt<3>(MI->getOperand(2).getImm()))
3556 return HexagonII::HSIG_L2;
3557 break;
3558 case Hexagon::L2_loadrd_io:
3559 // Rdd = memd(r29+#u5:3)
3560 DstReg = MI->getOperand(0).getReg();
3561 SrcReg = MI->getOperand(1).getReg();
3562 if (isDblRegForSubInst(DstReg, HRI) &&
3563 Hexagon::IntRegsRegClass.contains(SrcReg) &&
3564 HRI.getStackRegister() == SrcReg &&
3565 MI->getOperand(2).isImm() &&
3566 isShiftedUInt<5,3>(MI->getOperand(2).getImm()))
3567 return HexagonII::HSIG_L2;
3568 break;
3569 // dealloc_return is not documented in Hexagon Manual, but marked
3570 // with A_SUBINSN attribute in iset_v4classic.py.
3571 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
3572 case Hexagon::L4_return:
3573 case Hexagon::L2_deallocframe:
3574 return HexagonII::HSIG_L2;
3575 case Hexagon::EH_RETURN_JMPR:
3576 case Hexagon::JMPret :
3577 // jumpr r31
3578 // Actual form JMPR %PC<imp-def>, %R31<imp-use>, %R0<imp-use,internal>.
3579 DstReg = MI->getOperand(0).getReg();
3580 if (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg))
3581 return HexagonII::HSIG_L2;
3582 break;
3583 case Hexagon::JMPrett:
3584 case Hexagon::JMPretf:
3585 case Hexagon::JMPrettnewpt:
3586 case Hexagon::JMPretfnewpt :
3587 case Hexagon::JMPrettnew :
3588 case Hexagon::JMPretfnew :
3589 DstReg = MI->getOperand(1).getReg();
3590 SrcReg = MI->getOperand(0).getReg();
3591 // [if ([!]p0[.new])] jumpr r31
3592 if ((Hexagon::PredRegsRegClass.contains(SrcReg) &&
3593 (Hexagon::P0 == SrcReg)) &&
3594 (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg)))
3595 return HexagonII::HSIG_L2;
3596 break;
3597 case Hexagon::L4_return_t :
3598 case Hexagon::L4_return_f :
3599 case Hexagon::L4_return_tnew_pnt :
3600 case Hexagon::L4_return_fnew_pnt :
3601 case Hexagon::L4_return_tnew_pt :
3602 case Hexagon::L4_return_fnew_pt :
3603 // [if ([!]p0[.new])] dealloc_return
3604 SrcReg = MI->getOperand(0).getReg();
3605 if (Hexagon::PredRegsRegClass.contains(SrcReg) && (Hexagon::P0 == SrcReg))
3606 return HexagonII::HSIG_L2;
3607 break;
3608 //
3609 // Group S1:
3610 //
3611 // memw(Rs+#u4:2) = Rt
3612 // memb(Rs+#u4:0) = Rt
3613 case Hexagon::S2_storeri_io:
3614 // Special case this one from Group S2.
3615 // memw(r29+#u5:2) = Rt
3616 Src1Reg = MI->getOperand(0).getReg();
3617 Src2Reg = MI->getOperand(2).getReg();
3618 if (Hexagon::IntRegsRegClass.contains(Src1Reg) &&
3619 isIntRegForSubInst(Src2Reg) &&
3620 HRI.getStackRegister() == Src1Reg && MI->getOperand(1).isImm() &&
3621 isShiftedUInt<5,2>(MI->getOperand(1).getImm()))
3622 return HexagonII::HSIG_S2;
3623 // memw(Rs+#u4:2) = Rt
3624 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
3625 MI->getOperand(1).isImm() &&
3626 isShiftedUInt<4,2>(MI->getOperand(1).getImm()))
3627 return HexagonII::HSIG_S1;
3628 break;
3629 case Hexagon::S2_storerb_io:
3630 // memb(Rs+#u4:0) = Rt
3631 Src1Reg = MI->getOperand(0).getReg();
3632 Src2Reg = MI->getOperand(2).getReg();
3633 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
3634 MI->getOperand(1).isImm() && isUInt<4>(MI->getOperand(1).getImm()))
3635 return HexagonII::HSIG_S1;
3636 break;
3637 //
3638 // Group S2:
3639 //
3640 // memh(Rs+#u3:1) = Rt
3641 // memw(r29+#u5:2) = Rt
3642 // memd(r29+#s6:3) = Rtt
3643 // memw(Rs+#u4:2) = #U1
3644 // memb(Rs+#u4) = #U1
3645 // allocframe(#u5:3)
3646 case Hexagon::S2_storerh_io:
3647 // memh(Rs+#u3:1) = Rt
3648 Src1Reg = MI->getOperand(0).getReg();
3649 Src2Reg = MI->getOperand(2).getReg();
3650 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
3651 MI->getOperand(1).isImm() &&
3652 isShiftedUInt<3,1>(MI->getOperand(1).getImm()))
3653 return HexagonII::HSIG_S1;
3654 break;
3655 case Hexagon::S2_storerd_io:
3656 // memd(r29+#s6:3) = Rtt
3657 Src1Reg = MI->getOperand(0).getReg();
3658 Src2Reg = MI->getOperand(2).getReg();
3659 if (isDblRegForSubInst(Src2Reg, HRI) &&
3660 Hexagon::IntRegsRegClass.contains(Src1Reg) &&
3661 HRI.getStackRegister() == Src1Reg && MI->getOperand(1).isImm() &&
3662 isShiftedInt<6,3>(MI->getOperand(1).getImm()))
3663 return HexagonII::HSIG_S2;
3664 break;
3665 case Hexagon::S4_storeiri_io:
3666 // memw(Rs+#u4:2) = #U1
3667 Src1Reg = MI->getOperand(0).getReg();
3668 if (isIntRegForSubInst(Src1Reg) && MI->getOperand(1).isImm() &&
3669 isShiftedUInt<4,2>(MI->getOperand(1).getImm()) &&
3670 MI->getOperand(2).isImm() && isUInt<1>(MI->getOperand(2).getImm()))
3671 return HexagonII::HSIG_S2;
3672 break;
3673 case Hexagon::S4_storeirb_io:
3674 // memb(Rs+#u4) = #U1
3675 Src1Reg = MI->getOperand(0).getReg();
Krzysztof Parzyszekf2a4f8f2016-06-15 21:05:04 +00003676 if (isIntRegForSubInst(Src1Reg) &&
3677 MI->getOperand(1).isImm() && isUInt<4>(MI->getOperand(1).getImm()) &&
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003678 MI->getOperand(2).isImm() && isUInt<1>(MI->getOperand(2).getImm()))
3679 return HexagonII::HSIG_S2;
3680 break;
3681 case Hexagon::S2_allocframe:
3682 if (MI->getOperand(0).isImm() &&
3683 isShiftedUInt<5,3>(MI->getOperand(0).getImm()))
3684 return HexagonII::HSIG_S1;
3685 break;
3686 //
3687 // Group A:
3688 //
3689 // Rx = add(Rx,#s7)
3690 // Rd = Rs
3691 // Rd = #u6
3692 // Rd = #-1
3693 // if ([!]P0[.new]) Rd = #0
3694 // Rd = add(r29,#u6:2)
3695 // Rx = add(Rx,Rs)
3696 // P0 = cmp.eq(Rs,#u2)
3697 // Rdd = combine(#0,Rs)
3698 // Rdd = combine(Rs,#0)
3699 // Rdd = combine(#u2,#U2)
3700 // Rd = add(Rs,#1)
3701 // Rd = add(Rs,#-1)
3702 // Rd = sxth/sxtb/zxtb/zxth(Rs)
3703 // Rd = and(Rs,#1)
3704 case Hexagon::A2_addi:
3705 DstReg = MI->getOperand(0).getReg();
3706 SrcReg = MI->getOperand(1).getReg();
3707 if (isIntRegForSubInst(DstReg)) {
3708 // Rd = add(r29,#u6:2)
3709 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
3710 HRI.getStackRegister() == SrcReg && MI->getOperand(2).isImm() &&
3711 isShiftedUInt<6,2>(MI->getOperand(2).getImm()))
3712 return HexagonII::HSIG_A;
3713 // Rx = add(Rx,#s7)
3714 if ((DstReg == SrcReg) && MI->getOperand(2).isImm() &&
3715 isInt<7>(MI->getOperand(2).getImm()))
3716 return HexagonII::HSIG_A;
3717 // Rd = add(Rs,#1)
3718 // Rd = add(Rs,#-1)
3719 if (isIntRegForSubInst(SrcReg) && MI->getOperand(2).isImm() &&
3720 ((MI->getOperand(2).getImm() == 1) ||
3721 (MI->getOperand(2).getImm() == -1)))
3722 return HexagonII::HSIG_A;
3723 }
3724 break;
3725 case Hexagon::A2_add:
3726 // Rx = add(Rx,Rs)
3727 DstReg = MI->getOperand(0).getReg();
3728 Src1Reg = MI->getOperand(1).getReg();
3729 Src2Reg = MI->getOperand(2).getReg();
3730 if (isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&
3731 isIntRegForSubInst(Src2Reg))
3732 return HexagonII::HSIG_A;
3733 break;
3734 case Hexagon::A2_andir:
3735 // Same as zxtb.
3736 // Rd16=and(Rs16,#255)
3737 // Rd16=and(Rs16,#1)
3738 DstReg = MI->getOperand(0).getReg();
3739 SrcReg = MI->getOperand(1).getReg();
3740 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
3741 MI->getOperand(2).isImm() &&
3742 ((MI->getOperand(2).getImm() == 1) ||
3743 (MI->getOperand(2).getImm() == 255)))
3744 return HexagonII::HSIG_A;
3745 break;
3746 case Hexagon::A2_tfr:
3747 // Rd = Rs
3748 DstReg = MI->getOperand(0).getReg();
3749 SrcReg = MI->getOperand(1).getReg();
3750 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
3751 return HexagonII::HSIG_A;
3752 break;
3753 case Hexagon::A2_tfrsi:
3754 // Rd = #u6
3755 // Do not test for #u6 size since the const is getting extended
3756 // regardless and compound could be formed.
3757 // Rd = #-1
3758 DstReg = MI->getOperand(0).getReg();
3759 if (isIntRegForSubInst(DstReg))
3760 return HexagonII::HSIG_A;
3761 break;
3762 case Hexagon::C2_cmoveit:
3763 case Hexagon::C2_cmovenewit:
3764 case Hexagon::C2_cmoveif:
3765 case Hexagon::C2_cmovenewif:
3766 // if ([!]P0[.new]) Rd = #0
3767 // Actual form:
3768 // %R16<def> = C2_cmovenewit %P0<internal>, 0, %R16<imp-use,undef>;
3769 DstReg = MI->getOperand(0).getReg();
3770 SrcReg = MI->getOperand(1).getReg();
3771 if (isIntRegForSubInst(DstReg) &&
3772 Hexagon::PredRegsRegClass.contains(SrcReg) && Hexagon::P0 == SrcReg &&
3773 MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0)
3774 return HexagonII::HSIG_A;
3775 break;
3776 case Hexagon::C2_cmpeqi:
3777 // P0 = cmp.eq(Rs,#u2)
3778 DstReg = MI->getOperand(0).getReg();
3779 SrcReg = MI->getOperand(1).getReg();
3780 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3781 Hexagon::P0 == DstReg && isIntRegForSubInst(SrcReg) &&
3782 MI->getOperand(2).isImm() && isUInt<2>(MI->getOperand(2).getImm()))
3783 return HexagonII::HSIG_A;
3784 break;
3785 case Hexagon::A2_combineii:
3786 case Hexagon::A4_combineii:
3787 // Rdd = combine(#u2,#U2)
3788 DstReg = MI->getOperand(0).getReg();
3789 if (isDblRegForSubInst(DstReg, HRI) &&
3790 ((MI->getOperand(1).isImm() && isUInt<2>(MI->getOperand(1).getImm())) ||
3791 (MI->getOperand(1).isGlobal() &&
3792 isUInt<2>(MI->getOperand(1).getOffset()))) &&
3793 ((MI->getOperand(2).isImm() && isUInt<2>(MI->getOperand(2).getImm())) ||
3794 (MI->getOperand(2).isGlobal() &&
3795 isUInt<2>(MI->getOperand(2).getOffset()))))
3796 return HexagonII::HSIG_A;
3797 break;
3798 case Hexagon::A4_combineri:
3799 // Rdd = combine(Rs,#0)
3800 DstReg = MI->getOperand(0).getReg();
3801 SrcReg = MI->getOperand(1).getReg();
3802 if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&
3803 ((MI->getOperand(2).isImm() && MI->getOperand(2).getImm() == 0) ||
3804 (MI->getOperand(2).isGlobal() && MI->getOperand(2).getOffset() == 0)))
3805 return HexagonII::HSIG_A;
3806 break;
3807 case Hexagon::A4_combineir:
3808 // Rdd = combine(#0,Rs)
3809 DstReg = MI->getOperand(0).getReg();
3810 SrcReg = MI->getOperand(2).getReg();
3811 if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&
3812 ((MI->getOperand(1).isImm() && MI->getOperand(1).getImm() == 0) ||
3813 (MI->getOperand(1).isGlobal() && MI->getOperand(1).getOffset() == 0)))
3814 return HexagonII::HSIG_A;
3815 break;
3816 case Hexagon::A2_sxtb:
3817 case Hexagon::A2_sxth:
3818 case Hexagon::A2_zxtb:
3819 case Hexagon::A2_zxth:
3820 // Rd = sxth/sxtb/zxtb/zxth(Rs)
3821 DstReg = MI->getOperand(0).getReg();
3822 SrcReg = MI->getOperand(1).getReg();
3823 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
3824 return HexagonII::HSIG_A;
3825 break;
3826 }
3827
3828 return HexagonII::HSIG_None;
3829}
3830
3831
Krzysztof Parzyszek5e6f2bd2015-12-14 21:32:25 +00003832short HexagonInstrInfo::getEquivalentHWInstr(const MachineInstr *MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003833 return Hexagon::getRealHWInstr(MI->getOpcode(), Hexagon::InstrType_Real);
3834}
3835
3836
3837// Return first non-debug instruction in the basic block.
3838MachineInstr *HexagonInstrInfo::getFirstNonDbgInst(MachineBasicBlock *BB)
3839 const {
3840 for (auto MII = BB->instr_begin(), End = BB->instr_end(); MII != End; MII++) {
3841 MachineInstr *MI = &*MII;
3842 if (MI->isDebugValue())
3843 continue;
3844 return MI;
3845 }
3846 return nullptr;
3847}
3848
3849
3850unsigned HexagonInstrInfo::getInstrTimingClassLatency(
3851 const InstrItineraryData *ItinData, const MachineInstr *MI) const {
3852 // Default to one cycle for no itinerary. However, an "empty" itinerary may
3853 // still have a MinLatency property, which getStageLatency checks.
3854 if (!ItinData)
3855 return getInstrLatency(ItinData, MI);
3856
3857 // Get the latency embedded in the itinerary. If we're not using timing class
3858 // latencies or if we using BSB scheduling, then restrict the maximum latency
3859 // to 1 (that is, either 0 or 1).
3860 if (MI->isTransient())
3861 return 0;
3862 unsigned Latency = ItinData->getStageLatency(MI->getDesc().getSchedClass());
3863 if (!EnableTimingClassLatency ||
3864 MI->getParent()->getParent()->getSubtarget<HexagonSubtarget>().
3865 useBSBScheduling())
3866 if (Latency > 1)
3867 Latency = 1;
3868 return Latency;
3869}
3870
3871
3872// inverts the predication logic.
3873// p -> NotP
3874// NotP -> P
3875bool HexagonInstrInfo::getInvertedPredSense(
3876 SmallVectorImpl<MachineOperand> &Cond) const {
3877 if (Cond.empty())
3878 return false;
3879 unsigned Opc = getInvertedPredicatedOpcode(Cond[0].getImm());
3880 Cond[0].setImm(Opc);
3881 return true;
3882}
3883
3884
3885unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const {
3886 int InvPredOpcode;
3887 InvPredOpcode = isPredicatedTrue(Opc) ? Hexagon::getFalsePredOpcode(Opc)
3888 : Hexagon::getTruePredOpcode(Opc);
3889 if (InvPredOpcode >= 0) // Valid instruction with the inverted predicate.
3890 return InvPredOpcode;
3891
3892 llvm_unreachable("Unexpected predicated instruction");
3893}
3894
3895
3896// Returns the max value that doesn't need to be extended.
3897int HexagonInstrInfo::getMaxValue(const MachineInstr *MI) const {
3898 const uint64_t F = MI->getDesc().TSFlags;
3899 unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
3900 & HexagonII::ExtentSignedMask;
3901 unsigned bits = (F >> HexagonII::ExtentBitsPos)
3902 & HexagonII::ExtentBitsMask;
3903
3904 if (isSigned) // if value is signed
3905 return ~(-1U << (bits - 1));
3906 else
3907 return ~(-1U << bits);
3908}
3909
3910
3911unsigned HexagonInstrInfo::getMemAccessSize(const MachineInstr* MI) const {
3912 const uint64_t F = MI->getDesc().TSFlags;
3913 return (F >> HexagonII::MemAccessSizePos) & HexagonII::MemAccesSizeMask;
3914}
3915
3916
3917// Returns the min value that doesn't need to be extended.
3918int HexagonInstrInfo::getMinValue(const MachineInstr *MI) const {
3919 const uint64_t F = MI->getDesc().TSFlags;
3920 unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
3921 & HexagonII::ExtentSignedMask;
3922 unsigned bits = (F >> HexagonII::ExtentBitsPos)
3923 & HexagonII::ExtentBitsMask;
3924
3925 if (isSigned) // if value is signed
3926 return -1U << (bits - 1);
3927 else
3928 return 0;
3929}
3930
3931
3932// Returns opcode of the non-extended equivalent instruction.
3933short HexagonInstrInfo::getNonExtOpcode(const MachineInstr *MI) const {
Jyotsna Verma84256432013-03-01 17:37:13 +00003934 // Check if the instruction has a register form that uses register in place
3935 // of the extended operand, if so return that as the non-extended form.
3936 short NonExtOpcode = Hexagon::getRegForm(MI->getOpcode());
3937 if (NonExtOpcode >= 0)
3938 return NonExtOpcode;
3939
3940 if (MI->getDesc().mayLoad() || MI->getDesc().mayStore()) {
Alp Tokercb402912014-01-24 17:20:08 +00003941 // Check addressing mode and retrieve non-ext equivalent instruction.
Jyotsna Verma84256432013-03-01 17:37:13 +00003942 switch (getAddrMode(MI)) {
3943 case HexagonII::Absolute :
Krzysztof Parzyszek02579052015-10-20 19:21:05 +00003944 return Hexagon::getBaseWithImmOffset(MI->getOpcode());
Jyotsna Verma84256432013-03-01 17:37:13 +00003945 case HexagonII::BaseImmOffset :
3946 return Hexagon::getBaseWithRegOffset(MI->getOpcode());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003947 case HexagonII::BaseLongOffset:
3948 return Hexagon::getRegShlForm(MI->getOpcode());
3949
Jyotsna Verma84256432013-03-01 17:37:13 +00003950 default:
3951 return -1;
3952 }
3953 }
3954 return -1;
3955}
Jyotsna Verma5ed51812013-05-01 21:37:34 +00003956
Brendon Cahoondf43e682015-05-08 16:16:29 +00003957
Ahmed Bougachac88bf542015-06-11 19:30:37 +00003958bool HexagonInstrInfo::getPredReg(ArrayRef<MachineOperand> Cond,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003959 unsigned &PredReg, unsigned &PredRegPos, unsigned &PredRegFlags) const {
Brendon Cahoondf43e682015-05-08 16:16:29 +00003960 if (Cond.empty())
3961 return false;
3962 assert(Cond.size() == 2);
3963 if (isNewValueJump(Cond[0].getImm()) || Cond[1].isMBB()) {
3964 DEBUG(dbgs() << "No predregs for new-value jumps/endloop");
3965 return false;
3966 }
3967 PredReg = Cond[1].getReg();
3968 PredRegPos = 1;
3969 // See IfConversion.cpp why we add RegState::Implicit | RegState::Undef
3970 PredRegFlags = 0;
3971 if (Cond[1].isImplicit())
3972 PredRegFlags = RegState::Implicit;
3973 if (Cond[1].isUndef())
3974 PredRegFlags |= RegState::Undef;
3975 return true;
3976}
3977
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003978
Krzysztof Parzyszek5e6f2bd2015-12-14 21:32:25 +00003979short HexagonInstrInfo::getPseudoInstrPair(const MachineInstr *MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003980 return Hexagon::getRealHWInstr(MI->getOpcode(), Hexagon::InstrType_Pseudo);
3981}
3982
3983
3984short HexagonInstrInfo::getRegForm(const MachineInstr *MI) const {
3985 return Hexagon::getRegForm(MI->getOpcode());
3986}
3987
3988
3989// Return the number of bytes required to encode the instruction.
3990// Hexagon instructions are fixed length, 4 bytes, unless they
3991// use a constant extender, which requires another 4 bytes.
3992// For debug instructions and prolog labels, return 0.
3993unsigned HexagonInstrInfo::getSize(const MachineInstr *MI) const {
3994 if (MI->isDebugValue() || MI->isPosition())
3995 return 0;
3996
3997 unsigned Size = MI->getDesc().getSize();
3998 if (!Size)
3999 // Assume the default insn size in case it cannot be determined
4000 // for whatever reason.
4001 Size = HEXAGON_INSTR_SIZE;
4002
4003 if (isConstExtended(MI) || isExtended(MI))
4004 Size += HEXAGON_INSTR_SIZE;
4005
4006 // Try and compute number of instructions in asm.
4007 if (BranchRelaxAsmLarge && MI->getOpcode() == Hexagon::INLINEASM) {
4008 const MachineBasicBlock &MBB = *MI->getParent();
4009 const MachineFunction *MF = MBB.getParent();
4010 const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo();
4011
4012 // Count the number of register definitions to find the asm string.
4013 unsigned NumDefs = 0;
4014 for (; MI->getOperand(NumDefs).isReg() && MI->getOperand(NumDefs).isDef();
4015 ++NumDefs)
4016 assert(NumDefs != MI->getNumOperands()-2 && "No asm string?");
4017
4018 assert(MI->getOperand(NumDefs).isSymbol() && "No asm string?");
4019 // Disassemble the AsmStr and approximate number of instructions.
4020 const char *AsmStr = MI->getOperand(NumDefs).getSymbolName();
4021 Size = getInlineAsmLength(AsmStr, *MAI);
4022 }
4023
4024 return Size;
4025}
4026
4027
4028uint64_t HexagonInstrInfo::getType(const MachineInstr* MI) const {
4029 const uint64_t F = MI->getDesc().TSFlags;
4030 return (F >> HexagonII::TypePos) & HexagonII::TypeMask;
4031}
4032
4033
4034unsigned HexagonInstrInfo::getUnits(const MachineInstr* MI) const {
4035 const TargetSubtargetInfo &ST = MI->getParent()->getParent()->getSubtarget();
4036 const InstrItineraryData &II = *ST.getInstrItineraryData();
4037 const InstrStage &IS = *II.beginStage(MI->getDesc().getSchedClass());
4038
4039 return IS.getUnits();
4040}
4041
4042
4043unsigned HexagonInstrInfo::getValidSubTargets(const unsigned Opcode) const {
4044 const uint64_t F = get(Opcode).TSFlags;
4045 return (F >> HexagonII::validSubTargetPos) & HexagonII::validSubTargetMask;
4046}
4047
4048
4049// Calculate size of the basic block without debug instructions.
4050unsigned HexagonInstrInfo::nonDbgBBSize(const MachineBasicBlock *BB) const {
4051 return nonDbgMICount(BB->instr_begin(), BB->instr_end());
4052}
4053
4054
4055unsigned HexagonInstrInfo::nonDbgBundleSize(
4056 MachineBasicBlock::const_iterator BundleHead) const {
4057 assert(BundleHead->isBundle() && "Not a bundle header");
Duncan P. N. Exon Smithd84f6002016-02-22 21:30:15 +00004058 auto MII = BundleHead.getInstrIterator();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004059 // Skip the bundle header.
Duncan P. N. Exon Smithf9ab4162016-02-27 17:05:33 +00004060 return nonDbgMICount(++MII, getBundleEnd(*BundleHead));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004061}
4062
4063
4064/// immediateExtend - Changes the instruction in place to one using an immediate
4065/// extender.
4066void HexagonInstrInfo::immediateExtend(MachineInstr *MI) const {
4067 assert((isExtendable(MI)||isConstExtended(MI)) &&
4068 "Instruction must be extendable");
4069 // Find which operand is extendable.
4070 short ExtOpNum = getCExtOpNum(MI);
4071 MachineOperand &MO = MI->getOperand(ExtOpNum);
4072 // This needs to be something we understand.
4073 assert((MO.isMBB() || MO.isImm()) &&
4074 "Branch with unknown extendable field type");
4075 // Mark given operand as extended.
4076 MO.addTargetFlag(HexagonII::HMOTF_ConstExtended);
4077}
4078
4079
4080bool HexagonInstrInfo::invertAndChangeJumpTarget(
4081 MachineInstr* MI, MachineBasicBlock* NewTarget) const {
4082 DEBUG(dbgs() << "\n[invertAndChangeJumpTarget] to BB#"
4083 << NewTarget->getNumber(); MI->dump(););
4084 assert(MI->isBranch());
4085 unsigned NewOpcode = getInvertedPredicatedOpcode(MI->getOpcode());
4086 int TargetPos = MI->getNumOperands() - 1;
4087 // In general branch target is the last operand,
4088 // but some implicit defs added at the end might change it.
4089 while ((TargetPos > -1) && !MI->getOperand(TargetPos).isMBB())
4090 --TargetPos;
4091 assert((TargetPos >= 0) && MI->getOperand(TargetPos).isMBB());
4092 MI->getOperand(TargetPos).setMBB(NewTarget);
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00004093 if (EnableBranchPrediction && isPredicatedNew(*MI)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004094 NewOpcode = reversePrediction(NewOpcode);
4095 }
4096 MI->setDesc(get(NewOpcode));
4097 return true;
4098}
4099
4100
4101void HexagonInstrInfo::genAllInsnTimingClasses(MachineFunction &MF) const {
4102 /* +++ The code below is used to generate complete set of Hexagon Insn +++ */
4103 MachineFunction::iterator A = MF.begin();
4104 MachineBasicBlock &B = *A;
4105 MachineBasicBlock::iterator I = B.begin();
4106 MachineInstr *MI = &*I;
4107 DebugLoc DL = MI->getDebugLoc();
4108 MachineInstr *NewMI;
4109
4110 for (unsigned insn = TargetOpcode::GENERIC_OP_END+1;
4111 insn < Hexagon::INSTRUCTION_LIST_END; ++insn) {
4112 NewMI = BuildMI(B, MI, DL, get(insn));
4113 DEBUG(dbgs() << "\n" << getName(NewMI->getOpcode()) <<
4114 " Class: " << NewMI->getDesc().getSchedClass());
4115 NewMI->eraseFromParent();
4116 }
4117 /* --- The code above is used to generate complete set of Hexagon Insn --- */
4118}
4119
4120
4121// inverts the predication logic.
4122// p -> NotP
4123// NotP -> P
4124bool HexagonInstrInfo::reversePredSense(MachineInstr* MI) const {
4125 DEBUG(dbgs() << "\nTrying to reverse pred. sense of:"; MI->dump());
4126 MI->setDesc(get(getInvertedPredicatedOpcode(MI->getOpcode())));
4127 return true;
4128}
4129
4130
4131// Reverse the branch prediction.
4132unsigned HexagonInstrInfo::reversePrediction(unsigned Opcode) const {
4133 int PredRevOpcode = -1;
4134 if (isPredictedTaken(Opcode))
4135 PredRevOpcode = Hexagon::notTakenBranchPrediction(Opcode);
4136 else
4137 PredRevOpcode = Hexagon::takenBranchPrediction(Opcode);
4138 assert(PredRevOpcode > 0);
4139 return PredRevOpcode;
4140}
4141
4142
4143// TODO: Add more rigorous validation.
4144bool HexagonInstrInfo::validateBranchCond(const ArrayRef<MachineOperand> &Cond)
4145 const {
4146 return Cond.empty() || (Cond[0].isImm() && (Cond.size() != 1));
4147}
4148
Krzysztof Parzyszekf5cbac92016-04-29 15:49:13 +00004149
4150short HexagonInstrInfo::xformRegToImmOffset(const MachineInstr *MI) const {
4151 return Hexagon::xformRegToImmOffset(MI->getOpcode());
4152}