blob: 1f31e43bc5b7d2fdee504c93bdf879a870af23e7 [file] [log] [blame]
Eugene Zelenko3b873362017-09-28 22:27:31 +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
Chandler Carruth6bda14b2017-06-06 11:49:48 +000014#include "HexagonInstrInfo.h"
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +000015#include "Hexagon.h"
Eugene Zelenko3b873362017-09-28 22:27:31 +000016#include "HexagonFrameLowering.h"
Krzysztof Parzyszeke95e9552016-07-29 13:59:09 +000017#include "HexagonHazardRecognizer.h"
Craig Topperb25fda92012-03-17 18:46:09 +000018#include "HexagonRegisterInfo.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000019#include "HexagonSubtarget.h"
Eugene Zelenko3b873362017-09-28 22:27:31 +000020#include "llvm/ADT/ArrayRef.h"
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +000021#include "llvm/ADT/SmallPtrSet.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000022#include "llvm/ADT/SmallVector.h"
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +000023#include "llvm/ADT/StringRef.h"
Benjamin Kramerae87d7b2012-02-06 10:19:29 +000024#include "llvm/CodeGen/DFAPacketizer.h"
Ron Lieberman88159e52016-09-02 22:56:24 +000025#include "llvm/CodeGen/LivePhysRegs.h"
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +000026#include "llvm/CodeGen/MachineBasicBlock.h"
27#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000028#include "llvm/CodeGen/MachineFrameInfo.h"
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +000029#include "llvm/CodeGen/MachineFunction.h"
30#include "llvm/CodeGen/MachineInstr.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000031#include "llvm/CodeGen/MachineInstrBuilder.h"
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +000032#include "llvm/CodeGen/MachineInstrBundle.h"
33#include "llvm/CodeGen/MachineLoopInfo.h"
Tony Linthicum1213a7a2011-12-12 21:14:40 +000034#include "llvm/CodeGen/MachineMemOperand.h"
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +000035#include "llvm/CodeGen/MachineOperand.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000036#include "llvm/CodeGen/MachineRegisterInfo.h"
Eugene Zelenko3b873362017-09-28 22:27:31 +000037#include "llvm/CodeGen/MachineValueType.h"
Krzysztof Parzyszeke95e9552016-07-29 13:59:09 +000038#include "llvm/CodeGen/ScheduleDAG.h"
Eugene Zelenko3b873362017-09-28 22:27:31 +000039#include "llvm/IR/DebugLoc.h"
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +000040#include "llvm/MC/MCAsmInfo.h"
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +000041#include "llvm/MC/MCInstrDesc.h"
42#include "llvm/MC/MCInstrItineraries.h"
43#include "llvm/MC/MCRegisterInfo.h"
44#include "llvm/Support/BranchProbability.h"
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +000045#include "llvm/Support/CommandLine.h"
Jyotsna Verma5ed51812013-05-01 21:37:34 +000046#include "llvm/Support/Debug.h"
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +000047#include "llvm/Support/ErrorHandling.h"
Benjamin Kramerae87d7b2012-02-06 10:19:29 +000048#include "llvm/Support/MathExtras.h"
Reid Kleckner1c76f1552013-05-03 00:54:56 +000049#include "llvm/Support/raw_ostream.h"
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +000050#include "llvm/Target/TargetInstrInfo.h"
Eugene Zelenko3b873362017-09-28 22:27:31 +000051#include "llvm/Target/TargetMachine.h"
52#include "llvm/Target/TargetOpcodes.h"
53#include "llvm/Target/TargetRegisterInfo.h"
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +000054#include "llvm/Target/TargetSubtargetInfo.h"
55#include <cassert>
Krzysztof Parzyszekaa935752015-11-24 15:11:13 +000056#include <cctype>
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +000057#include <cstdint>
58#include <cstring>
59#include <iterator>
Eugene Zelenko3b873362017-09-28 22:27:31 +000060#include <string>
61#include <utility>
Tony Linthicum1213a7a2011-12-12 21:14:40 +000062
Tony Linthicum1213a7a2011-12-12 21:14:40 +000063using namespace llvm;
64
Chandler Carruthe96dd892014-04-21 22:55:11 +000065#define DEBUG_TYPE "hexagon-instrinfo"
66
Chandler Carruthd174b722014-04-22 02:03:14 +000067#define GET_INSTRINFO_CTOR_DTOR
68#define GET_INSTRMAP_INFO
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +000069#include "HexagonDepTimingClasses.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000070#include "HexagonGenDFAPacketizer.inc"
71#include "HexagonGenInstrInfo.inc"
Chandler Carruthd174b722014-04-22 02:03:14 +000072
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +000073cl::opt<bool> ScheduleInlineAsm("hexagon-sched-inline-asm", cl::Hidden,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +000074 cl::init(false), cl::desc("Do not consider inline-asm a scheduling/"
75 "packetization boundary."));
76
77static cl::opt<bool> EnableBranchPrediction("hexagon-enable-branch-prediction",
78 cl::Hidden, cl::init(true), cl::desc("Enable branch prediction"));
79
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +000080static cl::opt<bool> DisableNVSchedule("disable-hexagon-nv-schedule",
81 cl::Hidden, cl::ZeroOrMore, cl::init(false),
82 cl::desc("Disable schedule adjustment for new value stores."));
83
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +000084static cl::opt<bool> EnableTimingClassLatency(
85 "enable-timing-class-latency", cl::Hidden, cl::init(false),
86 cl::desc("Enable timing class latency"));
87
88static cl::opt<bool> EnableALUForwarding(
89 "enable-alu-forwarding", cl::Hidden, cl::init(true),
90 cl::desc("Enable vec alu forwarding"));
91
92static cl::opt<bool> EnableACCForwarding(
93 "enable-acc-forwarding", cl::Hidden, cl::init(true),
94 cl::desc("Enable vec acc forwarding"));
95
96static cl::opt<bool> BranchRelaxAsmLarge("branch-relax-asm-large",
97 cl::init(true), cl::Hidden, cl::ZeroOrMore, cl::desc("branch relax asm"));
98
Krzysztof Parzyszeke95e9552016-07-29 13:59:09 +000099static cl::opt<bool> UseDFAHazardRec("dfa-hazard-rec",
100 cl::init(true), cl::Hidden, cl::ZeroOrMore,
101 cl::desc("Use the DFA based hazard recognizer."));
102
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000103/// Constants for Hexagon instructions.
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000104const int Hexagon_MEMW_OFFSET_MAX = 4095;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000105const int Hexagon_MEMW_OFFSET_MIN = -4096;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000106const int Hexagon_MEMD_OFFSET_MAX = 8191;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000107const int Hexagon_MEMD_OFFSET_MIN = -8192;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000108const int Hexagon_MEMH_OFFSET_MAX = 2047;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000109const int Hexagon_MEMH_OFFSET_MIN = -2048;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000110const int Hexagon_MEMB_OFFSET_MAX = 1023;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000111const int Hexagon_MEMB_OFFSET_MIN = -1024;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000112const int Hexagon_ADDI_OFFSET_MAX = 32767;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +0000113const int Hexagon_ADDI_OFFSET_MIN = -32768;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000114
Juergen Ributzkad12ccbd2013-11-19 00:57:56 +0000115// Pin the vtable to this file.
116void HexagonInstrInfo::anchor() {}
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000117
118HexagonInstrInfo::HexagonInstrInfo(HexagonSubtarget &ST)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000119 : HexagonGenInstrInfo(Hexagon::ADJCALLSTACKDOWN, Hexagon::ADJCALLSTACKUP) {}
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000120
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000121static bool isIntRegForSubInst(unsigned Reg) {
122 return (Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||
123 (Reg >= Hexagon::R16 && Reg <= Hexagon::R23);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000124}
125
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000126static bool isDblRegForSubInst(unsigned Reg, const HexagonRegisterInfo &HRI) {
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +0000127 return isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::isub_lo)) &&
128 isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::isub_hi));
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000129}
130
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000131/// Calculate number of instructions excluding the debug instructions.
132static unsigned nonDbgMICount(MachineBasicBlock::const_instr_iterator MIB,
133 MachineBasicBlock::const_instr_iterator MIE) {
134 unsigned Count = 0;
135 for (; MIB != MIE; ++MIB) {
136 if (!MIB->isDebugValue())
137 ++Count;
138 }
139 return Count;
140}
141
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000142/// Find the hardware loop instruction used to set-up the specified loop.
143/// On Hexagon, we have two instructions used to set-up the hardware loop
144/// (LOOP0, LOOP1) with corresponding endloop (ENDLOOP0, ENDLOOP1) instructions
145/// to indicate the end of a loop.
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000146static MachineInstr *findLoopInstr(MachineBasicBlock *BB, unsigned EndLoopOp,
147 MachineBasicBlock *TargetBB,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000148 SmallPtrSet<MachineBasicBlock *, 8> &Visited) {
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000149 unsigned LOOPi;
150 unsigned LOOPr;
Brendon Cahoondf43e682015-05-08 16:16:29 +0000151 if (EndLoopOp == Hexagon::ENDLOOP0) {
152 LOOPi = Hexagon::J2_loop0i;
153 LOOPr = Hexagon::J2_loop0r;
154 } else { // EndLoopOp == Hexagon::EndLOOP1
155 LOOPi = Hexagon::J2_loop1i;
156 LOOPr = Hexagon::J2_loop1r;
157 }
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000158
Brendon Cahoondf43e682015-05-08 16:16:29 +0000159 // The loop set-up instruction will be in a predecessor block
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000160 for (MachineBasicBlock *PB : BB->predecessors()) {
Brendon Cahoondf43e682015-05-08 16:16:29 +0000161 // If this has been visited, already skip it.
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000162 if (!Visited.insert(PB).second)
Brendon Cahoondf43e682015-05-08 16:16:29 +0000163 continue;
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000164 if (PB == BB)
Brendon Cahoondf43e682015-05-08 16:16:29 +0000165 continue;
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000166 for (auto I = PB->instr_rbegin(), E = PB->instr_rend(); I != E; ++I) {
167 unsigned Opc = I->getOpcode();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000168 if (Opc == LOOPi || Opc == LOOPr)
169 return &*I;
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000170 // We've reached a different loop, which means the loop01 has been
171 // removed.
172 if (Opc == EndLoopOp && I->getOperand(0).getMBB() != TargetBB)
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +0000173 return nullptr;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000174 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000175 // Check the predecessors for the LOOP instruction.
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000176 if (MachineInstr *Loop = findLoopInstr(PB, EndLoopOp, TargetBB, Visited))
177 return Loop;
Brendon Cahoondf43e682015-05-08 16:16:29 +0000178 }
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +0000179 return nullptr;
Brendon Cahoondf43e682015-05-08 16:16:29 +0000180}
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000181
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000182/// Gather register def/uses from MI.
183/// This treats possible (predicated) defs as actually happening ones
184/// (conservatively).
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +0000185static inline void parseOperands(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000186 SmallVector<unsigned, 4> &Defs, SmallVector<unsigned, 8> &Uses) {
187 Defs.clear();
188 Uses.clear();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000189
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +0000190 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
191 const MachineOperand &MO = MI.getOperand(i);
Brendon Cahoondf43e682015-05-08 16:16:29 +0000192
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000193 if (!MO.isReg())
194 continue;
Brendon Cahoondf43e682015-05-08 16:16:29 +0000195
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000196 unsigned Reg = MO.getReg();
197 if (!Reg)
198 continue;
199
200 if (MO.isUse())
201 Uses.push_back(MO.getReg());
202
203 if (MO.isDef())
204 Defs.push_back(MO.getReg());
205 }
206}
207
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000208// Position dependent, so check twice for swap.
209static bool isDuplexPairMatch(unsigned Ga, unsigned Gb) {
210 switch (Ga) {
211 case HexagonII::HSIG_None:
212 default:
213 return false;
214 case HexagonII::HSIG_L1:
215 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_A);
216 case HexagonII::HSIG_L2:
217 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
218 Gb == HexagonII::HSIG_A);
219 case HexagonII::HSIG_S1:
220 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
221 Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_A);
222 case HexagonII::HSIG_S2:
223 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
224 Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_S2 ||
225 Gb == HexagonII::HSIG_A);
226 case HexagonII::HSIG_A:
227 return (Gb == HexagonII::HSIG_A);
228 case HexagonII::HSIG_Compound:
229 return (Gb == HexagonII::HSIG_Compound);
230 }
231 return false;
232}
233
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000234/// isLoadFromStackSlot - If the specified machine instruction is a direct
235/// load from a stack slot, return the virtual or physical register number of
236/// the destination along with the FrameIndex of the loaded stack slot. If
237/// not, return 0. This predicate must return 0 if the instruction has
238/// any side effects other than loading from the stack slot.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000239unsigned HexagonInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000240 int &FrameIndex) const {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000241 switch (MI.getOpcode()) {
242 default:
243 break;
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000244 case Hexagon::L2_loadri_io:
245 case Hexagon::L2_loadrd_io:
246 case Hexagon::V6_vL32b_ai:
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +0000247 case Hexagon::V6_vL32b_nt_ai:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000248 case Hexagon::V6_vL32Ub_ai:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000249 case Hexagon::LDriw_pred:
250 case Hexagon::LDriw_mod:
Krzysztof Parzyszek17aa4132016-08-16 15:43:54 +0000251 case Hexagon::PS_vloadrq_ai:
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +0000252 case Hexagon::PS_vloadrw_ai:
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000253 case Hexagon::PS_vloadrw_nt_ai: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000254 const MachineOperand OpFI = MI.getOperand(1);
255 if (!OpFI.isFI())
256 return 0;
257 const MachineOperand OpOff = MI.getOperand(2);
258 if (!OpOff.isImm() || OpOff.getImm() != 0)
259 return 0;
260 FrameIndex = OpFI.getIndex();
261 return MI.getOperand(0).getReg();
262 }
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +0000263
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000264 case Hexagon::L2_ploadrit_io:
265 case Hexagon::L2_ploadrif_io:
266 case Hexagon::L2_ploadrdt_io:
267 case Hexagon::L2_ploadrdf_io: {
268 const MachineOperand OpFI = MI.getOperand(2);
269 if (!OpFI.isFI())
270 return 0;
271 const MachineOperand OpOff = MI.getOperand(3);
272 if (!OpOff.isImm() || OpOff.getImm() != 0)
273 return 0;
274 FrameIndex = OpFI.getIndex();
275 return MI.getOperand(0).getReg();
276 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000277 }
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +0000278
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000279 return 0;
280}
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000281
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000282/// isStoreToStackSlot - If the specified machine instruction is a direct
283/// store to a stack slot, return the virtual or physical register number of
284/// the source reg along with the FrameIndex of the loaded stack slot. If
285/// not, return 0. This predicate must return 0 if the instruction has
286/// any side effects other than storing to the stack slot.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000287unsigned HexagonInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000288 int &FrameIndex) const {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000289 switch (MI.getOpcode()) {
290 default:
291 break;
292 case Hexagon::S2_storerb_io:
293 case Hexagon::S2_storerh_io:
294 case Hexagon::S2_storeri_io:
295 case Hexagon::S2_storerd_io:
296 case Hexagon::V6_vS32b_ai:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000297 case Hexagon::V6_vS32Ub_ai:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000298 case Hexagon::STriw_pred:
299 case Hexagon::STriw_mod:
Krzysztof Parzyszek17aa4132016-08-16 15:43:54 +0000300 case Hexagon::PS_vstorerq_ai:
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000301 case Hexagon::PS_vstorerw_ai: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000302 const MachineOperand &OpFI = MI.getOperand(0);
303 if (!OpFI.isFI())
304 return 0;
305 const MachineOperand &OpOff = MI.getOperand(1);
306 if (!OpOff.isImm() || OpOff.getImm() != 0)
307 return 0;
308 FrameIndex = OpFI.getIndex();
309 return MI.getOperand(2).getReg();
310 }
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +0000311
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000312 case Hexagon::S2_pstorerbt_io:
313 case Hexagon::S2_pstorerbf_io:
314 case Hexagon::S2_pstorerht_io:
315 case Hexagon::S2_pstorerhf_io:
316 case Hexagon::S2_pstorerit_io:
317 case Hexagon::S2_pstorerif_io:
318 case Hexagon::S2_pstorerdt_io:
319 case Hexagon::S2_pstorerdf_io: {
320 const MachineOperand &OpFI = MI.getOperand(1);
321 if (!OpFI.isFI())
322 return 0;
323 const MachineOperand &OpOff = MI.getOperand(2);
324 if (!OpOff.isImm() || OpOff.getImm() != 0)
325 return 0;
326 FrameIndex = OpFI.getIndex();
327 return MI.getOperand(3).getReg();
328 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000329 }
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +0000330
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000331 return 0;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000332}
333
Brendon Cahoondf43e682015-05-08 16:16:29 +0000334/// This function can analyze one/two way branching only and should (mostly) be
335/// called by target independent side.
336/// First entry is always the opcode of the branching instruction, except when
337/// the Cond vector is supposed to be empty, e.g., when AnalyzeBranch fails, a
338/// BB with only unconditional jump. Subsequent entries depend upon the opcode,
339/// e.g. Jump_c p will have
340/// Cond[0] = Jump_c
341/// Cond[1] = p
342/// HW-loop ENDLOOP:
343/// Cond[0] = ENDLOOP
344/// Cond[1] = MBB
345/// New value jump:
346/// Cond[0] = Hexagon::CMPEQri_f_Jumpnv_t_V4 -- specific opcode
347/// Cond[1] = R
348/// Cond[2] = Imm
Jacques Pienaar71c30a12016-07-15 14:41:04 +0000349bool HexagonInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000350 MachineBasicBlock *&TBB,
Brendon Cahoondf43e682015-05-08 16:16:29 +0000351 MachineBasicBlock *&FBB,
352 SmallVectorImpl<MachineOperand> &Cond,
353 bool AllowModify) const {
Craig Topper062a2ba2014-04-25 05:30:21 +0000354 TBB = nullptr;
355 FBB = nullptr;
Brendon Cahoondf43e682015-05-08 16:16:29 +0000356 Cond.clear();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000357
358 // If the block has no terminators, it just falls into the block after it.
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000359 MachineBasicBlock::instr_iterator I = MBB.instr_end();
360 if (I == MBB.instr_begin())
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000361 return false;
362
363 // A basic block may looks like this:
364 //
365 // [ insn
366 // EH_LABEL
367 // insn
368 // insn
369 // insn
370 // EH_LABEL
371 // insn ]
372 //
373 // It has two succs but does not have a terminator
374 // Don't know how to handle it.
375 do {
376 --I;
377 if (I->isEHLabel())
Brendon Cahoondf43e682015-05-08 16:16:29 +0000378 // Don't analyze EH branches.
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000379 return true;
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000380 } while (I != MBB.instr_begin());
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000381
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000382 I = MBB.instr_end();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000383 --I;
384
385 while (I->isDebugValue()) {
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000386 if (I == MBB.instr_begin())
387 return false;
388 --I;
389 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000390
Colin LeMahieu7b1799c2015-03-09 22:05:21 +0000391 bool JumpToBlock = I->getOpcode() == Hexagon::J2_jump &&
392 I->getOperand(0).isMBB();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000393 // Delete the J2_jump if it's equivalent to a fall-through.
Colin LeMahieu7b1799c2015-03-09 22:05:21 +0000394 if (AllowModify && JumpToBlock &&
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000395 MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +0000396 DEBUG(dbgs() << "\nErasing the jump to successor block\n";);
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000397 I->eraseFromParent();
398 I = MBB.instr_end();
399 if (I == MBB.instr_begin())
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000400 return false;
401 --I;
402 }
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +0000403 if (!isUnpredicatedTerminator(*I))
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000404 return false;
405
406 // Get the last instruction in the block.
Duncan P. N. Exon Smitha72c6e22015-10-20 00:46:39 +0000407 MachineInstr *LastInst = &*I;
Craig Topper062a2ba2014-04-25 05:30:21 +0000408 MachineInstr *SecondLastInst = nullptr;
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000409 // Find one more terminator if present.
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +0000410 while (true) {
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +0000411 if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000412 if (!SecondLastInst)
Duncan P. N. Exon Smitha72c6e22015-10-20 00:46:39 +0000413 SecondLastInst = &*I;
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000414 else
415 // This is a third branch.
416 return true;
417 }
418 if (I == MBB.instr_begin())
419 break;
420 --I;
Duncan P. N. Exon Smitha72c6e22015-10-20 00:46:39 +0000421 }
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000422
423 int LastOpcode = LastInst->getOpcode();
Colin LeMahieu7b1799c2015-03-09 22:05:21 +0000424 int SecLastOpcode = SecondLastInst ? SecondLastInst->getOpcode() : 0;
425 // If the branch target is not a basic block, it could be a tail call.
426 // (It is, if the target is a function.)
427 if (LastOpcode == Hexagon::J2_jump && !LastInst->getOperand(0).isMBB())
428 return true;
429 if (SecLastOpcode == Hexagon::J2_jump &&
430 !SecondLastInst->getOperand(0).isMBB())
431 return true;
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000432
433 bool LastOpcodeHasJMP_c = PredOpcodeHasJMP_c(LastOpcode);
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +0000434 bool LastOpcodeHasNVJump = isNewValueJump(*LastInst);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000435
Krzysztof Parzyszekb28ae102016-01-14 15:05:27 +0000436 if (LastOpcodeHasJMP_c && !LastInst->getOperand(1).isMBB())
437 return true;
438
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000439 // If there is only one terminator instruction, process it.
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000440 if (LastInst && !SecondLastInst) {
Colin LeMahieudb0b13c2014-12-10 21:24:10 +0000441 if (LastOpcode == Hexagon::J2_jump) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000442 TBB = LastInst->getOperand(0).getMBB();
443 return false;
444 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000445 if (isEndLoopN(LastOpcode)) {
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000446 TBB = LastInst->getOperand(0).getMBB();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000447 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000448 Cond.push_back(LastInst->getOperand(0));
449 return false;
450 }
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000451 if (LastOpcodeHasJMP_c) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000452 TBB = LastInst->getOperand(1).getMBB();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000453 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000454 Cond.push_back(LastInst->getOperand(0));
455 return false;
456 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000457 // Only supporting rr/ri versions of new-value jumps.
458 if (LastOpcodeHasNVJump && (LastInst->getNumExplicitOperands() == 3)) {
459 TBB = LastInst->getOperand(2).getMBB();
460 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
461 Cond.push_back(LastInst->getOperand(0));
462 Cond.push_back(LastInst->getOperand(1));
463 return false;
464 }
465 DEBUG(dbgs() << "\nCant analyze BB#" << MBB.getNumber()
466 << " with one jump\n";);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000467 // Otherwise, don't know what this is.
468 return true;
469 }
470
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000471 bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +0000472 bool SecLastOpcodeHasNVJump = isNewValueJump(*SecondLastInst);
Colin LeMahieudb0b13c2014-12-10 21:24:10 +0000473 if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) {
Krzysztof Parzyszekb28ae102016-01-14 15:05:27 +0000474 if (!SecondLastInst->getOperand(1).isMBB())
475 return true;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000476 TBB = SecondLastInst->getOperand(1).getMBB();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000477 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000478 Cond.push_back(SecondLastInst->getOperand(0));
479 FBB = LastInst->getOperand(0).getMBB();
480 return false;
481 }
482
Brendon Cahoondf43e682015-05-08 16:16:29 +0000483 // Only supporting rr/ri versions of new-value jumps.
484 if (SecLastOpcodeHasNVJump &&
485 (SecondLastInst->getNumExplicitOperands() == 3) &&
486 (LastOpcode == Hexagon::J2_jump)) {
487 TBB = SecondLastInst->getOperand(2).getMBB();
488 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
489 Cond.push_back(SecondLastInst->getOperand(0));
490 Cond.push_back(SecondLastInst->getOperand(1));
491 FBB = LastInst->getOperand(0).getMBB();
492 return false;
493 }
494
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000495 // If the block ends with two Hexagon:JMPs, handle it. The second one is not
496 // executed, so remove it.
Colin LeMahieudb0b13c2014-12-10 21:24:10 +0000497 if (SecLastOpcode == Hexagon::J2_jump && LastOpcode == Hexagon::J2_jump) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000498 TBB = SecondLastInst->getOperand(0).getMBB();
Duncan P. N. Exon Smithc5b668d2016-02-22 20:49:58 +0000499 I = LastInst->getIterator();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000500 if (AllowModify)
501 I->eraseFromParent();
502 return false;
503 }
504
Brendon Cahoondf43e682015-05-08 16:16:29 +0000505 // If the block ends with an ENDLOOP, and J2_jump, handle it.
506 if (isEndLoopN(SecLastOpcode) && LastOpcode == Hexagon::J2_jump) {
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000507 TBB = SecondLastInst->getOperand(0).getMBB();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000508 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000509 Cond.push_back(SecondLastInst->getOperand(0));
510 FBB = LastInst->getOperand(0).getMBB();
511 return false;
512 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000513 DEBUG(dbgs() << "\nCant analyze BB#" << MBB.getNumber()
514 << " with two jumps";);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000515 // Otherwise, can't handle this.
516 return true;
517}
518
Matt Arsenault1b9fc8e2016-09-14 20:43:16 +0000519unsigned HexagonInstrInfo::removeBranch(MachineBasicBlock &MBB,
Matt Arsenaulta2b036e2016-09-14 17:23:48 +0000520 int *BytesRemoved) const {
521 assert(!BytesRemoved && "code size not handled");
522
Brendon Cahoondf43e682015-05-08 16:16:29 +0000523 DEBUG(dbgs() << "\nRemoving branches out of BB#" << MBB.getNumber());
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000524 MachineBasicBlock::iterator I = MBB.end();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000525 unsigned Count = 0;
526 while (I != MBB.begin()) {
527 --I;
528 if (I->isDebugValue())
529 continue;
530 // Only removing branches from end of MBB.
531 if (!I->isBranch())
532 return Count;
533 if (Count && (I->getOpcode() == Hexagon::J2_jump))
534 llvm_unreachable("Malformed basic block: unconditional branch not last");
535 MBB.erase(&MBB.back());
536 I = MBB.end();
537 ++Count;
Krzysztof Parzyszek78cc36f2015-03-18 15:56:43 +0000538 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000539 return Count;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000540}
541
Matt Arsenaulte8e0f5c2016-09-14 17:24:15 +0000542unsigned HexagonInstrInfo::insertBranch(MachineBasicBlock &MBB,
Benjamin Kramerbdc49562016-06-12 15:39:02 +0000543 MachineBasicBlock *TBB,
544 MachineBasicBlock *FBB,
545 ArrayRef<MachineOperand> Cond,
Matt Arsenaulta2b036e2016-09-14 17:23:48 +0000546 const DebugLoc &DL,
547 int *BytesAdded) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000548 unsigned BOpc = Hexagon::J2_jump;
549 unsigned BccOpc = Hexagon::J2_jumpt;
550 assert(validateBranchCond(Cond) && "Invalid branching condition");
Matt Arsenaulte8e0f5c2016-09-14 17:24:15 +0000551 assert(TBB && "insertBranch must not be told to insert a fallthrough");
Matt Arsenaulta2b036e2016-09-14 17:23:48 +0000552 assert(!BytesAdded && "code size not handled");
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000553
Matt Arsenault1b9fc8e2016-09-14 20:43:16 +0000554 // Check if reverseBranchCondition has asked to reverse this branch
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000555 // If we want to reverse the branch an odd number of times, we want
556 // J2_jumpf.
557 if (!Cond.empty() && Cond[0].isImm())
558 BccOpc = Cond[0].getImm();
559
560 if (!FBB) {
561 if (Cond.empty()) {
562 // Due to a bug in TailMerging/CFG Optimization, we need to add a
563 // special case handling of a predicated jump followed by an
564 // unconditional jump. If not, Tail Merging and CFG Optimization go
565 // into an infinite loop.
566 MachineBasicBlock *NewTBB, *NewFBB;
567 SmallVector<MachineOperand, 4> Cond;
Duncan P. N. Exon Smith25b132e2016-07-08 18:26:20 +0000568 auto Term = MBB.getFirstTerminator();
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +0000569 if (Term != MBB.end() && isPredicated(*Term) &&
Duncan P. N. Exon Smithe04fe1a2016-08-17 00:34:00 +0000570 !analyzeBranch(MBB, NewTBB, NewFBB, Cond, false) &&
571 MachineFunction::iterator(NewTBB) == ++MBB.getIterator()) {
Matt Arsenault1b9fc8e2016-09-14 20:43:16 +0000572 reverseBranchCondition(Cond);
573 removeBranch(MBB);
Matt Arsenaulte8e0f5c2016-09-14 17:24:15 +0000574 return insertBranch(MBB, TBB, nullptr, Cond, DL);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000575 }
576 BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);
577 } else if (isEndLoopN(Cond[0].getImm())) {
578 int EndLoopOp = Cond[0].getImm();
579 assert(Cond[1].isMBB());
580 // Since we're adding an ENDLOOP, there better be a LOOP instruction.
581 // Check for it, and change the BB target if needed.
582 SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000583 MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),
584 VisitedBBs);
Eugene Zelenko3b873362017-09-28 22:27:31 +0000585 assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000586 Loop->getOperand(0).setMBB(TBB);
587 // Add the ENDLOOP after the finding the LOOP0.
588 BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
589 } else if (isNewValueJump(Cond[0].getImm())) {
590 assert((Cond.size() == 3) && "Only supporting rr/ri version of nvjump");
591 // New value jump
592 // (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset)
593 // (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset)
594 unsigned Flags1 = getUndefRegState(Cond[1].isUndef());
595 DEBUG(dbgs() << "\nInserting NVJump for BB#" << MBB.getNumber(););
596 if (Cond[2].isReg()) {
597 unsigned Flags2 = getUndefRegState(Cond[2].isUndef());
598 BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).
599 addReg(Cond[2].getReg(), Flags2).addMBB(TBB);
600 } else if(Cond[2].isImm()) {
601 BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).
602 addImm(Cond[2].getImm()).addMBB(TBB);
603 } else
604 llvm_unreachable("Invalid condition for branching");
605 } else {
606 assert((Cond.size() == 2) && "Malformed cond vector");
607 const MachineOperand &RO = Cond[1];
608 unsigned Flags = getUndefRegState(RO.isUndef());
609 BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);
610 }
611 return 1;
Krzysztof Parzyszekcfe285e2013-02-11 20:04:29 +0000612 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000613 assert((!Cond.empty()) &&
614 "Cond. cannot be empty when multiple branchings are required");
615 assert((!isNewValueJump(Cond[0].getImm())) &&
616 "NV-jump cannot be inserted with another branch");
617 // Special case for hardware loops. The condition is a basic block.
618 if (isEndLoopN(Cond[0].getImm())) {
619 int EndLoopOp = Cond[0].getImm();
620 assert(Cond[1].isMBB());
621 // Since we're adding an ENDLOOP, there better be a LOOP instruction.
622 // Check for it, and change the BB target if needed.
623 SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000624 MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),
625 VisitedBBs);
Eugene Zelenko3b873362017-09-28 22:27:31 +0000626 assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000627 Loop->getOperand(0).setMBB(TBB);
628 // Add the ENDLOOP after the finding the LOOP0.
629 BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
630 } else {
631 const MachineOperand &RO = Cond[1];
632 unsigned Flags = getUndefRegState(RO.isUndef());
633 BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);
Krzysztof Parzyszekcfe285e2013-02-11 20:04:29 +0000634 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000635 BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB);
Krzysztof Parzyszekcfe285e2013-02-11 20:04:29 +0000636
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000637 return 2;
638}
639
Brendon Cahoon254f8892016-07-29 16:44:44 +0000640/// Analyze the loop code to find the loop induction variable and compare used
641/// to compute the number of iterations. Currently, we analyze loop that are
642/// controlled using hardware loops. In this case, the induction variable
643/// instruction is null. For all other cases, this function returns true, which
644/// means we're unable to analyze it.
645bool HexagonInstrInfo::analyzeLoop(MachineLoop &L,
646 MachineInstr *&IndVarInst,
647 MachineInstr *&CmpInst) const {
648
649 MachineBasicBlock *LoopEnd = L.getBottomBlock();
650 MachineBasicBlock::iterator I = LoopEnd->getFirstTerminator();
651 // We really "analyze" only hardware loops right now.
652 if (I != LoopEnd->end() && isEndLoopN(I->getOpcode())) {
653 IndVarInst = nullptr;
654 CmpInst = &*I;
655 return false;
656 }
657 return true;
658}
659
660/// Generate code to reduce the loop iteration by one and check if the loop is
661/// finished. Return the value/register of the new loop count. this function
662/// assumes the nth iteration is peeled first.
663unsigned HexagonInstrInfo::reduceLoopCount(MachineBasicBlock &MBB,
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +0000664 MachineInstr *IndVar, MachineInstr &Cmp,
Brendon Cahoon254f8892016-07-29 16:44:44 +0000665 SmallVectorImpl<MachineOperand> &Cond,
666 SmallVectorImpl<MachineInstr *> &PrevInsts,
667 unsigned Iter, unsigned MaxIter) const {
668 // We expect a hardware loop currently. This means that IndVar is set
669 // to null, and the compare is the ENDLOOP instruction.
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +0000670 assert((!IndVar) && isEndLoopN(Cmp.getOpcode())
Brendon Cahoon254f8892016-07-29 16:44:44 +0000671 && "Expecting a hardware loop");
672 MachineFunction *MF = MBB.getParent();
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +0000673 DebugLoc DL = Cmp.getDebugLoc();
Brendon Cahoon254f8892016-07-29 16:44:44 +0000674 SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000675 MachineInstr *Loop = findLoopInstr(&MBB, Cmp.getOpcode(),
676 Cmp.getOperand(0).getMBB(), VisitedBBs);
Brendon Cahoon254f8892016-07-29 16:44:44 +0000677 if (!Loop)
678 return 0;
679 // If the loop trip count is a compile-time value, then just change the
680 // value.
681 if (Loop->getOpcode() == Hexagon::J2_loop0i ||
682 Loop->getOpcode() == Hexagon::J2_loop1i) {
683 int64_t Offset = Loop->getOperand(1).getImm();
684 if (Offset <= 1)
685 Loop->eraseFromParent();
686 else
687 Loop->getOperand(1).setImm(Offset - 1);
688 return Offset - 1;
689 }
690 // The loop trip count is a run-time value. We generate code to subtract
691 // one from the trip count, and update the loop instruction.
692 assert(Loop->getOpcode() == Hexagon::J2_loop0r && "Unexpected instruction");
693 unsigned LoopCount = Loop->getOperand(1).getReg();
694 // Check if we're done with the loop.
695 unsigned LoopEnd = createVR(MF, MVT::i1);
696 MachineInstr *NewCmp = BuildMI(&MBB, DL, get(Hexagon::C2_cmpgtui), LoopEnd).
697 addReg(LoopCount).addImm(1);
698 unsigned NewLoopCount = createVR(MF, MVT::i32);
699 MachineInstr *NewAdd = BuildMI(&MBB, DL, get(Hexagon::A2_addi), NewLoopCount).
700 addReg(LoopCount).addImm(-1);
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000701 const auto &HRI = *MF->getSubtarget<HexagonSubtarget>().getRegisterInfo();
Brendon Cahoon254f8892016-07-29 16:44:44 +0000702 // Update the previously generated instructions with the new loop counter.
703 for (SmallVectorImpl<MachineInstr *>::iterator I = PrevInsts.begin(),
704 E = PrevInsts.end(); I != E; ++I)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000705 (*I)->substituteRegister(LoopCount, NewLoopCount, 0, HRI);
Brendon Cahoon254f8892016-07-29 16:44:44 +0000706 PrevInsts.clear();
707 PrevInsts.push_back(NewCmp);
708 PrevInsts.push_back(NewAdd);
709 // Insert the new loop instruction if this is the last time the loop is
710 // decremented.
711 if (Iter == MaxIter)
712 BuildMI(&MBB, DL, get(Hexagon::J2_loop0r)).
713 addMBB(Loop->getOperand(0).getMBB()).addReg(NewLoopCount);
714 // Delete the old loop instruction.
715 if (Iter == 0)
716 Loop->eraseFromParent();
717 Cond.push_back(MachineOperand::CreateImm(Hexagon::J2_jumpf));
718 Cond.push_back(NewCmp->getOperand(0));
719 return NewLoopCount;
720}
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000721
722bool HexagonInstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,
723 unsigned NumCycles, unsigned ExtraPredCycles,
724 BranchProbability Probability) const {
725 return nonDbgBBSize(&MBB) <= 3;
726}
727
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000728bool HexagonInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB,
729 unsigned NumTCycles, unsigned ExtraTCycles, MachineBasicBlock &FMBB,
730 unsigned NumFCycles, unsigned ExtraFCycles, BranchProbability Probability)
731 const {
732 return nonDbgBBSize(&TMBB) <= 3 && nonDbgBBSize(&FMBB) <= 3;
733}
734
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000735bool HexagonInstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock &MBB,
736 unsigned NumInstrs, BranchProbability Probability) const {
737 return NumInstrs <= 4;
Krzysztof Parzyszekcfe285e2013-02-11 20:04:29 +0000738}
739
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000740void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
Benjamin Kramerbdc49562016-06-12 15:39:02 +0000741 MachineBasicBlock::iterator I,
742 const DebugLoc &DL, unsigned DestReg,
743 unsigned SrcReg, bool KillSrc) const {
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000744 MachineFunction &MF = *MBB.getParent();
745 auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000746 unsigned KillFlag = getKillRegState(KillSrc);
747
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000748 if (Hexagon::IntRegsRegClass.contains(SrcReg, DestReg)) {
Krzysztof Parzyszek3d6fc832016-06-02 14:33:08 +0000749 BuildMI(MBB, I, DL, get(Hexagon::A2_tfr), DestReg)
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000750 .addReg(SrcReg, KillFlag);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000751 return;
752 }
753 if (Hexagon::DoubleRegsRegClass.contains(SrcReg, DestReg)) {
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000754 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrp), DestReg)
755 .addReg(SrcReg, KillFlag);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000756 return;
757 }
758 if (Hexagon::PredRegsRegClass.contains(SrcReg, DestReg)) {
759 // Map Pd = Ps to Pd = or(Ps, Ps).
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000760 BuildMI(MBB, I, DL, get(Hexagon::C2_or), DestReg)
761 .addReg(SrcReg).addReg(SrcReg, KillFlag);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000762 return;
763 }
Colin LeMahieu402f7722014-12-19 18:56:10 +0000764 if (Hexagon::CtrRegsRegClass.contains(DestReg) &&
Sirish Pande8bb97452012-05-12 05:54:15 +0000765 Hexagon::IntRegsRegClass.contains(SrcReg)) {
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000766 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg)
767 .addReg(SrcReg, KillFlag);
768 return;
769 }
770 if (Hexagon::IntRegsRegClass.contains(DestReg) &&
771 Hexagon::CtrRegsRegClass.contains(SrcReg)) {
772 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrcrr), DestReg)
773 .addReg(SrcReg, KillFlag);
774 return;
775 }
776 if (Hexagon::ModRegsRegClass.contains(DestReg) &&
777 Hexagon::IntRegsRegClass.contains(SrcReg)) {
778 BuildMI(MBB, I, DL, get(Hexagon::A2_tfrrcr), DestReg)
779 .addReg(SrcReg, KillFlag);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000780 return;
Sirish Pande30804c22012-02-15 18:52:27 +0000781 }
Anshuman Dasguptae96f8042013-02-13 22:56:34 +0000782 if (Hexagon::PredRegsRegClass.contains(SrcReg) &&
783 Hexagon::IntRegsRegClass.contains(DestReg)) {
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000784 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg)
785 .addReg(SrcReg, KillFlag);
Anshuman Dasguptae96f8042013-02-13 22:56:34 +0000786 return;
787 }
788 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
789 Hexagon::PredRegsRegClass.contains(DestReg)) {
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000790 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrrp), DestReg)
791 .addReg(SrcReg, KillFlag);
Anshuman Dasguptae96f8042013-02-13 22:56:34 +0000792 return;
793 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000794 if (Hexagon::PredRegsRegClass.contains(SrcReg) &&
795 Hexagon::IntRegsRegClass.contains(DestReg)) {
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000796 BuildMI(MBB, I, DL, get(Hexagon::C2_tfrpr), DestReg)
797 .addReg(SrcReg, KillFlag);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000798 return;
799 }
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000800 if (Hexagon::HvxVRRegClass.contains(SrcReg, DestReg)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000801 BuildMI(MBB, I, DL, get(Hexagon::V6_vassign), DestReg).
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000802 addReg(SrcReg, KillFlag);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000803 return;
804 }
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000805 if (Hexagon::HvxWRRegClass.contains(SrcReg, DestReg)) {
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +0000806 unsigned LoSrc = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);
807 unsigned HiSrc = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000808 BuildMI(MBB, I, DL, get(Hexagon::V6_vcombine), DestReg)
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +0000809 .addReg(HiSrc, KillFlag)
810 .addReg(LoSrc, KillFlag);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000811 return;
812 }
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000813 if (Hexagon::HvxQRRegClass.contains(SrcReg, DestReg)) {
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000814 BuildMI(MBB, I, DL, get(Hexagon::V6_pred_and), DestReg)
815 .addReg(SrcReg)
816 .addReg(SrcReg, KillFlag);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000817 return;
818 }
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000819 if (Hexagon::HvxQRRegClass.contains(SrcReg) &&
820 Hexagon::HvxVRRegClass.contains(DestReg)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000821 llvm_unreachable("Unimplemented pred to vec");
822 return;
823 }
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000824 if (Hexagon::HvxQRRegClass.contains(DestReg) &&
825 Hexagon::HvxVRRegClass.contains(SrcReg)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000826 llvm_unreachable("Unimplemented vec to pred");
827 return;
828 }
Sirish Pande30804c22012-02-15 18:52:27 +0000829
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000830#ifndef NDEBUG
831 // Show the invalid registers to ease debugging.
832 dbgs() << "Invalid registers for copy in BB#" << MBB.getNumber()
833 << ": " << PrintReg(DestReg, &HRI)
834 << " = " << PrintReg(SrcReg, &HRI) << '\n';
835#endif
Sirish Pande30804c22012-02-15 18:52:27 +0000836 llvm_unreachable("Unimplemented");
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000837}
838
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000839void HexagonInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
840 MachineBasicBlock::iterator I, unsigned SrcReg, bool isKill, int FI,
841 const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000842 DebugLoc DL = MBB.findDebugLoc(I);
843 MachineFunction &MF = *MBB.getParent();
Matthias Braun941a7052016-07-28 18:40:00 +0000844 MachineFrameInfo &MFI = MF.getFrameInfo();
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000845 unsigned SlotAlign = MFI.getObjectAlignment(FI);
846 unsigned RegAlign = TRI->getSpillAlignment(*RC);
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000847 unsigned KillFlag = getKillRegState(isKill);
Krzysztof Parzyszek781324f2017-05-03 15:23:53 +0000848 bool HasAlloca = MFI.hasVarSizedObjects();
849 const auto &HST = MF.getSubtarget<HexagonSubtarget>();
850 const HexagonFrameLowering &HFI = *HST.getFrameLowering();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000851
Alex Lorenze40c8a22015-08-11 23:09:45 +0000852 MachineMemOperand *MMO = MF.getMachineMemOperand(
853 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000854 MFI.getObjectSize(FI), SlotAlign);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000855
Craig Topperc7242e02012-04-20 07:30:17 +0000856 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {
Colin LeMahieubda31b42014-12-29 20:44:51 +0000857 BuildMI(MBB, I, DL, get(Hexagon::S2_storeri_io))
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000858 .addFrameIndex(FI).addImm(0)
859 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
Craig Topperc7242e02012-04-20 07:30:17 +0000860 } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {
Colin LeMahieubda31b42014-12-29 20:44:51 +0000861 BuildMI(MBB, I, DL, get(Hexagon::S2_storerd_io))
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000862 .addFrameIndex(FI).addImm(0)
863 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
Craig Topperc7242e02012-04-20 07:30:17 +0000864 } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000865 BuildMI(MBB, I, DL, get(Hexagon::STriw_pred))
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000866 .addFrameIndex(FI).addImm(0)
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000867 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000868 } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {
869 BuildMI(MBB, I, DL, get(Hexagon::STriw_mod))
870 .addFrameIndex(FI).addImm(0)
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000871 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000872 } else if (Hexagon::HvxQRRegClass.hasSubClassEq(RC)) {
Krzysztof Parzyszek17aa4132016-08-16 15:43:54 +0000873 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerq_ai))
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000874 .addFrameIndex(FI).addImm(0)
875 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000876 } else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {
Krzysztof Parzyszek781324f2017-05-03 15:23:53 +0000877 // If there are variable-sized objects, spills will not be aligned.
878 if (HasAlloca)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000879 SlotAlign = HFI.getStackAlignment();
880 unsigned Opc = SlotAlign < RegAlign ? Hexagon::V6_vS32Ub_ai
881 : Hexagon::V6_vS32b_ai;
882 MachineMemOperand *MMOA = MF.getMachineMemOperand(
883 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
884 MFI.getObjectSize(FI), SlotAlign);
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +0000885 BuildMI(MBB, I, DL, get(Opc))
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000886 .addFrameIndex(FI).addImm(0)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000887 .addReg(SrcReg, KillFlag).addMemOperand(MMOA);
888 } else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {
Krzysztof Parzyszek781324f2017-05-03 15:23:53 +0000889 // If there are variable-sized objects, spills will not be aligned.
890 if (HasAlloca)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000891 SlotAlign = HFI.getStackAlignment();
892 unsigned Opc = SlotAlign < RegAlign ? Hexagon::PS_vstorerwu_ai
893 : Hexagon::PS_vstorerw_ai;
894 MachineMemOperand *MMOA = MF.getMachineMemOperand(
895 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
896 MFI.getObjectSize(FI), SlotAlign);
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +0000897 BuildMI(MBB, I, DL, get(Opc))
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000898 .addFrameIndex(FI).addImm(0)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000899 .addReg(SrcReg, KillFlag).addMemOperand(MMOA);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000900 } else {
Craig Toppere55c5562012-02-07 02:50:20 +0000901 llvm_unreachable("Unimplemented");
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000902 }
903}
904
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000905void HexagonInstrInfo::loadRegFromStackSlot(
906 MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg,
907 int FI, const TargetRegisterClass *RC,
908 const TargetRegisterInfo *TRI) const {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000909 DebugLoc DL = MBB.findDebugLoc(I);
910 MachineFunction &MF = *MBB.getParent();
Matthias Braun941a7052016-07-28 18:40:00 +0000911 MachineFrameInfo &MFI = MF.getFrameInfo();
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000912 unsigned SlotAlign = MFI.getObjectAlignment(FI);
913 unsigned RegAlign = TRI->getSpillAlignment(*RC);
Krzysztof Parzyszek781324f2017-05-03 15:23:53 +0000914 bool HasAlloca = MFI.hasVarSizedObjects();
915 const auto &HST = MF.getSubtarget<HexagonSubtarget>();
916 const HexagonFrameLowering &HFI = *HST.getFrameLowering();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000917
Alex Lorenze40c8a22015-08-11 23:09:45 +0000918 MachineMemOperand *MMO = MF.getMachineMemOperand(
919 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000920 MFI.getObjectSize(FI), SlotAlign);
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000921
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000922 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {
Colin LeMahieu026e88d2014-12-23 20:02:16 +0000923 BuildMI(MBB, I, DL, get(Hexagon::L2_loadri_io), DestReg)
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000924 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000925 } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {
Colin LeMahieu947cd702014-12-23 20:44:59 +0000926 BuildMI(MBB, I, DL, get(Hexagon::L2_loadrd_io), DestReg)
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000927 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000928 } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000929 BuildMI(MBB, I, DL, get(Hexagon::LDriw_pred), DestReg)
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000930 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
931 } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {
932 BuildMI(MBB, I, DL, get(Hexagon::LDriw_mod), DestReg)
933 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000934 } else if (Hexagon::HvxQRRegClass.hasSubClassEq(RC)) {
Krzysztof Parzyszek17aa4132016-08-16 15:43:54 +0000935 BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrq_ai), DestReg)
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000936 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000937 } else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {
Krzysztof Parzyszek781324f2017-05-03 15:23:53 +0000938 // If there are variable-sized objects, spills will not be aligned.
939 if (HasAlloca)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000940 SlotAlign = HFI.getStackAlignment();
941 unsigned Opc = SlotAlign < RegAlign ? Hexagon::V6_vL32Ub_ai
942 : Hexagon::V6_vL32b_ai;
943 MachineMemOperand *MMOA = MF.getMachineMemOperand(
944 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
945 MFI.getObjectSize(FI), SlotAlign);
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +0000946 BuildMI(MBB, I, DL, get(Opc), DestReg)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000947 .addFrameIndex(FI).addImm(0).addMemOperand(MMOA);
948 } else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {
Krzysztof Parzyszek781324f2017-05-03 15:23:53 +0000949 // If there are variable-sized objects, spills will not be aligned.
950 if (HasAlloca)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000951 SlotAlign = HFI.getStackAlignment();
952 unsigned Opc = SlotAlign < RegAlign ? Hexagon::PS_vloadrwu_ai
953 : Hexagon::PS_vloadrw_ai;
954 MachineMemOperand *MMOA = MF.getMachineMemOperand(
955 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
956 MFI.getObjectSize(FI), SlotAlign);
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +0000957 BuildMI(MBB, I, DL, get(Opc), DestReg)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000958 .addFrameIndex(FI).addImm(0).addMemOperand(MMOA);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000959 } else {
Craig Toppere55c5562012-02-07 02:50:20 +0000960 llvm_unreachable("Can't store this register to stack slot");
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000961 }
962}
963
Ron Lieberman88159e52016-09-02 22:56:24 +0000964static void getLiveRegsAt(LivePhysRegs &Regs, const MachineInstr &MI) {
965 const MachineBasicBlock &B = *MI.getParent();
966 Regs.addLiveOuts(B);
Duncan P. N. Exon Smith18720962016-09-11 18:51:28 +0000967 auto E = ++MachineBasicBlock::const_iterator(MI.getIterator()).getReverse();
Ron Lieberman88159e52016-09-02 22:56:24 +0000968 for (auto I = B.rbegin(); I != E; ++I)
969 Regs.stepBackward(*I);
970}
971
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000972/// expandPostRAPseudo - This function is called for all pseudo instructions
973/// that remain after register allocation. Many pseudo instructions are
974/// created to help register allocation. This is the place to convert them
975/// into real instructions. The target can edit MI in place, or it can insert
976/// new instructions and erase MI. The function should return true if
977/// anything was changed.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000978bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000979 MachineBasicBlock &MBB = *MI.getParent();
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000980 MachineFunction &MF = *MBB.getParent();
981 MachineRegisterInfo &MRI = MF.getRegInfo();
982 const auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000983 DebugLoc DL = MI.getDebugLoc();
984 unsigned Opc = MI.getOpcode();
Colin LeMahieu7b1799c2015-03-09 22:05:21 +0000985
986 switch (Opc) {
Krzysztof Parzyszek3d6fc832016-06-02 14:33:08 +0000987 case TargetOpcode::COPY: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000988 MachineOperand &MD = MI.getOperand(0);
989 MachineOperand &MS = MI.getOperand(1);
990 MachineBasicBlock::iterator MBBI = MI.getIterator();
Krzysztof Parzyszek3d6fc832016-06-02 14:33:08 +0000991 if (MD.getReg() != MS.getReg() && !MS.isUndef()) {
992 copyPhysReg(MBB, MI, DL, MD.getReg(), MS.getReg(), MS.isKill());
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000993 std::prev(MBBI)->copyImplicitOps(*MBB.getParent(), MI);
Krzysztof Parzyszek3d6fc832016-06-02 14:33:08 +0000994 }
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000995 MBB.erase(MBBI);
Krzysztof Parzyszek3d6fc832016-06-02 14:33:08 +0000996 return true;
997 }
Krzysztof Parzyszek1d01a792016-08-16 18:08:40 +0000998 case Hexagon::PS_aligna:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000999 BuildMI(MBB, MI, DL, get(Hexagon::A2_andir), MI.getOperand(0).getReg())
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00001000 .addReg(HRI.getFrameRegister())
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001001 .addImm(-MI.getOperand(1).getImm());
Krzysztof Parzyszek4fa2a9f2015-04-22 16:43:53 +00001002 MBB.erase(MI);
1003 return true;
Krzysztof Parzyszekeabc0d02016-08-16 17:14:44 +00001004 case Hexagon::V6_vassignp: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001005 unsigned SrcReg = MI.getOperand(1).getReg();
1006 unsigned DstReg = MI.getOperand(0).getReg();
Krzysztof Parzyszekeabc0d02016-08-16 17:14:44 +00001007 unsigned Kill = getKillRegState(MI.getOperand(1).isKill());
1008 BuildMI(MBB, MI, DL, get(Hexagon::V6_vcombine), DstReg)
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001009 .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_hi), Kill)
1010 .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_lo), Kill);
Krzysztof Parzyszek4eb6d4d2015-11-26 16:54:33 +00001011 MBB.erase(MI);
1012 return true;
1013 }
Krzysztof Parzyszekeabc0d02016-08-16 17:14:44 +00001014 case Hexagon::V6_lo: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001015 unsigned SrcReg = MI.getOperand(1).getReg();
1016 unsigned DstReg = MI.getOperand(0).getReg();
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001017 unsigned SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001018 copyPhysReg(MBB, MI, DL, DstReg, SrcSubLo, MI.getOperand(1).isKill());
Krzysztof Parzyszek4eb6d4d2015-11-26 16:54:33 +00001019 MBB.erase(MI);
1020 MRI.clearKillFlags(SrcSubLo);
1021 return true;
1022 }
Krzysztof Parzyszekeabc0d02016-08-16 17:14:44 +00001023 case Hexagon::V6_hi: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001024 unsigned SrcReg = MI.getOperand(1).getReg();
1025 unsigned DstReg = MI.getOperand(0).getReg();
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001026 unsigned SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001027 copyPhysReg(MBB, MI, DL, DstReg, SrcSubHi, MI.getOperand(1).isKill());
Krzysztof Parzyszek4eb6d4d2015-11-26 16:54:33 +00001028 MBB.erase(MI);
1029 MRI.clearKillFlags(SrcSubHi);
1030 return true;
1031 }
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +00001032 case Hexagon::PS_vstorerw_ai:
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00001033 case Hexagon::PS_vstorerwu_ai: {
1034 bool Aligned = Opc == Hexagon::PS_vstorerw_ai;
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001035 unsigned SrcReg = MI.getOperand(2).getReg();
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001036 unsigned SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);
1037 unsigned SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00001038 unsigned NewOpc = Aligned ? Hexagon::V6_vS32b_ai : Hexagon::V6_vS32Ub_ai;
1039 unsigned Offset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +00001040
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001041 MachineInstr *MI1New =
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +00001042 BuildMI(MBB, MI, DL, get(NewOpc))
Diana Picus116bbab2017-01-13 09:58:52 +00001043 .add(MI.getOperand(0))
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001044 .addImm(MI.getOperand(1).getImm())
1045 .addReg(SrcSubLo)
1046 .setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
Krzysztof Parzyszek195dc8d2015-11-26 04:33:11 +00001047 MI1New->getOperand(0).setIsKill(false);
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +00001048 BuildMI(MBB, MI, DL, get(NewOpc))
Diana Picus116bbab2017-01-13 09:58:52 +00001049 .add(MI.getOperand(0))
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001050 // The Vectors are indexed in multiples of vector size.
1051 .addImm(MI.getOperand(1).getImm() + Offset)
1052 .addReg(SrcSubHi)
1053 .setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
Krzysztof Parzyszek195dc8d2015-11-26 04:33:11 +00001054 MBB.erase(MI);
1055 return true;
1056 }
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +00001057 case Hexagon::PS_vloadrw_ai:
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00001058 case Hexagon::PS_vloadrwu_ai: {
1059 bool Aligned = Opc == Hexagon::PS_vloadrw_ai;
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001060 unsigned DstReg = MI.getOperand(0).getReg();
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00001061 unsigned NewOpc = Aligned ? Hexagon::V6_vL32b_ai : Hexagon::V6_vL32Ub_ai;
1062 unsigned Offset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
1063
Diana Picus116bbab2017-01-13 09:58:52 +00001064 MachineInstr *MI1New = BuildMI(MBB, MI, DL, get(NewOpc),
1065 HRI.getSubReg(DstReg, Hexagon::vsub_lo))
Krzysztof Parzyszek4be9d922017-05-03 15:26:13 +00001066 .add(MI.getOperand(1))
1067 .addImm(MI.getOperand(2).getImm())
1068 .setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
Krzysztof Parzyszek195dc8d2015-11-26 04:33:11 +00001069 MI1New->getOperand(1).setIsKill(false);
Diana Picus116bbab2017-01-13 09:58:52 +00001070 BuildMI(MBB, MI, DL, get(NewOpc), HRI.getSubReg(DstReg, Hexagon::vsub_hi))
1071 .add(MI.getOperand(1))
Krzysztof Parzyszek195dc8d2015-11-26 04:33:11 +00001072 // The Vectors are indexed in multiples of vector size.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001073 .addImm(MI.getOperand(2).getImm() + Offset)
1074 .setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
Krzysztof Parzyszek195dc8d2015-11-26 04:33:11 +00001075 MBB.erase(MI);
1076 return true;
1077 }
Krzysztof Parzyszek1d01a792016-08-16 18:08:40 +00001078 case Hexagon::PS_true: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001079 unsigned Reg = MI.getOperand(0).getReg();
Krzysztof Parzyszek36ccfa52015-03-18 19:07:53 +00001080 BuildMI(MBB, MI, DL, get(Hexagon::C2_orn), Reg)
1081 .addReg(Reg, RegState::Undef)
1082 .addReg(Reg, RegState::Undef);
1083 MBB.erase(MI);
1084 return true;
1085 }
Krzysztof Parzyszek1d01a792016-08-16 18:08:40 +00001086 case Hexagon::PS_false: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001087 unsigned Reg = MI.getOperand(0).getReg();
Krzysztof Parzyszek36ccfa52015-03-18 19:07:53 +00001088 BuildMI(MBB, MI, DL, get(Hexagon::C2_andn), Reg)
1089 .addReg(Reg, RegState::Undef)
1090 .addReg(Reg, RegState::Undef);
1091 MBB.erase(MI);
1092 return true;
1093 }
Krzysztof Parzyszek1d01a792016-08-16 18:08:40 +00001094 case Hexagon::PS_vmulw: {
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001095 // Expand a 64-bit vector multiply into 2 32-bit scalar multiplies.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001096 unsigned DstReg = MI.getOperand(0).getReg();
1097 unsigned Src1Reg = MI.getOperand(1).getReg();
1098 unsigned Src2Reg = MI.getOperand(2).getReg();
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001099 unsigned Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::isub_hi);
1100 unsigned Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::isub_lo);
1101 unsigned Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::isub_hi);
1102 unsigned Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::isub_lo);
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001103 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi),
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001104 HRI.getSubReg(DstReg, Hexagon::isub_hi))
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001105 .addReg(Src1SubHi)
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001106 .addReg(Src2SubHi);
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001107 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi),
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001108 HRI.getSubReg(DstReg, Hexagon::isub_lo))
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001109 .addReg(Src1SubLo)
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001110 .addReg(Src2SubLo);
1111 MBB.erase(MI);
1112 MRI.clearKillFlags(Src1SubHi);
1113 MRI.clearKillFlags(Src1SubLo);
1114 MRI.clearKillFlags(Src2SubHi);
1115 MRI.clearKillFlags(Src2SubLo);
1116 return true;
1117 }
Krzysztof Parzyszek1d01a792016-08-16 18:08:40 +00001118 case Hexagon::PS_vmulw_acc: {
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001119 // Expand 64-bit vector multiply with addition into 2 scalar multiplies.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001120 unsigned DstReg = MI.getOperand(0).getReg();
1121 unsigned Src1Reg = MI.getOperand(1).getReg();
1122 unsigned Src2Reg = MI.getOperand(2).getReg();
1123 unsigned Src3Reg = MI.getOperand(3).getReg();
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001124 unsigned Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::isub_hi);
1125 unsigned Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::isub_lo);
1126 unsigned Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::isub_hi);
1127 unsigned Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::isub_lo);
1128 unsigned Src3SubHi = HRI.getSubReg(Src3Reg, Hexagon::isub_hi);
1129 unsigned Src3SubLo = HRI.getSubReg(Src3Reg, Hexagon::isub_lo);
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001130 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci),
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001131 HRI.getSubReg(DstReg, Hexagon::isub_hi))
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001132 .addReg(Src1SubHi)
1133 .addReg(Src2SubHi)
1134 .addReg(Src3SubHi);
1135 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci),
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001136 HRI.getSubReg(DstReg, Hexagon::isub_lo))
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001137 .addReg(Src1SubLo)
1138 .addReg(Src2SubLo)
1139 .addReg(Src3SubLo);
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001140 MBB.erase(MI);
1141 MRI.clearKillFlags(Src1SubHi);
1142 MRI.clearKillFlags(Src1SubLo);
1143 MRI.clearKillFlags(Src2SubHi);
1144 MRI.clearKillFlags(Src2SubLo);
1145 MRI.clearKillFlags(Src3SubHi);
1146 MRI.clearKillFlags(Src3SubLo);
1147 return true;
1148 }
Krzysztof Parzyszek258af192016-08-11 19:12:18 +00001149 case Hexagon::PS_pselect: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001150 const MachineOperand &Op0 = MI.getOperand(0);
1151 const MachineOperand &Op1 = MI.getOperand(1);
1152 const MachineOperand &Op2 = MI.getOperand(2);
1153 const MachineOperand &Op3 = MI.getOperand(3);
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00001154 unsigned Rd = Op0.getReg();
1155 unsigned Pu = Op1.getReg();
1156 unsigned Rs = Op2.getReg();
1157 unsigned Rt = Op3.getReg();
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001158 DebugLoc DL = MI.getDebugLoc();
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00001159 unsigned K1 = getKillRegState(Op1.isKill());
1160 unsigned K2 = getKillRegState(Op2.isKill());
1161 unsigned K3 = getKillRegState(Op3.isKill());
1162 if (Rd != Rs)
1163 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpt), Rd)
1164 .addReg(Pu, (Rd == Rt) ? K1 : 0)
1165 .addReg(Rs, K2);
1166 if (Rd != Rt)
1167 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpf), Rd)
1168 .addReg(Pu, K1)
1169 .addReg(Rt, K3);
1170 MBB.erase(MI);
1171 return true;
1172 }
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00001173 case Hexagon::PS_vselect: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001174 const MachineOperand &Op0 = MI.getOperand(0);
1175 const MachineOperand &Op1 = MI.getOperand(1);
1176 const MachineOperand &Op2 = MI.getOperand(2);
1177 const MachineOperand &Op3 = MI.getOperand(3);
Matthias Braunac4307c2017-05-26 21:51:00 +00001178 LivePhysRegs LiveAtMI(HRI);
Ron Lieberman88159e52016-09-02 22:56:24 +00001179 getLiveRegsAt(LiveAtMI, MI);
1180 bool IsDestLive = !LiveAtMI.available(MRI, Op0.getReg());
Krzysztof Parzyszek25173e42017-06-27 19:59:46 +00001181 unsigned PReg = Op1.getReg();
1182 assert(Op1.getSubReg() == 0);
1183 unsigned PState = getRegState(Op1);
1184
Ron Lieberman88159e52016-09-02 22:56:24 +00001185 if (Op0.getReg() != Op2.getReg()) {
Krzysztof Parzyszek25173e42017-06-27 19:59:46 +00001186 unsigned S = Op0.getReg() != Op3.getReg() ? PState & ~RegState::Kill
1187 : PState;
Ron Lieberman88159e52016-09-02 22:56:24 +00001188 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vcmov))
Diana Picus116bbab2017-01-13 09:58:52 +00001189 .add(Op0)
Krzysztof Parzyszek25173e42017-06-27 19:59:46 +00001190 .addReg(PReg, S)
Diana Picus116bbab2017-01-13 09:58:52 +00001191 .add(Op2);
Ron Lieberman88159e52016-09-02 22:56:24 +00001192 if (IsDestLive)
1193 T.addReg(Op0.getReg(), RegState::Implicit);
1194 IsDestLive = true;
1195 }
1196 if (Op0.getReg() != Op3.getReg()) {
1197 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vncmov))
Diana Picus116bbab2017-01-13 09:58:52 +00001198 .add(Op0)
Krzysztof Parzyszek25173e42017-06-27 19:59:46 +00001199 .addReg(PReg, PState)
Diana Picus116bbab2017-01-13 09:58:52 +00001200 .add(Op3);
Ron Lieberman88159e52016-09-02 22:56:24 +00001201 if (IsDestLive)
1202 T.addReg(Op0.getReg(), RegState::Implicit);
1203 }
Krzysztof Parzyszek4afed552016-05-12 19:16:02 +00001204 MBB.erase(MI);
1205 return true;
1206 }
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00001207 case Hexagon::PS_wselect: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001208 MachineOperand &Op0 = MI.getOperand(0);
1209 MachineOperand &Op1 = MI.getOperand(1);
1210 MachineOperand &Op2 = MI.getOperand(2);
1211 MachineOperand &Op3 = MI.getOperand(3);
Matthias Braunac4307c2017-05-26 21:51:00 +00001212 LivePhysRegs LiveAtMI(HRI);
Ron Lieberman88159e52016-09-02 22:56:24 +00001213 getLiveRegsAt(LiveAtMI, MI);
1214 bool IsDestLive = !LiveAtMI.available(MRI, Op0.getReg());
Krzysztof Parzyszek25173e42017-06-27 19:59:46 +00001215 unsigned PReg = Op1.getReg();
1216 assert(Op1.getSubReg() == 0);
1217 unsigned PState = getRegState(Op1);
Ron Lieberman88159e52016-09-02 22:56:24 +00001218
1219 if (Op0.getReg() != Op2.getReg()) {
Krzysztof Parzyszek25173e42017-06-27 19:59:46 +00001220 unsigned S = Op0.getReg() != Op3.getReg() ? PState & ~RegState::Kill
1221 : PState;
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001222 unsigned SrcLo = HRI.getSubReg(Op2.getReg(), Hexagon::vsub_lo);
1223 unsigned SrcHi = HRI.getSubReg(Op2.getReg(), Hexagon::vsub_hi);
Ron Lieberman88159e52016-09-02 22:56:24 +00001224 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vccombine))
Diana Picus116bbab2017-01-13 09:58:52 +00001225 .add(Op0)
Krzysztof Parzyszek25173e42017-06-27 19:59:46 +00001226 .addReg(PReg, S)
Diana Picus116bbab2017-01-13 09:58:52 +00001227 .add(Op1)
1228 .addReg(SrcHi)
1229 .addReg(SrcLo);
Ron Lieberman88159e52016-09-02 22:56:24 +00001230 if (IsDestLive)
1231 T.addReg(Op0.getReg(), RegState::Implicit);
1232 IsDestLive = true;
1233 }
1234 if (Op0.getReg() != Op3.getReg()) {
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001235 unsigned SrcLo = HRI.getSubReg(Op3.getReg(), Hexagon::vsub_lo);
1236 unsigned SrcHi = HRI.getSubReg(Op3.getReg(), Hexagon::vsub_hi);
Ron Lieberman88159e52016-09-02 22:56:24 +00001237 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vnccombine))
Diana Picus116bbab2017-01-13 09:58:52 +00001238 .add(Op0)
Krzysztof Parzyszek25173e42017-06-27 19:59:46 +00001239 .addReg(PReg, PState)
Diana Picus116bbab2017-01-13 09:58:52 +00001240 .addReg(SrcHi)
1241 .addReg(SrcLo);
Ron Lieberman88159e52016-09-02 22:56:24 +00001242 if (IsDestLive)
1243 T.addReg(Op0.getReg(), RegState::Implicit);
1244 }
Krzysztof Parzyszek4afed552016-05-12 19:16:02 +00001245 MBB.erase(MI);
1246 return true;
1247 }
Krzysztof Parzyszekbe976d42016-08-12 11:12:02 +00001248 case Hexagon::PS_tailcall_i:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001249 MI.setDesc(get(Hexagon::J2_jump));
Colin LeMahieu7b1799c2015-03-09 22:05:21 +00001250 return true;
Krzysztof Parzyszekbe976d42016-08-12 11:12:02 +00001251 case Hexagon::PS_tailcall_r:
Krzysztof Parzyszek6421b932016-08-19 14:04:45 +00001252 case Hexagon::PS_jmpret:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001253 MI.setDesc(get(Hexagon::J2_jumpr));
Colin LeMahieu7b1799c2015-03-09 22:05:21 +00001254 return true;
Krzysztof Parzyszek6421b932016-08-19 14:04:45 +00001255 case Hexagon::PS_jmprett:
1256 MI.setDesc(get(Hexagon::J2_jumprt));
1257 return true;
1258 case Hexagon::PS_jmpretf:
1259 MI.setDesc(get(Hexagon::J2_jumprf));
1260 return true;
1261 case Hexagon::PS_jmprettnewpt:
1262 MI.setDesc(get(Hexagon::J2_jumprtnewpt));
1263 return true;
1264 case Hexagon::PS_jmpretfnewpt:
1265 MI.setDesc(get(Hexagon::J2_jumprfnewpt));
1266 return true;
1267 case Hexagon::PS_jmprettnew:
1268 MI.setDesc(get(Hexagon::J2_jumprtnew));
1269 return true;
1270 case Hexagon::PS_jmpretfnew:
1271 MI.setDesc(get(Hexagon::J2_jumprfnew));
1272 return true;
Colin LeMahieu7b1799c2015-03-09 22:05:21 +00001273 }
1274
1275 return false;
1276}
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001277
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001278// We indicate that we want to reverse the branch by
1279// inserting the reversed branching opcode.
Matt Arsenault1b9fc8e2016-09-14 20:43:16 +00001280bool HexagonInstrInfo::reverseBranchCondition(
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001281 SmallVectorImpl<MachineOperand> &Cond) const {
1282 if (Cond.empty())
Jyotsna Vermaf1214a82013-03-05 18:51:42 +00001283 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001284 assert(Cond[0].isImm() && "First entry in the cond vector not imm-val");
1285 unsigned opcode = Cond[0].getImm();
1286 //unsigned temp;
1287 assert(get(opcode).isBranch() && "Should be a branching condition.");
1288 if (isEndLoopN(opcode))
Jyotsna Vermaf1214a82013-03-05 18:51:42 +00001289 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001290 unsigned NewOpcode = getInvertedPredicatedOpcode(opcode);
1291 Cond[0].setImm(NewOpcode);
Jyotsna Vermaf1214a82013-03-05 18:51:42 +00001292 return false;
1293}
1294
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001295void HexagonInstrInfo::insertNoop(MachineBasicBlock &MBB,
1296 MachineBasicBlock::iterator MI) const {
1297 DebugLoc DL;
1298 BuildMI(MBB, MI, DL, get(Hexagon::A2_nop));
1299}
1300
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00001301bool HexagonInstrInfo::isPostIncrement(const MachineInstr &MI) const {
1302 return getAddrMode(MI) == HexagonII::PostInc;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001303}
1304
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001305// Returns true if an instruction is predicated irrespective of the predicate
1306// sense. For example, all of the following will return true.
1307// if (p0) R1 = add(R2, R3)
1308// if (!p0) R1 = add(R2, R3)
1309// if (p0.new) R1 = add(R2, R3)
1310// if (!p0.new) R1 = add(R2, R3)
1311// Note: New-value stores are not included here as in the current
1312// implementation, we don't need to check their predicate sense.
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001313bool HexagonInstrInfo::isPredicated(const MachineInstr &MI) const {
1314 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001315 return (F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask;
Brendon Cahoondf43e682015-05-08 16:16:29 +00001316}
1317
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001318bool HexagonInstrInfo::PredicateInstruction(
1319 MachineInstr &MI, ArrayRef<MachineOperand> Cond) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001320 if (Cond.empty() || isNewValueJump(Cond[0].getImm()) ||
1321 isEndLoopN(Cond[0].getImm())) {
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001322 DEBUG(dbgs() << "\nCannot predicate:"; MI.dump(););
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001323 return false;
1324 }
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001325 int Opc = MI.getOpcode();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001326 assert (isPredicable(MI) && "Expected predicable instruction");
1327 bool invertJump = predOpcodeHasNot(Cond);
1328
1329 // We have to predicate MI "in place", i.e. after this function returns,
1330 // MI will need to be transformed into a predicated form. To avoid com-
1331 // plicated manipulations with the operands (handling tied operands,
1332 // etc.), build a new temporary instruction, then overwrite MI with it.
1333
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001334 MachineBasicBlock &B = *MI.getParent();
1335 DebugLoc DL = MI.getDebugLoc();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001336 unsigned PredOpc = getCondOpcode(Opc, invertJump);
1337 MachineInstrBuilder T = BuildMI(B, MI, DL, get(PredOpc));
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001338 unsigned NOp = 0, NumOps = MI.getNumOperands();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001339 while (NOp < NumOps) {
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001340 MachineOperand &Op = MI.getOperand(NOp);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001341 if (!Op.isReg() || !Op.isDef() || Op.isImplicit())
1342 break;
Diana Picus116bbab2017-01-13 09:58:52 +00001343 T.add(Op);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001344 NOp++;
1345 }
1346
1347 unsigned PredReg, PredRegPos, PredRegFlags;
1348 bool GotPredReg = getPredReg(Cond, PredReg, PredRegPos, PredRegFlags);
1349 (void)GotPredReg;
1350 assert(GotPredReg);
1351 T.addReg(PredReg, PredRegFlags);
1352 while (NOp < NumOps)
Diana Picus116bbab2017-01-13 09:58:52 +00001353 T.add(MI.getOperand(NOp++));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001354
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001355 MI.setDesc(get(PredOpc));
1356 while (unsigned n = MI.getNumOperands())
1357 MI.RemoveOperand(n-1);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001358 for (unsigned i = 0, n = T->getNumOperands(); i < n; ++i)
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001359 MI.addOperand(T->getOperand(i));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001360
Duncan P. N. Exon Smithc5b668d2016-02-22 20:49:58 +00001361 MachineBasicBlock::instr_iterator TI = T->getIterator();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001362 B.erase(TI);
1363
1364 MachineRegisterInfo &MRI = B.getParent()->getRegInfo();
1365 MRI.clearKillFlags(PredReg);
1366 return true;
Brendon Cahoondf43e682015-05-08 16:16:29 +00001367}
1368
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001369bool HexagonInstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
1370 ArrayRef<MachineOperand> Pred2) const {
1371 // TODO: Fix this
1372 return false;
1373}
1374
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00001375bool HexagonInstrInfo::DefinesPredicate(MachineInstr &MI,
1376 std::vector<MachineOperand> &Pred) const {
1377 MachineFunction &MF = *MI.getParent()->getParent();
1378 const auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
1379
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001380 for (unsigned oper = 0; oper < MI.getNumOperands(); ++oper) {
1381 MachineOperand MO = MI.getOperand(oper);
Krzysztof Parzyszek1aaf41a2017-02-17 22:14:51 +00001382 if (MO.isReg()) {
1383 if (!MO.isDef())
1384 continue;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001385 const TargetRegisterClass* RC = HRI.getMinimalPhysRegClass(MO.getReg());
1386 if (RC == &Hexagon::PredRegsRegClass) {
1387 Pred.push_back(MO);
1388 return true;
1389 }
Krzysztof Parzyszek1aaf41a2017-02-17 22:14:51 +00001390 continue;
1391 } else if (MO.isRegMask()) {
1392 for (unsigned PR : Hexagon::PredRegsRegClass) {
1393 if (!MI.modifiesRegister(PR, &HRI))
1394 continue;
1395 Pred.push_back(MO);
1396 return true;
1397 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001398 }
1399 }
1400 return false;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +00001401}
Andrew Trickd06df962012-02-01 22:13:57 +00001402
Krzysztof Parzyszekcc318712017-03-03 18:30:54 +00001403bool HexagonInstrInfo::isPredicable(const MachineInstr &MI) const {
Krzysztof Parzyszekee93e002017-05-05 22:13:57 +00001404 if (!MI.getDesc().isPredicable())
1405 return false;
1406
1407 if (MI.isCall() || isTailCall(MI)) {
1408 const MachineFunction &MF = *MI.getParent()->getParent();
1409 if (!MF.getSubtarget<HexagonSubtarget>().usePredicatedCalls())
1410 return false;
1411 }
1412 return true;
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001413}
1414
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001415bool HexagonInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
1416 const MachineBasicBlock *MBB,
1417 const MachineFunction &MF) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001418 // Debug info is never a scheduling boundary. It's necessary to be explicit
1419 // due to the special treatment of IT instructions below, otherwise a
1420 // dbg_value followed by an IT will result in the IT instruction being
1421 // considered a scheduling hazard, which is wrong. It should be the actual
1422 // instruction preceding the dbg_value instruction(s), just like it is
1423 // when debug info is not present.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001424 if (MI.isDebugValue())
Brendon Cahoondf43e682015-05-08 16:16:29 +00001425 return false;
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001426
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001427 // Throwing call is a boundary.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001428 if (MI.isCall()) {
Krzysztof Parzyszekab9127c2016-08-12 11:01:10 +00001429 // Don't mess around with no return calls.
1430 if (doesNotReturn(MI))
1431 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001432 // If any of the block's successors is a landing pad, this could be a
1433 // throwing call.
1434 for (auto I : MBB->successors())
1435 if (I->isEHPad())
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001436 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001437 }
1438
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001439 // Terminators and labels can't be scheduled around.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001440 if (MI.getDesc().isTerminator() || MI.isPosition())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001441 return true;
1442
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001443 if (MI.isInlineAsm() && !ScheduleInlineAsm)
1444 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001445
1446 return false;
1447}
1448
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001449/// Measure the specified inline asm to determine an approximation of its
1450/// length.
1451/// Comments (which run till the next SeparatorString or newline) do not
1452/// count as an instruction.
1453/// Any other non-whitespace text is considered an instruction, with
1454/// multiple instructions separated by SeparatorString or newlines.
1455/// Variable-length instructions are not handled here; this function
1456/// may be overloaded in the target code to do that.
1457/// Hexagon counts the number of ##'s and adjust for that many
1458/// constant exenders.
1459unsigned HexagonInstrInfo::getInlineAsmLength(const char *Str,
1460 const MCAsmInfo &MAI) const {
1461 StringRef AStr(Str);
1462 // Count the number of instructions in the asm.
1463 bool atInsnStart = true;
1464 unsigned Length = 0;
1465 for (; *Str; ++Str) {
1466 if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
1467 strlen(MAI.getSeparatorString())) == 0)
1468 atInsnStart = true;
1469 if (atInsnStart && !std::isspace(static_cast<unsigned char>(*Str))) {
1470 Length += MAI.getMaxInstLength();
1471 atInsnStart = false;
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001472 }
Mehdi Amini36d33fc2016-10-01 06:46:33 +00001473 if (atInsnStart && strncmp(Str, MAI.getCommentString().data(),
1474 MAI.getCommentString().size()) == 0)
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001475 atInsnStart = false;
1476 }
1477
1478 // Add to size number of constant extenders seen * 4.
1479 StringRef Occ("##");
1480 Length += AStr.count(Occ)*4;
1481 return Length;
1482}
1483
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001484ScheduleHazardRecognizer*
1485HexagonInstrInfo::CreateTargetPostRAHazardRecognizer(
1486 const InstrItineraryData *II, const ScheduleDAG *DAG) const {
Krzysztof Parzyszeke95e9552016-07-29 13:59:09 +00001487 if (UseDFAHazardRec) {
1488 auto &HST = DAG->MF.getSubtarget<HexagonSubtarget>();
1489 return new HexagonHazardRecognizer(II, this, HST);
1490 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001491 return TargetInstrInfo::CreateTargetPostRAHazardRecognizer(II, DAG);
1492}
1493
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001494/// \brief For a comparison instruction, return the source registers in
1495/// \p SrcReg and \p SrcReg2 if having two register operands, and the value it
1496/// compares against in CmpValue. Return true if the comparison instruction
1497/// can be analyzed.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001498bool HexagonInstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
1499 unsigned &SrcReg2, int &Mask,
1500 int &Value) const {
1501 unsigned Opc = MI.getOpcode();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001502
1503 // Set mask and the first source register.
1504 switch (Opc) {
1505 case Hexagon::C2_cmpeq:
1506 case Hexagon::C2_cmpeqp:
1507 case Hexagon::C2_cmpgt:
1508 case Hexagon::C2_cmpgtp:
1509 case Hexagon::C2_cmpgtu:
1510 case Hexagon::C2_cmpgtup:
1511 case Hexagon::C4_cmpneq:
1512 case Hexagon::C4_cmplte:
1513 case Hexagon::C4_cmplteu:
1514 case Hexagon::C2_cmpeqi:
1515 case Hexagon::C2_cmpgti:
1516 case Hexagon::C2_cmpgtui:
1517 case Hexagon::C4_cmpneqi:
1518 case Hexagon::C4_cmplteui:
1519 case Hexagon::C4_cmpltei:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001520 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001521 Mask = ~0;
1522 break;
1523 case Hexagon::A4_cmpbeq:
1524 case Hexagon::A4_cmpbgt:
1525 case Hexagon::A4_cmpbgtu:
1526 case Hexagon::A4_cmpbeqi:
1527 case Hexagon::A4_cmpbgti:
1528 case Hexagon::A4_cmpbgtui:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001529 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001530 Mask = 0xFF;
1531 break;
1532 case Hexagon::A4_cmpheq:
1533 case Hexagon::A4_cmphgt:
1534 case Hexagon::A4_cmphgtu:
1535 case Hexagon::A4_cmpheqi:
1536 case Hexagon::A4_cmphgti:
1537 case Hexagon::A4_cmphgtui:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001538 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001539 Mask = 0xFFFF;
1540 break;
1541 }
1542
1543 // Set the value/second source register.
1544 switch (Opc) {
1545 case Hexagon::C2_cmpeq:
1546 case Hexagon::C2_cmpeqp:
1547 case Hexagon::C2_cmpgt:
1548 case Hexagon::C2_cmpgtp:
1549 case Hexagon::C2_cmpgtu:
1550 case Hexagon::C2_cmpgtup:
1551 case Hexagon::A4_cmpbeq:
1552 case Hexagon::A4_cmpbgt:
1553 case Hexagon::A4_cmpbgtu:
1554 case Hexagon::A4_cmpheq:
1555 case Hexagon::A4_cmphgt:
1556 case Hexagon::A4_cmphgtu:
1557 case Hexagon::C4_cmpneq:
1558 case Hexagon::C4_cmplte:
1559 case Hexagon::C4_cmplteu:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001560 SrcReg2 = MI.getOperand(2).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001561 return true;
1562
1563 case Hexagon::C2_cmpeqi:
1564 case Hexagon::C2_cmpgtui:
1565 case Hexagon::C2_cmpgti:
1566 case Hexagon::C4_cmpneqi:
1567 case Hexagon::C4_cmplteui:
1568 case Hexagon::C4_cmpltei:
1569 case Hexagon::A4_cmpbeqi:
1570 case Hexagon::A4_cmpbgti:
1571 case Hexagon::A4_cmpbgtui:
1572 case Hexagon::A4_cmpheqi:
1573 case Hexagon::A4_cmphgti:
1574 case Hexagon::A4_cmphgtui:
1575 SrcReg2 = 0;
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001576 Value = MI.getOperand(2).getImm();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001577 return true;
1578 }
1579
1580 return false;
1581}
1582
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001583unsigned HexagonInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001584 const MachineInstr &MI,
1585 unsigned *PredCost) const {
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001586 return getInstrTimingClassLatency(ItinData, MI);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001587}
1588
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001589DFAPacketizer *HexagonInstrInfo::CreateTargetScheduleState(
1590 const TargetSubtargetInfo &STI) const {
1591 const InstrItineraryData *II = STI.getInstrItineraryData();
1592 return static_cast<const HexagonSubtarget&>(STI).createDFAPacketizer(II);
1593}
1594
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001595// Inspired by this pair:
1596// %R13<def> = L2_loadri_io %R29, 136; mem:LD4[FixedStack0]
1597// S2_storeri_io %R29, 132, %R1<kill>; flags: mem:ST4[FixedStack1]
1598// Currently AA considers the addresses in these instructions to be aliasing.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001599bool HexagonInstrInfo::areMemAccessesTriviallyDisjoint(
1600 MachineInstr &MIa, MachineInstr &MIb, AliasAnalysis *AA) const {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001601 if (MIa.hasUnmodeledSideEffects() || MIb.hasUnmodeledSideEffects() ||
1602 MIa.hasOrderedMemoryRef() || MIb.hasOrderedMemoryRef())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001603 return false;
1604
1605 // Instructions that are pure loads, not loads and stores like memops are not
1606 // dependent.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001607 if (MIa.mayLoad() && !isMemOp(MIa) && MIb.mayLoad() && !isMemOp(MIb))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001608 return true;
1609
Krzysztof Parzyszek3fce9d92017-07-19 18:03:46 +00001610 // Get the base register in MIa.
1611 unsigned BasePosA, OffsetPosA;
1612 if (!getBaseAndOffsetPosition(MIa, BasePosA, OffsetPosA))
1613 return false;
1614 const MachineOperand &BaseA = MIa.getOperand(BasePosA);
1615 unsigned BaseRegA = BaseA.getReg();
1616 unsigned BaseSubA = BaseA.getSubReg();
1617
1618 // Get the base register in MIb.
1619 unsigned BasePosB, OffsetPosB;
1620 if (!getBaseAndOffsetPosition(MIb, BasePosB, OffsetPosB))
1621 return false;
1622 const MachineOperand &BaseB = MIb.getOperand(BasePosB);
1623 unsigned BaseRegB = BaseB.getReg();
1624 unsigned BaseSubB = BaseB.getSubReg();
1625
1626 if (BaseRegA != BaseRegB || BaseSubA != BaseSubB)
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001627 return false;
1628
Krzysztof Parzyszek3fce9d92017-07-19 18:03:46 +00001629 // Get the access sizes.
Krzysztof Parzyszek473d02d2017-09-14 12:06:40 +00001630 unsigned SizeA = getMemAccessSize(MIa);
1631 unsigned SizeB = getMemAccessSize(MIb);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001632
Krzysztof Parzyszek3fce9d92017-07-19 18:03:46 +00001633 // Get the offsets. Handle immediates only for now.
1634 const MachineOperand &OffA = MIa.getOperand(OffsetPosA);
1635 const MachineOperand &OffB = MIb.getOperand(OffsetPosB);
1636 if (!MIa.getOperand(OffsetPosA).isImm() ||
1637 !MIb.getOperand(OffsetPosB).isImm())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001638 return false;
Krzysztof Parzyszekac019942017-07-19 19:17:32 +00001639 int OffsetA = isPostIncrement(MIa) ? 0 : OffA.getImm();
1640 int OffsetB = isPostIncrement(MIb) ? 0 : OffB.getImm();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001641
1642 // This is a mem access with the same base register and known offsets from it.
1643 // Reason about it.
1644 if (OffsetA > OffsetB) {
Krzysztof Parzyszek3fce9d92017-07-19 18:03:46 +00001645 uint64_t OffDiff = (uint64_t)((int64_t)OffsetA - (int64_t)OffsetB);
1646 return SizeB <= OffDiff;
1647 }
1648 if (OffsetA < OffsetB) {
1649 uint64_t OffDiff = (uint64_t)((int64_t)OffsetB - (int64_t)OffsetA);
1650 return SizeA <= OffDiff;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001651 }
1652
1653 return false;
1654}
1655
Brendon Cahoon254f8892016-07-29 16:44:44 +00001656/// If the instruction is an increment of a constant value, return the amount.
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00001657bool HexagonInstrInfo::getIncrementValue(const MachineInstr &MI,
Brendon Cahoon254f8892016-07-29 16:44:44 +00001658 int &Value) const {
1659 if (isPostIncrement(MI)) {
1660 unsigned AccessSize;
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00001661 return getBaseAndOffset(MI, Value, AccessSize);
Brendon Cahoon254f8892016-07-29 16:44:44 +00001662 }
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00001663 if (MI.getOpcode() == Hexagon::A2_addi) {
1664 Value = MI.getOperand(2).getImm();
Brendon Cahoon254f8892016-07-29 16:44:44 +00001665 return true;
1666 }
1667
1668 return false;
1669}
1670
Krzysztof Parzyszek0ac065f2017-07-10 18:31:02 +00001671std::pair<unsigned, unsigned>
1672HexagonInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
1673 return std::make_pair(TF & ~HexagonII::MO_Bitmasks,
1674 TF & HexagonII::MO_Bitmasks);
1675}
1676
1677ArrayRef<std::pair<unsigned, const char*>>
1678HexagonInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
1679 using namespace HexagonII;
Eugene Zelenko3b873362017-09-28 22:27:31 +00001680
Krzysztof Parzyszek0ac065f2017-07-10 18:31:02 +00001681 static const std::pair<unsigned, const char*> Flags[] = {
1682 {MO_PCREL, "hexagon-pcrel"},
1683 {MO_GOT, "hexagon-got"},
1684 {MO_LO16, "hexagon-lo16"},
1685 {MO_HI16, "hexagon-hi16"},
1686 {MO_GPREL, "hexagon-gprel"},
1687 {MO_GDGOT, "hexagon-gdgot"},
1688 {MO_GDPLT, "hexagon-gdplt"},
1689 {MO_IE, "hexagon-ie"},
1690 {MO_IEGOT, "hexagon-iegot"},
1691 {MO_TPREL, "hexagon-tprel"}
1692 };
1693 return makeArrayRef(Flags);
1694}
1695
1696ArrayRef<std::pair<unsigned, const char*>>
1697HexagonInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
1698 using namespace HexagonII;
Eugene Zelenko3b873362017-09-28 22:27:31 +00001699
Krzysztof Parzyszek0ac065f2017-07-10 18:31:02 +00001700 static const std::pair<unsigned, const char*> Flags[] = {
1701 {HMOTF_ConstExtended, "hexagon-ext"}
1702 };
1703 return makeArrayRef(Flags);
1704}
1705
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001706unsigned HexagonInstrInfo::createVR(MachineFunction *MF, MVT VT) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001707 MachineRegisterInfo &MRI = MF->getRegInfo();
1708 const TargetRegisterClass *TRC;
1709 if (VT == MVT::i1) {
1710 TRC = &Hexagon::PredRegsRegClass;
1711 } else if (VT == MVT::i32 || VT == MVT::f32) {
1712 TRC = &Hexagon::IntRegsRegClass;
1713 } else if (VT == MVT::i64 || VT == MVT::f64) {
1714 TRC = &Hexagon::DoubleRegsRegClass;
1715 } else {
1716 llvm_unreachable("Cannot handle this register class");
1717 }
1718
1719 unsigned NewReg = MRI.createVirtualRegister(TRC);
1720 return NewReg;
1721}
1722
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001723bool HexagonInstrInfo::isAbsoluteSet(const MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001724 return (getAddrMode(MI) == HexagonII::AbsoluteSet);
1725}
1726
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001727bool HexagonInstrInfo::isAccumulator(const MachineInstr &MI) const {
1728 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001729 return((F >> HexagonII::AccumulatorPos) & HexagonII::AccumulatorMask);
1730}
1731
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001732bool HexagonInstrInfo::isComplex(const MachineInstr &MI) const {
1733 const MachineFunction *MF = MI.getParent()->getParent();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001734 const TargetInstrInfo *TII = MF->getSubtarget().getInstrInfo();
1735 const HexagonInstrInfo *QII = (const HexagonInstrInfo *) TII;
1736
1737 if (!(isTC1(MI))
1738 && !(QII->isTC2Early(MI))
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001739 && !(MI.getDesc().mayLoad())
1740 && !(MI.getDesc().mayStore())
1741 && (MI.getDesc().getOpcode() != Hexagon::S2_allocframe)
1742 && (MI.getDesc().getOpcode() != Hexagon::L2_deallocframe)
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001743 && !(QII->isMemOp(MI))
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001744 && !(MI.isBranch())
1745 && !(MI.isReturn())
1746 && !MI.isCall())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001747 return true;
1748
1749 return false;
1750}
1751
Sanjay Patele4b9f502015-12-07 19:21:39 +00001752// Return true if the instruction is a compund branch instruction.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001753bool HexagonInstrInfo::isCompoundBranchInstr(const MachineInstr &MI) const {
Krzysztof Parzyszekf65b8f12017-02-02 15:03:30 +00001754 return getType(MI) == HexagonII::TypeCJ && MI.isBranch();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001755}
1756
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001757// TODO: In order to have isExtendable for fpimm/f32Ext, we need to handle
1758// isFPImm and later getFPImm as well.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001759bool HexagonInstrInfo::isConstExtended(const MachineInstr &MI) const {
1760 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001761 unsigned isExtended = (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
1762 if (isExtended) // Instruction must be extended.
Krzysztof Parzyszekc6f19332015-03-19 15:18:57 +00001763 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001764
1765 unsigned isExtendable =
1766 (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;
1767 if (!isExtendable)
1768 return false;
1769
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001770 if (MI.isCall())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001771 return false;
1772
1773 short ExtOpNum = getCExtOpNum(MI);
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001774 const MachineOperand &MO = MI.getOperand(ExtOpNum);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001775 // Use MO operand flags to determine if MO
1776 // has the HMOTF_ConstExtended flag set.
Krzysztof Parzyszekdf4a05d2017-07-10 18:38:52 +00001777 if (MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended)
Brendon Cahoondf43e682015-05-08 16:16:29 +00001778 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001779 // If this is a Machine BB address we are talking about, and it is
1780 // not marked as extended, say so.
1781 if (MO.isMBB())
1782 return false;
1783
1784 // We could be using an instruction with an extendable immediate and shoehorn
1785 // a global address into it. If it is a global address it will be constant
1786 // extended. We do this for COMBINE.
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001787 if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress() ||
Krzysztof Parzyszeka3386502016-08-10 16:46:36 +00001788 MO.isJTI() || MO.isCPI() || MO.isFPImm())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001789 return true;
1790
1791 // If the extendable operand is not 'Immediate' type, the instruction should
1792 // have 'isExtended' flag set.
1793 assert(MO.isImm() && "Extendable operand must be Immediate type");
1794
1795 int MinValue = getMinValue(MI);
1796 int MaxValue = getMaxValue(MI);
1797 int ImmValue = MO.getImm();
1798
1799 return (ImmValue < MinValue || ImmValue > MaxValue);
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001800}
1801
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001802bool HexagonInstrInfo::isDeallocRet(const MachineInstr &MI) const {
1803 switch (MI.getOpcode()) {
Eugene Zelenko3b873362017-09-28 22:27:31 +00001804 case Hexagon::L4_return:
1805 case Hexagon::L4_return_t:
1806 case Hexagon::L4_return_f:
1807 case Hexagon::L4_return_tnew_pnt:
1808 case Hexagon::L4_return_fnew_pnt:
1809 case Hexagon::L4_return_tnew_pt:
1810 case Hexagon::L4_return_fnew_pt:
Krzysztof Parzyszek700a5f92017-05-03 15:34:52 +00001811 return true;
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001812 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001813 return false;
1814}
1815
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001816// Return true when ConsMI uses a register defined by ProdMI.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001817bool HexagonInstrInfo::isDependent(const MachineInstr &ProdMI,
1818 const MachineInstr &ConsMI) const {
1819 if (!ProdMI.getDesc().getNumDefs())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001820 return false;
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00001821 const MachineFunction &MF = *ProdMI.getParent()->getParent();
1822 const auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001823
1824 SmallVector<unsigned, 4> DefsA;
1825 SmallVector<unsigned, 4> DefsB;
1826 SmallVector<unsigned, 8> UsesA;
1827 SmallVector<unsigned, 8> UsesB;
1828
1829 parseOperands(ProdMI, DefsA, UsesA);
1830 parseOperands(ConsMI, DefsB, UsesB);
1831
1832 for (auto &RegA : DefsA)
1833 for (auto &RegB : UsesB) {
1834 // True data dependency.
1835 if (RegA == RegB)
1836 return true;
1837
Krzysztof Parzyszek9aaf9232017-05-02 18:12:19 +00001838 if (TargetRegisterInfo::isPhysicalRegister(RegA))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001839 for (MCSubRegIterator SubRegs(RegA, &HRI); SubRegs.isValid(); ++SubRegs)
1840 if (RegB == *SubRegs)
1841 return true;
1842
Krzysztof Parzyszek9aaf9232017-05-02 18:12:19 +00001843 if (TargetRegisterInfo::isPhysicalRegister(RegB))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001844 for (MCSubRegIterator SubRegs(RegB, &HRI); SubRegs.isValid(); ++SubRegs)
1845 if (RegA == *SubRegs)
1846 return true;
1847 }
1848
1849 return false;
1850}
1851
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001852// Returns true if the instruction is alread a .cur.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001853bool HexagonInstrInfo::isDotCurInst(const MachineInstr &MI) const {
1854 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001855 case Hexagon::V6_vL32b_cur_pi:
1856 case Hexagon::V6_vL32b_cur_ai:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001857 return true;
1858 }
1859 return false;
1860}
1861
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001862// Returns true, if any one of the operands is a dot new
1863// insn, whether it is predicated dot new or register dot new.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001864bool HexagonInstrInfo::isDotNewInst(const MachineInstr &MI) const {
1865 if (isNewValueInst(MI) || (isPredicated(MI) && isPredicatedNew(MI)))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001866 return true;
1867
1868 return false;
1869}
1870
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001871/// Symmetrical. See if these two instructions are fit for duplex pair.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001872bool HexagonInstrInfo::isDuplexPair(const MachineInstr &MIa,
1873 const MachineInstr &MIb) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001874 HexagonII::SubInstructionGroup MIaG = getDuplexCandidateGroup(MIa);
1875 HexagonII::SubInstructionGroup MIbG = getDuplexCandidateGroup(MIb);
1876 return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));
1877}
1878
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001879bool HexagonInstrInfo::isEarlySourceInstr(const MachineInstr &MI) const {
1880 if (MI.mayLoad() || MI.mayStore() || MI.isCompare())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001881 return true;
1882
1883 // Multiply
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001884 unsigned SchedClass = MI.getDesc().getSchedClass();
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00001885 return is_TC4x(SchedClass) || is_TC3x(SchedClass);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001886}
1887
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001888bool HexagonInstrInfo::isEndLoopN(unsigned Opcode) const {
1889 return (Opcode == Hexagon::ENDLOOP0 ||
1890 Opcode == Hexagon::ENDLOOP1);
1891}
1892
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001893bool HexagonInstrInfo::isExpr(unsigned OpType) const {
1894 switch(OpType) {
1895 case MachineOperand::MO_MachineBasicBlock:
1896 case MachineOperand::MO_GlobalAddress:
1897 case MachineOperand::MO_ExternalSymbol:
1898 case MachineOperand::MO_JumpTableIndex:
1899 case MachineOperand::MO_ConstantPoolIndex:
1900 case MachineOperand::MO_BlockAddress:
1901 return true;
1902 default:
1903 return false;
1904 }
1905}
1906
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001907bool HexagonInstrInfo::isExtendable(const MachineInstr &MI) const {
1908 const MCInstrDesc &MID = MI.getDesc();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001909 const uint64_t F = MID.TSFlags;
1910 if ((F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask)
1911 return true;
1912
1913 // TODO: This is largely obsolete now. Will need to be removed
1914 // in consecutive patches.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001915 switch (MI.getOpcode()) {
Krzysztof Parzyszek1d01a792016-08-16 18:08:40 +00001916 // PS_fi and PS_fia remain special cases.
1917 case Hexagon::PS_fi:
1918 case Hexagon::PS_fia:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001919 return true;
1920 default:
1921 return false;
1922 }
1923 return false;
1924}
1925
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001926// This returns true in two cases:
1927// - The OP code itself indicates that this is an extended instruction.
1928// - One of MOs has been marked with HMOTF_ConstExtended flag.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001929bool HexagonInstrInfo::isExtended(const MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001930 // First check if this is permanently extended op code.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001931 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001932 if ((F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask)
1933 return true;
1934 // Use MO operand flags to determine if one of MI's operands
1935 // has HMOTF_ConstExtended flag set.
Krzysztof Parzyszekdf4a05d2017-07-10 18:38:52 +00001936 for (const MachineOperand &MO : MI.operands())
1937 if (MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended)
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001938 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001939 return false;
1940}
1941
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001942bool HexagonInstrInfo::isFloat(const MachineInstr &MI) const {
1943 unsigned Opcode = MI.getOpcode();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001944 const uint64_t F = get(Opcode).TSFlags;
1945 return (F >> HexagonII::FPPos) & HexagonII::FPMask;
1946}
1947
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00001948// No V60 HVX VMEM with A_INDIRECT.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001949bool HexagonInstrInfo::isHVXMemWithAIndirect(const MachineInstr &I,
1950 const MachineInstr &J) const {
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00001951 if (!isHVXVec(I))
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00001952 return false;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001953 if (!I.mayLoad() && !I.mayStore())
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00001954 return false;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001955 return J.isIndirectBranch() || isIndirectCall(J) || isIndirectL4Return(J);
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00001956}
1957
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001958bool HexagonInstrInfo::isIndirectCall(const MachineInstr &MI) const {
1959 switch (MI.getOpcode()) {
Eugene Zelenko3b873362017-09-28 22:27:31 +00001960 case Hexagon::J2_callr:
1961 case Hexagon::J2_callrf:
1962 case Hexagon::J2_callrt:
1963 case Hexagon::PS_call_nr:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001964 return true;
1965 }
1966 return false;
1967}
1968
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001969bool HexagonInstrInfo::isIndirectL4Return(const MachineInstr &MI) const {
1970 switch (MI.getOpcode()) {
Eugene Zelenko3b873362017-09-28 22:27:31 +00001971 case Hexagon::L4_return:
1972 case Hexagon::L4_return_t:
1973 case Hexagon::L4_return_f:
1974 case Hexagon::L4_return_fnew_pnt:
1975 case Hexagon::L4_return_fnew_pt:
1976 case Hexagon::L4_return_tnew_pnt:
1977 case Hexagon::L4_return_tnew_pt:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001978 return true;
1979 }
1980 return false;
1981}
1982
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001983bool HexagonInstrInfo::isJumpR(const MachineInstr &MI) const {
1984 switch (MI.getOpcode()) {
Eugene Zelenko3b873362017-09-28 22:27:31 +00001985 case Hexagon::J2_jumpr:
1986 case Hexagon::J2_jumprt:
1987 case Hexagon::J2_jumprf:
1988 case Hexagon::J2_jumprtnewpt:
1989 case Hexagon::J2_jumprfnewpt:
1990 case Hexagon::J2_jumprtnew:
1991 case Hexagon::J2_jumprfnew:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001992 return true;
1993 }
1994 return false;
1995}
1996
Simon Pilgrim6ba672e2016-11-17 19:21:20 +00001997// Return true if a given MI can accommodate given offset.
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001998// Use abs estimate as oppose to the exact number.
1999// TODO: This will need to be changed to use MC level
2000// definition of instruction extendable field size.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002001bool HexagonInstrInfo::isJumpWithinBranchRange(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002002 unsigned offset) const {
2003 // This selection of jump instructions matches to that what
Krzysztof Parzyszek700a5f92017-05-03 15:34:52 +00002004 // analyzeBranch can parse, plus NVJ.
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002005 if (isNewValueJump(MI)) // r9:2
2006 return isInt<11>(offset);
2007
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002008 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002009 // Still missing Jump to address condition on register value.
2010 default:
2011 return false;
2012 case Hexagon::J2_jump: // bits<24> dst; // r22:2
2013 case Hexagon::J2_call:
Krzysztof Parzyszekbe976d42016-08-12 11:12:02 +00002014 case Hexagon::PS_call_nr:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002015 return isInt<24>(offset);
2016 case Hexagon::J2_jumpt: //bits<17> dst; // r15:2
2017 case Hexagon::J2_jumpf:
2018 case Hexagon::J2_jumptnew:
2019 case Hexagon::J2_jumptnewpt:
2020 case Hexagon::J2_jumpfnew:
2021 case Hexagon::J2_jumpfnewpt:
2022 case Hexagon::J2_callt:
2023 case Hexagon::J2_callf:
2024 return isInt<17>(offset);
2025 case Hexagon::J2_loop0i:
2026 case Hexagon::J2_loop0iext:
2027 case Hexagon::J2_loop0r:
2028 case Hexagon::J2_loop0rext:
2029 case Hexagon::J2_loop1i:
2030 case Hexagon::J2_loop1iext:
2031 case Hexagon::J2_loop1r:
2032 case Hexagon::J2_loop1rext:
2033 return isInt<9>(offset);
2034 // TODO: Add all the compound branches here. Can we do this in Relation model?
2035 case Hexagon::J4_cmpeqi_tp0_jump_nt:
2036 case Hexagon::J4_cmpeqi_tp1_jump_nt:
2037 return isInt<11>(offset);
2038 }
2039}
2040
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002041bool HexagonInstrInfo::isLateInstrFeedsEarlyInstr(const MachineInstr &LRMI,
2042 const MachineInstr &ESMI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002043 bool isLate = isLateResultInstr(LRMI);
2044 bool isEarly = isEarlySourceInstr(ESMI);
2045
2046 DEBUG(dbgs() << "V60" << (isLate ? "-LR " : " -- "));
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002047 DEBUG(LRMI.dump());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002048 DEBUG(dbgs() << "V60" << (isEarly ? "-ES " : " -- "));
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002049 DEBUG(ESMI.dump());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002050
2051 if (isLate && isEarly) {
2052 DEBUG(dbgs() << "++Is Late Result feeding Early Source\n");
2053 return true;
2054 }
2055
2056 return false;
2057}
2058
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002059bool HexagonInstrInfo::isLateResultInstr(const MachineInstr &MI) const {
2060 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002061 case TargetOpcode::EXTRACT_SUBREG:
2062 case TargetOpcode::INSERT_SUBREG:
2063 case TargetOpcode::SUBREG_TO_REG:
2064 case TargetOpcode::REG_SEQUENCE:
2065 case TargetOpcode::IMPLICIT_DEF:
2066 case TargetOpcode::COPY:
2067 case TargetOpcode::INLINEASM:
2068 case TargetOpcode::PHI:
2069 return false;
2070 default:
2071 break;
2072 }
2073
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002074 unsigned SchedClass = MI.getDesc().getSchedClass();
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002075 return !is_TC1(SchedClass);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002076}
2077
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002078bool HexagonInstrInfo::isLateSourceInstr(const MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002079 // Instructions with iclass A_CVI_VX and attribute A_CVI_LATE uses a multiply
2080 // resource, but all operands can be received late like an ALU instruction.
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002081 return getType(MI) == HexagonII::TypeCVI_VX_LATE;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002082}
2083
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002084bool HexagonInstrInfo::isLoopN(const MachineInstr &MI) const {
2085 unsigned Opcode = MI.getOpcode();
Krzysztof Parzyszek5e6f2bd2015-12-14 21:32:25 +00002086 return Opcode == Hexagon::J2_loop0i ||
2087 Opcode == Hexagon::J2_loop0r ||
2088 Opcode == Hexagon::J2_loop0iext ||
2089 Opcode == Hexagon::J2_loop0rext ||
2090 Opcode == Hexagon::J2_loop1i ||
2091 Opcode == Hexagon::J2_loop1r ||
2092 Opcode == Hexagon::J2_loop1iext ||
2093 Opcode == Hexagon::J2_loop1rext;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002094}
2095
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002096bool HexagonInstrInfo::isMemOp(const MachineInstr &MI) const {
2097 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002098 default: return false;
Eugene Zelenko3b873362017-09-28 22:27:31 +00002099 case Hexagon::L4_iadd_memopw_io:
2100 case Hexagon::L4_isub_memopw_io:
2101 case Hexagon::L4_add_memopw_io:
2102 case Hexagon::L4_sub_memopw_io:
2103 case Hexagon::L4_and_memopw_io:
2104 case Hexagon::L4_or_memopw_io:
2105 case Hexagon::L4_iadd_memoph_io:
2106 case Hexagon::L4_isub_memoph_io:
2107 case Hexagon::L4_add_memoph_io:
2108 case Hexagon::L4_sub_memoph_io:
2109 case Hexagon::L4_and_memoph_io:
2110 case Hexagon::L4_or_memoph_io:
2111 case Hexagon::L4_iadd_memopb_io:
2112 case Hexagon::L4_isub_memopb_io:
2113 case Hexagon::L4_add_memopb_io:
2114 case Hexagon::L4_sub_memopb_io:
2115 case Hexagon::L4_and_memopb_io:
2116 case Hexagon::L4_or_memopb_io:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002117 case Hexagon::L4_ior_memopb_io:
2118 case Hexagon::L4_ior_memoph_io:
2119 case Hexagon::L4_ior_memopw_io:
2120 case Hexagon::L4_iand_memopb_io:
2121 case Hexagon::L4_iand_memoph_io:
2122 case Hexagon::L4_iand_memopw_io:
2123 return true;
2124 }
2125 return false;
2126}
2127
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002128bool HexagonInstrInfo::isNewValue(const MachineInstr &MI) const {
2129 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002130 return (F >> HexagonII::NewValuePos) & HexagonII::NewValueMask;
2131}
2132
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002133bool HexagonInstrInfo::isNewValue(unsigned Opcode) const {
2134 const uint64_t F = get(Opcode).TSFlags;
2135 return (F >> HexagonII::NewValuePos) & HexagonII::NewValueMask;
2136}
2137
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002138bool HexagonInstrInfo::isNewValueInst(const MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002139 return isNewValueJump(MI) || isNewValueStore(MI);
2140}
2141
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002142bool HexagonInstrInfo::isNewValueJump(const MachineInstr &MI) const {
2143 return isNewValue(MI) && MI.isBranch();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002144}
2145
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002146bool HexagonInstrInfo::isNewValueJump(unsigned Opcode) const {
2147 return isNewValue(Opcode) && get(Opcode).isBranch() && isPredicated(Opcode);
2148}
2149
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002150bool HexagonInstrInfo::isNewValueStore(const MachineInstr &MI) const {
2151 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002152 return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask;
2153}
2154
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002155bool HexagonInstrInfo::isNewValueStore(unsigned Opcode) const {
2156 const uint64_t F = get(Opcode).TSFlags;
2157 return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask;
2158}
2159
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002160// Returns true if a particular operand is extendable for an instruction.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002161bool HexagonInstrInfo::isOperandExtended(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002162 unsigned OperandNum) const {
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002163 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002164 return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask)
2165 == OperandNum;
2166}
2167
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00002168bool HexagonInstrInfo::isPredicatedNew(const MachineInstr &MI) const {
2169 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002170 assert(isPredicated(MI));
2171 return (F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask;
2172}
2173
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002174bool HexagonInstrInfo::isPredicatedNew(unsigned Opcode) const {
2175 const uint64_t F = get(Opcode).TSFlags;
2176 assert(isPredicated(Opcode));
2177 return (F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask;
2178}
2179
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00002180bool HexagonInstrInfo::isPredicatedTrue(const MachineInstr &MI) const {
2181 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002182 return !((F >> HexagonII::PredicatedFalsePos) &
2183 HexagonII::PredicatedFalseMask);
2184}
2185
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002186bool HexagonInstrInfo::isPredicatedTrue(unsigned Opcode) const {
2187 const uint64_t F = get(Opcode).TSFlags;
2188 // Make sure that the instruction is predicated.
2189 assert((F>> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);
2190 return !((F >> HexagonII::PredicatedFalsePos) &
2191 HexagonII::PredicatedFalseMask);
2192}
2193
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002194bool HexagonInstrInfo::isPredicated(unsigned Opcode) const {
2195 const uint64_t F = get(Opcode).TSFlags;
2196 return (F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask;
2197}
2198
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002199bool HexagonInstrInfo::isPredicateLate(unsigned Opcode) const {
2200 const uint64_t F = get(Opcode).TSFlags;
2201 return ~(F >> HexagonII::PredicateLatePos) & HexagonII::PredicateLateMask;
2202}
2203
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002204bool HexagonInstrInfo::isPredictedTaken(unsigned Opcode) const {
2205 const uint64_t F = get(Opcode).TSFlags;
2206 assert(get(Opcode).isBranch() &&
2207 (isPredicatedNew(Opcode) || isNewValue(Opcode)));
2208 return (F >> HexagonII::TakenPos) & HexagonII::TakenMask;
2209}
2210
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002211bool HexagonInstrInfo::isSaveCalleeSavedRegsCall(const MachineInstr &MI) const {
2212 return MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4 ||
2213 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT ||
2214 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_PIC ||
2215 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002216}
2217
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00002218bool HexagonInstrInfo::isSignExtendingLoad(const MachineInstr &MI) const {
2219 switch (MI.getOpcode()) {
2220 // Byte
2221 case Hexagon::L2_loadrb_io:
2222 case Hexagon::L4_loadrb_ur:
2223 case Hexagon::L4_loadrb_ap:
2224 case Hexagon::L2_loadrb_pr:
2225 case Hexagon::L2_loadrb_pbr:
2226 case Hexagon::L2_loadrb_pi:
2227 case Hexagon::L2_loadrb_pci:
2228 case Hexagon::L2_loadrb_pcr:
2229 case Hexagon::L2_loadbsw2_io:
2230 case Hexagon::L4_loadbsw2_ur:
2231 case Hexagon::L4_loadbsw2_ap:
2232 case Hexagon::L2_loadbsw2_pr:
2233 case Hexagon::L2_loadbsw2_pbr:
2234 case Hexagon::L2_loadbsw2_pi:
2235 case Hexagon::L2_loadbsw2_pci:
2236 case Hexagon::L2_loadbsw2_pcr:
2237 case Hexagon::L2_loadbsw4_io:
2238 case Hexagon::L4_loadbsw4_ur:
2239 case Hexagon::L4_loadbsw4_ap:
2240 case Hexagon::L2_loadbsw4_pr:
2241 case Hexagon::L2_loadbsw4_pbr:
2242 case Hexagon::L2_loadbsw4_pi:
2243 case Hexagon::L2_loadbsw4_pci:
2244 case Hexagon::L2_loadbsw4_pcr:
2245 case Hexagon::L4_loadrb_rr:
2246 case Hexagon::L2_ploadrbt_io:
2247 case Hexagon::L2_ploadrbt_pi:
2248 case Hexagon::L2_ploadrbf_io:
2249 case Hexagon::L2_ploadrbf_pi:
2250 case Hexagon::L2_ploadrbtnew_io:
2251 case Hexagon::L2_ploadrbfnew_io:
2252 case Hexagon::L4_ploadrbt_rr:
2253 case Hexagon::L4_ploadrbf_rr:
2254 case Hexagon::L4_ploadrbtnew_rr:
2255 case Hexagon::L4_ploadrbfnew_rr:
2256 case Hexagon::L2_ploadrbtnew_pi:
2257 case Hexagon::L2_ploadrbfnew_pi:
2258 case Hexagon::L4_ploadrbt_abs:
2259 case Hexagon::L4_ploadrbf_abs:
2260 case Hexagon::L4_ploadrbtnew_abs:
2261 case Hexagon::L4_ploadrbfnew_abs:
2262 case Hexagon::L2_loadrbgp:
2263 // Half
2264 case Hexagon::L2_loadrh_io:
2265 case Hexagon::L4_loadrh_ur:
2266 case Hexagon::L4_loadrh_ap:
2267 case Hexagon::L2_loadrh_pr:
2268 case Hexagon::L2_loadrh_pbr:
2269 case Hexagon::L2_loadrh_pi:
2270 case Hexagon::L2_loadrh_pci:
2271 case Hexagon::L2_loadrh_pcr:
2272 case Hexagon::L4_loadrh_rr:
2273 case Hexagon::L2_ploadrht_io:
2274 case Hexagon::L2_ploadrht_pi:
2275 case Hexagon::L2_ploadrhf_io:
2276 case Hexagon::L2_ploadrhf_pi:
2277 case Hexagon::L2_ploadrhtnew_io:
2278 case Hexagon::L2_ploadrhfnew_io:
2279 case Hexagon::L4_ploadrht_rr:
2280 case Hexagon::L4_ploadrhf_rr:
2281 case Hexagon::L4_ploadrhtnew_rr:
2282 case Hexagon::L4_ploadrhfnew_rr:
2283 case Hexagon::L2_ploadrhtnew_pi:
2284 case Hexagon::L2_ploadrhfnew_pi:
2285 case Hexagon::L4_ploadrht_abs:
2286 case Hexagon::L4_ploadrhf_abs:
2287 case Hexagon::L4_ploadrhtnew_abs:
2288 case Hexagon::L4_ploadrhfnew_abs:
2289 case Hexagon::L2_loadrhgp:
2290 return true;
2291 default:
2292 return false;
Krzysztof Parzyszekfd02aad2016-02-12 18:37:23 +00002293 }
2294}
2295
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002296bool HexagonInstrInfo::isSolo(const MachineInstr &MI) const {
2297 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002298 return (F >> HexagonII::SoloPos) & HexagonII::SoloMask;
2299}
2300
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002301bool HexagonInstrInfo::isSpillPredRegOp(const MachineInstr &MI) const {
2302 switch (MI.getOpcode()) {
Eugene Zelenko3b873362017-09-28 22:27:31 +00002303 case Hexagon::STriw_pred:
2304 case Hexagon::LDriw_pred:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002305 return true;
2306 default:
2307 return false;
2308 }
2309}
2310
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002311bool HexagonInstrInfo::isTailCall(const MachineInstr &MI) const {
2312 if (!MI.isBranch())
Krzysztof Parzyszekecea07c2016-07-14 19:30:55 +00002313 return false;
2314
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002315 for (auto &Op : MI.operands())
Krzysztof Parzyszekecea07c2016-07-14 19:30:55 +00002316 if (Op.isGlobal() || Op.isSymbol())
2317 return true;
2318 return false;
2319}
2320
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002321// Returns true when SU has a timing class TC1.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002322bool HexagonInstrInfo::isTC1(const MachineInstr &MI) const {
2323 unsigned SchedClass = MI.getDesc().getSchedClass();
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002324 return is_TC1(SchedClass);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002325}
2326
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002327bool HexagonInstrInfo::isTC2(const MachineInstr &MI) const {
2328 unsigned SchedClass = MI.getDesc().getSchedClass();
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002329 return is_TC2(SchedClass);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002330}
2331
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002332bool HexagonInstrInfo::isTC2Early(const MachineInstr &MI) const {
2333 unsigned SchedClass = MI.getDesc().getSchedClass();
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002334 return is_TC2early(SchedClass);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002335}
2336
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002337bool HexagonInstrInfo::isTC4x(const MachineInstr &MI) const {
2338 unsigned SchedClass = MI.getDesc().getSchedClass();
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002339 return is_TC4x(SchedClass);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002340}
2341
Krzysztof Parzyszek408e3002016-07-15 21:34:02 +00002342// Schedule this ASAP.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002343bool HexagonInstrInfo::isToBeScheduledASAP(const MachineInstr &MI1,
2344 const MachineInstr &MI2) const {
Krzysztof Parzyszek408e3002016-07-15 21:34:02 +00002345 if (mayBeCurLoad(MI1)) {
2346 // if (result of SU is used in Next) return true;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002347 unsigned DstReg = MI1.getOperand(0).getReg();
2348 int N = MI2.getNumOperands();
Krzysztof Parzyszek408e3002016-07-15 21:34:02 +00002349 for (int I = 0; I < N; I++)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002350 if (MI2.getOperand(I).isReg() && DstReg == MI2.getOperand(I).getReg())
Krzysztof Parzyszek408e3002016-07-15 21:34:02 +00002351 return true;
2352 }
2353 if (mayBeNewStore(MI2))
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002354 if (MI2.getOpcode() == Hexagon::V6_vS32b_pi)
2355 if (MI1.getOperand(0).isReg() && MI2.getOperand(3).isReg() &&
2356 MI1.getOperand(0).getReg() == MI2.getOperand(3).getReg())
Krzysztof Parzyszek408e3002016-07-15 21:34:02 +00002357 return true;
2358 return false;
2359}
2360
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002361bool HexagonInstrInfo::isHVXVec(const MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002362 const uint64_t V = getType(MI);
2363 return HexagonII::TypeCVI_FIRST <= V && V <= HexagonII::TypeCVI_LAST;
2364}
2365
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002366// Check if the Offset is a valid auto-inc imm by Load/Store Type.
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00002367bool HexagonInstrInfo::isValidAutoIncImm(const EVT VT, int Offset) const {
2368 int Size = VT.getSizeInBits() / 8;
2369 if (Offset % Size != 0)
2370 return false;
2371 int Count = Offset / Size;
2372
2373 switch (VT.getSimpleVT().SimpleTy) {
2374 // For scalars the auto-inc is s4
2375 case MVT::i8:
2376 case MVT::i16:
2377 case MVT::i32:
2378 case MVT::i64:
2379 return isInt<4>(Count);
2380 // For HVX vectors the auto-inc is s3
2381 case MVT::v64i8:
2382 case MVT::v32i16:
2383 case MVT::v16i32:
2384 case MVT::v8i64:
2385 case MVT::v128i8:
2386 case MVT::v64i16:
2387 case MVT::v32i32:
2388 case MVT::v16i64:
2389 return isInt<3>(Count);
2390 default:
2391 break;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002392 }
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00002393
2394 llvm_unreachable("Not an valid type!");
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002395}
2396
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002397bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset,
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00002398 const TargetRegisterInfo *TRI, bool Extend) const {
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002399 // This function is to check whether the "Offset" is in the correct range of
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002400 // the given "Opcode". If "Offset" is not in the correct range, "A2_addi" is
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002401 // inserted to calculate the final address. Due to this reason, the function
2402 // assumes that the "Offset" has correct alignment.
Jyotsna Vermaec613662013-03-14 19:08:03 +00002403 // We used to assert if the offset was not properly aligned, however,
2404 // there are cases where a misaligned pointer recast can cause this
2405 // problem, and we need to allow for it. The front end warns of such
2406 // misaligns with respect to load size.
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002407 switch (Opcode) {
Krzysztof Parzyszek17aa4132016-08-16 15:43:54 +00002408 case Hexagon::PS_vstorerq_ai:
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +00002409 case Hexagon::PS_vstorerw_ai:
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002410 case Hexagon::PS_vstorerw_nt_ai:
Krzysztof Parzyszek17aa4132016-08-16 15:43:54 +00002411 case Hexagon::PS_vloadrq_ai:
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +00002412 case Hexagon::PS_vloadrw_ai:
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002413 case Hexagon::PS_vloadrw_nt_ai:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002414 case Hexagon::V6_vL32b_ai:
2415 case Hexagon::V6_vS32b_ai:
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002416 case Hexagon::V6_vL32b_nt_ai:
2417 case Hexagon::V6_vS32b_nt_ai:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002418 case Hexagon::V6_vL32Ub_ai:
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00002419 case Hexagon::V6_vS32Ub_ai: {
2420 unsigned VectorSize = TRI->getSpillSize(Hexagon::HvxVRRegClass);
2421 assert(isPowerOf2_32(VectorSize));
2422 if (Offset & (VectorSize-1))
2423 return false;
2424 return isInt<4>(Offset >> Log2_32(VectorSize));
2425 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002426
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002427 case Hexagon::J2_loop0i:
2428 case Hexagon::J2_loop1i:
2429 return isUInt<10>(Offset);
Krzysztof Parzyszekbba0bf72016-07-15 15:35:52 +00002430
2431 case Hexagon::S4_storeirb_io:
2432 case Hexagon::S4_storeirbt_io:
2433 case Hexagon::S4_storeirbf_io:
2434 return isUInt<6>(Offset);
2435
2436 case Hexagon::S4_storeirh_io:
2437 case Hexagon::S4_storeirht_io:
2438 case Hexagon::S4_storeirhf_io:
2439 return isShiftedUInt<6,1>(Offset);
2440
2441 case Hexagon::S4_storeiri_io:
2442 case Hexagon::S4_storeirit_io:
2443 case Hexagon::S4_storeirif_io:
2444 return isShiftedUInt<6,2>(Offset);
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002445 }
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002446
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002447 if (Extend)
2448 return true;
2449
2450 switch (Opcode) {
Colin LeMahieu026e88d2014-12-23 20:02:16 +00002451 case Hexagon::L2_loadri_io:
Colin LeMahieubda31b42014-12-29 20:44:51 +00002452 case Hexagon::S2_storeri_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002453 return (Offset >= Hexagon_MEMW_OFFSET_MIN) &&
2454 (Offset <= Hexagon_MEMW_OFFSET_MAX);
2455
Colin LeMahieu947cd702014-12-23 20:44:59 +00002456 case Hexagon::L2_loadrd_io:
Colin LeMahieubda31b42014-12-29 20:44:51 +00002457 case Hexagon::S2_storerd_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002458 return (Offset >= Hexagon_MEMD_OFFSET_MIN) &&
2459 (Offset <= Hexagon_MEMD_OFFSET_MAX);
2460
Colin LeMahieu8e39cad2014-12-23 17:25:57 +00002461 case Hexagon::L2_loadrh_io:
Colin LeMahieua9386d22014-12-23 16:42:57 +00002462 case Hexagon::L2_loadruh_io:
Colin LeMahieubda31b42014-12-29 20:44:51 +00002463 case Hexagon::S2_storerh_io:
Krzysztof Parzyszekd10df492017-05-03 15:36:51 +00002464 case Hexagon::S2_storerf_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002465 return (Offset >= Hexagon_MEMH_OFFSET_MIN) &&
2466 (Offset <= Hexagon_MEMH_OFFSET_MAX);
2467
Colin LeMahieu4b1eac42014-12-22 21:40:43 +00002468 case Hexagon::L2_loadrb_io:
Colin LeMahieuaf1e5de2014-12-22 21:20:03 +00002469 case Hexagon::L2_loadrub_io:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002470 case Hexagon::S2_storerb_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002471 return (Offset >= Hexagon_MEMB_OFFSET_MIN) &&
2472 (Offset <= Hexagon_MEMB_OFFSET_MAX);
2473
Colin LeMahieuf297dbe2015-02-05 17:49:13 +00002474 case Hexagon::A2_addi:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002475 return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&
2476 (Offset <= Hexagon_ADDI_OFFSET_MAX);
2477
Eugene Zelenko3b873362017-09-28 22:27:31 +00002478 case Hexagon::L4_iadd_memopw_io:
2479 case Hexagon::L4_isub_memopw_io:
2480 case Hexagon::L4_add_memopw_io:
2481 case Hexagon::L4_sub_memopw_io:
2482 case Hexagon::L4_and_memopw_io:
2483 case Hexagon::L4_or_memopw_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002484 return (0 <= Offset && Offset <= 255);
2485
Eugene Zelenko3b873362017-09-28 22:27:31 +00002486 case Hexagon::L4_iadd_memoph_io:
2487 case Hexagon::L4_isub_memoph_io:
2488 case Hexagon::L4_add_memoph_io:
2489 case Hexagon::L4_sub_memoph_io:
2490 case Hexagon::L4_and_memoph_io:
2491 case Hexagon::L4_or_memoph_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002492 return (0 <= Offset && Offset <= 127);
2493
Eugene Zelenko3b873362017-09-28 22:27:31 +00002494 case Hexagon::L4_iadd_memopb_io:
2495 case Hexagon::L4_isub_memopb_io:
2496 case Hexagon::L4_add_memopb_io:
2497 case Hexagon::L4_sub_memopb_io:
2498 case Hexagon::L4_and_memopb_io:
2499 case Hexagon::L4_or_memopb_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002500 return (0 <= Offset && Offset <= 63);
2501
Krzysztof Parzyszekfd02aad2016-02-12 18:37:23 +00002502 // LDriw_xxx and STriw_xxx are pseudo operations, so it has to take offset of
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002503 // any size. Later pass knows how to handle it.
2504 case Hexagon::STriw_pred:
2505 case Hexagon::LDriw_pred:
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +00002506 case Hexagon::STriw_mod:
2507 case Hexagon::LDriw_mod:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002508 return true;
2509
Krzysztof Parzyszek1d01a792016-08-16 18:08:40 +00002510 case Hexagon::PS_fi:
2511 case Hexagon::PS_fia:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002512 case Hexagon::INLINEASM:
2513 return true;
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00002514
2515 case Hexagon::L2_ploadrbt_io:
2516 case Hexagon::L2_ploadrbf_io:
2517 case Hexagon::L2_ploadrubt_io:
2518 case Hexagon::L2_ploadrubf_io:
2519 case Hexagon::S2_pstorerbt_io:
2520 case Hexagon::S2_pstorerbf_io:
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00002521 return isUInt<6>(Offset);
2522
2523 case Hexagon::L2_ploadrht_io:
2524 case Hexagon::L2_ploadrhf_io:
2525 case Hexagon::L2_ploadruht_io:
2526 case Hexagon::L2_ploadruhf_io:
2527 case Hexagon::S2_pstorerht_io:
2528 case Hexagon::S2_pstorerhf_io:
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00002529 return isShiftedUInt<6,1>(Offset);
2530
2531 case Hexagon::L2_ploadrit_io:
2532 case Hexagon::L2_ploadrif_io:
2533 case Hexagon::S2_pstorerit_io:
2534 case Hexagon::S2_pstorerif_io:
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00002535 return isShiftedUInt<6,2>(Offset);
2536
2537 case Hexagon::L2_ploadrdt_io:
2538 case Hexagon::L2_ploadrdf_io:
2539 case Hexagon::S2_pstorerdt_io:
2540 case Hexagon::S2_pstorerdf_io:
2541 return isShiftedUInt<6,3>(Offset);
2542 } // switch
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002543
Benjamin Kramerb6684012011-12-27 11:41:05 +00002544 llvm_unreachable("No offset range is defined for this opcode. "
2545 "Please define it in the above switch statement!");
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002546}
2547
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002548bool HexagonInstrInfo::isVecAcc(const MachineInstr &MI) const {
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002549 return isHVXVec(MI) && isAccumulator(MI);
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002550}
2551
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002552bool HexagonInstrInfo::isVecALU(const MachineInstr &MI) const {
2553 const uint64_t F = get(MI.getOpcode()).TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002554 const uint64_t V = ((F >> HexagonII::TypePos) & HexagonII::TypeMask);
2555 return
2556 V == HexagonII::TypeCVI_VA ||
2557 V == HexagonII::TypeCVI_VA_DV;
2558}
Andrew Trickd06df962012-02-01 22:13:57 +00002559
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002560bool HexagonInstrInfo::isVecUsableNextPacket(const MachineInstr &ProdMI,
2561 const MachineInstr &ConsMI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002562 if (EnableACCForwarding && isVecAcc(ProdMI) && isVecAcc(ConsMI))
2563 return true;
2564
2565 if (EnableALUForwarding && (isVecALU(ConsMI) || isLateSourceInstr(ConsMI)))
2566 return true;
2567
2568 if (mayBeNewStore(ConsMI))
Andrew Trickd06df962012-02-01 22:13:57 +00002569 return true;
2570
2571 return false;
2572}
Jyotsna Verma84256432013-03-01 17:37:13 +00002573
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00002574bool HexagonInstrInfo::isZeroExtendingLoad(const MachineInstr &MI) const {
2575 switch (MI.getOpcode()) {
2576 // Byte
2577 case Hexagon::L2_loadrub_io:
2578 case Hexagon::L4_loadrub_ur:
2579 case Hexagon::L4_loadrub_ap:
2580 case Hexagon::L2_loadrub_pr:
2581 case Hexagon::L2_loadrub_pbr:
2582 case Hexagon::L2_loadrub_pi:
2583 case Hexagon::L2_loadrub_pci:
2584 case Hexagon::L2_loadrub_pcr:
2585 case Hexagon::L2_loadbzw2_io:
2586 case Hexagon::L4_loadbzw2_ur:
2587 case Hexagon::L4_loadbzw2_ap:
2588 case Hexagon::L2_loadbzw2_pr:
2589 case Hexagon::L2_loadbzw2_pbr:
2590 case Hexagon::L2_loadbzw2_pi:
2591 case Hexagon::L2_loadbzw2_pci:
2592 case Hexagon::L2_loadbzw2_pcr:
2593 case Hexagon::L2_loadbzw4_io:
2594 case Hexagon::L4_loadbzw4_ur:
2595 case Hexagon::L4_loadbzw4_ap:
2596 case Hexagon::L2_loadbzw4_pr:
2597 case Hexagon::L2_loadbzw4_pbr:
2598 case Hexagon::L2_loadbzw4_pi:
2599 case Hexagon::L2_loadbzw4_pci:
2600 case Hexagon::L2_loadbzw4_pcr:
2601 case Hexagon::L4_loadrub_rr:
2602 case Hexagon::L2_ploadrubt_io:
2603 case Hexagon::L2_ploadrubt_pi:
2604 case Hexagon::L2_ploadrubf_io:
2605 case Hexagon::L2_ploadrubf_pi:
2606 case Hexagon::L2_ploadrubtnew_io:
2607 case Hexagon::L2_ploadrubfnew_io:
2608 case Hexagon::L4_ploadrubt_rr:
2609 case Hexagon::L4_ploadrubf_rr:
2610 case Hexagon::L4_ploadrubtnew_rr:
2611 case Hexagon::L4_ploadrubfnew_rr:
2612 case Hexagon::L2_ploadrubtnew_pi:
2613 case Hexagon::L2_ploadrubfnew_pi:
2614 case Hexagon::L4_ploadrubt_abs:
2615 case Hexagon::L4_ploadrubf_abs:
2616 case Hexagon::L4_ploadrubtnew_abs:
2617 case Hexagon::L4_ploadrubfnew_abs:
2618 case Hexagon::L2_loadrubgp:
2619 // Half
2620 case Hexagon::L2_loadruh_io:
2621 case Hexagon::L4_loadruh_ur:
2622 case Hexagon::L4_loadruh_ap:
2623 case Hexagon::L2_loadruh_pr:
2624 case Hexagon::L2_loadruh_pbr:
2625 case Hexagon::L2_loadruh_pi:
2626 case Hexagon::L2_loadruh_pci:
2627 case Hexagon::L2_loadruh_pcr:
2628 case Hexagon::L4_loadruh_rr:
2629 case Hexagon::L2_ploadruht_io:
2630 case Hexagon::L2_ploadruht_pi:
2631 case Hexagon::L2_ploadruhf_io:
2632 case Hexagon::L2_ploadruhf_pi:
2633 case Hexagon::L2_ploadruhtnew_io:
2634 case Hexagon::L2_ploadruhfnew_io:
2635 case Hexagon::L4_ploadruht_rr:
2636 case Hexagon::L4_ploadruhf_rr:
2637 case Hexagon::L4_ploadruhtnew_rr:
2638 case Hexagon::L4_ploadruhfnew_rr:
2639 case Hexagon::L2_ploadruhtnew_pi:
2640 case Hexagon::L2_ploadruhfnew_pi:
2641 case Hexagon::L4_ploadruht_abs:
2642 case Hexagon::L4_ploadruhf_abs:
2643 case Hexagon::L4_ploadruhtnew_abs:
2644 case Hexagon::L4_ploadruhfnew_abs:
2645 case Hexagon::L2_loadruhgp:
2646 return true;
2647 default:
2648 return false;
Krzysztof Parzyszekfd02aad2016-02-12 18:37:23 +00002649 }
2650}
2651
Krzysztof Parzyszek408e3002016-07-15 21:34:02 +00002652// Add latency to instruction.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002653bool HexagonInstrInfo::addLatencyToSchedule(const MachineInstr &MI1,
2654 const MachineInstr &MI2) const {
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002655 if (isHVXVec(MI1) && isHVXVec(MI2))
Krzysztof Parzyszek408e3002016-07-15 21:34:02 +00002656 if (!isVecUsableNextPacket(MI1, MI2))
2657 return true;
2658 return false;
2659}
2660
Brendon Cahoon254f8892016-07-29 16:44:44 +00002661/// \brief Get the base register and byte offset of a load/store instr.
2662bool HexagonInstrInfo::getMemOpBaseRegImmOfs(MachineInstr &LdSt,
2663 unsigned &BaseReg, int64_t &Offset, const TargetRegisterInfo *TRI)
2664 const {
2665 unsigned AccessSize = 0;
2666 int OffsetVal = 0;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002667 BaseReg = getBaseAndOffset(LdSt, OffsetVal, AccessSize);
Brendon Cahoon254f8892016-07-29 16:44:44 +00002668 Offset = OffsetVal;
2669 return BaseReg != 0;
2670}
2671
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00002672/// \brief Can these instructions execute at the same time in a bundle.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002673bool HexagonInstrInfo::canExecuteInBundle(const MachineInstr &First,
2674 const MachineInstr &Second) const {
Krzysztof Parzyszek4763c2d2017-05-03 15:33:09 +00002675 if (Second.mayStore() && First.getOpcode() == Hexagon::S2_allocframe) {
2676 const MachineOperand &Op = Second.getOperand(0);
2677 if (Op.isReg() && Op.isUse() && Op.getReg() == Hexagon::R29)
2678 return true;
2679 }
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00002680 if (DisableNVSchedule)
2681 return false;
2682 if (mayBeNewStore(Second)) {
2683 // Make sure the definition of the first instruction is the value being
2684 // stored.
2685 const MachineOperand &Stored =
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002686 Second.getOperand(Second.getNumOperands() - 1);
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00002687 if (!Stored.isReg())
2688 return false;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002689 for (unsigned i = 0, e = First.getNumOperands(); i < e; ++i) {
2690 const MachineOperand &Op = First.getOperand(i);
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00002691 if (Op.isReg() && Op.isDef() && Op.getReg() == Stored.getReg())
2692 return true;
2693 }
2694 }
2695 return false;
2696}
2697
Krzysztof Parzyszek1b689da2016-08-11 21:14:25 +00002698bool HexagonInstrInfo::doesNotReturn(const MachineInstr &CallMI) const {
2699 unsigned Opc = CallMI.getOpcode();
Krzysztof Parzyszekbe976d42016-08-12 11:12:02 +00002700 return Opc == Hexagon::PS_call_nr || Opc == Hexagon::PS_callr_nr;
Krzysztof Parzyszek1b689da2016-08-11 21:14:25 +00002701}
2702
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002703bool HexagonInstrInfo::hasEHLabel(const MachineBasicBlock *B) const {
2704 for (auto &I : *B)
2705 if (I.isEHLabel())
2706 return true;
2707 return false;
Jyotsna Verma84256432013-03-01 17:37:13 +00002708}
2709
Jyotsna Verma84256432013-03-01 17:37:13 +00002710// Returns true if an instruction can be converted into a non-extended
2711// equivalent instruction.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002712bool HexagonInstrInfo::hasNonExtEquivalent(const MachineInstr &MI) const {
Jyotsna Verma84256432013-03-01 17:37:13 +00002713 short NonExtOpcode;
2714 // Check if the instruction has a register form that uses register in place
2715 // of the extended operand, if so return that as the non-extended form.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002716 if (Hexagon::getRegForm(MI.getOpcode()) >= 0)
Jyotsna Verma84256432013-03-01 17:37:13 +00002717 return true;
2718
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002719 if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {
Alp Tokercb402912014-01-24 17:20:08 +00002720 // Check addressing mode and retrieve non-ext equivalent instruction.
Jyotsna Verma84256432013-03-01 17:37:13 +00002721
2722 switch (getAddrMode(MI)) {
Eugene Zelenko3b873362017-09-28 22:27:31 +00002723 case HexagonII::Absolute:
Jyotsna Verma84256432013-03-01 17:37:13 +00002724 // Load/store with absolute addressing mode can be converted into
2725 // base+offset mode.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002726 NonExtOpcode = Hexagon::getBaseWithImmOffset(MI.getOpcode());
Jyotsna Verma84256432013-03-01 17:37:13 +00002727 break;
Eugene Zelenko3b873362017-09-28 22:27:31 +00002728 case HexagonII::BaseImmOffset:
Jyotsna Verma84256432013-03-01 17:37:13 +00002729 // Load/store with base+offset addressing mode can be converted into
2730 // base+register offset addressing mode. However left shift operand should
2731 // be set to 0.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002732 NonExtOpcode = Hexagon::getBaseWithRegOffset(MI.getOpcode());
Jyotsna Verma84256432013-03-01 17:37:13 +00002733 break;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002734 case HexagonII::BaseLongOffset:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002735 NonExtOpcode = Hexagon::getRegShlForm(MI.getOpcode());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002736 break;
Jyotsna Verma84256432013-03-01 17:37:13 +00002737 default:
2738 return false;
2739 }
2740 if (NonExtOpcode < 0)
2741 return false;
2742 return true;
2743 }
2744 return false;
2745}
2746
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002747bool HexagonInstrInfo::hasPseudoInstrPair(const MachineInstr &MI) const {
2748 return Hexagon::getRealHWInstr(MI.getOpcode(),
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002749 Hexagon::InstrType_Pseudo) >= 0;
2750}
2751
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002752bool HexagonInstrInfo::hasUncondBranch(const MachineBasicBlock *B)
2753 const {
2754 MachineBasicBlock::const_iterator I = B->getFirstTerminator(), E = B->end();
2755 while (I != E) {
2756 if (I->isBarrier())
2757 return true;
2758 ++I;
2759 }
2760 return false;
2761}
2762
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002763// Returns true, if a LD insn can be promoted to a cur load.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002764bool HexagonInstrInfo::mayBeCurLoad(const MachineInstr &MI) const {
2765 auto &HST = MI.getParent()->getParent()->getSubtarget<HexagonSubtarget>();
2766 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002767 return ((F >> HexagonII::mayCVLoadPos) & HexagonII::mayCVLoadMask) &&
2768 HST.hasV60TOps();
2769}
2770
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002771// Returns true, if a ST insn can be promoted to a new-value store.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002772bool HexagonInstrInfo::mayBeNewStore(const MachineInstr &MI) const {
2773 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002774 return (F >> HexagonII::mayNVStorePos) & HexagonII::mayNVStoreMask;
2775}
2776
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002777bool HexagonInstrInfo::producesStall(const MachineInstr &ProdMI,
2778 const MachineInstr &ConsMI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002779 // There is no stall when ProdMI is not a V60 vector.
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002780 if (!isHVXVec(ProdMI))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002781 return false;
2782
2783 // There is no stall when ProdMI and ConsMI are not dependent.
2784 if (!isDependent(ProdMI, ConsMI))
2785 return false;
2786
2787 // When Forward Scheduling is enabled, there is no stall if ProdMI and ConsMI
2788 // are scheduled in consecutive packets.
2789 if (isVecUsableNextPacket(ProdMI, ConsMI))
2790 return false;
2791
2792 return true;
2793}
2794
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002795bool HexagonInstrInfo::producesStall(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002796 MachineBasicBlock::const_instr_iterator BII) const {
2797 // There is no stall when I is not a V60 vector.
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002798 if (!isHVXVec(MI))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002799 return false;
2800
2801 MachineBasicBlock::const_instr_iterator MII = BII;
2802 MachineBasicBlock::const_instr_iterator MIE = MII->getParent()->instr_end();
2803
Krzysztof Parzyszek9aaf9232017-05-02 18:12:19 +00002804 if (!(*MII).isBundle()) {
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002805 const MachineInstr &J = *MII;
Krzysztof Parzyszek9aaf9232017-05-02 18:12:19 +00002806 return producesStall(J, MI);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002807 }
2808
2809 for (++MII; MII != MIE && MII->isInsideBundle(); ++MII) {
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002810 const MachineInstr &J = *MII;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002811 if (producesStall(J, MI))
2812 return true;
2813 }
2814 return false;
2815}
2816
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002817bool HexagonInstrInfo::predCanBeUsedAsDotNew(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002818 unsigned PredReg) const {
Krzysztof Parzyszek1aaf41a2017-02-17 22:14:51 +00002819 for (const MachineOperand &MO : MI.operands()) {
2820 // Predicate register must be explicitly defined.
2821 if (MO.isRegMask() && MO.clobbersPhysReg(PredReg))
2822 return false;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002823 if (MO.isReg() && MO.isDef() && MO.isImplicit() && (MO.getReg() == PredReg))
Krzysztof Parzyszek1aaf41a2017-02-17 22:14:51 +00002824 return false;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002825 }
2826
2827 // Hexagon Programmer's Reference says that decbin, memw_locked, and
2828 // memd_locked cannot be used as .new as well,
2829 // but we don't seem to have these instructions defined.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002830 return MI.getOpcode() != Hexagon::A4_tlbmatch;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002831}
2832
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002833bool HexagonInstrInfo::PredOpcodeHasJMP_c(unsigned Opcode) const {
Krzysztof Parzyszek19635bd2017-05-03 15:30:46 +00002834 return Opcode == Hexagon::J2_jumpt ||
2835 Opcode == Hexagon::J2_jumptpt ||
2836 Opcode == Hexagon::J2_jumpf ||
2837 Opcode == Hexagon::J2_jumpfpt ||
2838 Opcode == Hexagon::J2_jumptnew ||
2839 Opcode == Hexagon::J2_jumpfnew ||
2840 Opcode == Hexagon::J2_jumptnewpt ||
2841 Opcode == Hexagon::J2_jumpfnewpt;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002842}
2843
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002844bool HexagonInstrInfo::predOpcodeHasNot(ArrayRef<MachineOperand> Cond) const {
2845 if (Cond.empty() || !isPredicated(Cond[0].getImm()))
2846 return false;
2847 return !isPredicatedTrue(Cond[0].getImm());
2848}
2849
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002850short HexagonInstrInfo::getAbsoluteForm(const MachineInstr &MI) const {
2851 return Hexagon::getAbsoluteForm(MI.getOpcode());
Krzysztof Parzyszekf5cbac92016-04-29 15:49:13 +00002852}
2853
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002854unsigned HexagonInstrInfo::getAddrMode(const MachineInstr &MI) const {
2855 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002856 return (F >> HexagonII::AddrModePos) & HexagonII::AddrModeMask;
2857}
2858
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002859// Returns the base register in a memory access (load/store). The offset is
2860// returned in Offset and the access size is returned in AccessSize.
Krzysztof Parzyszekb449dc12017-07-19 15:39:28 +00002861// If the base register has a subregister or the offset field does not contain
2862// an immediate value, return 0.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002863unsigned HexagonInstrInfo::getBaseAndOffset(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002864 int &Offset, unsigned &AccessSize) const {
2865 // Return if it is not a base+offset type instruction or a MemOp.
2866 if (getAddrMode(MI) != HexagonII::BaseImmOffset &&
2867 getAddrMode(MI) != HexagonII::BaseLongOffset &&
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00002868 !isMemOp(MI) && !isPostIncrement(MI))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002869 return 0;
2870
Krzysztof Parzyszek473d02d2017-09-14 12:06:40 +00002871 AccessSize = getMemAccessSize(MI);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002872
Krzysztof Parzyszekb449dc12017-07-19 15:39:28 +00002873 unsigned BasePos = 0, OffsetPos = 0;
2874 if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002875 return 0;
2876
2877 // Post increment updates its EA after the mem access,
2878 // so we need to treat its offset as zero.
Krzysztof Parzyszekb449dc12017-07-19 15:39:28 +00002879 if (isPostIncrement(MI)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002880 Offset = 0;
Krzysztof Parzyszekb449dc12017-07-19 15:39:28 +00002881 } else {
2882 const MachineOperand &OffsetOp = MI.getOperand(OffsetPos);
2883 if (!OffsetOp.isImm())
2884 return 0;
2885 Offset = OffsetOp.getImm();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002886 }
2887
Krzysztof Parzyszekb449dc12017-07-19 15:39:28 +00002888 const MachineOperand &BaseOp = MI.getOperand(BasePos);
2889 if (BaseOp.getSubReg() != 0)
2890 return 0;
2891 return BaseOp.getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002892}
2893
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002894/// Return the position of the base and offset operands for this instruction.
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00002895bool HexagonInstrInfo::getBaseAndOffsetPosition(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002896 unsigned &BasePos, unsigned &OffsetPos) const {
2897 // Deal with memops first.
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00002898 if (isMemOp(MI)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002899 BasePos = 0;
2900 OffsetPos = 1;
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00002901 } else if (MI.mayStore()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002902 BasePos = 0;
2903 OffsetPos = 1;
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00002904 } else if (MI.mayLoad()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002905 BasePos = 1;
2906 OffsetPos = 2;
2907 } else
2908 return false;
2909
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00002910 if (isPredicated(MI)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002911 BasePos++;
2912 OffsetPos++;
2913 }
2914 if (isPostIncrement(MI)) {
2915 BasePos++;
2916 OffsetPos++;
2917 }
2918
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00002919 if (!MI.getOperand(BasePos).isReg() || !MI.getOperand(OffsetPos).isImm())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002920 return false;
2921
2922 return true;
2923}
2924
Simon Pilgrim6ba672e2016-11-17 19:21:20 +00002925// Inserts branching instructions in reverse order of their occurrence.
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002926// e.g. jump_t t1 (i1)
2927// jump t2 (i2)
2928// Jumpers = {i2, i1}
2929SmallVector<MachineInstr*, 2> HexagonInstrInfo::getBranchingInstrs(
2930 MachineBasicBlock& MBB) const {
2931 SmallVector<MachineInstr*, 2> Jumpers;
2932 // If the block has no terminators, it just falls into the block after it.
2933 MachineBasicBlock::instr_iterator I = MBB.instr_end();
2934 if (I == MBB.instr_begin())
2935 return Jumpers;
2936
2937 // A basic block may looks like this:
2938 //
2939 // [ insn
2940 // EH_LABEL
2941 // insn
2942 // insn
2943 // insn
2944 // EH_LABEL
2945 // insn ]
2946 //
2947 // It has two succs but does not have a terminator
2948 // Don't know how to handle it.
2949 do {
2950 --I;
2951 if (I->isEHLabel())
2952 return Jumpers;
2953 } while (I != MBB.instr_begin());
2954
2955 I = MBB.instr_end();
2956 --I;
2957
2958 while (I->isDebugValue()) {
2959 if (I == MBB.instr_begin())
2960 return Jumpers;
2961 --I;
2962 }
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00002963 if (!isUnpredicatedTerminator(*I))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002964 return Jumpers;
2965
2966 // Get the last instruction in the block.
2967 MachineInstr *LastInst = &*I;
2968 Jumpers.push_back(LastInst);
2969 MachineInstr *SecondLastInst = nullptr;
2970 // Find one more terminator if present.
2971 do {
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00002972 if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002973 if (!SecondLastInst) {
2974 SecondLastInst = &*I;
2975 Jumpers.push_back(SecondLastInst);
2976 } else // This is a third branch.
2977 return Jumpers;
2978 }
2979 if (I == MBB.instr_begin())
2980 break;
2981 --I;
2982 } while (true);
2983 return Jumpers;
2984}
2985
Krzysztof Parzyszekf5cbac92016-04-29 15:49:13 +00002986short HexagonInstrInfo::getBaseWithLongOffset(short Opcode) const {
2987 if (Opcode < 0)
2988 return -1;
2989 return Hexagon::getBaseWithLongOffset(Opcode);
2990}
2991
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002992short HexagonInstrInfo::getBaseWithLongOffset(const MachineInstr &MI) const {
2993 return Hexagon::getBaseWithLongOffset(MI.getOpcode());
Krzysztof Parzyszekf5cbac92016-04-29 15:49:13 +00002994}
2995
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002996short HexagonInstrInfo::getBaseWithRegOffset(const MachineInstr &MI) const {
2997 return Hexagon::getBaseWithRegOffset(MI.getOpcode());
Krzysztof Parzyszekf5cbac92016-04-29 15:49:13 +00002998}
2999
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003000// Returns Operand Index for the constant extended instruction.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003001unsigned HexagonInstrInfo::getCExtOpNum(const MachineInstr &MI) const {
3002 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003003 return (F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask;
3004}
3005
3006// See if instruction could potentially be a duplex candidate.
3007// If so, return its group. Zero otherwise.
3008HexagonII::CompoundGroup HexagonInstrInfo::getCompoundCandidateGroup(
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003009 const MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003010 unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
3011
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003012 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003013 default:
3014 return HexagonII::HCG_None;
3015 //
3016 // Compound pairs.
3017 // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
3018 // "Rd16=#U6 ; jump #r9:2"
3019 // "Rd16=Rs16 ; jump #r9:2"
3020 //
3021 case Hexagon::C2_cmpeq:
3022 case Hexagon::C2_cmpgt:
3023 case Hexagon::C2_cmpgtu:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003024 DstReg = MI.getOperand(0).getReg();
3025 Src1Reg = MI.getOperand(1).getReg();
3026 Src2Reg = MI.getOperand(2).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003027 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3028 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3029 isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg))
3030 return HexagonII::HCG_A;
3031 break;
3032 case Hexagon::C2_cmpeqi:
3033 case Hexagon::C2_cmpgti:
3034 case Hexagon::C2_cmpgtui:
3035 // P0 = cmp.eq(Rs,#u2)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003036 DstReg = MI.getOperand(0).getReg();
3037 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003038 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3039 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003040 isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() &&
3041 ((isUInt<5>(MI.getOperand(2).getImm())) ||
3042 (MI.getOperand(2).getImm() == -1)))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003043 return HexagonII::HCG_A;
3044 break;
3045 case Hexagon::A2_tfr:
3046 // Rd = Rs
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003047 DstReg = MI.getOperand(0).getReg();
3048 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003049 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
3050 return HexagonII::HCG_A;
3051 break;
3052 case Hexagon::A2_tfrsi:
3053 // Rd = #u6
3054 // Do not test for #u6 size since the const is getting extended
3055 // regardless and compound could be formed.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003056 DstReg = MI.getOperand(0).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003057 if (isIntRegForSubInst(DstReg))
3058 return HexagonII::HCG_A;
3059 break;
3060 case Hexagon::S2_tstbit_i:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003061 DstReg = MI.getOperand(0).getReg();
3062 Src1Reg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003063 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3064 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003065 MI.getOperand(2).isImm() &&
3066 isIntRegForSubInst(Src1Reg) && (MI.getOperand(2).getImm() == 0))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003067 return HexagonII::HCG_A;
3068 break;
3069 // The fact that .new form is used pretty much guarantees
3070 // that predicate register will match. Nevertheless,
3071 // there could be some false positives without additional
3072 // checking.
3073 case Hexagon::J2_jumptnew:
3074 case Hexagon::J2_jumpfnew:
3075 case Hexagon::J2_jumptnewpt:
3076 case Hexagon::J2_jumpfnewpt:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003077 Src1Reg = MI.getOperand(0).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003078 if (Hexagon::PredRegsRegClass.contains(Src1Reg) &&
3079 (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg))
3080 return HexagonII::HCG_B;
3081 break;
3082 // Transfer and jump:
3083 // Rd=#U6 ; jump #r9:2
3084 // Rd=Rs ; jump #r9:2
3085 // Do not test for jump range here.
3086 case Hexagon::J2_jump:
3087 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
Krzysztof Parzyszek5a7bef92016-08-19 17:20:57 +00003088 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003089 return HexagonII::HCG_C;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003090 }
3091
3092 return HexagonII::HCG_None;
3093}
3094
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003095// Returns -1 when there is no opcode found.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003096unsigned HexagonInstrInfo::getCompoundOpcode(const MachineInstr &GA,
3097 const MachineInstr &GB) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003098 assert(getCompoundCandidateGroup(GA) == HexagonII::HCG_A);
3099 assert(getCompoundCandidateGroup(GB) == HexagonII::HCG_B);
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003100 if ((GA.getOpcode() != Hexagon::C2_cmpeqi) ||
3101 (GB.getOpcode() != Hexagon::J2_jumptnew))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003102 return -1;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003103 unsigned DestReg = GA.getOperand(0).getReg();
3104 if (!GB.readsRegister(DestReg))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003105 return -1;
3106 if (DestReg == Hexagon::P0)
3107 return Hexagon::J4_cmpeqi_tp0_jump_nt;
3108 if (DestReg == Hexagon::P1)
3109 return Hexagon::J4_cmpeqi_tp1_jump_nt;
3110 return -1;
3111}
3112
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003113int HexagonInstrInfo::getCondOpcode(int Opc, bool invertPredicate) const {
3114 enum Hexagon::PredSense inPredSense;
3115 inPredSense = invertPredicate ? Hexagon::PredSense_false :
3116 Hexagon::PredSense_true;
3117 int CondOpcode = Hexagon::getPredOpcode(Opc, inPredSense);
3118 if (CondOpcode >= 0) // Valid Conditional opcode/instruction
3119 return CondOpcode;
3120
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003121 llvm_unreachable("Unexpected predicable instruction");
3122}
3123
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003124// Return the cur value instruction for a given store.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003125int HexagonInstrInfo::getDotCurOp(const MachineInstr &MI) const {
3126 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003127 default: llvm_unreachable("Unknown .cur type");
3128 case Hexagon::V6_vL32b_pi:
3129 return Hexagon::V6_vL32b_cur_pi;
3130 case Hexagon::V6_vL32b_ai:
3131 return Hexagon::V6_vL32b_cur_ai;
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00003132 case Hexagon::V6_vL32b_nt_pi:
3133 return Hexagon::V6_vL32b_nt_cur_pi;
3134 case Hexagon::V6_vL32b_nt_ai:
3135 return Hexagon::V6_vL32b_nt_cur_ai;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003136 }
3137 return 0;
3138}
3139
Krzysztof Parzyszek0a8043e2017-05-03 15:28:56 +00003140// Return the regular version of the .cur instruction.
3141int HexagonInstrInfo::getNonDotCurOp(const MachineInstr &MI) const {
3142 switch (MI.getOpcode()) {
3143 default: llvm_unreachable("Unknown .cur type");
3144 case Hexagon::V6_vL32b_cur_pi:
3145 return Hexagon::V6_vL32b_pi;
3146 case Hexagon::V6_vL32b_cur_ai:
3147 return Hexagon::V6_vL32b_ai;
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00003148 case Hexagon::V6_vL32b_nt_cur_pi:
3149 return Hexagon::V6_vL32b_nt_pi;
3150 case Hexagon::V6_vL32b_nt_cur_ai:
3151 return Hexagon::V6_vL32b_nt_ai;
Krzysztof Parzyszek0a8043e2017-05-03 15:28:56 +00003152 }
3153 return 0;
3154}
3155
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003156// The diagram below shows the steps involved in the conversion of a predicated
3157// store instruction to its .new predicated new-value form.
3158//
Krzysztof Parzyszek0a8043e2017-05-03 15:28:56 +00003159// Note: It doesn't include conditional new-value stores as they can't be
3160// converted to .new predicate.
3161//
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003162// p.new NV store [ if(p0.new)memw(R0+#0)=R2.new ]
3163// ^ ^
3164// / \ (not OK. it will cause new-value store to be
3165// / X conditional on p0.new while R2 producer is
3166// / \ on p0)
3167// / \.
3168// p.new store p.old NV store
3169// [if(p0.new)memw(R0+#0)=R2] [if(p0)memw(R0+#0)=R2.new]
3170// ^ ^
3171// \ /
3172// \ /
3173// \ /
3174// p.old store
3175// [if (p0)memw(R0+#0)=R2]
3176//
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003177// The following set of instructions further explains the scenario where
3178// conditional new-value store becomes invalid when promoted to .new predicate
3179// form.
3180//
3181// { 1) if (p0) r0 = add(r1, r2)
3182// 2) p0 = cmp.eq(r3, #0) }
3183//
3184// 3) if (p0) memb(r1+#0) = r0 --> this instruction can't be grouped with
3185// the first two instructions because in instr 1, r0 is conditional on old value
3186// of p0 but its use in instr 3 is conditional on p0 modified by instr 2 which
3187// is not valid for new-value stores.
3188// Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded
3189// from the "Conditional Store" list. Because a predicated new value store
3190// would NOT be promoted to a double dot new store. See diagram below:
3191// This function returns yes for those stores that are predicated but not
3192// yet promoted to predicate dot new instructions.
3193//
3194// +---------------------+
3195// /-----| if (p0) memw(..)=r0 |---------\~
3196// || +---------------------+ ||
3197// promote || /\ /\ || promote
3198// || /||\ /||\ ||
3199// \||/ demote || \||/
3200// \/ || || \/
3201// +-------------------------+ || +-------------------------+
3202// | if (p0.new) memw(..)=r0 | || | if (p0) memw(..)=r0.new |
3203// +-------------------------+ || +-------------------------+
3204// || || ||
3205// || demote \||/
3206// promote || \/ NOT possible
3207// || || /\~
3208// \||/ || /||\~
3209// \/ || ||
3210// +-----------------------------+
3211// | if (p0.new) memw(..)=r0.new |
3212// +-----------------------------+
3213// Double Dot New Store
3214//
3215// Returns the most basic instruction for the .new predicated instructions and
3216// new-value stores.
3217// For example, all of the following instructions will be converted back to the
3218// same instruction:
3219// 1) if (p0.new) memw(R0+#0) = R1.new --->
3220// 2) if (p0) memw(R0+#0)= R1.new -------> if (p0) memw(R0+#0) = R1
3221// 3) if (p0.new) memw(R0+#0) = R1 --->
3222//
3223// To understand the translation of instruction 1 to its original form, consider
3224// a packet with 3 instructions.
3225// { p0 = cmp.eq(R0,R1)
3226// if (p0.new) R2 = add(R3, R4)
3227// R5 = add (R3, R1)
3228// }
3229// if (p0) memw(R5+#0) = R2 <--- trying to include it in the previous packet
3230//
3231// This instruction can be part of the previous packet only if both p0 and R2
3232// are promoted to .new values. This promotion happens in steps, first
3233// predicate register is promoted to .new and in the next iteration R2 is
3234// promoted. Therefore, in case of dependence check failure (due to R5) during
3235// next iteration, it should be converted back to its most basic form.
3236
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003237// Return the new value instruction for a given store.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003238int HexagonInstrInfo::getDotNewOp(const MachineInstr &MI) const {
3239 int NVOpcode = Hexagon::getNewValueOpcode(MI.getOpcode());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003240 if (NVOpcode >= 0) // Valid new-value store instruction.
3241 return NVOpcode;
3242
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003243 switch (MI.getOpcode()) {
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +00003244 default:
Eugene Zelenko3b873362017-09-28 22:27:31 +00003245 report_fatal_error(std::string("Unknown .new type: ") +
3246 std::to_string(MI.getOpcode()));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003247 case Hexagon::S4_storerb_ur:
3248 return Hexagon::S4_storerbnew_ur;
3249
3250 case Hexagon::S2_storerb_pci:
3251 return Hexagon::S2_storerb_pci;
3252
3253 case Hexagon::S2_storeri_pci:
3254 return Hexagon::S2_storeri_pci;
3255
3256 case Hexagon::S2_storerh_pci:
3257 return Hexagon::S2_storerh_pci;
3258
3259 case Hexagon::S2_storerd_pci:
3260 return Hexagon::S2_storerd_pci;
3261
3262 case Hexagon::S2_storerf_pci:
3263 return Hexagon::S2_storerf_pci;
3264
3265 case Hexagon::V6_vS32b_ai:
3266 return Hexagon::V6_vS32b_new_ai;
3267
3268 case Hexagon::V6_vS32b_pi:
3269 return Hexagon::V6_vS32b_new_pi;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003270 }
3271 return 0;
3272}
3273
3274// Returns the opcode to use when converting MI, which is a conditional jump,
3275// into a conditional instruction which uses the .new value of the predicate.
3276// We also use branch probabilities to add a hint to the jump.
Krzysztof Parzyszek3cf16572017-06-01 18:02:40 +00003277// If MBPI is null, all edges will be treated as equally likely for the
3278// purposes of establishing a predication hint.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003279int HexagonInstrInfo::getDotNewPredJumpOp(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003280 const MachineBranchProbabilityInfo *MBPI) const {
3281 // We assume that block can have at most two successors.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003282 const MachineBasicBlock *Src = MI.getParent();
3283 const MachineOperand &BrTarget = MI.getOperand(1);
Krzysztof Parzyszeke720feb2017-03-02 21:49:49 +00003284 bool Taken = false;
3285 const BranchProbability OneHalf(1, 2);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003286
Krzysztof Parzyszek3cf16572017-06-01 18:02:40 +00003287 auto getEdgeProbability = [MBPI] (const MachineBasicBlock *Src,
3288 const MachineBasicBlock *Dst) {
3289 if (MBPI)
3290 return MBPI->getEdgeProbability(Src, Dst);
3291 return BranchProbability(1, Src->succ_size());
3292 };
3293
Krzysztof Parzyszeke720feb2017-03-02 21:49:49 +00003294 if (BrTarget.isMBB()) {
3295 const MachineBasicBlock *Dst = BrTarget.getMBB();
Krzysztof Parzyszek3cf16572017-06-01 18:02:40 +00003296 Taken = getEdgeProbability(Src, Dst) >= OneHalf;
Krzysztof Parzyszeke720feb2017-03-02 21:49:49 +00003297 } else {
3298 // The branch target is not a basic block (most likely a function).
3299 // Since BPI only gives probabilities for targets that are basic blocks,
3300 // try to identify another target of this branch (potentially a fall-
3301 // -through) and check the probability of that target.
3302 //
3303 // The only handled branch combinations are:
3304 // - one conditional branch,
3305 // - one conditional branch followed by one unconditional branch.
3306 // Otherwise, assume not-taken.
3307 assert(MI.isConditionalBranch());
3308 const MachineBasicBlock &B = *MI.getParent();
3309 bool SawCond = false, Bad = false;
3310 for (const MachineInstr &I : B) {
3311 if (!I.isBranch())
3312 continue;
3313 if (I.isConditionalBranch()) {
3314 SawCond = true;
3315 if (&I != &MI) {
3316 Bad = true;
3317 break;
3318 }
3319 }
3320 if (I.isUnconditionalBranch() && !SawCond) {
3321 Bad = true;
3322 break;
3323 }
3324 }
3325 if (!Bad) {
3326 MachineBasicBlock::const_instr_iterator It(MI);
3327 MachineBasicBlock::const_instr_iterator NextIt = std::next(It);
3328 if (NextIt == B.instr_end()) {
3329 // If this branch is the last, look for the fall-through block.
3330 for (const MachineBasicBlock *SB : B.successors()) {
3331 if (!B.isLayoutSuccessor(SB))
3332 continue;
Krzysztof Parzyszek3cf16572017-06-01 18:02:40 +00003333 Taken = getEdgeProbability(Src, SB) < OneHalf;
Krzysztof Parzyszeke720feb2017-03-02 21:49:49 +00003334 break;
3335 }
3336 } else {
3337 assert(NextIt->isUnconditionalBranch());
3338 // Find the first MBB operand and assume it's the target.
3339 const MachineBasicBlock *BT = nullptr;
3340 for (const MachineOperand &Op : NextIt->operands()) {
3341 if (!Op.isMBB())
3342 continue;
3343 BT = Op.getMBB();
3344 break;
3345 }
Krzysztof Parzyszek3cf16572017-06-01 18:02:40 +00003346 Taken = BT && getEdgeProbability(Src, BT) < OneHalf;
Krzysztof Parzyszeke720feb2017-03-02 21:49:49 +00003347 }
3348 } // if (!Bad)
3349 }
3350
3351 // The Taken flag should be set to something reasonable by this point.
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003352
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003353 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003354 case Hexagon::J2_jumpt:
Krzysztof Parzyszeke720feb2017-03-02 21:49:49 +00003355 return Taken ? Hexagon::J2_jumptnewpt : Hexagon::J2_jumptnew;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003356 case Hexagon::J2_jumpf:
Krzysztof Parzyszeke720feb2017-03-02 21:49:49 +00003357 return Taken ? Hexagon::J2_jumpfnewpt : Hexagon::J2_jumpfnew;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003358
3359 default:
3360 llvm_unreachable("Unexpected jump instruction.");
3361 }
3362}
3363
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003364// Return .new predicate version for an instruction.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003365int HexagonInstrInfo::getDotNewPredOp(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003366 const MachineBranchProbabilityInfo *MBPI) const {
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003367 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003368 // Condtional Jumps
3369 case Hexagon::J2_jumpt:
3370 case Hexagon::J2_jumpf:
3371 return getDotNewPredJumpOp(MI, MBPI);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003372 }
Krzysztof Parzyszeke720feb2017-03-02 21:49:49 +00003373
3374 int NewOpcode = Hexagon::getPredNewOpcode(MI.getOpcode());
3375 if (NewOpcode >= 0)
3376 return NewOpcode;
Krzysztof Parzyszek066e8b52017-06-02 14:07:06 +00003377 return 0;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003378}
3379
Krzysztof Parzyszek143158b2017-03-06 17:03:16 +00003380int HexagonInstrInfo::getDotOldOp(const MachineInstr &MI) const {
Krzysztof Parzyszek19635bd2017-05-03 15:30:46 +00003381 const MachineFunction &MF = *MI.getParent()->getParent();
3382 const HexagonSubtarget &HST = MF.getSubtarget<HexagonSubtarget>();
Krzysztof Parzyszek143158b2017-03-06 17:03:16 +00003383 int NewOp = MI.getOpcode();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003384 if (isPredicated(NewOp) && isPredicatedNew(NewOp)) { // Get predicate old form
3385 NewOp = Hexagon::getPredOldOpcode(NewOp);
Krzysztof Parzyszek143158b2017-03-06 17:03:16 +00003386 // All Hexagon architectures have prediction bits on dot-new branches,
3387 // but only Hexagon V60+ has prediction bits on dot-old ones. Make sure
3388 // to pick the right opcode when converting back to dot-old.
3389 if (!HST.getFeatureBits()[Hexagon::ArchV60]) {
3390 switch (NewOp) {
3391 case Hexagon::J2_jumptpt:
3392 NewOp = Hexagon::J2_jumpt;
3393 break;
3394 case Hexagon::J2_jumpfpt:
3395 NewOp = Hexagon::J2_jumpf;
3396 break;
3397 case Hexagon::J2_jumprtpt:
3398 NewOp = Hexagon::J2_jumprt;
3399 break;
3400 case Hexagon::J2_jumprfpt:
3401 NewOp = Hexagon::J2_jumprf;
3402 break;
3403 }
3404 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003405 assert(NewOp >= 0 &&
3406 "Couldn't change predicate new instruction to its old form.");
3407 }
3408
3409 if (isNewValueStore(NewOp)) { // Convert into non-new-value format
3410 NewOp = Hexagon::getNonNVStore(NewOp);
3411 assert(NewOp >= 0 && "Couldn't change new-value store to its old form.");
3412 }
Krzysztof Parzyszek19635bd2017-05-03 15:30:46 +00003413
3414 if (HST.hasV60TOps())
3415 return NewOp;
3416
3417 // Subtargets prior to V60 didn't support 'taken' forms of predicated jumps.
3418 switch (NewOp) {
3419 case Hexagon::J2_jumpfpt:
3420 return Hexagon::J2_jumpf;
3421 case Hexagon::J2_jumptpt:
3422 return Hexagon::J2_jumpt;
3423 case Hexagon::J2_jumprfpt:
3424 return Hexagon::J2_jumprf;
3425 case Hexagon::J2_jumprtpt:
3426 return Hexagon::J2_jumprt;
3427 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003428 return NewOp;
3429}
3430
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003431// See if instruction could potentially be a duplex candidate.
3432// If so, return its group. Zero otherwise.
3433HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup(
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003434 const MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003435 unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00003436 const MachineFunction &MF = *MI.getParent()->getParent();
3437 const auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003438
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003439 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003440 default:
3441 return HexagonII::HSIG_None;
3442 //
3443 // Group L1:
3444 //
3445 // Rd = memw(Rs+#u4:2)
3446 // Rd = memub(Rs+#u4:0)
3447 case Hexagon::L2_loadri_io:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003448 DstReg = MI.getOperand(0).getReg();
3449 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003450 // Special case this one from Group L2.
3451 // Rd = memw(r29+#u5:2)
3452 if (isIntRegForSubInst(DstReg)) {
3453 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
3454 HRI.getStackRegister() == SrcReg &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003455 MI.getOperand(2).isImm() &&
3456 isShiftedUInt<5,2>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003457 return HexagonII::HSIG_L2;
3458 // Rd = memw(Rs+#u4:2)
3459 if (isIntRegForSubInst(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003460 (MI.getOperand(2).isImm() &&
3461 isShiftedUInt<4,2>(MI.getOperand(2).getImm())))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003462 return HexagonII::HSIG_L1;
3463 }
3464 break;
3465 case Hexagon::L2_loadrub_io:
3466 // Rd = memub(Rs+#u4:0)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003467 DstReg = MI.getOperand(0).getReg();
3468 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003469 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003470 MI.getOperand(2).isImm() && isUInt<4>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003471 return HexagonII::HSIG_L1;
3472 break;
3473 //
3474 // Group L2:
3475 //
3476 // Rd = memh/memuh(Rs+#u3:1)
3477 // Rd = memb(Rs+#u3:0)
3478 // Rd = memw(r29+#u5:2) - Handled above.
3479 // Rdd = memd(r29+#u5:3)
3480 // deallocframe
3481 // [if ([!]p0[.new])] dealloc_return
3482 // [if ([!]p0[.new])] jumpr r31
3483 case Hexagon::L2_loadrh_io:
3484 case Hexagon::L2_loadruh_io:
3485 // Rd = memh/memuh(Rs+#u3:1)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003486 DstReg = MI.getOperand(0).getReg();
3487 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003488 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003489 MI.getOperand(2).isImm() &&
3490 isShiftedUInt<3,1>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003491 return HexagonII::HSIG_L2;
3492 break;
3493 case Hexagon::L2_loadrb_io:
3494 // Rd = memb(Rs+#u3:0)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003495 DstReg = MI.getOperand(0).getReg();
3496 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003497 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003498 MI.getOperand(2).isImm() &&
3499 isUInt<3>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003500 return HexagonII::HSIG_L2;
3501 break;
3502 case Hexagon::L2_loadrd_io:
3503 // Rdd = memd(r29+#u5:3)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003504 DstReg = MI.getOperand(0).getReg();
3505 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003506 if (isDblRegForSubInst(DstReg, HRI) &&
3507 Hexagon::IntRegsRegClass.contains(SrcReg) &&
3508 HRI.getStackRegister() == SrcReg &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003509 MI.getOperand(2).isImm() &&
3510 isShiftedUInt<5,3>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003511 return HexagonII::HSIG_L2;
3512 break;
3513 // dealloc_return is not documented in Hexagon Manual, but marked
3514 // with A_SUBINSN attribute in iset_v4classic.py.
3515 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
Krzysztof Parzyszek5a7bef92016-08-19 17:20:57 +00003516 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003517 case Hexagon::L4_return:
3518 case Hexagon::L2_deallocframe:
3519 return HexagonII::HSIG_L2;
3520 case Hexagon::EH_RETURN_JMPR:
Krzysztof Parzyszekbe976d42016-08-12 11:12:02 +00003521 case Hexagon::PS_jmpret:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003522 // jumpr r31
3523 // Actual form JMPR %PC<imp-def>, %R31<imp-use>, %R0<imp-use,internal>.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003524 DstReg = MI.getOperand(0).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003525 if (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg))
3526 return HexagonII::HSIG_L2;
3527 break;
Krzysztof Parzyszekbe976d42016-08-12 11:12:02 +00003528 case Hexagon::PS_jmprett:
3529 case Hexagon::PS_jmpretf:
3530 case Hexagon::PS_jmprettnewpt:
3531 case Hexagon::PS_jmpretfnewpt:
3532 case Hexagon::PS_jmprettnew:
3533 case Hexagon::PS_jmpretfnew:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003534 DstReg = MI.getOperand(1).getReg();
3535 SrcReg = MI.getOperand(0).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003536 // [if ([!]p0[.new])] jumpr r31
3537 if ((Hexagon::PredRegsRegClass.contains(SrcReg) &&
3538 (Hexagon::P0 == SrcReg)) &&
3539 (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg)))
3540 return HexagonII::HSIG_L2;
Krzysztof Parzyszekfb4c4172016-08-19 19:29:15 +00003541 break;
Eugene Zelenko3b873362017-09-28 22:27:31 +00003542 case Hexagon::L4_return_t:
3543 case Hexagon::L4_return_f:
3544 case Hexagon::L4_return_tnew_pnt:
3545 case Hexagon::L4_return_fnew_pnt:
3546 case Hexagon::L4_return_tnew_pt:
3547 case Hexagon::L4_return_fnew_pt:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003548 // [if ([!]p0[.new])] dealloc_return
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003549 SrcReg = MI.getOperand(0).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003550 if (Hexagon::PredRegsRegClass.contains(SrcReg) && (Hexagon::P0 == SrcReg))
3551 return HexagonII::HSIG_L2;
3552 break;
3553 //
3554 // Group S1:
3555 //
3556 // memw(Rs+#u4:2) = Rt
3557 // memb(Rs+#u4:0) = Rt
3558 case Hexagon::S2_storeri_io:
3559 // Special case this one from Group S2.
3560 // memw(r29+#u5:2) = Rt
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003561 Src1Reg = MI.getOperand(0).getReg();
3562 Src2Reg = MI.getOperand(2).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003563 if (Hexagon::IntRegsRegClass.contains(Src1Reg) &&
3564 isIntRegForSubInst(Src2Reg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003565 HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() &&
3566 isShiftedUInt<5,2>(MI.getOperand(1).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003567 return HexagonII::HSIG_S2;
3568 // memw(Rs+#u4:2) = Rt
3569 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003570 MI.getOperand(1).isImm() &&
3571 isShiftedUInt<4,2>(MI.getOperand(1).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003572 return HexagonII::HSIG_S1;
3573 break;
3574 case Hexagon::S2_storerb_io:
3575 // memb(Rs+#u4:0) = Rt
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003576 Src1Reg = MI.getOperand(0).getReg();
3577 Src2Reg = MI.getOperand(2).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003578 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003579 MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003580 return HexagonII::HSIG_S1;
3581 break;
3582 //
3583 // Group S2:
3584 //
3585 // memh(Rs+#u3:1) = Rt
3586 // memw(r29+#u5:2) = Rt
3587 // memd(r29+#s6:3) = Rtt
3588 // memw(Rs+#u4:2) = #U1
3589 // memb(Rs+#u4) = #U1
3590 // allocframe(#u5:3)
3591 case Hexagon::S2_storerh_io:
3592 // memh(Rs+#u3:1) = Rt
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003593 Src1Reg = MI.getOperand(0).getReg();
3594 Src2Reg = MI.getOperand(2).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003595 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003596 MI.getOperand(1).isImm() &&
3597 isShiftedUInt<3,1>(MI.getOperand(1).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003598 return HexagonII::HSIG_S1;
3599 break;
3600 case Hexagon::S2_storerd_io:
3601 // memd(r29+#s6:3) = Rtt
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003602 Src1Reg = MI.getOperand(0).getReg();
3603 Src2Reg = MI.getOperand(2).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003604 if (isDblRegForSubInst(Src2Reg, HRI) &&
3605 Hexagon::IntRegsRegClass.contains(Src1Reg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003606 HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() &&
3607 isShiftedInt<6,3>(MI.getOperand(1).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003608 return HexagonII::HSIG_S2;
3609 break;
3610 case Hexagon::S4_storeiri_io:
3611 // memw(Rs+#u4:2) = #U1
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003612 Src1Reg = MI.getOperand(0).getReg();
3613 if (isIntRegForSubInst(Src1Reg) && MI.getOperand(1).isImm() &&
3614 isShiftedUInt<4,2>(MI.getOperand(1).getImm()) &&
3615 MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003616 return HexagonII::HSIG_S2;
3617 break;
3618 case Hexagon::S4_storeirb_io:
3619 // memb(Rs+#u4) = #U1
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003620 Src1Reg = MI.getOperand(0).getReg();
Krzysztof Parzyszekf2a4f8f2016-06-15 21:05:04 +00003621 if (isIntRegForSubInst(Src1Reg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003622 MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()) &&
3623 MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003624 return HexagonII::HSIG_S2;
3625 break;
3626 case Hexagon::S2_allocframe:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003627 if (MI.getOperand(0).isImm() &&
3628 isShiftedUInt<5,3>(MI.getOperand(0).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003629 return HexagonII::HSIG_S1;
3630 break;
3631 //
3632 // Group A:
3633 //
3634 // Rx = add(Rx,#s7)
3635 // Rd = Rs
3636 // Rd = #u6
3637 // Rd = #-1
3638 // if ([!]P0[.new]) Rd = #0
3639 // Rd = add(r29,#u6:2)
3640 // Rx = add(Rx,Rs)
3641 // P0 = cmp.eq(Rs,#u2)
3642 // Rdd = combine(#0,Rs)
3643 // Rdd = combine(Rs,#0)
3644 // Rdd = combine(#u2,#U2)
3645 // Rd = add(Rs,#1)
3646 // Rd = add(Rs,#-1)
3647 // Rd = sxth/sxtb/zxtb/zxth(Rs)
3648 // Rd = and(Rs,#1)
3649 case Hexagon::A2_addi:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003650 DstReg = MI.getOperand(0).getReg();
3651 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003652 if (isIntRegForSubInst(DstReg)) {
3653 // Rd = add(r29,#u6:2)
3654 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003655 HRI.getStackRegister() == SrcReg && MI.getOperand(2).isImm() &&
3656 isShiftedUInt<6,2>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003657 return HexagonII::HSIG_A;
3658 // Rx = add(Rx,#s7)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003659 if ((DstReg == SrcReg) && MI.getOperand(2).isImm() &&
3660 isInt<7>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003661 return HexagonII::HSIG_A;
3662 // Rd = add(Rs,#1)
3663 // Rd = add(Rs,#-1)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003664 if (isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() &&
3665 ((MI.getOperand(2).getImm() == 1) ||
3666 (MI.getOperand(2).getImm() == -1)))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003667 return HexagonII::HSIG_A;
3668 }
3669 break;
3670 case Hexagon::A2_add:
3671 // Rx = add(Rx,Rs)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003672 DstReg = MI.getOperand(0).getReg();
3673 Src1Reg = MI.getOperand(1).getReg();
3674 Src2Reg = MI.getOperand(2).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003675 if (isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&
3676 isIntRegForSubInst(Src2Reg))
3677 return HexagonII::HSIG_A;
3678 break;
3679 case Hexagon::A2_andir:
3680 // Same as zxtb.
3681 // Rd16=and(Rs16,#255)
3682 // Rd16=and(Rs16,#1)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003683 DstReg = MI.getOperand(0).getReg();
3684 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003685 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003686 MI.getOperand(2).isImm() &&
3687 ((MI.getOperand(2).getImm() == 1) ||
3688 (MI.getOperand(2).getImm() == 255)))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003689 return HexagonII::HSIG_A;
3690 break;
3691 case Hexagon::A2_tfr:
3692 // Rd = Rs
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003693 DstReg = MI.getOperand(0).getReg();
3694 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003695 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
3696 return HexagonII::HSIG_A;
3697 break;
3698 case Hexagon::A2_tfrsi:
3699 // Rd = #u6
3700 // Do not test for #u6 size since the const is getting extended
3701 // regardless and compound could be formed.
3702 // Rd = #-1
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003703 DstReg = MI.getOperand(0).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003704 if (isIntRegForSubInst(DstReg))
3705 return HexagonII::HSIG_A;
3706 break;
3707 case Hexagon::C2_cmoveit:
3708 case Hexagon::C2_cmovenewit:
3709 case Hexagon::C2_cmoveif:
3710 case Hexagon::C2_cmovenewif:
3711 // if ([!]P0[.new]) Rd = #0
3712 // Actual form:
3713 // %R16<def> = C2_cmovenewit %P0<internal>, 0, %R16<imp-use,undef>;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003714 DstReg = MI.getOperand(0).getReg();
3715 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003716 if (isIntRegForSubInst(DstReg) &&
3717 Hexagon::PredRegsRegClass.contains(SrcReg) && Hexagon::P0 == SrcReg &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003718 MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0)
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003719 return HexagonII::HSIG_A;
3720 break;
3721 case Hexagon::C2_cmpeqi:
3722 // P0 = cmp.eq(Rs,#u2)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003723 DstReg = MI.getOperand(0).getReg();
3724 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003725 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3726 Hexagon::P0 == DstReg && isIntRegForSubInst(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003727 MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003728 return HexagonII::HSIG_A;
3729 break;
3730 case Hexagon::A2_combineii:
3731 case Hexagon::A4_combineii:
3732 // Rdd = combine(#u2,#U2)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003733 DstReg = MI.getOperand(0).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003734 if (isDblRegForSubInst(DstReg, HRI) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003735 ((MI.getOperand(1).isImm() && isUInt<2>(MI.getOperand(1).getImm())) ||
3736 (MI.getOperand(1).isGlobal() &&
3737 isUInt<2>(MI.getOperand(1).getOffset()))) &&
3738 ((MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm())) ||
3739 (MI.getOperand(2).isGlobal() &&
3740 isUInt<2>(MI.getOperand(2).getOffset()))))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003741 return HexagonII::HSIG_A;
3742 break;
3743 case Hexagon::A4_combineri:
3744 // Rdd = combine(Rs,#0)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003745 DstReg = MI.getOperand(0).getReg();
3746 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003747 if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003748 ((MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) ||
3749 (MI.getOperand(2).isGlobal() && MI.getOperand(2).getOffset() == 0)))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003750 return HexagonII::HSIG_A;
3751 break;
3752 case Hexagon::A4_combineir:
3753 // Rdd = combine(#0,Rs)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003754 DstReg = MI.getOperand(0).getReg();
3755 SrcReg = MI.getOperand(2).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003756 if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003757 ((MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) ||
3758 (MI.getOperand(1).isGlobal() && MI.getOperand(1).getOffset() == 0)))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003759 return HexagonII::HSIG_A;
3760 break;
3761 case Hexagon::A2_sxtb:
3762 case Hexagon::A2_sxth:
3763 case Hexagon::A2_zxtb:
3764 case Hexagon::A2_zxth:
3765 // Rd = sxth/sxtb/zxtb/zxth(Rs)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003766 DstReg = MI.getOperand(0).getReg();
3767 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003768 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
3769 return HexagonII::HSIG_A;
3770 break;
3771 }
3772
3773 return HexagonII::HSIG_None;
3774}
3775
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003776short HexagonInstrInfo::getEquivalentHWInstr(const MachineInstr &MI) const {
3777 return Hexagon::getRealHWInstr(MI.getOpcode(), Hexagon::InstrType_Real);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003778}
3779
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003780unsigned HexagonInstrInfo::getInstrTimingClassLatency(
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003781 const InstrItineraryData *ItinData, const MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003782 // Default to one cycle for no itinerary. However, an "empty" itinerary may
3783 // still have a MinLatency property, which getStageLatency checks.
3784 if (!ItinData)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003785 return getInstrLatency(ItinData, MI);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003786
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003787 if (MI.isTransient())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003788 return 0;
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00003789 return ItinData->getStageLatency(MI.getDesc().getSchedClass());
3790}
3791
3792/// getOperandLatency - Compute and return the use operand latency of a given
3793/// pair of def and use.
3794/// In most cases, the static scheduling itinerary was enough to determine the
3795/// operand latency. But it may not be possible for instructions with variable
3796/// number of defs / uses.
3797///
3798/// This is a raw interface to the itinerary that may be directly overriden by
3799/// a target. Use computeOperandLatency to get the best estimate of latency.
3800int HexagonInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
3801 const MachineInstr &DefMI,
3802 unsigned DefIdx,
3803 const MachineInstr &UseMI,
3804 unsigned UseIdx) const {
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00003805 const MachineFunction &MF = *DefMI.getParent()->getParent();
3806 const auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
3807
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00003808 // Get DefIdx and UseIdx for super registers.
3809 MachineOperand DefMO = DefMI.getOperand(DefIdx);
3810
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00003811 if (HRI.isPhysicalRegister(DefMO.getReg())) {
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00003812 if (DefMO.isImplicit()) {
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00003813 for (MCSuperRegIterator SR(DefMO.getReg(), &HRI); SR.isValid(); ++SR) {
3814 int Idx = DefMI.findRegisterDefOperandIdx(*SR, false, false, &HRI);
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00003815 if (Idx != -1) {
3816 DefIdx = Idx;
3817 break;
3818 }
3819 }
3820 }
3821
3822 MachineOperand UseMO = UseMI.getOperand(UseIdx);
3823 if (UseMO.isImplicit()) {
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00003824 for (MCSuperRegIterator SR(UseMO.getReg(), &HRI); SR.isValid(); ++SR) {
3825 int Idx = UseMI.findRegisterUseOperandIdx(*SR, false, &HRI);
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00003826 if (Idx != -1) {
3827 UseIdx = Idx;
3828 break;
3829 }
3830 }
3831 }
3832 }
3833
3834 return TargetInstrInfo::getOperandLatency(ItinData, DefMI, DefIdx,
3835 UseMI, UseIdx);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003836}
3837
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003838// inverts the predication logic.
3839// p -> NotP
3840// NotP -> P
3841bool HexagonInstrInfo::getInvertedPredSense(
3842 SmallVectorImpl<MachineOperand> &Cond) const {
3843 if (Cond.empty())
3844 return false;
3845 unsigned Opc = getInvertedPredicatedOpcode(Cond[0].getImm());
3846 Cond[0].setImm(Opc);
3847 return true;
3848}
3849
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003850unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const {
3851 int InvPredOpcode;
3852 InvPredOpcode = isPredicatedTrue(Opc) ? Hexagon::getFalsePredOpcode(Opc)
3853 : Hexagon::getTruePredOpcode(Opc);
3854 if (InvPredOpcode >= 0) // Valid instruction with the inverted predicate.
3855 return InvPredOpcode;
3856
3857 llvm_unreachable("Unexpected predicated instruction");
3858}
3859
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003860// Returns the max value that doesn't need to be extended.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003861int HexagonInstrInfo::getMaxValue(const MachineInstr &MI) const {
3862 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003863 unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
3864 & HexagonII::ExtentSignedMask;
3865 unsigned bits = (F >> HexagonII::ExtentBitsPos)
3866 & HexagonII::ExtentBitsMask;
3867
3868 if (isSigned) // if value is signed
3869 return ~(-1U << (bits - 1));
3870 else
3871 return ~(-1U << bits);
3872}
3873
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003874unsigned HexagonInstrInfo::getMemAccessSize(const MachineInstr &MI) const {
Krzysztof Parzyszek473d02d2017-09-14 12:06:40 +00003875 using namespace HexagonII;
Eugene Zelenko3b873362017-09-28 22:27:31 +00003876
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003877 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszek473d02d2017-09-14 12:06:40 +00003878 unsigned S = (F >> MemAccessSizePos) & MemAccesSizeMask;
3879 unsigned Size = getMemAccessSizeInBytes(MemAccessSize(S));
3880 if (Size != 0)
3881 return Size;
3882
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00003883 const MachineFunction &MF = *MI.getParent()->getParent();
3884 const auto &HRI = *MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
3885
Krzysztof Parzyszek473d02d2017-09-14 12:06:40 +00003886 // Handle vector access sizes.
3887 switch (S) {
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00003888 case HexagonII::HVXVectorAccess:
3889 return HRI.getSpillSize(Hexagon::HvxVRRegClass);
Krzysztof Parzyszek473d02d2017-09-14 12:06:40 +00003890 default:
3891 llvm_unreachable("Unexpected instruction");
3892 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003893}
3894
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003895// Returns the min value that doesn't need to be extended.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003896int HexagonInstrInfo::getMinValue(const MachineInstr &MI) const {
3897 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003898 unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
3899 & HexagonII::ExtentSignedMask;
3900 unsigned bits = (F >> HexagonII::ExtentBitsPos)
3901 & HexagonII::ExtentBitsMask;
3902
3903 if (isSigned) // if value is signed
3904 return -1U << (bits - 1);
3905 else
3906 return 0;
3907}
3908
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003909// Returns opcode of the non-extended equivalent instruction.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003910short HexagonInstrInfo::getNonExtOpcode(const MachineInstr &MI) const {
Jyotsna Verma84256432013-03-01 17:37:13 +00003911 // Check if the instruction has a register form that uses register in place
3912 // of the extended operand, if so return that as the non-extended form.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003913 short NonExtOpcode = Hexagon::getRegForm(MI.getOpcode());
Jyotsna Verma84256432013-03-01 17:37:13 +00003914 if (NonExtOpcode >= 0)
3915 return NonExtOpcode;
3916
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003917 if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {
Alp Tokercb402912014-01-24 17:20:08 +00003918 // Check addressing mode and retrieve non-ext equivalent instruction.
Jyotsna Verma84256432013-03-01 17:37:13 +00003919 switch (getAddrMode(MI)) {
Eugene Zelenko3b873362017-09-28 22:27:31 +00003920 case HexagonII::Absolute:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003921 return Hexagon::getBaseWithImmOffset(MI.getOpcode());
Eugene Zelenko3b873362017-09-28 22:27:31 +00003922 case HexagonII::BaseImmOffset:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003923 return Hexagon::getBaseWithRegOffset(MI.getOpcode());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003924 case HexagonII::BaseLongOffset:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003925 return Hexagon::getRegShlForm(MI.getOpcode());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003926
Jyotsna Verma84256432013-03-01 17:37:13 +00003927 default:
3928 return -1;
3929 }
3930 }
3931 return -1;
3932}
Jyotsna Verma5ed51812013-05-01 21:37:34 +00003933
Ahmed Bougachac88bf542015-06-11 19:30:37 +00003934bool HexagonInstrInfo::getPredReg(ArrayRef<MachineOperand> Cond,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003935 unsigned &PredReg, unsigned &PredRegPos, unsigned &PredRegFlags) const {
Brendon Cahoondf43e682015-05-08 16:16:29 +00003936 if (Cond.empty())
3937 return false;
3938 assert(Cond.size() == 2);
3939 if (isNewValueJump(Cond[0].getImm()) || Cond[1].isMBB()) {
Krzysztof Parzyszekfb4c4172016-08-19 19:29:15 +00003940 DEBUG(dbgs() << "No predregs for new-value jumps/endloop");
3941 return false;
Brendon Cahoondf43e682015-05-08 16:16:29 +00003942 }
3943 PredReg = Cond[1].getReg();
3944 PredRegPos = 1;
3945 // See IfConversion.cpp why we add RegState::Implicit | RegState::Undef
3946 PredRegFlags = 0;
3947 if (Cond[1].isImplicit())
3948 PredRegFlags = RegState::Implicit;
3949 if (Cond[1].isUndef())
3950 PredRegFlags |= RegState::Undef;
3951 return true;
3952}
3953
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003954short HexagonInstrInfo::getPseudoInstrPair(const MachineInstr &MI) const {
3955 return Hexagon::getRealHWInstr(MI.getOpcode(), Hexagon::InstrType_Pseudo);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003956}
3957
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003958short HexagonInstrInfo::getRegForm(const MachineInstr &MI) const {
3959 return Hexagon::getRegForm(MI.getOpcode());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003960}
3961
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003962// Return the number of bytes required to encode the instruction.
3963// Hexagon instructions are fixed length, 4 bytes, unless they
3964// use a constant extender, which requires another 4 bytes.
3965// For debug instructions and prolog labels, return 0.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003966unsigned HexagonInstrInfo::getSize(const MachineInstr &MI) const {
3967 if (MI.isDebugValue() || MI.isPosition())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003968 return 0;
3969
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003970 unsigned Size = MI.getDesc().getSize();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003971 if (!Size)
3972 // Assume the default insn size in case it cannot be determined
3973 // for whatever reason.
3974 Size = HEXAGON_INSTR_SIZE;
3975
3976 if (isConstExtended(MI) || isExtended(MI))
3977 Size += HEXAGON_INSTR_SIZE;
3978
3979 // Try and compute number of instructions in asm.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003980 if (BranchRelaxAsmLarge && MI.getOpcode() == Hexagon::INLINEASM) {
3981 const MachineBasicBlock &MBB = *MI.getParent();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003982 const MachineFunction *MF = MBB.getParent();
3983 const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo();
3984
3985 // Count the number of register definitions to find the asm string.
3986 unsigned NumDefs = 0;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003987 for (; MI.getOperand(NumDefs).isReg() && MI.getOperand(NumDefs).isDef();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003988 ++NumDefs)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003989 assert(NumDefs != MI.getNumOperands()-2 && "No asm string?");
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003990
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003991 assert(MI.getOperand(NumDefs).isSymbol() && "No asm string?");
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003992 // Disassemble the AsmStr and approximate number of instructions.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003993 const char *AsmStr = MI.getOperand(NumDefs).getSymbolName();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003994 Size = getInlineAsmLength(AsmStr, *MAI);
3995 }
3996
3997 return Size;
3998}
3999
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004000uint64_t HexagonInstrInfo::getType(const MachineInstr &MI) const {
4001 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004002 return (F >> HexagonII::TypePos) & HexagonII::TypeMask;
4003}
4004
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004005unsigned HexagonInstrInfo::getUnits(const MachineInstr &MI) const {
4006 const TargetSubtargetInfo &ST = MI.getParent()->getParent()->getSubtarget();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004007 const InstrItineraryData &II = *ST.getInstrItineraryData();
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004008 const InstrStage &IS = *II.beginStage(MI.getDesc().getSchedClass());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004009
4010 return IS.getUnits();
4011}
4012
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004013// Calculate size of the basic block without debug instructions.
4014unsigned HexagonInstrInfo::nonDbgBBSize(const MachineBasicBlock *BB) const {
4015 return nonDbgMICount(BB->instr_begin(), BB->instr_end());
4016}
4017
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004018unsigned HexagonInstrInfo::nonDbgBundleSize(
4019 MachineBasicBlock::const_iterator BundleHead) const {
4020 assert(BundleHead->isBundle() && "Not a bundle header");
Duncan P. N. Exon Smithd84f6002016-02-22 21:30:15 +00004021 auto MII = BundleHead.getInstrIterator();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004022 // Skip the bundle header.
Matthias Braunc8440dd2016-10-25 02:55:17 +00004023 return nonDbgMICount(++MII, getBundleEnd(BundleHead.getInstrIterator()));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004024}
4025
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004026/// immediateExtend - Changes the instruction in place to one using an immediate
4027/// extender.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004028void HexagonInstrInfo::immediateExtend(MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004029 assert((isExtendable(MI)||isConstExtended(MI)) &&
4030 "Instruction must be extendable");
4031 // Find which operand is extendable.
4032 short ExtOpNum = getCExtOpNum(MI);
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004033 MachineOperand &MO = MI.getOperand(ExtOpNum);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004034 // This needs to be something we understand.
4035 assert((MO.isMBB() || MO.isImm()) &&
4036 "Branch with unknown extendable field type");
4037 // Mark given operand as extended.
4038 MO.addTargetFlag(HexagonII::HMOTF_ConstExtended);
4039}
4040
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004041bool HexagonInstrInfo::invertAndChangeJumpTarget(
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004042 MachineInstr &MI, MachineBasicBlock *NewTarget) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004043 DEBUG(dbgs() << "\n[invertAndChangeJumpTarget] to BB#"
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004044 << NewTarget->getNumber(); MI.dump(););
4045 assert(MI.isBranch());
4046 unsigned NewOpcode = getInvertedPredicatedOpcode(MI.getOpcode());
4047 int TargetPos = MI.getNumOperands() - 1;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004048 // In general branch target is the last operand,
4049 // but some implicit defs added at the end might change it.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004050 while ((TargetPos > -1) && !MI.getOperand(TargetPos).isMBB())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004051 --TargetPos;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004052 assert((TargetPos >= 0) && MI.getOperand(TargetPos).isMBB());
4053 MI.getOperand(TargetPos).setMBB(NewTarget);
4054 if (EnableBranchPrediction && isPredicatedNew(MI)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004055 NewOpcode = reversePrediction(NewOpcode);
4056 }
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004057 MI.setDesc(get(NewOpcode));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004058 return true;
4059}
4060
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004061void HexagonInstrInfo::genAllInsnTimingClasses(MachineFunction &MF) const {
4062 /* +++ The code below is used to generate complete set of Hexagon Insn +++ */
4063 MachineFunction::iterator A = MF.begin();
4064 MachineBasicBlock &B = *A;
4065 MachineBasicBlock::iterator I = B.begin();
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004066 DebugLoc DL = I->getDebugLoc();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004067 MachineInstr *NewMI;
4068
4069 for (unsigned insn = TargetOpcode::GENERIC_OP_END+1;
4070 insn < Hexagon::INSTRUCTION_LIST_END; ++insn) {
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004071 NewMI = BuildMI(B, I, DL, get(insn));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004072 DEBUG(dbgs() << "\n" << getName(NewMI->getOpcode()) <<
4073 " Class: " << NewMI->getDesc().getSchedClass());
4074 NewMI->eraseFromParent();
4075 }
4076 /* --- The code above is used to generate complete set of Hexagon Insn --- */
4077}
4078
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004079// inverts the predication logic.
4080// p -> NotP
4081// NotP -> P
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004082bool HexagonInstrInfo::reversePredSense(MachineInstr &MI) const {
4083 DEBUG(dbgs() << "\nTrying to reverse pred. sense of:"; MI.dump());
4084 MI.setDesc(get(getInvertedPredicatedOpcode(MI.getOpcode())));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004085 return true;
4086}
4087
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004088// Reverse the branch prediction.
4089unsigned HexagonInstrInfo::reversePrediction(unsigned Opcode) const {
4090 int PredRevOpcode = -1;
4091 if (isPredictedTaken(Opcode))
4092 PredRevOpcode = Hexagon::notTakenBranchPrediction(Opcode);
4093 else
4094 PredRevOpcode = Hexagon::takenBranchPrediction(Opcode);
4095 assert(PredRevOpcode > 0);
4096 return PredRevOpcode;
4097}
4098
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004099// TODO: Add more rigorous validation.
4100bool HexagonInstrInfo::validateBranchCond(const ArrayRef<MachineOperand> &Cond)
4101 const {
4102 return Cond.empty() || (Cond[0].isImm() && (Cond.size() != 1));
4103}
4104
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004105short HexagonInstrInfo::xformRegToImmOffset(const MachineInstr &MI) const {
4106 return Hexagon::xformRegToImmOffset(MI.getOpcode());
Krzysztof Parzyszekf5cbac92016-04-29 15:49:13 +00004107}