blob: cb00bc770c09b264df04293cd43e154b4017107a [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"
David Blaikie3f833ed2017-11-08 01:01:31 +000039#include "llvm/CodeGen/TargetInstrInfo.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +000040#include "llvm/CodeGen/TargetOpcodes.h"
41#include "llvm/CodeGen/TargetRegisterInfo.h"
42#include "llvm/CodeGen/TargetSubtargetInfo.h"
Eugene Zelenko3b873362017-09-28 22:27:31 +000043#include "llvm/IR/DebugLoc.h"
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +000044#include "llvm/MC/MCAsmInfo.h"
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +000045#include "llvm/MC/MCInstrDesc.h"
46#include "llvm/MC/MCInstrItineraries.h"
47#include "llvm/MC/MCRegisterInfo.h"
48#include "llvm/Support/BranchProbability.h"
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +000049#include "llvm/Support/CommandLine.h"
Jyotsna Verma5ed51812013-05-01 21:37:34 +000050#include "llvm/Support/Debug.h"
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +000051#include "llvm/Support/ErrorHandling.h"
Benjamin Kramerae87d7b2012-02-06 10:19:29 +000052#include "llvm/Support/MathExtras.h"
Reid Kleckner1c76f1552013-05-03 00:54:56 +000053#include "llvm/Support/raw_ostream.h"
Eugene Zelenko3b873362017-09-28 22:27:31 +000054#include "llvm/Target/TargetMachine.h"
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +000055#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 Parzyszek4697dde2017-10-04 18:00:15 +0000119 : HexagonGenInstrInfo(Hexagon::ADJCALLSTACKDOWN, Hexagon::ADJCALLSTACKUP),
120 Subtarget(ST) {}
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000121
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000122static bool isIntRegForSubInst(unsigned Reg) {
123 return (Reg >= Hexagon::R0 && Reg <= Hexagon::R7) ||
124 (Reg >= Hexagon::R16 && Reg <= Hexagon::R23);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000125}
126
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000127static bool isDblRegForSubInst(unsigned Reg, const HexagonRegisterInfo &HRI) {
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +0000128 return isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::isub_lo)) &&
129 isIntRegForSubInst(HRI.getSubReg(Reg, Hexagon::isub_hi));
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000130}
131
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000132/// Calculate number of instructions excluding the debug instructions.
133static unsigned nonDbgMICount(MachineBasicBlock::const_instr_iterator MIB,
134 MachineBasicBlock::const_instr_iterator MIE) {
135 unsigned Count = 0;
136 for (; MIB != MIE; ++MIB) {
137 if (!MIB->isDebugValue())
138 ++Count;
139 }
140 return Count;
141}
142
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000143/// Find the hardware loop instruction used to set-up the specified loop.
144/// On Hexagon, we have two instructions used to set-up the hardware loop
145/// (LOOP0, LOOP1) with corresponding endloop (ENDLOOP0, ENDLOOP1) instructions
146/// to indicate the end of a loop.
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000147static MachineInstr *findLoopInstr(MachineBasicBlock *BB, unsigned EndLoopOp,
148 MachineBasicBlock *TargetBB,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000149 SmallPtrSet<MachineBasicBlock *, 8> &Visited) {
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000150 unsigned LOOPi;
151 unsigned LOOPr;
Brendon Cahoondf43e682015-05-08 16:16:29 +0000152 if (EndLoopOp == Hexagon::ENDLOOP0) {
153 LOOPi = Hexagon::J2_loop0i;
154 LOOPr = Hexagon::J2_loop0r;
155 } else { // EndLoopOp == Hexagon::EndLOOP1
156 LOOPi = Hexagon::J2_loop1i;
157 LOOPr = Hexagon::J2_loop1r;
158 }
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000159
Brendon Cahoondf43e682015-05-08 16:16:29 +0000160 // The loop set-up instruction will be in a predecessor block
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000161 for (MachineBasicBlock *PB : BB->predecessors()) {
Brendon Cahoondf43e682015-05-08 16:16:29 +0000162 // If this has been visited, already skip it.
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000163 if (!Visited.insert(PB).second)
Brendon Cahoondf43e682015-05-08 16:16:29 +0000164 continue;
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000165 if (PB == BB)
Brendon Cahoondf43e682015-05-08 16:16:29 +0000166 continue;
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000167 for (auto I = PB->instr_rbegin(), E = PB->instr_rend(); I != E; ++I) {
168 unsigned Opc = I->getOpcode();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000169 if (Opc == LOOPi || Opc == LOOPr)
170 return &*I;
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000171 // We've reached a different loop, which means the loop01 has been
172 // removed.
173 if (Opc == EndLoopOp && I->getOperand(0).getMBB() != TargetBB)
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +0000174 return nullptr;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000175 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000176 // Check the predecessors for the LOOP instruction.
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000177 if (MachineInstr *Loop = findLoopInstr(PB, EndLoopOp, TargetBB, Visited))
178 return Loop;
Brendon Cahoondf43e682015-05-08 16:16:29 +0000179 }
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +0000180 return nullptr;
Brendon Cahoondf43e682015-05-08 16:16:29 +0000181}
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000182
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000183/// Gather register def/uses from MI.
184/// This treats possible (predicated) defs as actually happening ones
185/// (conservatively).
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +0000186static inline void parseOperands(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000187 SmallVector<unsigned, 4> &Defs, SmallVector<unsigned, 8> &Uses) {
188 Defs.clear();
189 Uses.clear();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000190
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +0000191 for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
192 const MachineOperand &MO = MI.getOperand(i);
Brendon Cahoondf43e682015-05-08 16:16:29 +0000193
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000194 if (!MO.isReg())
195 continue;
Brendon Cahoondf43e682015-05-08 16:16:29 +0000196
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000197 unsigned Reg = MO.getReg();
198 if (!Reg)
199 continue;
200
201 if (MO.isUse())
202 Uses.push_back(MO.getReg());
203
204 if (MO.isDef())
205 Defs.push_back(MO.getReg());
206 }
207}
208
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000209// Position dependent, so check twice for swap.
210static bool isDuplexPairMatch(unsigned Ga, unsigned Gb) {
211 switch (Ga) {
212 case HexagonII::HSIG_None:
213 default:
214 return false;
215 case HexagonII::HSIG_L1:
216 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_A);
217 case HexagonII::HSIG_L2:
218 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
219 Gb == HexagonII::HSIG_A);
220 case HexagonII::HSIG_S1:
221 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
222 Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_A);
223 case HexagonII::HSIG_S2:
224 return (Gb == HexagonII::HSIG_L1 || Gb == HexagonII::HSIG_L2 ||
225 Gb == HexagonII::HSIG_S1 || Gb == HexagonII::HSIG_S2 ||
226 Gb == HexagonII::HSIG_A);
227 case HexagonII::HSIG_A:
228 return (Gb == HexagonII::HSIG_A);
229 case HexagonII::HSIG_Compound:
230 return (Gb == HexagonII::HSIG_Compound);
231 }
232 return false;
233}
234
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000235/// isLoadFromStackSlot - If the specified machine instruction is a direct
236/// load from a stack slot, return the virtual or physical register number of
237/// the destination along with the FrameIndex of the loaded stack slot. If
238/// not, return 0. This predicate must return 0 if the instruction has
239/// any side effects other than loading from the stack slot.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000240unsigned HexagonInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000241 int &FrameIndex) const {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000242 switch (MI.getOpcode()) {
243 default:
244 break;
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000245 case Hexagon::L2_loadri_io:
246 case Hexagon::L2_loadrd_io:
247 case Hexagon::V6_vL32b_ai:
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +0000248 case Hexagon::V6_vL32b_nt_ai:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000249 case Hexagon::V6_vL32Ub_ai:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000250 case Hexagon::LDriw_pred:
251 case Hexagon::LDriw_mod:
Krzysztof Parzyszek17aa4132016-08-16 15:43:54 +0000252 case Hexagon::PS_vloadrq_ai:
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +0000253 case Hexagon::PS_vloadrw_ai:
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000254 case Hexagon::PS_vloadrw_nt_ai: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000255 const MachineOperand OpFI = MI.getOperand(1);
256 if (!OpFI.isFI())
257 return 0;
258 const MachineOperand OpOff = MI.getOperand(2);
259 if (!OpOff.isImm() || OpOff.getImm() != 0)
260 return 0;
261 FrameIndex = OpFI.getIndex();
262 return MI.getOperand(0).getReg();
263 }
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +0000264
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000265 case Hexagon::L2_ploadrit_io:
266 case Hexagon::L2_ploadrif_io:
267 case Hexagon::L2_ploadrdt_io:
268 case Hexagon::L2_ploadrdf_io: {
269 const MachineOperand OpFI = MI.getOperand(2);
270 if (!OpFI.isFI())
271 return 0;
272 const MachineOperand OpOff = MI.getOperand(3);
273 if (!OpOff.isImm() || OpOff.getImm() != 0)
274 return 0;
275 FrameIndex = OpFI.getIndex();
276 return MI.getOperand(0).getReg();
277 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000278 }
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +0000279
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000280 return 0;
281}
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000282
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000283/// isStoreToStackSlot - If the specified machine instruction is a direct
284/// store to a stack slot, return the virtual or physical register number of
285/// the source reg along with the FrameIndex of the loaded stack slot. If
286/// not, return 0. This predicate must return 0 if the instruction has
287/// any side effects other than storing to the stack slot.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000288unsigned HexagonInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000289 int &FrameIndex) const {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000290 switch (MI.getOpcode()) {
291 default:
292 break;
293 case Hexagon::S2_storerb_io:
294 case Hexagon::S2_storerh_io:
295 case Hexagon::S2_storeri_io:
296 case Hexagon::S2_storerd_io:
297 case Hexagon::V6_vS32b_ai:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000298 case Hexagon::V6_vS32Ub_ai:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000299 case Hexagon::STriw_pred:
300 case Hexagon::STriw_mod:
Krzysztof Parzyszek17aa4132016-08-16 15:43:54 +0000301 case Hexagon::PS_vstorerq_ai:
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000302 case Hexagon::PS_vstorerw_ai: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000303 const MachineOperand &OpFI = MI.getOperand(0);
304 if (!OpFI.isFI())
305 return 0;
306 const MachineOperand &OpOff = MI.getOperand(1);
307 if (!OpOff.isImm() || OpOff.getImm() != 0)
308 return 0;
309 FrameIndex = OpFI.getIndex();
310 return MI.getOperand(2).getReg();
311 }
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +0000312
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000313 case Hexagon::S2_pstorerbt_io:
314 case Hexagon::S2_pstorerbf_io:
315 case Hexagon::S2_pstorerht_io:
316 case Hexagon::S2_pstorerhf_io:
317 case Hexagon::S2_pstorerit_io:
318 case Hexagon::S2_pstorerif_io:
319 case Hexagon::S2_pstorerdt_io:
320 case Hexagon::S2_pstorerdf_io: {
321 const MachineOperand &OpFI = MI.getOperand(1);
322 if (!OpFI.isFI())
323 return 0;
324 const MachineOperand &OpOff = MI.getOperand(2);
325 if (!OpOff.isImm() || OpOff.getImm() != 0)
326 return 0;
327 FrameIndex = OpFI.getIndex();
328 return MI.getOperand(3).getReg();
329 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000330 }
Krzysztof Parzyszekfeb65a32016-02-12 20:54:15 +0000331
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000332 return 0;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000333}
334
Brendon Cahoondf43e682015-05-08 16:16:29 +0000335/// This function can analyze one/two way branching only and should (mostly) be
336/// called by target independent side.
337/// First entry is always the opcode of the branching instruction, except when
338/// the Cond vector is supposed to be empty, e.g., when AnalyzeBranch fails, a
339/// BB with only unconditional jump. Subsequent entries depend upon the opcode,
340/// e.g. Jump_c p will have
341/// Cond[0] = Jump_c
342/// Cond[1] = p
343/// HW-loop ENDLOOP:
344/// Cond[0] = ENDLOOP
345/// Cond[1] = MBB
346/// New value jump:
347/// Cond[0] = Hexagon::CMPEQri_f_Jumpnv_t_V4 -- specific opcode
348/// Cond[1] = R
349/// Cond[2] = Imm
Jacques Pienaar71c30a12016-07-15 14:41:04 +0000350bool HexagonInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000351 MachineBasicBlock *&TBB,
Brendon Cahoondf43e682015-05-08 16:16:29 +0000352 MachineBasicBlock *&FBB,
353 SmallVectorImpl<MachineOperand> &Cond,
354 bool AllowModify) const {
Craig Topper062a2ba2014-04-25 05:30:21 +0000355 TBB = nullptr;
356 FBB = nullptr;
Brendon Cahoondf43e682015-05-08 16:16:29 +0000357 Cond.clear();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000358
359 // If the block has no terminators, it just falls into the block after it.
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000360 MachineBasicBlock::instr_iterator I = MBB.instr_end();
361 if (I == MBB.instr_begin())
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000362 return false;
363
364 // A basic block may looks like this:
365 //
366 // [ insn
367 // EH_LABEL
368 // insn
369 // insn
370 // insn
371 // EH_LABEL
372 // insn ]
373 //
374 // It has two succs but does not have a terminator
375 // Don't know how to handle it.
376 do {
377 --I;
378 if (I->isEHLabel())
Brendon Cahoondf43e682015-05-08 16:16:29 +0000379 // Don't analyze EH branches.
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000380 return true;
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000381 } while (I != MBB.instr_begin());
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000382
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000383 I = MBB.instr_end();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000384 --I;
385
386 while (I->isDebugValue()) {
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000387 if (I == MBB.instr_begin())
388 return false;
389 --I;
390 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000391
Colin LeMahieu7b1799c2015-03-09 22:05:21 +0000392 bool JumpToBlock = I->getOpcode() == Hexagon::J2_jump &&
393 I->getOperand(0).isMBB();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000394 // Delete the J2_jump if it's equivalent to a fall-through.
Colin LeMahieu7b1799c2015-03-09 22:05:21 +0000395 if (AllowModify && JumpToBlock &&
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000396 MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +0000397 DEBUG(dbgs() << "\nErasing the jump to successor block\n";);
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000398 I->eraseFromParent();
399 I = MBB.instr_end();
400 if (I == MBB.instr_begin())
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000401 return false;
402 --I;
403 }
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +0000404 if (!isUnpredicatedTerminator(*I))
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000405 return false;
406
407 // Get the last instruction in the block.
Duncan P. N. Exon Smitha72c6e22015-10-20 00:46:39 +0000408 MachineInstr *LastInst = &*I;
Craig Topper062a2ba2014-04-25 05:30:21 +0000409 MachineInstr *SecondLastInst = nullptr;
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000410 // Find one more terminator if present.
Eugene Zelenkob2ca1b32017-01-04 02:02:05 +0000411 while (true) {
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +0000412 if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000413 if (!SecondLastInst)
Duncan P. N. Exon Smitha72c6e22015-10-20 00:46:39 +0000414 SecondLastInst = &*I;
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000415 else
416 // This is a third branch.
417 return true;
418 }
419 if (I == MBB.instr_begin())
420 break;
421 --I;
Duncan P. N. Exon Smitha72c6e22015-10-20 00:46:39 +0000422 }
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000423
424 int LastOpcode = LastInst->getOpcode();
Colin LeMahieu7b1799c2015-03-09 22:05:21 +0000425 int SecLastOpcode = SecondLastInst ? SecondLastInst->getOpcode() : 0;
426 // If the branch target is not a basic block, it could be a tail call.
427 // (It is, if the target is a function.)
428 if (LastOpcode == Hexagon::J2_jump && !LastInst->getOperand(0).isMBB())
429 return true;
430 if (SecLastOpcode == Hexagon::J2_jump &&
431 !SecondLastInst->getOperand(0).isMBB())
432 return true;
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000433
434 bool LastOpcodeHasJMP_c = PredOpcodeHasJMP_c(LastOpcode);
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +0000435 bool LastOpcodeHasNVJump = isNewValueJump(*LastInst);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000436
Krzysztof Parzyszekb28ae102016-01-14 15:05:27 +0000437 if (LastOpcodeHasJMP_c && !LastInst->getOperand(1).isMBB())
438 return true;
439
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000440 // If there is only one terminator instruction, process it.
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000441 if (LastInst && !SecondLastInst) {
Colin LeMahieudb0b13c2014-12-10 21:24:10 +0000442 if (LastOpcode == Hexagon::J2_jump) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000443 TBB = LastInst->getOperand(0).getMBB();
444 return false;
445 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000446 if (isEndLoopN(LastOpcode)) {
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000447 TBB = LastInst->getOperand(0).getMBB();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000448 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000449 Cond.push_back(LastInst->getOperand(0));
450 return false;
451 }
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000452 if (LastOpcodeHasJMP_c) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000453 TBB = LastInst->getOperand(1).getMBB();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000454 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000455 Cond.push_back(LastInst->getOperand(0));
456 return false;
457 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000458 // Only supporting rr/ri versions of new-value jumps.
459 if (LastOpcodeHasNVJump && (LastInst->getNumExplicitOperands() == 3)) {
460 TBB = LastInst->getOperand(2).getMBB();
461 Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode()));
462 Cond.push_back(LastInst->getOperand(0));
463 Cond.push_back(LastInst->getOperand(1));
464 return false;
465 }
Francis Visoiu Mistrih25528d62017-12-04 17:18:51 +0000466 DEBUG(dbgs() << "\nCant analyze " << printMBBReference(MBB)
Brendon Cahoondf43e682015-05-08 16:16:29 +0000467 << " with one jump\n";);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000468 // Otherwise, don't know what this is.
469 return true;
470 }
471
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000472 bool SecLastOpcodeHasJMP_c = PredOpcodeHasJMP_c(SecLastOpcode);
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +0000473 bool SecLastOpcodeHasNVJump = isNewValueJump(*SecondLastInst);
Colin LeMahieudb0b13c2014-12-10 21:24:10 +0000474 if (SecLastOpcodeHasJMP_c && (LastOpcode == Hexagon::J2_jump)) {
Krzysztof Parzyszekb28ae102016-01-14 15:05:27 +0000475 if (!SecondLastInst->getOperand(1).isMBB())
476 return true;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000477 TBB = SecondLastInst->getOperand(1).getMBB();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000478 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000479 Cond.push_back(SecondLastInst->getOperand(0));
480 FBB = LastInst->getOperand(0).getMBB();
481 return false;
482 }
483
Brendon Cahoondf43e682015-05-08 16:16:29 +0000484 // Only supporting rr/ri versions of new-value jumps.
485 if (SecLastOpcodeHasNVJump &&
486 (SecondLastInst->getNumExplicitOperands() == 3) &&
487 (LastOpcode == Hexagon::J2_jump)) {
488 TBB = SecondLastInst->getOperand(2).getMBB();
489 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
490 Cond.push_back(SecondLastInst->getOperand(0));
491 Cond.push_back(SecondLastInst->getOperand(1));
492 FBB = LastInst->getOperand(0).getMBB();
493 return false;
494 }
495
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000496 // If the block ends with two Hexagon:JMPs, handle it. The second one is not
497 // executed, so remove it.
Colin LeMahieudb0b13c2014-12-10 21:24:10 +0000498 if (SecLastOpcode == Hexagon::J2_jump && LastOpcode == Hexagon::J2_jump) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000499 TBB = SecondLastInst->getOperand(0).getMBB();
Duncan P. N. Exon Smithc5b668d2016-02-22 20:49:58 +0000500 I = LastInst->getIterator();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000501 if (AllowModify)
502 I->eraseFromParent();
503 return false;
504 }
505
Brendon Cahoondf43e682015-05-08 16:16:29 +0000506 // If the block ends with an ENDLOOP, and J2_jump, handle it.
507 if (isEndLoopN(SecLastOpcode) && LastOpcode == Hexagon::J2_jump) {
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000508 TBB = SecondLastInst->getOperand(0).getMBB();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000509 Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode()));
Jyotsna Verma5ed51812013-05-01 21:37:34 +0000510 Cond.push_back(SecondLastInst->getOperand(0));
511 FBB = LastInst->getOperand(0).getMBB();
512 return false;
513 }
Francis Visoiu Mistrih25528d62017-12-04 17:18:51 +0000514 DEBUG(dbgs() << "\nCant analyze " << printMBBReference(MBB)
Brendon Cahoondf43e682015-05-08 16:16:29 +0000515 << " with two jumps";);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000516 // Otherwise, can't handle this.
517 return true;
518}
519
Matt Arsenault1b9fc8e2016-09-14 20:43:16 +0000520unsigned HexagonInstrInfo::removeBranch(MachineBasicBlock &MBB,
Matt Arsenaulta2b036e2016-09-14 17:23:48 +0000521 int *BytesRemoved) const {
522 assert(!BytesRemoved && "code size not handled");
523
Francis Visoiu Mistrih25528d62017-12-04 17:18:51 +0000524 DEBUG(dbgs() << "\nRemoving branches out of " << printMBBReference(MBB));
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000525 MachineBasicBlock::iterator I = MBB.end();
Brendon Cahoondf43e682015-05-08 16:16:29 +0000526 unsigned Count = 0;
527 while (I != MBB.begin()) {
528 --I;
529 if (I->isDebugValue())
530 continue;
531 // Only removing branches from end of MBB.
532 if (!I->isBranch())
533 return Count;
534 if (Count && (I->getOpcode() == Hexagon::J2_jump))
535 llvm_unreachable("Malformed basic block: unconditional branch not last");
536 MBB.erase(&MBB.back());
537 I = MBB.end();
538 ++Count;
Krzysztof Parzyszek78cc36f2015-03-18 15:56:43 +0000539 }
Brendon Cahoondf43e682015-05-08 16:16:29 +0000540 return Count;
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000541}
542
Matt Arsenaulte8e0f5c2016-09-14 17:24:15 +0000543unsigned HexagonInstrInfo::insertBranch(MachineBasicBlock &MBB,
Benjamin Kramerbdc49562016-06-12 15:39:02 +0000544 MachineBasicBlock *TBB,
545 MachineBasicBlock *FBB,
546 ArrayRef<MachineOperand> Cond,
Matt Arsenaulta2b036e2016-09-14 17:23:48 +0000547 const DebugLoc &DL,
548 int *BytesAdded) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000549 unsigned BOpc = Hexagon::J2_jump;
550 unsigned BccOpc = Hexagon::J2_jumpt;
551 assert(validateBranchCond(Cond) && "Invalid branching condition");
Matt Arsenaulte8e0f5c2016-09-14 17:24:15 +0000552 assert(TBB && "insertBranch must not be told to insert a fallthrough");
Matt Arsenaulta2b036e2016-09-14 17:23:48 +0000553 assert(!BytesAdded && "code size not handled");
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000554
Matt Arsenault1b9fc8e2016-09-14 20:43:16 +0000555 // Check if reverseBranchCondition has asked to reverse this branch
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000556 // If we want to reverse the branch an odd number of times, we want
557 // J2_jumpf.
558 if (!Cond.empty() && Cond[0].isImm())
559 BccOpc = Cond[0].getImm();
560
561 if (!FBB) {
562 if (Cond.empty()) {
563 // Due to a bug in TailMerging/CFG Optimization, we need to add a
564 // special case handling of a predicated jump followed by an
565 // unconditional jump. If not, Tail Merging and CFG Optimization go
566 // into an infinite loop.
567 MachineBasicBlock *NewTBB, *NewFBB;
568 SmallVector<MachineOperand, 4> Cond;
Duncan P. N. Exon Smith25b132e2016-07-08 18:26:20 +0000569 auto Term = MBB.getFirstTerminator();
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +0000570 if (Term != MBB.end() && isPredicated(*Term) &&
Duncan P. N. Exon Smithe04fe1a2016-08-17 00:34:00 +0000571 !analyzeBranch(MBB, NewTBB, NewFBB, Cond, false) &&
572 MachineFunction::iterator(NewTBB) == ++MBB.getIterator()) {
Matt Arsenault1b9fc8e2016-09-14 20:43:16 +0000573 reverseBranchCondition(Cond);
574 removeBranch(MBB);
Matt Arsenaulte8e0f5c2016-09-14 17:24:15 +0000575 return insertBranch(MBB, TBB, nullptr, Cond, DL);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000576 }
577 BuildMI(&MBB, DL, get(BOpc)).addMBB(TBB);
578 } else if (isEndLoopN(Cond[0].getImm())) {
579 int EndLoopOp = Cond[0].getImm();
580 assert(Cond[1].isMBB());
581 // Since we're adding an ENDLOOP, there better be a LOOP instruction.
582 // Check for it, and change the BB target if needed.
583 SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000584 MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),
585 VisitedBBs);
Eugene Zelenko3b873362017-09-28 22:27:31 +0000586 assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000587 Loop->getOperand(0).setMBB(TBB);
588 // Add the ENDLOOP after the finding the LOOP0.
589 BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
590 } else if (isNewValueJump(Cond[0].getImm())) {
591 assert((Cond.size() == 3) && "Only supporting rr/ri version of nvjump");
592 // New value jump
593 // (ins IntRegs:$src1, IntRegs:$src2, brtarget:$offset)
594 // (ins IntRegs:$src1, u5Imm:$src2, brtarget:$offset)
595 unsigned Flags1 = getUndefRegState(Cond[1].isUndef());
Francis Visoiu Mistrih25528d62017-12-04 17:18:51 +0000596 DEBUG(dbgs() << "\nInserting NVJump for " << printMBBReference(MBB););
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000597 if (Cond[2].isReg()) {
598 unsigned Flags2 = getUndefRegState(Cond[2].isUndef());
599 BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).
600 addReg(Cond[2].getReg(), Flags2).addMBB(TBB);
601 } else if(Cond[2].isImm()) {
602 BuildMI(&MBB, DL, get(BccOpc)).addReg(Cond[1].getReg(), Flags1).
603 addImm(Cond[2].getImm()).addMBB(TBB);
604 } else
605 llvm_unreachable("Invalid condition for branching");
606 } else {
607 assert((Cond.size() == 2) && "Malformed cond vector");
608 const MachineOperand &RO = Cond[1];
609 unsigned Flags = getUndefRegState(RO.isUndef());
610 BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);
611 }
612 return 1;
Krzysztof Parzyszekcfe285e2013-02-11 20:04:29 +0000613 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000614 assert((!Cond.empty()) &&
615 "Cond. cannot be empty when multiple branchings are required");
616 assert((!isNewValueJump(Cond[0].getImm())) &&
617 "NV-jump cannot be inserted with another branch");
618 // Special case for hardware loops. The condition is a basic block.
619 if (isEndLoopN(Cond[0].getImm())) {
620 int EndLoopOp = Cond[0].getImm();
621 assert(Cond[1].isMBB());
622 // Since we're adding an ENDLOOP, there better be a LOOP instruction.
623 // Check for it, and change the BB target if needed.
624 SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000625 MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),
626 VisitedBBs);
Eugene Zelenko3b873362017-09-28 22:27:31 +0000627 assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000628 Loop->getOperand(0).setMBB(TBB);
629 // Add the ENDLOOP after the finding the LOOP0.
630 BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
631 } else {
632 const MachineOperand &RO = Cond[1];
633 unsigned Flags = getUndefRegState(RO.isUndef());
634 BuildMI(&MBB, DL, get(BccOpc)).addReg(RO.getReg(), Flags).addMBB(TBB);
Krzysztof Parzyszekcfe285e2013-02-11 20:04:29 +0000635 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000636 BuildMI(&MBB, DL, get(BOpc)).addMBB(FBB);
Krzysztof Parzyszekcfe285e2013-02-11 20:04:29 +0000637
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000638 return 2;
639}
640
Brendon Cahoon254f8892016-07-29 16:44:44 +0000641/// Analyze the loop code to find the loop induction variable and compare used
642/// to compute the number of iterations. Currently, we analyze loop that are
643/// controlled using hardware loops. In this case, the induction variable
644/// instruction is null. For all other cases, this function returns true, which
645/// means we're unable to analyze it.
646bool HexagonInstrInfo::analyzeLoop(MachineLoop &L,
647 MachineInstr *&IndVarInst,
648 MachineInstr *&CmpInst) const {
649
650 MachineBasicBlock *LoopEnd = L.getBottomBlock();
651 MachineBasicBlock::iterator I = LoopEnd->getFirstTerminator();
652 // We really "analyze" only hardware loops right now.
653 if (I != LoopEnd->end() && isEndLoopN(I->getOpcode())) {
654 IndVarInst = nullptr;
655 CmpInst = &*I;
656 return false;
657 }
658 return true;
659}
660
661/// Generate code to reduce the loop iteration by one and check if the loop is
662/// finished. Return the value/register of the new loop count. this function
663/// assumes the nth iteration is peeled first.
664unsigned HexagonInstrInfo::reduceLoopCount(MachineBasicBlock &MBB,
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +0000665 MachineInstr *IndVar, MachineInstr &Cmp,
Brendon Cahoon254f8892016-07-29 16:44:44 +0000666 SmallVectorImpl<MachineOperand> &Cond,
667 SmallVectorImpl<MachineInstr *> &PrevInsts,
668 unsigned Iter, unsigned MaxIter) const {
669 // We expect a hardware loop currently. This means that IndVar is set
670 // to null, and the compare is the ENDLOOP instruction.
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +0000671 assert((!IndVar) && isEndLoopN(Cmp.getOpcode())
Brendon Cahoon254f8892016-07-29 16:44:44 +0000672 && "Expecting a hardware loop");
673 MachineFunction *MF = MBB.getParent();
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +0000674 DebugLoc DL = Cmp.getDebugLoc();
Brendon Cahoon254f8892016-07-29 16:44:44 +0000675 SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
Krzysztof Parzyszekd67ab622017-02-02 19:36:37 +0000676 MachineInstr *Loop = findLoopInstr(&MBB, Cmp.getOpcode(),
677 Cmp.getOperand(0).getMBB(), VisitedBBs);
Brendon Cahoon254f8892016-07-29 16:44:44 +0000678 if (!Loop)
679 return 0;
680 // If the loop trip count is a compile-time value, then just change the
681 // value.
682 if (Loop->getOpcode() == Hexagon::J2_loop0i ||
683 Loop->getOpcode() == Hexagon::J2_loop1i) {
684 int64_t Offset = Loop->getOperand(1).getImm();
685 if (Offset <= 1)
686 Loop->eraseFromParent();
687 else
688 Loop->getOperand(1).setImm(Offset - 1);
689 return Offset - 1;
690 }
691 // The loop trip count is a run-time value. We generate code to subtract
692 // one from the trip count, and update the loop instruction.
693 assert(Loop->getOpcode() == Hexagon::J2_loop0r && "Unexpected instruction");
694 unsigned LoopCount = Loop->getOperand(1).getReg();
695 // Check if we're done with the loop.
696 unsigned LoopEnd = createVR(MF, MVT::i1);
697 MachineInstr *NewCmp = BuildMI(&MBB, DL, get(Hexagon::C2_cmpgtui), LoopEnd).
698 addReg(LoopCount).addImm(1);
699 unsigned NewLoopCount = createVR(MF, MVT::i32);
700 MachineInstr *NewAdd = BuildMI(&MBB, DL, get(Hexagon::A2_addi), NewLoopCount).
701 addReg(LoopCount).addImm(-1);
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +0000702 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
Brendon Cahoon254f8892016-07-29 16:44:44 +0000703 // Update the previously generated instructions with the new loop counter.
704 for (SmallVectorImpl<MachineInstr *>::iterator I = PrevInsts.begin(),
705 E = PrevInsts.end(); I != E; ++I)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000706 (*I)->substituteRegister(LoopCount, NewLoopCount, 0, HRI);
Brendon Cahoon254f8892016-07-29 16:44:44 +0000707 PrevInsts.clear();
708 PrevInsts.push_back(NewCmp);
709 PrevInsts.push_back(NewAdd);
710 // Insert the new loop instruction if this is the last time the loop is
711 // decremented.
712 if (Iter == MaxIter)
713 BuildMI(&MBB, DL, get(Hexagon::J2_loop0r)).
714 addMBB(Loop->getOperand(0).getMBB()).addReg(NewLoopCount);
715 // Delete the old loop instruction.
716 if (Iter == 0)
717 Loop->eraseFromParent();
718 Cond.push_back(MachineOperand::CreateImm(Hexagon::J2_jumpf));
719 Cond.push_back(NewCmp->getOperand(0));
720 return NewLoopCount;
721}
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000722
723bool HexagonInstrInfo::isProfitableToIfCvt(MachineBasicBlock &MBB,
724 unsigned NumCycles, unsigned ExtraPredCycles,
725 BranchProbability Probability) const {
726 return nonDbgBBSize(&MBB) <= 3;
727}
728
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000729bool HexagonInstrInfo::isProfitableToIfCvt(MachineBasicBlock &TMBB,
730 unsigned NumTCycles, unsigned ExtraTCycles, MachineBasicBlock &FMBB,
731 unsigned NumFCycles, unsigned ExtraFCycles, BranchProbability Probability)
732 const {
733 return nonDbgBBSize(&TMBB) <= 3 && nonDbgBBSize(&FMBB) <= 3;
734}
735
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000736bool HexagonInstrInfo::isProfitableToDupForIfCvt(MachineBasicBlock &MBB,
737 unsigned NumInstrs, BranchProbability Probability) const {
738 return NumInstrs <= 4;
Krzysztof Parzyszekcfe285e2013-02-11 20:04:29 +0000739}
740
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000741void HexagonInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
Benjamin Kramerbdc49562016-06-12 15:39:02 +0000742 MachineBasicBlock::iterator I,
743 const DebugLoc &DL, unsigned DestReg,
744 unsigned SrcReg, bool KillSrc) const {
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +0000745 const HexagonRegisterInfo &HRI = *Subtarget.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.
Francis Visoiu Mistrih25528d62017-12-04 17:18:51 +0000832 dbgs() << "Invalid registers for copy in " << printMBBReference(MBB) << ": "
833 << printReg(DestReg, &HRI) << " = " << printReg(SrcReg, &HRI) << '\n';
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000834#endif
Sirish Pande30804c22012-02-15 18:52:27 +0000835 llvm_unreachable("Unimplemented");
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000836}
837
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000838void HexagonInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
839 MachineBasicBlock::iterator I, unsigned SrcReg, bool isKill, int FI,
840 const TargetRegisterClass *RC, const TargetRegisterInfo *TRI) const {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000841 DebugLoc DL = MBB.findDebugLoc(I);
842 MachineFunction &MF = *MBB.getParent();
Matthias Braun941a7052016-07-28 18:40:00 +0000843 MachineFrameInfo &MFI = MF.getFrameInfo();
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000844 unsigned SlotAlign = MFI.getObjectAlignment(FI);
845 unsigned RegAlign = TRI->getSpillAlignment(*RC);
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000846 unsigned KillFlag = getKillRegState(isKill);
Krzysztof Parzyszek781324f2017-05-03 15:23:53 +0000847 bool HasAlloca = MFI.hasVarSizedObjects();
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +0000848 const HexagonFrameLowering &HFI = *Subtarget.getFrameLowering();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000849
Alex Lorenze40c8a22015-08-11 23:09:45 +0000850 MachineMemOperand *MMO = MF.getMachineMemOperand(
851 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000852 MFI.getObjectSize(FI), SlotAlign);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000853
Craig Topperc7242e02012-04-20 07:30:17 +0000854 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {
Colin LeMahieubda31b42014-12-29 20:44:51 +0000855 BuildMI(MBB, I, DL, get(Hexagon::S2_storeri_io))
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000856 .addFrameIndex(FI).addImm(0)
857 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
Craig Topperc7242e02012-04-20 07:30:17 +0000858 } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {
Colin LeMahieubda31b42014-12-29 20:44:51 +0000859 BuildMI(MBB, I, DL, get(Hexagon::S2_storerd_io))
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000860 .addFrameIndex(FI).addImm(0)
861 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
Craig Topperc7242e02012-04-20 07:30:17 +0000862 } else if (Hexagon::PredRegsRegClass.hasSubClassEq(RC)) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000863 BuildMI(MBB, I, DL, get(Hexagon::STriw_pred))
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000864 .addFrameIndex(FI).addImm(0)
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000865 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000866 } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {
867 BuildMI(MBB, I, DL, get(Hexagon::STriw_mod))
868 .addFrameIndex(FI).addImm(0)
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000869 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000870 } else if (Hexagon::HvxQRRegClass.hasSubClassEq(RC)) {
Krzysztof Parzyszek17aa4132016-08-16 15:43:54 +0000871 BuildMI(MBB, I, DL, get(Hexagon::PS_vstorerq_ai))
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000872 .addFrameIndex(FI).addImm(0)
873 .addReg(SrcReg, KillFlag).addMemOperand(MMO);
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000874 } else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {
Krzysztof Parzyszek781324f2017-05-03 15:23:53 +0000875 // If there are variable-sized objects, spills will not be aligned.
876 if (HasAlloca)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000877 SlotAlign = HFI.getStackAlignment();
878 unsigned Opc = SlotAlign < RegAlign ? Hexagon::V6_vS32Ub_ai
879 : Hexagon::V6_vS32b_ai;
880 MachineMemOperand *MMOA = MF.getMachineMemOperand(
881 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
882 MFI.getObjectSize(FI), SlotAlign);
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +0000883 BuildMI(MBB, I, DL, get(Opc))
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000884 .addFrameIndex(FI).addImm(0)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000885 .addReg(SrcReg, KillFlag).addMemOperand(MMOA);
886 } else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {
Krzysztof Parzyszek781324f2017-05-03 15:23:53 +0000887 // If there are variable-sized objects, spills will not be aligned.
888 if (HasAlloca)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000889 SlotAlign = HFI.getStackAlignment();
890 unsigned Opc = SlotAlign < RegAlign ? Hexagon::PS_vstorerwu_ai
891 : Hexagon::PS_vstorerw_ai;
892 MachineMemOperand *MMOA = MF.getMachineMemOperand(
893 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
894 MFI.getObjectSize(FI), SlotAlign);
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +0000895 BuildMI(MBB, I, DL, get(Opc))
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000896 .addFrameIndex(FI).addImm(0)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000897 .addReg(SrcReg, KillFlag).addMemOperand(MMOA);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000898 } else {
Craig Toppere55c5562012-02-07 02:50:20 +0000899 llvm_unreachable("Unimplemented");
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000900 }
901}
902
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000903void HexagonInstrInfo::loadRegFromStackSlot(
904 MachineBasicBlock &MBB, MachineBasicBlock::iterator I, unsigned DestReg,
905 int FI, const TargetRegisterClass *RC,
906 const TargetRegisterInfo *TRI) const {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000907 DebugLoc DL = MBB.findDebugLoc(I);
908 MachineFunction &MF = *MBB.getParent();
Matthias Braun941a7052016-07-28 18:40:00 +0000909 MachineFrameInfo &MFI = MF.getFrameInfo();
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000910 unsigned SlotAlign = MFI.getObjectAlignment(FI);
911 unsigned RegAlign = TRI->getSpillAlignment(*RC);
Krzysztof Parzyszek781324f2017-05-03 15:23:53 +0000912 bool HasAlloca = MFI.hasVarSizedObjects();
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +0000913 const HexagonFrameLowering &HFI = *Subtarget.getFrameLowering();
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000914
Alex Lorenze40c8a22015-08-11 23:09:45 +0000915 MachineMemOperand *MMO = MF.getMachineMemOperand(
916 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000917 MFI.getObjectSize(FI), SlotAlign);
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000918
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000919 if (Hexagon::IntRegsRegClass.hasSubClassEq(RC)) {
Colin LeMahieu026e88d2014-12-23 20:02:16 +0000920 BuildMI(MBB, I, DL, get(Hexagon::L2_loadri_io), DestReg)
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000921 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000922 } else if (Hexagon::DoubleRegsRegClass.hasSubClassEq(RC)) {
Colin LeMahieu947cd702014-12-23 20:44:59 +0000923 BuildMI(MBB, I, DL, get(Hexagon::L2_loadrd_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::PredRegsRegClass.hasSubClassEq(RC)) {
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000926 BuildMI(MBB, I, DL, get(Hexagon::LDriw_pred), DestReg)
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +0000927 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
928 } else if (Hexagon::ModRegsRegClass.hasSubClassEq(RC)) {
929 BuildMI(MBB, I, DL, get(Hexagon::LDriw_mod), DestReg)
930 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000931 } else if (Hexagon::HvxQRRegClass.hasSubClassEq(RC)) {
Krzysztof Parzyszek17aa4132016-08-16 15:43:54 +0000932 BuildMI(MBB, I, DL, get(Hexagon::PS_vloadrq_ai), DestReg)
Krzysztof Parzyszek79a886b2016-02-12 21:56:41 +0000933 .addFrameIndex(FI).addImm(0).addMemOperand(MMO);
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000934 } else if (Hexagon::HvxVRRegClass.hasSubClassEq(RC)) {
Krzysztof Parzyszek781324f2017-05-03 15:23:53 +0000935 // If there are variable-sized objects, spills will not be aligned.
936 if (HasAlloca)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000937 SlotAlign = HFI.getStackAlignment();
938 unsigned Opc = SlotAlign < RegAlign ? Hexagon::V6_vL32Ub_ai
939 : Hexagon::V6_vL32b_ai;
940 MachineMemOperand *MMOA = MF.getMachineMemOperand(
941 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
942 MFI.getObjectSize(FI), SlotAlign);
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +0000943 BuildMI(MBB, I, DL, get(Opc), DestReg)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000944 .addFrameIndex(FI).addImm(0).addMemOperand(MMOA);
945 } else if (Hexagon::HvxWRRegClass.hasSubClassEq(RC)) {
Krzysztof Parzyszek781324f2017-05-03 15:23:53 +0000946 // If there are variable-sized objects, spills will not be aligned.
947 if (HasAlloca)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000948 SlotAlign = HFI.getStackAlignment();
949 unsigned Opc = SlotAlign < RegAlign ? Hexagon::PS_vloadrwu_ai
950 : Hexagon::PS_vloadrw_ai;
951 MachineMemOperand *MMOA = MF.getMachineMemOperand(
952 MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
953 MFI.getObjectSize(FI), SlotAlign);
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +0000954 BuildMI(MBB, I, DL, get(Opc), DestReg)
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000955 .addFrameIndex(FI).addImm(0).addMemOperand(MMOA);
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000956 } else {
Craig Toppere55c5562012-02-07 02:50:20 +0000957 llvm_unreachable("Can't store this register to stack slot");
Tony Linthicum1213a7a2011-12-12 21:14:40 +0000958 }
959}
960
Ron Lieberman88159e52016-09-02 22:56:24 +0000961static void getLiveRegsAt(LivePhysRegs &Regs, const MachineInstr &MI) {
962 const MachineBasicBlock &B = *MI.getParent();
963 Regs.addLiveOuts(B);
Duncan P. N. Exon Smith18720962016-09-11 18:51:28 +0000964 auto E = ++MachineBasicBlock::const_iterator(MI.getIterator()).getReverse();
Ron Lieberman88159e52016-09-02 22:56:24 +0000965 for (auto I = B.rbegin(); I != E; ++I)
966 Regs.stepBackward(*I);
967}
968
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +0000969/// expandPostRAPseudo - This function is called for all pseudo instructions
970/// that remain after register allocation. Many pseudo instructions are
971/// created to help register allocation. This is the place to convert them
972/// into real instructions. The target can edit MI in place, or it can insert
973/// new instructions and erase MI. The function should return true if
974/// anything was changed.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000975bool HexagonInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000976 MachineBasicBlock &MBB = *MI.getParent();
Krzysztof Parzyszek55772972017-09-15 15:46:05 +0000977 MachineFunction &MF = *MBB.getParent();
978 MachineRegisterInfo &MRI = MF.getRegInfo();
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +0000979 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000980 DebugLoc DL = MI.getDebugLoc();
981 unsigned Opc = MI.getOpcode();
Colin LeMahieu7b1799c2015-03-09 22:05:21 +0000982
983 switch (Opc) {
Krzysztof Parzyszek3d6fc832016-06-02 14:33:08 +0000984 case TargetOpcode::COPY: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000985 MachineOperand &MD = MI.getOperand(0);
986 MachineOperand &MS = MI.getOperand(1);
987 MachineBasicBlock::iterator MBBI = MI.getIterator();
Krzysztof Parzyszek3d6fc832016-06-02 14:33:08 +0000988 if (MD.getReg() != MS.getReg() && !MS.isUndef()) {
989 copyPhysReg(MBB, MI, DL, MD.getReg(), MS.getReg(), MS.isKill());
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000990 std::prev(MBBI)->copyImplicitOps(*MBB.getParent(), MI);
Krzysztof Parzyszek3d6fc832016-06-02 14:33:08 +0000991 }
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000992 MBB.erase(MBBI);
Krzysztof Parzyszek3d6fc832016-06-02 14:33:08 +0000993 return true;
994 }
Krzysztof Parzyszek1d01a792016-08-16 18:08:40 +0000995 case Hexagon::PS_aligna:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000996 BuildMI(MBB, MI, DL, get(Hexagon::A2_andir), MI.getOperand(0).getReg())
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +0000997 .addReg(HRI.getFrameRegister())
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +0000998 .addImm(-MI.getOperand(1).getImm());
Krzysztof Parzyszek4fa2a9f2015-04-22 16:43:53 +0000999 MBB.erase(MI);
1000 return true;
Krzysztof Parzyszekeabc0d02016-08-16 17:14:44 +00001001 case Hexagon::V6_vassignp: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001002 unsigned SrcReg = MI.getOperand(1).getReg();
1003 unsigned DstReg = MI.getOperand(0).getReg();
Krzysztof Parzyszekeabc0d02016-08-16 17:14:44 +00001004 unsigned Kill = getKillRegState(MI.getOperand(1).isKill());
1005 BuildMI(MBB, MI, DL, get(Hexagon::V6_vcombine), DstReg)
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001006 .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_hi), Kill)
1007 .addReg(HRI.getSubReg(SrcReg, Hexagon::vsub_lo), Kill);
Krzysztof Parzyszek4eb6d4d2015-11-26 16:54:33 +00001008 MBB.erase(MI);
1009 return true;
1010 }
Krzysztof Parzyszekeabc0d02016-08-16 17:14:44 +00001011 case Hexagon::V6_lo: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001012 unsigned SrcReg = MI.getOperand(1).getReg();
1013 unsigned DstReg = MI.getOperand(0).getReg();
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001014 unsigned SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001015 copyPhysReg(MBB, MI, DL, DstReg, SrcSubLo, MI.getOperand(1).isKill());
Krzysztof Parzyszek4eb6d4d2015-11-26 16:54:33 +00001016 MBB.erase(MI);
1017 MRI.clearKillFlags(SrcSubLo);
1018 return true;
1019 }
Krzysztof Parzyszekeabc0d02016-08-16 17:14:44 +00001020 case Hexagon::V6_hi: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001021 unsigned SrcReg = MI.getOperand(1).getReg();
1022 unsigned DstReg = MI.getOperand(0).getReg();
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001023 unsigned SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001024 copyPhysReg(MBB, MI, DL, DstReg, SrcSubHi, MI.getOperand(1).isKill());
Krzysztof Parzyszek4eb6d4d2015-11-26 16:54:33 +00001025 MBB.erase(MI);
1026 MRI.clearKillFlags(SrcSubHi);
1027 return true;
1028 }
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +00001029 case Hexagon::PS_vstorerw_ai:
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00001030 case Hexagon::PS_vstorerwu_ai: {
1031 bool Aligned = Opc == Hexagon::PS_vstorerw_ai;
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001032 unsigned SrcReg = MI.getOperand(2).getReg();
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001033 unsigned SrcSubHi = HRI.getSubReg(SrcReg, Hexagon::vsub_hi);
1034 unsigned SrcSubLo = HRI.getSubReg(SrcReg, Hexagon::vsub_lo);
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00001035 unsigned NewOpc = Aligned ? Hexagon::V6_vS32b_ai : Hexagon::V6_vS32Ub_ai;
1036 unsigned Offset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +00001037
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001038 MachineInstr *MI1New =
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +00001039 BuildMI(MBB, MI, DL, get(NewOpc))
Diana Picus116bbab2017-01-13 09:58:52 +00001040 .add(MI.getOperand(0))
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001041 .addImm(MI.getOperand(1).getImm())
1042 .addReg(SrcSubLo)
1043 .setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
Krzysztof Parzyszek195dc8d2015-11-26 04:33:11 +00001044 MI1New->getOperand(0).setIsKill(false);
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +00001045 BuildMI(MBB, MI, DL, get(NewOpc))
Diana Picus116bbab2017-01-13 09:58:52 +00001046 .add(MI.getOperand(0))
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001047 // The Vectors are indexed in multiples of vector size.
1048 .addImm(MI.getOperand(1).getImm() + Offset)
1049 .addReg(SrcSubHi)
1050 .setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
Krzysztof Parzyszek195dc8d2015-11-26 04:33:11 +00001051 MBB.erase(MI);
1052 return true;
1053 }
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +00001054 case Hexagon::PS_vloadrw_ai:
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00001055 case Hexagon::PS_vloadrwu_ai: {
1056 bool Aligned = Opc == Hexagon::PS_vloadrw_ai;
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001057 unsigned DstReg = MI.getOperand(0).getReg();
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00001058 unsigned NewOpc = Aligned ? Hexagon::V6_vL32b_ai : Hexagon::V6_vL32Ub_ai;
1059 unsigned Offset = HRI.getSpillSize(Hexagon::HvxVRRegClass);
1060
Diana Picus116bbab2017-01-13 09:58:52 +00001061 MachineInstr *MI1New = BuildMI(MBB, MI, DL, get(NewOpc),
1062 HRI.getSubReg(DstReg, Hexagon::vsub_lo))
Krzysztof Parzyszek4be9d922017-05-03 15:26:13 +00001063 .add(MI.getOperand(1))
1064 .addImm(MI.getOperand(2).getImm())
1065 .setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
Krzysztof Parzyszek195dc8d2015-11-26 04:33:11 +00001066 MI1New->getOperand(1).setIsKill(false);
Diana Picus116bbab2017-01-13 09:58:52 +00001067 BuildMI(MBB, MI, DL, get(NewOpc), HRI.getSubReg(DstReg, Hexagon::vsub_hi))
1068 .add(MI.getOperand(1))
Krzysztof Parzyszek195dc8d2015-11-26 04:33:11 +00001069 // The Vectors are indexed in multiples of vector size.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001070 .addImm(MI.getOperand(2).getImm() + Offset)
1071 .setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
Krzysztof Parzyszek195dc8d2015-11-26 04:33:11 +00001072 MBB.erase(MI);
1073 return true;
1074 }
Krzysztof Parzyszek1d01a792016-08-16 18:08:40 +00001075 case Hexagon::PS_true: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001076 unsigned Reg = MI.getOperand(0).getReg();
Krzysztof Parzyszek36ccfa52015-03-18 19:07:53 +00001077 BuildMI(MBB, MI, DL, get(Hexagon::C2_orn), Reg)
1078 .addReg(Reg, RegState::Undef)
1079 .addReg(Reg, RegState::Undef);
1080 MBB.erase(MI);
1081 return true;
1082 }
Krzysztof Parzyszek1d01a792016-08-16 18:08:40 +00001083 case Hexagon::PS_false: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001084 unsigned Reg = MI.getOperand(0).getReg();
Krzysztof Parzyszek36ccfa52015-03-18 19:07:53 +00001085 BuildMI(MBB, MI, DL, get(Hexagon::C2_andn), Reg)
1086 .addReg(Reg, RegState::Undef)
1087 .addReg(Reg, RegState::Undef);
1088 MBB.erase(MI);
1089 return true;
1090 }
Krzysztof Parzyszek1d01a792016-08-16 18:08:40 +00001091 case Hexagon::PS_vmulw: {
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001092 // Expand a 64-bit vector multiply into 2 32-bit scalar multiplies.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001093 unsigned DstReg = MI.getOperand(0).getReg();
1094 unsigned Src1Reg = MI.getOperand(1).getReg();
1095 unsigned Src2Reg = MI.getOperand(2).getReg();
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001096 unsigned Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::isub_hi);
1097 unsigned Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::isub_lo);
1098 unsigned Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::isub_hi);
1099 unsigned Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::isub_lo);
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001100 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi),
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001101 HRI.getSubReg(DstReg, Hexagon::isub_hi))
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001102 .addReg(Src1SubHi)
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001103 .addReg(Src2SubHi);
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001104 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_mpyi),
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001105 HRI.getSubReg(DstReg, Hexagon::isub_lo))
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001106 .addReg(Src1SubLo)
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001107 .addReg(Src2SubLo);
1108 MBB.erase(MI);
1109 MRI.clearKillFlags(Src1SubHi);
1110 MRI.clearKillFlags(Src1SubLo);
1111 MRI.clearKillFlags(Src2SubHi);
1112 MRI.clearKillFlags(Src2SubLo);
1113 return true;
1114 }
Krzysztof Parzyszek1d01a792016-08-16 18:08:40 +00001115 case Hexagon::PS_vmulw_acc: {
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001116 // Expand 64-bit vector multiply with addition into 2 scalar multiplies.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001117 unsigned DstReg = MI.getOperand(0).getReg();
1118 unsigned Src1Reg = MI.getOperand(1).getReg();
1119 unsigned Src2Reg = MI.getOperand(2).getReg();
1120 unsigned Src3Reg = MI.getOperand(3).getReg();
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001121 unsigned Src1SubHi = HRI.getSubReg(Src1Reg, Hexagon::isub_hi);
1122 unsigned Src1SubLo = HRI.getSubReg(Src1Reg, Hexagon::isub_lo);
1123 unsigned Src2SubHi = HRI.getSubReg(Src2Reg, Hexagon::isub_hi);
1124 unsigned Src2SubLo = HRI.getSubReg(Src2Reg, Hexagon::isub_lo);
1125 unsigned Src3SubHi = HRI.getSubReg(Src3Reg, Hexagon::isub_hi);
1126 unsigned Src3SubLo = HRI.getSubReg(Src3Reg, Hexagon::isub_lo);
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001127 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci),
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001128 HRI.getSubReg(DstReg, Hexagon::isub_hi))
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001129 .addReg(Src1SubHi)
1130 .addReg(Src2SubHi)
1131 .addReg(Src3SubHi);
1132 BuildMI(MBB, MI, MI.getDebugLoc(), get(Hexagon::M2_maci),
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001133 HRI.getSubReg(DstReg, Hexagon::isub_lo))
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001134 .addReg(Src1SubLo)
1135 .addReg(Src2SubLo)
1136 .addReg(Src3SubLo);
Krzysztof Parzyszek42113342015-03-19 16:33:08 +00001137 MBB.erase(MI);
1138 MRI.clearKillFlags(Src1SubHi);
1139 MRI.clearKillFlags(Src1SubLo);
1140 MRI.clearKillFlags(Src2SubHi);
1141 MRI.clearKillFlags(Src2SubLo);
1142 MRI.clearKillFlags(Src3SubHi);
1143 MRI.clearKillFlags(Src3SubLo);
1144 return true;
1145 }
Krzysztof Parzyszek258af192016-08-11 19:12:18 +00001146 case Hexagon::PS_pselect: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001147 const MachineOperand &Op0 = MI.getOperand(0);
1148 const MachineOperand &Op1 = MI.getOperand(1);
1149 const MachineOperand &Op2 = MI.getOperand(2);
1150 const MachineOperand &Op3 = MI.getOperand(3);
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00001151 unsigned Rd = Op0.getReg();
1152 unsigned Pu = Op1.getReg();
1153 unsigned Rs = Op2.getReg();
1154 unsigned Rt = Op3.getReg();
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001155 DebugLoc DL = MI.getDebugLoc();
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00001156 unsigned K1 = getKillRegState(Op1.isKill());
1157 unsigned K2 = getKillRegState(Op2.isKill());
1158 unsigned K3 = getKillRegState(Op3.isKill());
1159 if (Rd != Rs)
1160 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpt), Rd)
1161 .addReg(Pu, (Rd == Rt) ? K1 : 0)
1162 .addReg(Rs, K2);
1163 if (Rd != Rt)
1164 BuildMI(MBB, MI, DL, get(Hexagon::A2_tfrpf), Rd)
1165 .addReg(Pu, K1)
1166 .addReg(Rt, K3);
1167 MBB.erase(MI);
1168 return true;
1169 }
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00001170 case Hexagon::PS_vselect: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001171 const MachineOperand &Op0 = MI.getOperand(0);
1172 const MachineOperand &Op1 = MI.getOperand(1);
1173 const MachineOperand &Op2 = MI.getOperand(2);
1174 const MachineOperand &Op3 = MI.getOperand(3);
Matthias Braunac4307c2017-05-26 21:51:00 +00001175 LivePhysRegs LiveAtMI(HRI);
Ron Lieberman88159e52016-09-02 22:56:24 +00001176 getLiveRegsAt(LiveAtMI, MI);
1177 bool IsDestLive = !LiveAtMI.available(MRI, Op0.getReg());
Krzysztof Parzyszek25173e42017-06-27 19:59:46 +00001178 unsigned PReg = Op1.getReg();
1179 assert(Op1.getSubReg() == 0);
1180 unsigned PState = getRegState(Op1);
1181
Ron Lieberman88159e52016-09-02 22:56:24 +00001182 if (Op0.getReg() != Op2.getReg()) {
Krzysztof Parzyszek25173e42017-06-27 19:59:46 +00001183 unsigned S = Op0.getReg() != Op3.getReg() ? PState & ~RegState::Kill
1184 : PState;
Ron Lieberman88159e52016-09-02 22:56:24 +00001185 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vcmov))
Diana Picus116bbab2017-01-13 09:58:52 +00001186 .add(Op0)
Krzysztof Parzyszek25173e42017-06-27 19:59:46 +00001187 .addReg(PReg, S)
Diana Picus116bbab2017-01-13 09:58:52 +00001188 .add(Op2);
Ron Lieberman88159e52016-09-02 22:56:24 +00001189 if (IsDestLive)
1190 T.addReg(Op0.getReg(), RegState::Implicit);
1191 IsDestLive = true;
1192 }
1193 if (Op0.getReg() != Op3.getReg()) {
1194 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vncmov))
Diana Picus116bbab2017-01-13 09:58:52 +00001195 .add(Op0)
Krzysztof Parzyszek25173e42017-06-27 19:59:46 +00001196 .addReg(PReg, PState)
Diana Picus116bbab2017-01-13 09:58:52 +00001197 .add(Op3);
Ron Lieberman88159e52016-09-02 22:56:24 +00001198 if (IsDestLive)
1199 T.addReg(Op0.getReg(), RegState::Implicit);
1200 }
Krzysztof Parzyszek4afed552016-05-12 19:16:02 +00001201 MBB.erase(MI);
1202 return true;
1203 }
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00001204 case Hexagon::PS_wselect: {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001205 MachineOperand &Op0 = MI.getOperand(0);
1206 MachineOperand &Op1 = MI.getOperand(1);
1207 MachineOperand &Op2 = MI.getOperand(2);
1208 MachineOperand &Op3 = MI.getOperand(3);
Matthias Braunac4307c2017-05-26 21:51:00 +00001209 LivePhysRegs LiveAtMI(HRI);
Ron Lieberman88159e52016-09-02 22:56:24 +00001210 getLiveRegsAt(LiveAtMI, MI);
1211 bool IsDestLive = !LiveAtMI.available(MRI, Op0.getReg());
Krzysztof Parzyszek25173e42017-06-27 19:59:46 +00001212 unsigned PReg = Op1.getReg();
1213 assert(Op1.getSubReg() == 0);
1214 unsigned PState = getRegState(Op1);
Ron Lieberman88159e52016-09-02 22:56:24 +00001215
1216 if (Op0.getReg() != Op2.getReg()) {
Krzysztof Parzyszek25173e42017-06-27 19:59:46 +00001217 unsigned S = Op0.getReg() != Op3.getReg() ? PState & ~RegState::Kill
1218 : PState;
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001219 unsigned SrcLo = HRI.getSubReg(Op2.getReg(), Hexagon::vsub_lo);
1220 unsigned SrcHi = HRI.getSubReg(Op2.getReg(), Hexagon::vsub_hi);
Ron Lieberman88159e52016-09-02 22:56:24 +00001221 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vccombine))
Diana Picus116bbab2017-01-13 09:58:52 +00001222 .add(Op0)
Krzysztof Parzyszek25173e42017-06-27 19:59:46 +00001223 .addReg(PReg, S)
Diana Picus116bbab2017-01-13 09:58:52 +00001224 .add(Op1)
1225 .addReg(SrcHi)
1226 .addReg(SrcLo);
Ron Lieberman88159e52016-09-02 22:56:24 +00001227 if (IsDestLive)
1228 T.addReg(Op0.getReg(), RegState::Implicit);
1229 IsDestLive = true;
1230 }
1231 if (Op0.getReg() != Op3.getReg()) {
Krzysztof Parzyszeka5409972016-11-09 16:19:08 +00001232 unsigned SrcLo = HRI.getSubReg(Op3.getReg(), Hexagon::vsub_lo);
1233 unsigned SrcHi = HRI.getSubReg(Op3.getReg(), Hexagon::vsub_hi);
Ron Lieberman88159e52016-09-02 22:56:24 +00001234 auto T = BuildMI(MBB, MI, DL, get(Hexagon::V6_vnccombine))
Diana Picus116bbab2017-01-13 09:58:52 +00001235 .add(Op0)
Krzysztof Parzyszek25173e42017-06-27 19:59:46 +00001236 .addReg(PReg, PState)
Diana Picus116bbab2017-01-13 09:58:52 +00001237 .addReg(SrcHi)
1238 .addReg(SrcLo);
Ron Lieberman88159e52016-09-02 22:56:24 +00001239 if (IsDestLive)
1240 T.addReg(Op0.getReg(), RegState::Implicit);
1241 }
Krzysztof Parzyszek4afed552016-05-12 19:16:02 +00001242 MBB.erase(MI);
1243 return true;
1244 }
Krzysztof Parzyszekbe976d42016-08-12 11:12:02 +00001245 case Hexagon::PS_tailcall_i:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001246 MI.setDesc(get(Hexagon::J2_jump));
Colin LeMahieu7b1799c2015-03-09 22:05:21 +00001247 return true;
Krzysztof Parzyszekbe976d42016-08-12 11:12:02 +00001248 case Hexagon::PS_tailcall_r:
Krzysztof Parzyszek6421b932016-08-19 14:04:45 +00001249 case Hexagon::PS_jmpret:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001250 MI.setDesc(get(Hexagon::J2_jumpr));
Colin LeMahieu7b1799c2015-03-09 22:05:21 +00001251 return true;
Krzysztof Parzyszek6421b932016-08-19 14:04:45 +00001252 case Hexagon::PS_jmprett:
1253 MI.setDesc(get(Hexagon::J2_jumprt));
1254 return true;
1255 case Hexagon::PS_jmpretf:
1256 MI.setDesc(get(Hexagon::J2_jumprf));
1257 return true;
1258 case Hexagon::PS_jmprettnewpt:
1259 MI.setDesc(get(Hexagon::J2_jumprtnewpt));
1260 return true;
1261 case Hexagon::PS_jmpretfnewpt:
1262 MI.setDesc(get(Hexagon::J2_jumprfnewpt));
1263 return true;
1264 case Hexagon::PS_jmprettnew:
1265 MI.setDesc(get(Hexagon::J2_jumprtnew));
1266 return true;
1267 case Hexagon::PS_jmpretfnew:
1268 MI.setDesc(get(Hexagon::J2_jumprfnew));
1269 return true;
Colin LeMahieu7b1799c2015-03-09 22:05:21 +00001270 }
1271
1272 return false;
1273}
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001274
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001275// We indicate that we want to reverse the branch by
1276// inserting the reversed branching opcode.
Matt Arsenault1b9fc8e2016-09-14 20:43:16 +00001277bool HexagonInstrInfo::reverseBranchCondition(
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001278 SmallVectorImpl<MachineOperand> &Cond) const {
1279 if (Cond.empty())
Jyotsna Vermaf1214a82013-03-05 18:51:42 +00001280 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001281 assert(Cond[0].isImm() && "First entry in the cond vector not imm-val");
1282 unsigned opcode = Cond[0].getImm();
1283 //unsigned temp;
1284 assert(get(opcode).isBranch() && "Should be a branching condition.");
1285 if (isEndLoopN(opcode))
Jyotsna Vermaf1214a82013-03-05 18:51:42 +00001286 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001287 unsigned NewOpcode = getInvertedPredicatedOpcode(opcode);
1288 Cond[0].setImm(NewOpcode);
Jyotsna Vermaf1214a82013-03-05 18:51:42 +00001289 return false;
1290}
1291
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001292void HexagonInstrInfo::insertNoop(MachineBasicBlock &MBB,
1293 MachineBasicBlock::iterator MI) const {
1294 DebugLoc DL;
1295 BuildMI(MBB, MI, DL, get(Hexagon::A2_nop));
1296}
1297
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00001298bool HexagonInstrInfo::isPostIncrement(const MachineInstr &MI) const {
1299 return getAddrMode(MI) == HexagonII::PostInc;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001300}
1301
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001302// Returns true if an instruction is predicated irrespective of the predicate
1303// sense. For example, all of the following will return true.
1304// if (p0) R1 = add(R2, R3)
1305// if (!p0) R1 = add(R2, R3)
1306// if (p0.new) R1 = add(R2, R3)
1307// if (!p0.new) R1 = add(R2, R3)
1308// Note: New-value stores are not included here as in the current
1309// implementation, we don't need to check their predicate sense.
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001310bool HexagonInstrInfo::isPredicated(const MachineInstr &MI) const {
1311 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001312 return (F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask;
Brendon Cahoondf43e682015-05-08 16:16:29 +00001313}
1314
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001315bool HexagonInstrInfo::PredicateInstruction(
1316 MachineInstr &MI, ArrayRef<MachineOperand> Cond) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001317 if (Cond.empty() || isNewValueJump(Cond[0].getImm()) ||
1318 isEndLoopN(Cond[0].getImm())) {
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001319 DEBUG(dbgs() << "\nCannot predicate:"; MI.dump(););
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001320 return false;
1321 }
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001322 int Opc = MI.getOpcode();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001323 assert (isPredicable(MI) && "Expected predicable instruction");
1324 bool invertJump = predOpcodeHasNot(Cond);
1325
1326 // We have to predicate MI "in place", i.e. after this function returns,
1327 // MI will need to be transformed into a predicated form. To avoid com-
1328 // plicated manipulations with the operands (handling tied operands,
1329 // etc.), build a new temporary instruction, then overwrite MI with it.
1330
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001331 MachineBasicBlock &B = *MI.getParent();
1332 DebugLoc DL = MI.getDebugLoc();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001333 unsigned PredOpc = getCondOpcode(Opc, invertJump);
1334 MachineInstrBuilder T = BuildMI(B, MI, DL, get(PredOpc));
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001335 unsigned NOp = 0, NumOps = MI.getNumOperands();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001336 while (NOp < NumOps) {
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001337 MachineOperand &Op = MI.getOperand(NOp);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001338 if (!Op.isReg() || !Op.isDef() || Op.isImplicit())
1339 break;
Diana Picus116bbab2017-01-13 09:58:52 +00001340 T.add(Op);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001341 NOp++;
1342 }
1343
1344 unsigned PredReg, PredRegPos, PredRegFlags;
1345 bool GotPredReg = getPredReg(Cond, PredReg, PredRegPos, PredRegFlags);
1346 (void)GotPredReg;
1347 assert(GotPredReg);
1348 T.addReg(PredReg, PredRegFlags);
1349 while (NOp < NumOps)
Diana Picus116bbab2017-01-13 09:58:52 +00001350 T.add(MI.getOperand(NOp++));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001351
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001352 MI.setDesc(get(PredOpc));
1353 while (unsigned n = MI.getNumOperands())
1354 MI.RemoveOperand(n-1);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001355 for (unsigned i = 0, n = T->getNumOperands(); i < n; ++i)
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001356 MI.addOperand(T->getOperand(i));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001357
Duncan P. N. Exon Smithc5b668d2016-02-22 20:49:58 +00001358 MachineBasicBlock::instr_iterator TI = T->getIterator();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001359 B.erase(TI);
1360
1361 MachineRegisterInfo &MRI = B.getParent()->getRegInfo();
1362 MRI.clearKillFlags(PredReg);
1363 return true;
Brendon Cahoondf43e682015-05-08 16:16:29 +00001364}
1365
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001366bool HexagonInstrInfo::SubsumesPredicate(ArrayRef<MachineOperand> Pred1,
1367 ArrayRef<MachineOperand> Pred2) const {
1368 // TODO: Fix this
1369 return false;
1370}
1371
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00001372bool HexagonInstrInfo::DefinesPredicate(MachineInstr &MI,
1373 std::vector<MachineOperand> &Pred) const {
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +00001374 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00001375
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00001376 for (unsigned oper = 0; oper < MI.getNumOperands(); ++oper) {
1377 MachineOperand MO = MI.getOperand(oper);
Krzysztof Parzyszek1aaf41a2017-02-17 22:14:51 +00001378 if (MO.isReg()) {
1379 if (!MO.isDef())
1380 continue;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001381 const TargetRegisterClass* RC = HRI.getMinimalPhysRegClass(MO.getReg());
1382 if (RC == &Hexagon::PredRegsRegClass) {
1383 Pred.push_back(MO);
1384 return true;
1385 }
Krzysztof Parzyszek1aaf41a2017-02-17 22:14:51 +00001386 continue;
1387 } else if (MO.isRegMask()) {
1388 for (unsigned PR : Hexagon::PredRegsRegClass) {
1389 if (!MI.modifiesRegister(PR, &HRI))
1390 continue;
1391 Pred.push_back(MO);
1392 return true;
1393 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001394 }
1395 }
1396 return false;
Sirish Pandef8e5e3c2012-05-03 21:52:53 +00001397}
Andrew Trickd06df962012-02-01 22:13:57 +00001398
Krzysztof Parzyszekcc318712017-03-03 18:30:54 +00001399bool HexagonInstrInfo::isPredicable(const MachineInstr &MI) const {
Krzysztof Parzyszekee93e002017-05-05 22:13:57 +00001400 if (!MI.getDesc().isPredicable())
1401 return false;
1402
1403 if (MI.isCall() || isTailCall(MI)) {
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +00001404 if (!Subtarget.usePredicatedCalls())
Krzysztof Parzyszekee93e002017-05-05 22:13:57 +00001405 return false;
1406 }
Krzysztof Parzyszek8c53c952017-10-18 17:36:46 +00001407
1408 // HVX loads are not predicable on v60, but are on v62.
1409 if (!Subtarget.hasV62TOps()) {
1410 switch (MI.getOpcode()) {
1411 case Hexagon::V6_vL32b_ai:
1412 case Hexagon::V6_vL32b_pi:
1413 case Hexagon::V6_vL32b_ppu:
1414 case Hexagon::V6_vL32b_cur_ai:
1415 case Hexagon::V6_vL32b_cur_pi:
1416 case Hexagon::V6_vL32b_cur_ppu:
1417 case Hexagon::V6_vL32b_nt_ai:
1418 case Hexagon::V6_vL32b_nt_pi:
1419 case Hexagon::V6_vL32b_nt_ppu:
1420 case Hexagon::V6_vL32b_tmp_ai:
1421 case Hexagon::V6_vL32b_tmp_pi:
1422 case Hexagon::V6_vL32b_tmp_ppu:
1423 case Hexagon::V6_vL32b_nt_cur_ai:
1424 case Hexagon::V6_vL32b_nt_cur_pi:
1425 case Hexagon::V6_vL32b_nt_cur_ppu:
1426 case Hexagon::V6_vL32b_nt_tmp_ai:
1427 case Hexagon::V6_vL32b_nt_tmp_pi:
1428 case Hexagon::V6_vL32b_nt_tmp_ppu:
1429 return false;
1430 }
1431 }
Krzysztof Parzyszekee93e002017-05-05 22:13:57 +00001432 return true;
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001433}
1434
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001435bool HexagonInstrInfo::isSchedulingBoundary(const MachineInstr &MI,
1436 const MachineBasicBlock *MBB,
1437 const MachineFunction &MF) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001438 // Debug info is never a scheduling boundary. It's necessary to be explicit
1439 // due to the special treatment of IT instructions below, otherwise a
1440 // dbg_value followed by an IT will result in the IT instruction being
1441 // considered a scheduling hazard, which is wrong. It should be the actual
1442 // instruction preceding the dbg_value instruction(s), just like it is
1443 // when debug info is not present.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001444 if (MI.isDebugValue())
Brendon Cahoondf43e682015-05-08 16:16:29 +00001445 return false;
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001446
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001447 // Throwing call is a boundary.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001448 if (MI.isCall()) {
Krzysztof Parzyszekab9127c2016-08-12 11:01:10 +00001449 // Don't mess around with no return calls.
1450 if (doesNotReturn(MI))
1451 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001452 // If any of the block's successors is a landing pad, this could be a
1453 // throwing call.
1454 for (auto I : MBB->successors())
1455 if (I->isEHPad())
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001456 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001457 }
1458
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001459 // Terminators and labels can't be scheduled around.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001460 if (MI.getDesc().isTerminator() || MI.isPosition())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001461 return true;
1462
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001463 if (MI.isInlineAsm() && !ScheduleInlineAsm)
1464 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001465
1466 return false;
1467}
1468
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001469/// Measure the specified inline asm to determine an approximation of its
1470/// length.
1471/// Comments (which run till the next SeparatorString or newline) do not
1472/// count as an instruction.
1473/// Any other non-whitespace text is considered an instruction, with
1474/// multiple instructions separated by SeparatorString or newlines.
1475/// Variable-length instructions are not handled here; this function
1476/// may be overloaded in the target code to do that.
1477/// Hexagon counts the number of ##'s and adjust for that many
1478/// constant exenders.
1479unsigned HexagonInstrInfo::getInlineAsmLength(const char *Str,
1480 const MCAsmInfo &MAI) const {
1481 StringRef AStr(Str);
1482 // Count the number of instructions in the asm.
1483 bool atInsnStart = true;
1484 unsigned Length = 0;
1485 for (; *Str; ++Str) {
1486 if (*Str == '\n' || strncmp(Str, MAI.getSeparatorString(),
1487 strlen(MAI.getSeparatorString())) == 0)
1488 atInsnStart = true;
1489 if (atInsnStart && !std::isspace(static_cast<unsigned char>(*Str))) {
1490 Length += MAI.getMaxInstLength();
1491 atInsnStart = false;
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001492 }
Mehdi Amini36d33fc2016-10-01 06:46:33 +00001493 if (atInsnStart && strncmp(Str, MAI.getCommentString().data(),
1494 MAI.getCommentString().size()) == 0)
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001495 atInsnStart = false;
1496 }
1497
1498 // Add to size number of constant extenders seen * 4.
1499 StringRef Occ("##");
1500 Length += AStr.count(Occ)*4;
1501 return Length;
1502}
1503
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001504ScheduleHazardRecognizer*
1505HexagonInstrInfo::CreateTargetPostRAHazardRecognizer(
1506 const InstrItineraryData *II, const ScheduleDAG *DAG) const {
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +00001507 if (UseDFAHazardRec)
1508 return new HexagonHazardRecognizer(II, this, Subtarget);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001509 return TargetInstrInfo::CreateTargetPostRAHazardRecognizer(II, DAG);
1510}
1511
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001512/// \brief For a comparison instruction, return the source registers in
1513/// \p SrcReg and \p SrcReg2 if having two register operands, and the value it
1514/// compares against in CmpValue. Return true if the comparison instruction
1515/// can be analyzed.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001516bool HexagonInstrInfo::analyzeCompare(const MachineInstr &MI, unsigned &SrcReg,
1517 unsigned &SrcReg2, int &Mask,
1518 int &Value) const {
1519 unsigned Opc = MI.getOpcode();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001520
1521 // Set mask and the first source register.
1522 switch (Opc) {
1523 case Hexagon::C2_cmpeq:
1524 case Hexagon::C2_cmpeqp:
1525 case Hexagon::C2_cmpgt:
1526 case Hexagon::C2_cmpgtp:
1527 case Hexagon::C2_cmpgtu:
1528 case Hexagon::C2_cmpgtup:
1529 case Hexagon::C4_cmpneq:
1530 case Hexagon::C4_cmplte:
1531 case Hexagon::C4_cmplteu:
1532 case Hexagon::C2_cmpeqi:
1533 case Hexagon::C2_cmpgti:
1534 case Hexagon::C2_cmpgtui:
1535 case Hexagon::C4_cmpneqi:
1536 case Hexagon::C4_cmplteui:
1537 case Hexagon::C4_cmpltei:
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 = ~0;
1540 break;
1541 case Hexagon::A4_cmpbeq:
1542 case Hexagon::A4_cmpbgt:
1543 case Hexagon::A4_cmpbgtu:
1544 case Hexagon::A4_cmpbeqi:
1545 case Hexagon::A4_cmpbgti:
1546 case Hexagon::A4_cmpbgtui:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001547 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001548 Mask = 0xFF;
1549 break;
1550 case Hexagon::A4_cmpheq:
1551 case Hexagon::A4_cmphgt:
1552 case Hexagon::A4_cmphgtu:
1553 case Hexagon::A4_cmpheqi:
1554 case Hexagon::A4_cmphgti:
1555 case Hexagon::A4_cmphgtui:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001556 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001557 Mask = 0xFFFF;
1558 break;
1559 }
1560
1561 // Set the value/second source register.
1562 switch (Opc) {
1563 case Hexagon::C2_cmpeq:
1564 case Hexagon::C2_cmpeqp:
1565 case Hexagon::C2_cmpgt:
1566 case Hexagon::C2_cmpgtp:
1567 case Hexagon::C2_cmpgtu:
1568 case Hexagon::C2_cmpgtup:
1569 case Hexagon::A4_cmpbeq:
1570 case Hexagon::A4_cmpbgt:
1571 case Hexagon::A4_cmpbgtu:
1572 case Hexagon::A4_cmpheq:
1573 case Hexagon::A4_cmphgt:
1574 case Hexagon::A4_cmphgtu:
1575 case Hexagon::C4_cmpneq:
1576 case Hexagon::C4_cmplte:
1577 case Hexagon::C4_cmplteu:
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001578 SrcReg2 = MI.getOperand(2).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001579 return true;
1580
1581 case Hexagon::C2_cmpeqi:
1582 case Hexagon::C2_cmpgtui:
1583 case Hexagon::C2_cmpgti:
1584 case Hexagon::C4_cmpneqi:
1585 case Hexagon::C4_cmplteui:
1586 case Hexagon::C4_cmpltei:
1587 case Hexagon::A4_cmpbeqi:
1588 case Hexagon::A4_cmpbgti:
1589 case Hexagon::A4_cmpbgtui:
1590 case Hexagon::A4_cmpheqi:
1591 case Hexagon::A4_cmphgti:
Krzysztof Parzyszek64e5d7d2017-10-20 19:33:12 +00001592 case Hexagon::A4_cmphgtui: {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001593 SrcReg2 = 0;
Krzysztof Parzyszek64e5d7d2017-10-20 19:33:12 +00001594 const MachineOperand &Op2 = MI.getOperand(2);
1595 if (!Op2.isImm())
1596 return false;
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001597 Value = MI.getOperand(2).getImm();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001598 return true;
Krzysztof Parzyszek64e5d7d2017-10-20 19:33:12 +00001599 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001600 }
1601
1602 return false;
1603}
1604
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001605unsigned HexagonInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001606 const MachineInstr &MI,
1607 unsigned *PredCost) const {
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001608 return getInstrTimingClassLatency(ItinData, MI);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001609}
1610
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001611DFAPacketizer *HexagonInstrInfo::CreateTargetScheduleState(
1612 const TargetSubtargetInfo &STI) const {
1613 const InstrItineraryData *II = STI.getInstrItineraryData();
1614 return static_cast<const HexagonSubtarget&>(STI).createDFAPacketizer(II);
1615}
1616
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001617// Inspired by this pair:
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +00001618// %r13<def> = L2_loadri_io %r29, 136; mem:LD4[FixedStack0]
1619// S2_storeri_io %r29, 132, %r1<kill>; flags: mem:ST4[FixedStack1]
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001620// Currently AA considers the addresses in these instructions to be aliasing.
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001621bool HexagonInstrInfo::areMemAccessesTriviallyDisjoint(
1622 MachineInstr &MIa, MachineInstr &MIb, AliasAnalysis *AA) const {
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00001623 if (MIa.hasUnmodeledSideEffects() || MIb.hasUnmodeledSideEffects() ||
1624 MIa.hasOrderedMemoryRef() || MIb.hasOrderedMemoryRef())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001625 return false;
1626
1627 // Instructions that are pure loads, not loads and stores like memops are not
1628 // dependent.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001629 if (MIa.mayLoad() && !isMemOp(MIa) && MIb.mayLoad() && !isMemOp(MIb))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001630 return true;
1631
Krzysztof Parzyszek3fce9d92017-07-19 18:03:46 +00001632 // Get the base register in MIa.
1633 unsigned BasePosA, OffsetPosA;
1634 if (!getBaseAndOffsetPosition(MIa, BasePosA, OffsetPosA))
1635 return false;
1636 const MachineOperand &BaseA = MIa.getOperand(BasePosA);
1637 unsigned BaseRegA = BaseA.getReg();
1638 unsigned BaseSubA = BaseA.getSubReg();
1639
1640 // Get the base register in MIb.
1641 unsigned BasePosB, OffsetPosB;
1642 if (!getBaseAndOffsetPosition(MIb, BasePosB, OffsetPosB))
1643 return false;
1644 const MachineOperand &BaseB = MIb.getOperand(BasePosB);
1645 unsigned BaseRegB = BaseB.getReg();
1646 unsigned BaseSubB = BaseB.getSubReg();
1647
1648 if (BaseRegA != BaseRegB || BaseSubA != BaseSubB)
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001649 return false;
1650
Krzysztof Parzyszek3fce9d92017-07-19 18:03:46 +00001651 // Get the access sizes.
Krzysztof Parzyszek473d02d2017-09-14 12:06:40 +00001652 unsigned SizeA = getMemAccessSize(MIa);
1653 unsigned SizeB = getMemAccessSize(MIb);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001654
Krzysztof Parzyszek3fce9d92017-07-19 18:03:46 +00001655 // Get the offsets. Handle immediates only for now.
1656 const MachineOperand &OffA = MIa.getOperand(OffsetPosA);
1657 const MachineOperand &OffB = MIb.getOperand(OffsetPosB);
1658 if (!MIa.getOperand(OffsetPosA).isImm() ||
1659 !MIb.getOperand(OffsetPosB).isImm())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001660 return false;
Krzysztof Parzyszekac019942017-07-19 19:17:32 +00001661 int OffsetA = isPostIncrement(MIa) ? 0 : OffA.getImm();
1662 int OffsetB = isPostIncrement(MIb) ? 0 : OffB.getImm();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001663
1664 // This is a mem access with the same base register and known offsets from it.
1665 // Reason about it.
1666 if (OffsetA > OffsetB) {
Krzysztof Parzyszek3fce9d92017-07-19 18:03:46 +00001667 uint64_t OffDiff = (uint64_t)((int64_t)OffsetA - (int64_t)OffsetB);
1668 return SizeB <= OffDiff;
1669 }
1670 if (OffsetA < OffsetB) {
1671 uint64_t OffDiff = (uint64_t)((int64_t)OffsetB - (int64_t)OffsetA);
1672 return SizeA <= OffDiff;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001673 }
1674
1675 return false;
1676}
1677
Brendon Cahoon254f8892016-07-29 16:44:44 +00001678/// If the instruction is an increment of a constant value, return the amount.
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00001679bool HexagonInstrInfo::getIncrementValue(const MachineInstr &MI,
Brendon Cahoon254f8892016-07-29 16:44:44 +00001680 int &Value) const {
1681 if (isPostIncrement(MI)) {
Krzysztof Parzyszek12bdcab2017-10-11 15:59:51 +00001682 unsigned BasePos = 0, OffsetPos = 0;
1683 if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))
1684 return false;
1685 const MachineOperand &OffsetOp = MI.getOperand(OffsetPos);
1686 if (OffsetOp.isImm()) {
1687 Value = OffsetOp.getImm();
1688 return true;
1689 }
Krzysztof Parzyszekbf626192017-10-11 16:15:31 +00001690 } else if (MI.getOpcode() == Hexagon::A2_addi) {
1691 const MachineOperand &AddOp = MI.getOperand(2);
1692 if (AddOp.isImm()) {
1693 Value = AddOp.getImm();
1694 return true;
1695 }
Brendon Cahoon254f8892016-07-29 16:44:44 +00001696 }
1697
1698 return false;
1699}
1700
Krzysztof Parzyszek0ac065f2017-07-10 18:31:02 +00001701std::pair<unsigned, unsigned>
1702HexagonInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
1703 return std::make_pair(TF & ~HexagonII::MO_Bitmasks,
1704 TF & HexagonII::MO_Bitmasks);
1705}
1706
1707ArrayRef<std::pair<unsigned, const char*>>
1708HexagonInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
1709 using namespace HexagonII;
Eugene Zelenko3b873362017-09-28 22:27:31 +00001710
Krzysztof Parzyszek0ac065f2017-07-10 18:31:02 +00001711 static const std::pair<unsigned, const char*> Flags[] = {
1712 {MO_PCREL, "hexagon-pcrel"},
1713 {MO_GOT, "hexagon-got"},
1714 {MO_LO16, "hexagon-lo16"},
1715 {MO_HI16, "hexagon-hi16"},
1716 {MO_GPREL, "hexagon-gprel"},
1717 {MO_GDGOT, "hexagon-gdgot"},
1718 {MO_GDPLT, "hexagon-gdplt"},
1719 {MO_IE, "hexagon-ie"},
1720 {MO_IEGOT, "hexagon-iegot"},
1721 {MO_TPREL, "hexagon-tprel"}
1722 };
1723 return makeArrayRef(Flags);
1724}
1725
1726ArrayRef<std::pair<unsigned, const char*>>
1727HexagonInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
1728 using namespace HexagonII;
Eugene Zelenko3b873362017-09-28 22:27:31 +00001729
Krzysztof Parzyszek0ac065f2017-07-10 18:31:02 +00001730 static const std::pair<unsigned, const char*> Flags[] = {
1731 {HMOTF_ConstExtended, "hexagon-ext"}
1732 };
1733 return makeArrayRef(Flags);
1734}
1735
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001736unsigned HexagonInstrInfo::createVR(MachineFunction *MF, MVT VT) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001737 MachineRegisterInfo &MRI = MF->getRegInfo();
1738 const TargetRegisterClass *TRC;
1739 if (VT == MVT::i1) {
1740 TRC = &Hexagon::PredRegsRegClass;
1741 } else if (VT == MVT::i32 || VT == MVT::f32) {
1742 TRC = &Hexagon::IntRegsRegClass;
1743 } else if (VT == MVT::i64 || VT == MVT::f64) {
1744 TRC = &Hexagon::DoubleRegsRegClass;
1745 } else {
1746 llvm_unreachable("Cannot handle this register class");
1747 }
1748
1749 unsigned NewReg = MRI.createVirtualRegister(TRC);
1750 return NewReg;
1751}
1752
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001753bool HexagonInstrInfo::isAbsoluteSet(const MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001754 return (getAddrMode(MI) == HexagonII::AbsoluteSet);
1755}
1756
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001757bool HexagonInstrInfo::isAccumulator(const MachineInstr &MI) const {
1758 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001759 return((F >> HexagonII::AccumulatorPos) & HexagonII::AccumulatorMask);
1760}
1761
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001762bool HexagonInstrInfo::isComplex(const MachineInstr &MI) const {
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +00001763 return !isTC1(MI) && !isTC2Early(MI) && !MI.getDesc().mayLoad() &&
1764 !MI.getDesc().mayStore() &&
1765 MI.getDesc().getOpcode() != Hexagon::S2_allocframe &&
1766 MI.getDesc().getOpcode() != Hexagon::L2_deallocframe &&
1767 !isMemOp(MI) && !MI.isBranch() && !MI.isReturn() && !MI.isCall();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001768}
1769
Sanjay Patele4b9f502015-12-07 19:21:39 +00001770// Return true if the instruction is a compund branch instruction.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001771bool HexagonInstrInfo::isCompoundBranchInstr(const MachineInstr &MI) const {
Krzysztof Parzyszekf65b8f12017-02-02 15:03:30 +00001772 return getType(MI) == HexagonII::TypeCJ && MI.isBranch();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001773}
1774
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001775// TODO: In order to have isExtendable for fpimm/f32Ext, we need to handle
1776// isFPImm and later getFPImm as well.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001777bool HexagonInstrInfo::isConstExtended(const MachineInstr &MI) const {
1778 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001779 unsigned isExtended = (F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask;
1780 if (isExtended) // Instruction must be extended.
Krzysztof Parzyszekc6f19332015-03-19 15:18:57 +00001781 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001782
1783 unsigned isExtendable =
1784 (F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask;
1785 if (!isExtendable)
1786 return false;
1787
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001788 if (MI.isCall())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001789 return false;
1790
1791 short ExtOpNum = getCExtOpNum(MI);
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001792 const MachineOperand &MO = MI.getOperand(ExtOpNum);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001793 // Use MO operand flags to determine if MO
1794 // has the HMOTF_ConstExtended flag set.
Krzysztof Parzyszekdf4a05d2017-07-10 18:38:52 +00001795 if (MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended)
Brendon Cahoondf43e682015-05-08 16:16:29 +00001796 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001797 // If this is a Machine BB address we are talking about, and it is
1798 // not marked as extended, say so.
1799 if (MO.isMBB())
1800 return false;
1801
1802 // We could be using an instruction with an extendable immediate and shoehorn
1803 // a global address into it. If it is a global address it will be constant
1804 // extended. We do this for COMBINE.
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001805 if (MO.isGlobal() || MO.isSymbol() || MO.isBlockAddress() ||
Krzysztof Parzyszeka3386502016-08-10 16:46:36 +00001806 MO.isJTI() || MO.isCPI() || MO.isFPImm())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001807 return true;
1808
1809 // If the extendable operand is not 'Immediate' type, the instruction should
1810 // have 'isExtended' flag set.
1811 assert(MO.isImm() && "Extendable operand must be Immediate type");
1812
1813 int MinValue = getMinValue(MI);
1814 int MaxValue = getMaxValue(MI);
1815 int ImmValue = MO.getImm();
1816
1817 return (ImmValue < MinValue || ImmValue > MaxValue);
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001818}
1819
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001820bool HexagonInstrInfo::isDeallocRet(const MachineInstr &MI) const {
1821 switch (MI.getOpcode()) {
Eugene Zelenko3b873362017-09-28 22:27:31 +00001822 case Hexagon::L4_return:
1823 case Hexagon::L4_return_t:
1824 case Hexagon::L4_return_f:
1825 case Hexagon::L4_return_tnew_pnt:
1826 case Hexagon::L4_return_fnew_pnt:
1827 case Hexagon::L4_return_tnew_pt:
1828 case Hexagon::L4_return_fnew_pt:
Krzysztof Parzyszek700a5f92017-05-03 15:34:52 +00001829 return true;
Tony Linthicum1213a7a2011-12-12 21:14:40 +00001830 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001831 return false;
1832}
1833
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001834// Return true when ConsMI uses a register defined by ProdMI.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001835bool HexagonInstrInfo::isDependent(const MachineInstr &ProdMI,
1836 const MachineInstr &ConsMI) const {
1837 if (!ProdMI.getDesc().getNumDefs())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001838 return false;
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +00001839 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001840
1841 SmallVector<unsigned, 4> DefsA;
1842 SmallVector<unsigned, 4> DefsB;
1843 SmallVector<unsigned, 8> UsesA;
1844 SmallVector<unsigned, 8> UsesB;
1845
1846 parseOperands(ProdMI, DefsA, UsesA);
1847 parseOperands(ConsMI, DefsB, UsesB);
1848
1849 for (auto &RegA : DefsA)
1850 for (auto &RegB : UsesB) {
1851 // True data dependency.
1852 if (RegA == RegB)
1853 return true;
1854
Krzysztof Parzyszek9aaf9232017-05-02 18:12:19 +00001855 if (TargetRegisterInfo::isPhysicalRegister(RegA))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001856 for (MCSubRegIterator SubRegs(RegA, &HRI); SubRegs.isValid(); ++SubRegs)
1857 if (RegB == *SubRegs)
1858 return true;
1859
Krzysztof Parzyszek9aaf9232017-05-02 18:12:19 +00001860 if (TargetRegisterInfo::isPhysicalRegister(RegB))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001861 for (MCSubRegIterator SubRegs(RegB, &HRI); SubRegs.isValid(); ++SubRegs)
1862 if (RegA == *SubRegs)
1863 return true;
1864 }
1865
1866 return false;
1867}
1868
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001869// Returns true if the instruction is alread a .cur.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001870bool HexagonInstrInfo::isDotCurInst(const MachineInstr &MI) const {
1871 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001872 case Hexagon::V6_vL32b_cur_pi:
1873 case Hexagon::V6_vL32b_cur_ai:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001874 return true;
1875 }
1876 return false;
1877}
1878
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001879// Returns true, if any one of the operands is a dot new
1880// insn, whether it is predicated dot new or register dot new.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001881bool HexagonInstrInfo::isDotNewInst(const MachineInstr &MI) const {
1882 if (isNewValueInst(MI) || (isPredicated(MI) && isPredicatedNew(MI)))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001883 return true;
1884
1885 return false;
1886}
1887
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001888/// Symmetrical. See if these two instructions are fit for duplex pair.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001889bool HexagonInstrInfo::isDuplexPair(const MachineInstr &MIa,
1890 const MachineInstr &MIb) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001891 HexagonII::SubInstructionGroup MIaG = getDuplexCandidateGroup(MIa);
1892 HexagonII::SubInstructionGroup MIbG = getDuplexCandidateGroup(MIb);
1893 return (isDuplexPairMatch(MIaG, MIbG) || isDuplexPairMatch(MIbG, MIaG));
1894}
1895
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001896bool HexagonInstrInfo::isEarlySourceInstr(const MachineInstr &MI) const {
1897 if (MI.mayLoad() || MI.mayStore() || MI.isCompare())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001898 return true;
1899
1900 // Multiply
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001901 unsigned SchedClass = MI.getDesc().getSchedClass();
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00001902 return is_TC4x(SchedClass) || is_TC3x(SchedClass);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001903}
1904
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001905bool HexagonInstrInfo::isEndLoopN(unsigned Opcode) const {
1906 return (Opcode == Hexagon::ENDLOOP0 ||
1907 Opcode == Hexagon::ENDLOOP1);
1908}
1909
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001910bool HexagonInstrInfo::isExpr(unsigned OpType) const {
1911 switch(OpType) {
1912 case MachineOperand::MO_MachineBasicBlock:
1913 case MachineOperand::MO_GlobalAddress:
1914 case MachineOperand::MO_ExternalSymbol:
1915 case MachineOperand::MO_JumpTableIndex:
1916 case MachineOperand::MO_ConstantPoolIndex:
1917 case MachineOperand::MO_BlockAddress:
1918 return true;
1919 default:
1920 return false;
1921 }
1922}
1923
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001924bool HexagonInstrInfo::isExtendable(const MachineInstr &MI) const {
1925 const MCInstrDesc &MID = MI.getDesc();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001926 const uint64_t F = MID.TSFlags;
1927 if ((F >> HexagonII::ExtendablePos) & HexagonII::ExtendableMask)
1928 return true;
1929
1930 // TODO: This is largely obsolete now. Will need to be removed
1931 // in consecutive patches.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001932 switch (MI.getOpcode()) {
Krzysztof Parzyszek1d01a792016-08-16 18:08:40 +00001933 // PS_fi and PS_fia remain special cases.
1934 case Hexagon::PS_fi:
1935 case Hexagon::PS_fia:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001936 return true;
1937 default:
1938 return false;
1939 }
1940 return false;
1941}
1942
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001943// This returns true in two cases:
1944// - The OP code itself indicates that this is an extended instruction.
1945// - One of MOs has been marked with HMOTF_ConstExtended flag.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001946bool HexagonInstrInfo::isExtended(const MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001947 // First check if this is permanently extended op code.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001948 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001949 if ((F >> HexagonII::ExtendedPos) & HexagonII::ExtendedMask)
1950 return true;
1951 // Use MO operand flags to determine if one of MI's operands
1952 // has HMOTF_ConstExtended flag set.
Krzysztof Parzyszekdf4a05d2017-07-10 18:38:52 +00001953 for (const MachineOperand &MO : MI.operands())
1954 if (MO.getTargetFlags() & HexagonII::HMOTF_ConstExtended)
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001955 return true;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001956 return false;
1957}
1958
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001959bool HexagonInstrInfo::isFloat(const MachineInstr &MI) const {
1960 unsigned Opcode = MI.getOpcode();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001961 const uint64_t F = get(Opcode).TSFlags;
1962 return (F >> HexagonII::FPPos) & HexagonII::FPMask;
1963}
1964
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00001965// No V60 HVX VMEM with A_INDIRECT.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001966bool HexagonInstrInfo::isHVXMemWithAIndirect(const MachineInstr &I,
1967 const MachineInstr &J) const {
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00001968 if (!isHVXVec(I))
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00001969 return false;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001970 if (!I.mayLoad() && !I.mayStore())
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00001971 return false;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001972 return J.isIndirectBranch() || isIndirectCall(J) || isIndirectL4Return(J);
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00001973}
1974
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001975bool HexagonInstrInfo::isIndirectCall(const MachineInstr &MI) const {
1976 switch (MI.getOpcode()) {
Eugene Zelenko3b873362017-09-28 22:27:31 +00001977 case Hexagon::J2_callr:
1978 case Hexagon::J2_callrf:
1979 case Hexagon::J2_callrt:
1980 case Hexagon::PS_call_nr:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001981 return true;
1982 }
1983 return false;
1984}
1985
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00001986bool HexagonInstrInfo::isIndirectL4Return(const MachineInstr &MI) const {
1987 switch (MI.getOpcode()) {
Eugene Zelenko3b873362017-09-28 22:27:31 +00001988 case Hexagon::L4_return:
1989 case Hexagon::L4_return_t:
1990 case Hexagon::L4_return_f:
1991 case Hexagon::L4_return_fnew_pnt:
1992 case Hexagon::L4_return_fnew_pt:
1993 case Hexagon::L4_return_tnew_pnt:
1994 case Hexagon::L4_return_tnew_pt:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00001995 return true;
1996 }
1997 return false;
1998}
1999
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002000bool HexagonInstrInfo::isJumpR(const MachineInstr &MI) const {
2001 switch (MI.getOpcode()) {
Eugene Zelenko3b873362017-09-28 22:27:31 +00002002 case Hexagon::J2_jumpr:
2003 case Hexagon::J2_jumprt:
2004 case Hexagon::J2_jumprf:
2005 case Hexagon::J2_jumprtnewpt:
2006 case Hexagon::J2_jumprfnewpt:
2007 case Hexagon::J2_jumprtnew:
2008 case Hexagon::J2_jumprfnew:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002009 return true;
2010 }
2011 return false;
2012}
2013
Simon Pilgrim6ba672e2016-11-17 19:21:20 +00002014// Return true if a given MI can accommodate given offset.
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002015// Use abs estimate as oppose to the exact number.
2016// TODO: This will need to be changed to use MC level
2017// definition of instruction extendable field size.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002018bool HexagonInstrInfo::isJumpWithinBranchRange(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002019 unsigned offset) const {
2020 // This selection of jump instructions matches to that what
Krzysztof Parzyszek700a5f92017-05-03 15:34:52 +00002021 // analyzeBranch can parse, plus NVJ.
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002022 if (isNewValueJump(MI)) // r9:2
2023 return isInt<11>(offset);
2024
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002025 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002026 // Still missing Jump to address condition on register value.
2027 default:
2028 return false;
2029 case Hexagon::J2_jump: // bits<24> dst; // r22:2
2030 case Hexagon::J2_call:
Krzysztof Parzyszekbe976d42016-08-12 11:12:02 +00002031 case Hexagon::PS_call_nr:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002032 return isInt<24>(offset);
2033 case Hexagon::J2_jumpt: //bits<17> dst; // r15:2
2034 case Hexagon::J2_jumpf:
2035 case Hexagon::J2_jumptnew:
2036 case Hexagon::J2_jumptnewpt:
2037 case Hexagon::J2_jumpfnew:
2038 case Hexagon::J2_jumpfnewpt:
2039 case Hexagon::J2_callt:
2040 case Hexagon::J2_callf:
2041 return isInt<17>(offset);
2042 case Hexagon::J2_loop0i:
2043 case Hexagon::J2_loop0iext:
2044 case Hexagon::J2_loop0r:
2045 case Hexagon::J2_loop0rext:
2046 case Hexagon::J2_loop1i:
2047 case Hexagon::J2_loop1iext:
2048 case Hexagon::J2_loop1r:
2049 case Hexagon::J2_loop1rext:
2050 return isInt<9>(offset);
2051 // TODO: Add all the compound branches here. Can we do this in Relation model?
2052 case Hexagon::J4_cmpeqi_tp0_jump_nt:
2053 case Hexagon::J4_cmpeqi_tp1_jump_nt:
2054 return isInt<11>(offset);
2055 }
2056}
2057
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002058bool HexagonInstrInfo::isLateInstrFeedsEarlyInstr(const MachineInstr &LRMI,
2059 const MachineInstr &ESMI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002060 bool isLate = isLateResultInstr(LRMI);
2061 bool isEarly = isEarlySourceInstr(ESMI);
2062
2063 DEBUG(dbgs() << "V60" << (isLate ? "-LR " : " -- "));
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002064 DEBUG(LRMI.dump());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002065 DEBUG(dbgs() << "V60" << (isEarly ? "-ES " : " -- "));
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002066 DEBUG(ESMI.dump());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002067
2068 if (isLate && isEarly) {
2069 DEBUG(dbgs() << "++Is Late Result feeding Early Source\n");
2070 return true;
2071 }
2072
2073 return false;
2074}
2075
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002076bool HexagonInstrInfo::isLateResultInstr(const MachineInstr &MI) const {
2077 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002078 case TargetOpcode::EXTRACT_SUBREG:
2079 case TargetOpcode::INSERT_SUBREG:
2080 case TargetOpcode::SUBREG_TO_REG:
2081 case TargetOpcode::REG_SEQUENCE:
2082 case TargetOpcode::IMPLICIT_DEF:
2083 case TargetOpcode::COPY:
2084 case TargetOpcode::INLINEASM:
2085 case TargetOpcode::PHI:
2086 return false;
2087 default:
2088 break;
2089 }
2090
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002091 unsigned SchedClass = MI.getDesc().getSchedClass();
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002092 return !is_TC1(SchedClass);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002093}
2094
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002095bool HexagonInstrInfo::isLateSourceInstr(const MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002096 // Instructions with iclass A_CVI_VX and attribute A_CVI_LATE uses a multiply
2097 // resource, but all operands can be received late like an ALU instruction.
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002098 return getType(MI) == HexagonII::TypeCVI_VX_LATE;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002099}
2100
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002101bool HexagonInstrInfo::isLoopN(const MachineInstr &MI) const {
2102 unsigned Opcode = MI.getOpcode();
Krzysztof Parzyszek5e6f2bd2015-12-14 21:32:25 +00002103 return Opcode == Hexagon::J2_loop0i ||
2104 Opcode == Hexagon::J2_loop0r ||
2105 Opcode == Hexagon::J2_loop0iext ||
2106 Opcode == Hexagon::J2_loop0rext ||
2107 Opcode == Hexagon::J2_loop1i ||
2108 Opcode == Hexagon::J2_loop1r ||
2109 Opcode == Hexagon::J2_loop1iext ||
2110 Opcode == Hexagon::J2_loop1rext;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002111}
2112
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002113bool HexagonInstrInfo::isMemOp(const MachineInstr &MI) const {
2114 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002115 default: return false;
Eugene Zelenko3b873362017-09-28 22:27:31 +00002116 case Hexagon::L4_iadd_memopw_io:
2117 case Hexagon::L4_isub_memopw_io:
2118 case Hexagon::L4_add_memopw_io:
2119 case Hexagon::L4_sub_memopw_io:
2120 case Hexagon::L4_and_memopw_io:
2121 case Hexagon::L4_or_memopw_io:
2122 case Hexagon::L4_iadd_memoph_io:
2123 case Hexagon::L4_isub_memoph_io:
2124 case Hexagon::L4_add_memoph_io:
2125 case Hexagon::L4_sub_memoph_io:
2126 case Hexagon::L4_and_memoph_io:
2127 case Hexagon::L4_or_memoph_io:
2128 case Hexagon::L4_iadd_memopb_io:
2129 case Hexagon::L4_isub_memopb_io:
2130 case Hexagon::L4_add_memopb_io:
2131 case Hexagon::L4_sub_memopb_io:
2132 case Hexagon::L4_and_memopb_io:
2133 case Hexagon::L4_or_memopb_io:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002134 case Hexagon::L4_ior_memopb_io:
2135 case Hexagon::L4_ior_memoph_io:
2136 case Hexagon::L4_ior_memopw_io:
2137 case Hexagon::L4_iand_memopb_io:
2138 case Hexagon::L4_iand_memoph_io:
2139 case Hexagon::L4_iand_memopw_io:
2140 return true;
2141 }
2142 return false;
2143}
2144
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002145bool HexagonInstrInfo::isNewValue(const MachineInstr &MI) const {
2146 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002147 return (F >> HexagonII::NewValuePos) & HexagonII::NewValueMask;
2148}
2149
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002150bool HexagonInstrInfo::isNewValue(unsigned Opcode) const {
2151 const uint64_t F = get(Opcode).TSFlags;
2152 return (F >> HexagonII::NewValuePos) & HexagonII::NewValueMask;
2153}
2154
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002155bool HexagonInstrInfo::isNewValueInst(const MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002156 return isNewValueJump(MI) || isNewValueStore(MI);
2157}
2158
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002159bool HexagonInstrInfo::isNewValueJump(const MachineInstr &MI) const {
2160 return isNewValue(MI) && MI.isBranch();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002161}
2162
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002163bool HexagonInstrInfo::isNewValueJump(unsigned Opcode) const {
2164 return isNewValue(Opcode) && get(Opcode).isBranch() && isPredicated(Opcode);
2165}
2166
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002167bool HexagonInstrInfo::isNewValueStore(const MachineInstr &MI) const {
2168 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002169 return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask;
2170}
2171
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002172bool HexagonInstrInfo::isNewValueStore(unsigned Opcode) const {
2173 const uint64_t F = get(Opcode).TSFlags;
2174 return (F >> HexagonII::NVStorePos) & HexagonII::NVStoreMask;
2175}
2176
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002177// Returns true if a particular operand is extendable for an instruction.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002178bool HexagonInstrInfo::isOperandExtended(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002179 unsigned OperandNum) const {
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002180 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002181 return ((F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask)
2182 == OperandNum;
2183}
2184
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00002185bool HexagonInstrInfo::isPredicatedNew(const MachineInstr &MI) const {
2186 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002187 assert(isPredicated(MI));
2188 return (F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask;
2189}
2190
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002191bool HexagonInstrInfo::isPredicatedNew(unsigned Opcode) const {
2192 const uint64_t F = get(Opcode).TSFlags;
2193 assert(isPredicated(Opcode));
2194 return (F >> HexagonII::PredicatedNewPos) & HexagonII::PredicatedNewMask;
2195}
2196
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00002197bool HexagonInstrInfo::isPredicatedTrue(const MachineInstr &MI) const {
2198 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002199 return !((F >> HexagonII::PredicatedFalsePos) &
2200 HexagonII::PredicatedFalseMask);
2201}
2202
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002203bool HexagonInstrInfo::isPredicatedTrue(unsigned Opcode) const {
2204 const uint64_t F = get(Opcode).TSFlags;
2205 // Make sure that the instruction is predicated.
2206 assert((F>> HexagonII::PredicatedPos) & HexagonII::PredicatedMask);
2207 return !((F >> HexagonII::PredicatedFalsePos) &
2208 HexagonII::PredicatedFalseMask);
2209}
2210
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002211bool HexagonInstrInfo::isPredicated(unsigned Opcode) const {
2212 const uint64_t F = get(Opcode).TSFlags;
2213 return (F >> HexagonII::PredicatedPos) & HexagonII::PredicatedMask;
2214}
2215
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002216bool HexagonInstrInfo::isPredicateLate(unsigned Opcode) const {
2217 const uint64_t F = get(Opcode).TSFlags;
2218 return ~(F >> HexagonII::PredicateLatePos) & HexagonII::PredicateLateMask;
2219}
2220
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002221bool HexagonInstrInfo::isPredictedTaken(unsigned Opcode) const {
2222 const uint64_t F = get(Opcode).TSFlags;
2223 assert(get(Opcode).isBranch() &&
2224 (isPredicatedNew(Opcode) || isNewValue(Opcode)));
2225 return (F >> HexagonII::TakenPos) & HexagonII::TakenMask;
2226}
2227
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002228bool HexagonInstrInfo::isSaveCalleeSavedRegsCall(const MachineInstr &MI) const {
2229 return MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4 ||
2230 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT ||
2231 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_PIC ||
2232 MI.getOpcode() == Hexagon::SAVE_REGISTERS_CALL_V4_EXT_PIC;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002233}
2234
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00002235bool HexagonInstrInfo::isSignExtendingLoad(const MachineInstr &MI) const {
2236 switch (MI.getOpcode()) {
2237 // Byte
2238 case Hexagon::L2_loadrb_io:
2239 case Hexagon::L4_loadrb_ur:
2240 case Hexagon::L4_loadrb_ap:
2241 case Hexagon::L2_loadrb_pr:
2242 case Hexagon::L2_loadrb_pbr:
2243 case Hexagon::L2_loadrb_pi:
2244 case Hexagon::L2_loadrb_pci:
2245 case Hexagon::L2_loadrb_pcr:
2246 case Hexagon::L2_loadbsw2_io:
2247 case Hexagon::L4_loadbsw2_ur:
2248 case Hexagon::L4_loadbsw2_ap:
2249 case Hexagon::L2_loadbsw2_pr:
2250 case Hexagon::L2_loadbsw2_pbr:
2251 case Hexagon::L2_loadbsw2_pi:
2252 case Hexagon::L2_loadbsw2_pci:
2253 case Hexagon::L2_loadbsw2_pcr:
2254 case Hexagon::L2_loadbsw4_io:
2255 case Hexagon::L4_loadbsw4_ur:
2256 case Hexagon::L4_loadbsw4_ap:
2257 case Hexagon::L2_loadbsw4_pr:
2258 case Hexagon::L2_loadbsw4_pbr:
2259 case Hexagon::L2_loadbsw4_pi:
2260 case Hexagon::L2_loadbsw4_pci:
2261 case Hexagon::L2_loadbsw4_pcr:
2262 case Hexagon::L4_loadrb_rr:
2263 case Hexagon::L2_ploadrbt_io:
2264 case Hexagon::L2_ploadrbt_pi:
2265 case Hexagon::L2_ploadrbf_io:
2266 case Hexagon::L2_ploadrbf_pi:
2267 case Hexagon::L2_ploadrbtnew_io:
2268 case Hexagon::L2_ploadrbfnew_io:
2269 case Hexagon::L4_ploadrbt_rr:
2270 case Hexagon::L4_ploadrbf_rr:
2271 case Hexagon::L4_ploadrbtnew_rr:
2272 case Hexagon::L4_ploadrbfnew_rr:
2273 case Hexagon::L2_ploadrbtnew_pi:
2274 case Hexagon::L2_ploadrbfnew_pi:
2275 case Hexagon::L4_ploadrbt_abs:
2276 case Hexagon::L4_ploadrbf_abs:
2277 case Hexagon::L4_ploadrbtnew_abs:
2278 case Hexagon::L4_ploadrbfnew_abs:
2279 case Hexagon::L2_loadrbgp:
2280 // Half
2281 case Hexagon::L2_loadrh_io:
2282 case Hexagon::L4_loadrh_ur:
2283 case Hexagon::L4_loadrh_ap:
2284 case Hexagon::L2_loadrh_pr:
2285 case Hexagon::L2_loadrh_pbr:
2286 case Hexagon::L2_loadrh_pi:
2287 case Hexagon::L2_loadrh_pci:
2288 case Hexagon::L2_loadrh_pcr:
2289 case Hexagon::L4_loadrh_rr:
2290 case Hexagon::L2_ploadrht_io:
2291 case Hexagon::L2_ploadrht_pi:
2292 case Hexagon::L2_ploadrhf_io:
2293 case Hexagon::L2_ploadrhf_pi:
2294 case Hexagon::L2_ploadrhtnew_io:
2295 case Hexagon::L2_ploadrhfnew_io:
2296 case Hexagon::L4_ploadrht_rr:
2297 case Hexagon::L4_ploadrhf_rr:
2298 case Hexagon::L4_ploadrhtnew_rr:
2299 case Hexagon::L4_ploadrhfnew_rr:
2300 case Hexagon::L2_ploadrhtnew_pi:
2301 case Hexagon::L2_ploadrhfnew_pi:
2302 case Hexagon::L4_ploadrht_abs:
2303 case Hexagon::L4_ploadrhf_abs:
2304 case Hexagon::L4_ploadrhtnew_abs:
2305 case Hexagon::L4_ploadrhfnew_abs:
2306 case Hexagon::L2_loadrhgp:
2307 return true;
2308 default:
2309 return false;
Krzysztof Parzyszekfd02aad2016-02-12 18:37:23 +00002310 }
2311}
2312
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002313bool HexagonInstrInfo::isSolo(const MachineInstr &MI) const {
2314 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002315 return (F >> HexagonII::SoloPos) & HexagonII::SoloMask;
2316}
2317
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002318bool HexagonInstrInfo::isSpillPredRegOp(const MachineInstr &MI) const {
2319 switch (MI.getOpcode()) {
Eugene Zelenko3b873362017-09-28 22:27:31 +00002320 case Hexagon::STriw_pred:
2321 case Hexagon::LDriw_pred:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002322 return true;
2323 default:
2324 return false;
2325 }
2326}
2327
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002328bool HexagonInstrInfo::isTailCall(const MachineInstr &MI) const {
2329 if (!MI.isBranch())
Krzysztof Parzyszekecea07c2016-07-14 19:30:55 +00002330 return false;
2331
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002332 for (auto &Op : MI.operands())
Krzysztof Parzyszekecea07c2016-07-14 19:30:55 +00002333 if (Op.isGlobal() || Op.isSymbol())
2334 return true;
2335 return false;
2336}
2337
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002338// Returns true when SU has a timing class TC1.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002339bool HexagonInstrInfo::isTC1(const MachineInstr &MI) const {
2340 unsigned SchedClass = MI.getDesc().getSchedClass();
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002341 return is_TC1(SchedClass);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002342}
2343
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002344bool HexagonInstrInfo::isTC2(const MachineInstr &MI) const {
2345 unsigned SchedClass = MI.getDesc().getSchedClass();
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002346 return is_TC2(SchedClass);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002347}
2348
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002349bool HexagonInstrInfo::isTC2Early(const MachineInstr &MI) const {
2350 unsigned SchedClass = MI.getDesc().getSchedClass();
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002351 return is_TC2early(SchedClass);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002352}
2353
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002354bool HexagonInstrInfo::isTC4x(const MachineInstr &MI) const {
2355 unsigned SchedClass = MI.getDesc().getSchedClass();
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002356 return is_TC4x(SchedClass);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002357}
2358
Krzysztof Parzyszek408e3002016-07-15 21:34:02 +00002359// Schedule this ASAP.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002360bool HexagonInstrInfo::isToBeScheduledASAP(const MachineInstr &MI1,
2361 const MachineInstr &MI2) const {
Krzysztof Parzyszek408e3002016-07-15 21:34:02 +00002362 if (mayBeCurLoad(MI1)) {
2363 // if (result of SU is used in Next) return true;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002364 unsigned DstReg = MI1.getOperand(0).getReg();
2365 int N = MI2.getNumOperands();
Krzysztof Parzyszek408e3002016-07-15 21:34:02 +00002366 for (int I = 0; I < N; I++)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002367 if (MI2.getOperand(I).isReg() && DstReg == MI2.getOperand(I).getReg())
Krzysztof Parzyszek408e3002016-07-15 21:34:02 +00002368 return true;
2369 }
2370 if (mayBeNewStore(MI2))
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002371 if (MI2.getOpcode() == Hexagon::V6_vS32b_pi)
2372 if (MI1.getOperand(0).isReg() && MI2.getOperand(3).isReg() &&
2373 MI1.getOperand(0).getReg() == MI2.getOperand(3).getReg())
Krzysztof Parzyszek408e3002016-07-15 21:34:02 +00002374 return true;
2375 return false;
2376}
2377
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002378bool HexagonInstrInfo::isHVXVec(const MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002379 const uint64_t V = getType(MI);
2380 return HexagonII::TypeCVI_FIRST <= V && V <= HexagonII::TypeCVI_LAST;
2381}
2382
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002383// Check if the Offset is a valid auto-inc imm by Load/Store Type.
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00002384bool HexagonInstrInfo::isValidAutoIncImm(const EVT VT, int Offset) const {
2385 int Size = VT.getSizeInBits() / 8;
2386 if (Offset % Size != 0)
2387 return false;
2388 int Count = Offset / Size;
2389
2390 switch (VT.getSimpleVT().SimpleTy) {
2391 // For scalars the auto-inc is s4
2392 case MVT::i8:
2393 case MVT::i16:
2394 case MVT::i32:
2395 case MVT::i64:
2396 return isInt<4>(Count);
2397 // For HVX vectors the auto-inc is s3
2398 case MVT::v64i8:
2399 case MVT::v32i16:
2400 case MVT::v16i32:
2401 case MVT::v8i64:
2402 case MVT::v128i8:
2403 case MVT::v64i16:
2404 case MVT::v32i32:
2405 case MVT::v16i64:
2406 return isInt<3>(Count);
2407 default:
2408 break;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002409 }
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00002410
2411 llvm_unreachable("Not an valid type!");
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002412}
2413
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002414bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset,
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00002415 const TargetRegisterInfo *TRI, bool Extend) const {
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002416 // This function is to check whether the "Offset" is in the correct range of
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002417 // the given "Opcode". If "Offset" is not in the correct range, "A2_addi" is
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002418 // inserted to calculate the final address. Due to this reason, the function
2419 // assumes that the "Offset" has correct alignment.
Jyotsna Vermaec613662013-03-14 19:08:03 +00002420 // We used to assert if the offset was not properly aligned, however,
2421 // there are cases where a misaligned pointer recast can cause this
2422 // problem, and we need to allow for it. The front end warns of such
2423 // misaligns with respect to load size.
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002424 switch (Opcode) {
Krzysztof Parzyszek17aa4132016-08-16 15:43:54 +00002425 case Hexagon::PS_vstorerq_ai:
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +00002426 case Hexagon::PS_vstorerw_ai:
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002427 case Hexagon::PS_vstorerw_nt_ai:
Krzysztof Parzyszek17aa4132016-08-16 15:43:54 +00002428 case Hexagon::PS_vloadrq_ai:
Krzysztof Parzyszekf2859632016-08-12 21:05:05 +00002429 case Hexagon::PS_vloadrw_ai:
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002430 case Hexagon::PS_vloadrw_nt_ai:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002431 case Hexagon::V6_vL32b_ai:
2432 case Hexagon::V6_vS32b_ai:
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00002433 case Hexagon::V6_vL32b_nt_ai:
2434 case Hexagon::V6_vS32b_nt_ai:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002435 case Hexagon::V6_vL32Ub_ai:
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00002436 case Hexagon::V6_vS32Ub_ai: {
2437 unsigned VectorSize = TRI->getSpillSize(Hexagon::HvxVRRegClass);
2438 assert(isPowerOf2_32(VectorSize));
2439 if (Offset & (VectorSize-1))
2440 return false;
2441 return isInt<4>(Offset >> Log2_32(VectorSize));
2442 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002443
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002444 case Hexagon::J2_loop0i:
2445 case Hexagon::J2_loop1i:
2446 return isUInt<10>(Offset);
Krzysztof Parzyszekbba0bf72016-07-15 15:35:52 +00002447
2448 case Hexagon::S4_storeirb_io:
2449 case Hexagon::S4_storeirbt_io:
2450 case Hexagon::S4_storeirbf_io:
2451 return isUInt<6>(Offset);
2452
2453 case Hexagon::S4_storeirh_io:
2454 case Hexagon::S4_storeirht_io:
2455 case Hexagon::S4_storeirhf_io:
2456 return isShiftedUInt<6,1>(Offset);
2457
2458 case Hexagon::S4_storeiri_io:
2459 case Hexagon::S4_storeirit_io:
2460 case Hexagon::S4_storeirif_io:
2461 return isShiftedUInt<6,2>(Offset);
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002462 }
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002463
Krzysztof Parzyszek05902162015-04-22 17:51:26 +00002464 if (Extend)
2465 return true;
2466
2467 switch (Opcode) {
Colin LeMahieu026e88d2014-12-23 20:02:16 +00002468 case Hexagon::L2_loadri_io:
Colin LeMahieubda31b42014-12-29 20:44:51 +00002469 case Hexagon::S2_storeri_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002470 return (Offset >= Hexagon_MEMW_OFFSET_MIN) &&
2471 (Offset <= Hexagon_MEMW_OFFSET_MAX);
2472
Colin LeMahieu947cd702014-12-23 20:44:59 +00002473 case Hexagon::L2_loadrd_io:
Colin LeMahieubda31b42014-12-29 20:44:51 +00002474 case Hexagon::S2_storerd_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002475 return (Offset >= Hexagon_MEMD_OFFSET_MIN) &&
2476 (Offset <= Hexagon_MEMD_OFFSET_MAX);
2477
Colin LeMahieu8e39cad2014-12-23 17:25:57 +00002478 case Hexagon::L2_loadrh_io:
Colin LeMahieua9386d22014-12-23 16:42:57 +00002479 case Hexagon::L2_loadruh_io:
Colin LeMahieubda31b42014-12-29 20:44:51 +00002480 case Hexagon::S2_storerh_io:
Krzysztof Parzyszekd10df492017-05-03 15:36:51 +00002481 case Hexagon::S2_storerf_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002482 return (Offset >= Hexagon_MEMH_OFFSET_MIN) &&
2483 (Offset <= Hexagon_MEMH_OFFSET_MAX);
2484
Colin LeMahieu4b1eac42014-12-22 21:40:43 +00002485 case Hexagon::L2_loadrb_io:
Colin LeMahieuaf1e5de2014-12-22 21:20:03 +00002486 case Hexagon::L2_loadrub_io:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002487 case Hexagon::S2_storerb_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002488 return (Offset >= Hexagon_MEMB_OFFSET_MIN) &&
2489 (Offset <= Hexagon_MEMB_OFFSET_MAX);
2490
Colin LeMahieuf297dbe2015-02-05 17:49:13 +00002491 case Hexagon::A2_addi:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002492 return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&
2493 (Offset <= Hexagon_ADDI_OFFSET_MAX);
2494
Eugene Zelenko3b873362017-09-28 22:27:31 +00002495 case Hexagon::L4_iadd_memopw_io:
2496 case Hexagon::L4_isub_memopw_io:
2497 case Hexagon::L4_add_memopw_io:
2498 case Hexagon::L4_sub_memopw_io:
2499 case Hexagon::L4_and_memopw_io:
2500 case Hexagon::L4_or_memopw_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002501 return (0 <= Offset && Offset <= 255);
2502
Eugene Zelenko3b873362017-09-28 22:27:31 +00002503 case Hexagon::L4_iadd_memoph_io:
2504 case Hexagon::L4_isub_memoph_io:
2505 case Hexagon::L4_add_memoph_io:
2506 case Hexagon::L4_sub_memoph_io:
2507 case Hexagon::L4_and_memoph_io:
2508 case Hexagon::L4_or_memoph_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002509 return (0 <= Offset && Offset <= 127);
2510
Eugene Zelenko3b873362017-09-28 22:27:31 +00002511 case Hexagon::L4_iadd_memopb_io:
2512 case Hexagon::L4_isub_memopb_io:
2513 case Hexagon::L4_add_memopb_io:
2514 case Hexagon::L4_sub_memopb_io:
2515 case Hexagon::L4_and_memopb_io:
2516 case Hexagon::L4_or_memopb_io:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002517 return (0 <= Offset && Offset <= 63);
2518
Krzysztof Parzyszekfd02aad2016-02-12 18:37:23 +00002519 // LDriw_xxx and STriw_xxx are pseudo operations, so it has to take offset of
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002520 // any size. Later pass knows how to handle it.
2521 case Hexagon::STriw_pred:
2522 case Hexagon::LDriw_pred:
Krzysztof Parzyszek7b413c62016-01-22 19:15:58 +00002523 case Hexagon::STriw_mod:
2524 case Hexagon::LDriw_mod:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002525 return true;
2526
Krzysztof Parzyszek1d01a792016-08-16 18:08:40 +00002527 case Hexagon::PS_fi:
2528 case Hexagon::PS_fia:
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002529 case Hexagon::INLINEASM:
2530 return true;
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00002531
2532 case Hexagon::L2_ploadrbt_io:
2533 case Hexagon::L2_ploadrbf_io:
2534 case Hexagon::L2_ploadrubt_io:
2535 case Hexagon::L2_ploadrubf_io:
2536 case Hexagon::S2_pstorerbt_io:
2537 case Hexagon::S2_pstorerbf_io:
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00002538 return isUInt<6>(Offset);
2539
2540 case Hexagon::L2_ploadrht_io:
2541 case Hexagon::L2_ploadrhf_io:
2542 case Hexagon::L2_ploadruht_io:
2543 case Hexagon::L2_ploadruhf_io:
2544 case Hexagon::S2_pstorerht_io:
2545 case Hexagon::S2_pstorerhf_io:
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00002546 return isShiftedUInt<6,1>(Offset);
2547
2548 case Hexagon::L2_ploadrit_io:
2549 case Hexagon::L2_ploadrif_io:
2550 case Hexagon::S2_pstorerit_io:
2551 case Hexagon::S2_pstorerif_io:
Krzysztof Parzyszekfb338242015-10-06 15:49:14 +00002552 return isShiftedUInt<6,2>(Offset);
2553
2554 case Hexagon::L2_ploadrdt_io:
2555 case Hexagon::L2_ploadrdf_io:
2556 case Hexagon::S2_pstorerdt_io:
2557 case Hexagon::S2_pstorerdf_io:
2558 return isShiftedUInt<6,3>(Offset);
2559 } // switch
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002560
Benjamin Kramerb6684012011-12-27 11:41:05 +00002561 llvm_unreachable("No offset range is defined for this opcode. "
2562 "Please define it in the above switch statement!");
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002563}
2564
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002565bool HexagonInstrInfo::isVecAcc(const MachineInstr &MI) const {
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002566 return isHVXVec(MI) && isAccumulator(MI);
Tony Linthicum1213a7a2011-12-12 21:14:40 +00002567}
2568
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002569bool HexagonInstrInfo::isVecALU(const MachineInstr &MI) const {
2570 const uint64_t F = get(MI.getOpcode()).TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002571 const uint64_t V = ((F >> HexagonII::TypePos) & HexagonII::TypeMask);
2572 return
2573 V == HexagonII::TypeCVI_VA ||
2574 V == HexagonII::TypeCVI_VA_DV;
2575}
Andrew Trickd06df962012-02-01 22:13:57 +00002576
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002577bool HexagonInstrInfo::isVecUsableNextPacket(const MachineInstr &ProdMI,
2578 const MachineInstr &ConsMI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002579 if (EnableACCForwarding && isVecAcc(ProdMI) && isVecAcc(ConsMI))
2580 return true;
2581
2582 if (EnableALUForwarding && (isVecALU(ConsMI) || isLateSourceInstr(ConsMI)))
2583 return true;
2584
2585 if (mayBeNewStore(ConsMI))
Andrew Trickd06df962012-02-01 22:13:57 +00002586 return true;
2587
2588 return false;
2589}
Jyotsna Verma84256432013-03-01 17:37:13 +00002590
Duncan P. N. Exon Smith9cfc75c2016-06-30 00:01:54 +00002591bool HexagonInstrInfo::isZeroExtendingLoad(const MachineInstr &MI) const {
2592 switch (MI.getOpcode()) {
2593 // Byte
2594 case Hexagon::L2_loadrub_io:
2595 case Hexagon::L4_loadrub_ur:
2596 case Hexagon::L4_loadrub_ap:
2597 case Hexagon::L2_loadrub_pr:
2598 case Hexagon::L2_loadrub_pbr:
2599 case Hexagon::L2_loadrub_pi:
2600 case Hexagon::L2_loadrub_pci:
2601 case Hexagon::L2_loadrub_pcr:
2602 case Hexagon::L2_loadbzw2_io:
2603 case Hexagon::L4_loadbzw2_ur:
2604 case Hexagon::L4_loadbzw2_ap:
2605 case Hexagon::L2_loadbzw2_pr:
2606 case Hexagon::L2_loadbzw2_pbr:
2607 case Hexagon::L2_loadbzw2_pi:
2608 case Hexagon::L2_loadbzw2_pci:
2609 case Hexagon::L2_loadbzw2_pcr:
2610 case Hexagon::L2_loadbzw4_io:
2611 case Hexagon::L4_loadbzw4_ur:
2612 case Hexagon::L4_loadbzw4_ap:
2613 case Hexagon::L2_loadbzw4_pr:
2614 case Hexagon::L2_loadbzw4_pbr:
2615 case Hexagon::L2_loadbzw4_pi:
2616 case Hexagon::L2_loadbzw4_pci:
2617 case Hexagon::L2_loadbzw4_pcr:
2618 case Hexagon::L4_loadrub_rr:
2619 case Hexagon::L2_ploadrubt_io:
2620 case Hexagon::L2_ploadrubt_pi:
2621 case Hexagon::L2_ploadrubf_io:
2622 case Hexagon::L2_ploadrubf_pi:
2623 case Hexagon::L2_ploadrubtnew_io:
2624 case Hexagon::L2_ploadrubfnew_io:
2625 case Hexagon::L4_ploadrubt_rr:
2626 case Hexagon::L4_ploadrubf_rr:
2627 case Hexagon::L4_ploadrubtnew_rr:
2628 case Hexagon::L4_ploadrubfnew_rr:
2629 case Hexagon::L2_ploadrubtnew_pi:
2630 case Hexagon::L2_ploadrubfnew_pi:
2631 case Hexagon::L4_ploadrubt_abs:
2632 case Hexagon::L4_ploadrubf_abs:
2633 case Hexagon::L4_ploadrubtnew_abs:
2634 case Hexagon::L4_ploadrubfnew_abs:
2635 case Hexagon::L2_loadrubgp:
2636 // Half
2637 case Hexagon::L2_loadruh_io:
2638 case Hexagon::L4_loadruh_ur:
2639 case Hexagon::L4_loadruh_ap:
2640 case Hexagon::L2_loadruh_pr:
2641 case Hexagon::L2_loadruh_pbr:
2642 case Hexagon::L2_loadruh_pi:
2643 case Hexagon::L2_loadruh_pci:
2644 case Hexagon::L2_loadruh_pcr:
2645 case Hexagon::L4_loadruh_rr:
2646 case Hexagon::L2_ploadruht_io:
2647 case Hexagon::L2_ploadruht_pi:
2648 case Hexagon::L2_ploadruhf_io:
2649 case Hexagon::L2_ploadruhf_pi:
2650 case Hexagon::L2_ploadruhtnew_io:
2651 case Hexagon::L2_ploadruhfnew_io:
2652 case Hexagon::L4_ploadruht_rr:
2653 case Hexagon::L4_ploadruhf_rr:
2654 case Hexagon::L4_ploadruhtnew_rr:
2655 case Hexagon::L4_ploadruhfnew_rr:
2656 case Hexagon::L2_ploadruhtnew_pi:
2657 case Hexagon::L2_ploadruhfnew_pi:
2658 case Hexagon::L4_ploadruht_abs:
2659 case Hexagon::L4_ploadruhf_abs:
2660 case Hexagon::L4_ploadruhtnew_abs:
2661 case Hexagon::L4_ploadruhfnew_abs:
2662 case Hexagon::L2_loadruhgp:
2663 return true;
2664 default:
2665 return false;
Krzysztof Parzyszekfd02aad2016-02-12 18:37:23 +00002666 }
2667}
2668
Krzysztof Parzyszek408e3002016-07-15 21:34:02 +00002669// Add latency to instruction.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002670bool HexagonInstrInfo::addLatencyToSchedule(const MachineInstr &MI1,
2671 const MachineInstr &MI2) const {
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002672 if (isHVXVec(MI1) && isHVXVec(MI2))
Krzysztof Parzyszek408e3002016-07-15 21:34:02 +00002673 if (!isVecUsableNextPacket(MI1, MI2))
2674 return true;
2675 return false;
2676}
2677
Brendon Cahoon254f8892016-07-29 16:44:44 +00002678/// \brief Get the base register and byte offset of a load/store instr.
2679bool HexagonInstrInfo::getMemOpBaseRegImmOfs(MachineInstr &LdSt,
2680 unsigned &BaseReg, int64_t &Offset, const TargetRegisterInfo *TRI)
2681 const {
2682 unsigned AccessSize = 0;
2683 int OffsetVal = 0;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002684 BaseReg = getBaseAndOffset(LdSt, OffsetVal, AccessSize);
Brendon Cahoon254f8892016-07-29 16:44:44 +00002685 Offset = OffsetVal;
2686 return BaseReg != 0;
2687}
2688
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00002689/// \brief Can these instructions execute at the same time in a bundle.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002690bool HexagonInstrInfo::canExecuteInBundle(const MachineInstr &First,
2691 const MachineInstr &Second) const {
Krzysztof Parzyszek4763c2d2017-05-03 15:33:09 +00002692 if (Second.mayStore() && First.getOpcode() == Hexagon::S2_allocframe) {
2693 const MachineOperand &Op = Second.getOperand(0);
2694 if (Op.isReg() && Op.isUse() && Op.getReg() == Hexagon::R29)
2695 return true;
2696 }
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00002697 if (DisableNVSchedule)
2698 return false;
2699 if (mayBeNewStore(Second)) {
2700 // Make sure the definition of the first instruction is the value being
2701 // stored.
2702 const MachineOperand &Stored =
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002703 Second.getOperand(Second.getNumOperands() - 1);
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00002704 if (!Stored.isReg())
2705 return false;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002706 for (unsigned i = 0, e = First.getNumOperands(); i < e; ++i) {
2707 const MachineOperand &Op = First.getOperand(i);
Krzysztof Parzyszek56bbf542015-12-16 19:36:12 +00002708 if (Op.isReg() && Op.isDef() && Op.getReg() == Stored.getReg())
2709 return true;
2710 }
2711 }
2712 return false;
2713}
2714
Krzysztof Parzyszek1b689da2016-08-11 21:14:25 +00002715bool HexagonInstrInfo::doesNotReturn(const MachineInstr &CallMI) const {
2716 unsigned Opc = CallMI.getOpcode();
Krzysztof Parzyszekbe976d42016-08-12 11:12:02 +00002717 return Opc == Hexagon::PS_call_nr || Opc == Hexagon::PS_callr_nr;
Krzysztof Parzyszek1b689da2016-08-11 21:14:25 +00002718}
2719
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002720bool HexagonInstrInfo::hasEHLabel(const MachineBasicBlock *B) const {
2721 for (auto &I : *B)
2722 if (I.isEHLabel())
2723 return true;
2724 return false;
Jyotsna Verma84256432013-03-01 17:37:13 +00002725}
2726
Jyotsna Verma84256432013-03-01 17:37:13 +00002727// Returns true if an instruction can be converted into a non-extended
2728// equivalent instruction.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002729bool HexagonInstrInfo::hasNonExtEquivalent(const MachineInstr &MI) const {
Jyotsna Verma84256432013-03-01 17:37:13 +00002730 short NonExtOpcode;
2731 // Check if the instruction has a register form that uses register in place
2732 // of the extended operand, if so return that as the non-extended form.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002733 if (Hexagon::getRegForm(MI.getOpcode()) >= 0)
Jyotsna Verma84256432013-03-01 17:37:13 +00002734 return true;
2735
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002736 if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {
Alp Tokercb402912014-01-24 17:20:08 +00002737 // Check addressing mode and retrieve non-ext equivalent instruction.
Jyotsna Verma84256432013-03-01 17:37:13 +00002738
2739 switch (getAddrMode(MI)) {
Eugene Zelenko3b873362017-09-28 22:27:31 +00002740 case HexagonII::Absolute:
Jyotsna Verma84256432013-03-01 17:37:13 +00002741 // Load/store with absolute addressing mode can be converted into
2742 // base+offset mode.
Krzysztof Parzyszek7ae3ae92017-10-05 20:01:38 +00002743 NonExtOpcode = Hexagon::changeAddrMode_abs_io(MI.getOpcode());
Jyotsna Verma84256432013-03-01 17:37:13 +00002744 break;
Eugene Zelenko3b873362017-09-28 22:27:31 +00002745 case HexagonII::BaseImmOffset:
Jyotsna Verma84256432013-03-01 17:37:13 +00002746 // Load/store with base+offset addressing mode can be converted into
2747 // base+register offset addressing mode. However left shift operand should
2748 // be set to 0.
Krzysztof Parzyszek7ae3ae92017-10-05 20:01:38 +00002749 NonExtOpcode = Hexagon::changeAddrMode_io_rr(MI.getOpcode());
Jyotsna Verma84256432013-03-01 17:37:13 +00002750 break;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002751 case HexagonII::BaseLongOffset:
Krzysztof Parzyszek7ae3ae92017-10-05 20:01:38 +00002752 NonExtOpcode = Hexagon::changeAddrMode_ur_rr(MI.getOpcode());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002753 break;
Jyotsna Verma84256432013-03-01 17:37:13 +00002754 default:
2755 return false;
2756 }
2757 if (NonExtOpcode < 0)
2758 return false;
2759 return true;
2760 }
2761 return false;
2762}
2763
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002764bool HexagonInstrInfo::hasPseudoInstrPair(const MachineInstr &MI) const {
2765 return Hexagon::getRealHWInstr(MI.getOpcode(),
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002766 Hexagon::InstrType_Pseudo) >= 0;
2767}
2768
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002769bool HexagonInstrInfo::hasUncondBranch(const MachineBasicBlock *B)
2770 const {
2771 MachineBasicBlock::const_iterator I = B->getFirstTerminator(), E = B->end();
2772 while (I != E) {
2773 if (I->isBarrier())
2774 return true;
2775 ++I;
2776 }
2777 return false;
2778}
2779
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002780// Returns true, if a LD insn can be promoted to a cur load.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002781bool HexagonInstrInfo::mayBeCurLoad(const MachineInstr &MI) const {
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002782 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002783 return ((F >> HexagonII::mayCVLoadPos) & HexagonII::mayCVLoadMask) &&
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +00002784 Subtarget.hasV60TOps();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002785}
2786
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002787// Returns true, if a ST insn can be promoted to a new-value store.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002788bool HexagonInstrInfo::mayBeNewStore(const MachineInstr &MI) const {
2789 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002790 return (F >> HexagonII::mayNVStorePos) & HexagonII::mayNVStoreMask;
2791}
2792
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002793bool HexagonInstrInfo::producesStall(const MachineInstr &ProdMI,
2794 const MachineInstr &ConsMI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002795 // There is no stall when ProdMI is not a V60 vector.
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002796 if (!isHVXVec(ProdMI))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002797 return false;
2798
2799 // There is no stall when ProdMI and ConsMI are not dependent.
2800 if (!isDependent(ProdMI, ConsMI))
2801 return false;
2802
2803 // When Forward Scheduling is enabled, there is no stall if ProdMI and ConsMI
2804 // are scheduled in consecutive packets.
2805 if (isVecUsableNextPacket(ProdMI, ConsMI))
2806 return false;
2807
2808 return true;
2809}
2810
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002811bool HexagonInstrInfo::producesStall(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002812 MachineBasicBlock::const_instr_iterator BII) const {
2813 // There is no stall when I is not a V60 vector.
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00002814 if (!isHVXVec(MI))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002815 return false;
2816
2817 MachineBasicBlock::const_instr_iterator MII = BII;
2818 MachineBasicBlock::const_instr_iterator MIE = MII->getParent()->instr_end();
2819
Krzysztof Parzyszek9aaf9232017-05-02 18:12:19 +00002820 if (!(*MII).isBundle()) {
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002821 const MachineInstr &J = *MII;
Krzysztof Parzyszek9aaf9232017-05-02 18:12:19 +00002822 return producesStall(J, MI);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002823 }
2824
2825 for (++MII; MII != MIE && MII->isInsideBundle(); ++MII) {
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002826 const MachineInstr &J = *MII;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002827 if (producesStall(J, MI))
2828 return true;
2829 }
2830 return false;
2831}
2832
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002833bool HexagonInstrInfo::predCanBeUsedAsDotNew(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002834 unsigned PredReg) const {
Krzysztof Parzyszek1aaf41a2017-02-17 22:14:51 +00002835 for (const MachineOperand &MO : MI.operands()) {
2836 // Predicate register must be explicitly defined.
2837 if (MO.isRegMask() && MO.clobbersPhysReg(PredReg))
2838 return false;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002839 if (MO.isReg() && MO.isDef() && MO.isImplicit() && (MO.getReg() == PredReg))
Krzysztof Parzyszek1aaf41a2017-02-17 22:14:51 +00002840 return false;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002841 }
2842
2843 // Hexagon Programmer's Reference says that decbin, memw_locked, and
2844 // memd_locked cannot be used as .new as well,
2845 // but we don't seem to have these instructions defined.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002846 return MI.getOpcode() != Hexagon::A4_tlbmatch;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002847}
2848
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002849bool HexagonInstrInfo::PredOpcodeHasJMP_c(unsigned Opcode) const {
Krzysztof Parzyszek19635bd2017-05-03 15:30:46 +00002850 return Opcode == Hexagon::J2_jumpt ||
2851 Opcode == Hexagon::J2_jumptpt ||
2852 Opcode == Hexagon::J2_jumpf ||
2853 Opcode == Hexagon::J2_jumpfpt ||
2854 Opcode == Hexagon::J2_jumptnew ||
2855 Opcode == Hexagon::J2_jumpfnew ||
2856 Opcode == Hexagon::J2_jumptnewpt ||
2857 Opcode == Hexagon::J2_jumpfnewpt;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002858}
2859
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002860bool HexagonInstrInfo::predOpcodeHasNot(ArrayRef<MachineOperand> Cond) const {
2861 if (Cond.empty() || !isPredicated(Cond[0].getImm()))
2862 return false;
2863 return !isPredicatedTrue(Cond[0].getImm());
2864}
2865
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002866unsigned HexagonInstrInfo::getAddrMode(const MachineInstr &MI) const {
2867 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002868 return (F >> HexagonII::AddrModePos) & HexagonII::AddrModeMask;
2869}
2870
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002871// Returns the base register in a memory access (load/store). The offset is
2872// returned in Offset and the access size is returned in AccessSize.
Krzysztof Parzyszekb449dc12017-07-19 15:39:28 +00002873// If the base register has a subregister or the offset field does not contain
2874// an immediate value, return 0.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002875unsigned HexagonInstrInfo::getBaseAndOffset(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002876 int &Offset, unsigned &AccessSize) const {
2877 // Return if it is not a base+offset type instruction or a MemOp.
2878 if (getAddrMode(MI) != HexagonII::BaseImmOffset &&
2879 getAddrMode(MI) != HexagonII::BaseLongOffset &&
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00002880 !isMemOp(MI) && !isPostIncrement(MI))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002881 return 0;
2882
Krzysztof Parzyszek473d02d2017-09-14 12:06:40 +00002883 AccessSize = getMemAccessSize(MI);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002884
Krzysztof Parzyszekb449dc12017-07-19 15:39:28 +00002885 unsigned BasePos = 0, OffsetPos = 0;
2886 if (!getBaseAndOffsetPosition(MI, BasePos, OffsetPos))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002887 return 0;
2888
2889 // Post increment updates its EA after the mem access,
2890 // so we need to treat its offset as zero.
Krzysztof Parzyszekb449dc12017-07-19 15:39:28 +00002891 if (isPostIncrement(MI)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002892 Offset = 0;
Krzysztof Parzyszekb449dc12017-07-19 15:39:28 +00002893 } else {
2894 const MachineOperand &OffsetOp = MI.getOperand(OffsetPos);
2895 if (!OffsetOp.isImm())
2896 return 0;
2897 Offset = OffsetOp.getImm();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002898 }
2899
Krzysztof Parzyszekb449dc12017-07-19 15:39:28 +00002900 const MachineOperand &BaseOp = MI.getOperand(BasePos);
2901 if (BaseOp.getSubReg() != 0)
2902 return 0;
2903 return BaseOp.getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002904}
2905
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002906/// Return the position of the base and offset operands for this instruction.
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00002907bool HexagonInstrInfo::getBaseAndOffsetPosition(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002908 unsigned &BasePos, unsigned &OffsetPos) const {
2909 // Deal with memops first.
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00002910 if (isMemOp(MI)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002911 BasePos = 0;
2912 OffsetPos = 1;
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00002913 } else if (MI.mayStore()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002914 BasePos = 0;
2915 OffsetPos = 1;
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00002916 } else if (MI.mayLoad()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002917 BasePos = 1;
2918 OffsetPos = 2;
2919 } else
2920 return false;
2921
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00002922 if (isPredicated(MI)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002923 BasePos++;
2924 OffsetPos++;
2925 }
2926 if (isPostIncrement(MI)) {
2927 BasePos++;
2928 OffsetPos++;
2929 }
2930
Krzysztof Parzyszek8fb181c2016-08-01 17:55:48 +00002931 if (!MI.getOperand(BasePos).isReg() || !MI.getOperand(OffsetPos).isImm())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002932 return false;
2933
2934 return true;
2935}
2936
Simon Pilgrim6ba672e2016-11-17 19:21:20 +00002937// Inserts branching instructions in reverse order of their occurrence.
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002938// e.g. jump_t t1 (i1)
2939// jump t2 (i2)
2940// Jumpers = {i2, i1}
2941SmallVector<MachineInstr*, 2> HexagonInstrInfo::getBranchingInstrs(
2942 MachineBasicBlock& MBB) const {
2943 SmallVector<MachineInstr*, 2> Jumpers;
2944 // If the block has no terminators, it just falls into the block after it.
2945 MachineBasicBlock::instr_iterator I = MBB.instr_end();
2946 if (I == MBB.instr_begin())
2947 return Jumpers;
2948
2949 // A basic block may looks like this:
2950 //
2951 // [ insn
2952 // EH_LABEL
2953 // insn
2954 // insn
2955 // insn
2956 // EH_LABEL
2957 // insn ]
2958 //
2959 // It has two succs but does not have a terminator
2960 // Don't know how to handle it.
2961 do {
2962 --I;
2963 if (I->isEHLabel())
2964 return Jumpers;
2965 } while (I != MBB.instr_begin());
2966
2967 I = MBB.instr_end();
2968 --I;
2969
2970 while (I->isDebugValue()) {
2971 if (I == MBB.instr_begin())
2972 return Jumpers;
2973 --I;
2974 }
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00002975 if (!isUnpredicatedTerminator(*I))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002976 return Jumpers;
2977
2978 // Get the last instruction in the block.
2979 MachineInstr *LastInst = &*I;
2980 Jumpers.push_back(LastInst);
2981 MachineInstr *SecondLastInst = nullptr;
2982 // Find one more terminator if present.
2983 do {
Duncan P. N. Exon Smith6307eb52016-02-23 02:46:52 +00002984 if (&*I != LastInst && !I->isBundle() && isUnpredicatedTerminator(*I)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002985 if (!SecondLastInst) {
2986 SecondLastInst = &*I;
2987 Jumpers.push_back(SecondLastInst);
2988 } else // This is a third branch.
2989 return Jumpers;
2990 }
2991 if (I == MBB.instr_begin())
2992 break;
2993 --I;
2994 } while (true);
2995 return Jumpers;
2996}
2997
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00002998// Returns Operand Index for the constant extended instruction.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00002999unsigned HexagonInstrInfo::getCExtOpNum(const MachineInstr &MI) const {
3000 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003001 return (F >> HexagonII::ExtendableOpPos) & HexagonII::ExtendableOpMask;
3002}
3003
3004// See if instruction could potentially be a duplex candidate.
3005// If so, return its group. Zero otherwise.
3006HexagonII::CompoundGroup HexagonInstrInfo::getCompoundCandidateGroup(
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003007 const MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003008 unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
3009
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003010 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003011 default:
3012 return HexagonII::HCG_None;
3013 //
3014 // Compound pairs.
3015 // "p0=cmp.eq(Rs16,Rt16); if (p0.new) jump:nt #r9:2"
3016 // "Rd16=#U6 ; jump #r9:2"
3017 // "Rd16=Rs16 ; jump #r9:2"
3018 //
3019 case Hexagon::C2_cmpeq:
3020 case Hexagon::C2_cmpgt:
3021 case Hexagon::C2_cmpgtu:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003022 DstReg = MI.getOperand(0).getReg();
3023 Src1Reg = MI.getOperand(1).getReg();
3024 Src2Reg = MI.getOperand(2).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003025 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3026 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
3027 isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg))
3028 return HexagonII::HCG_A;
3029 break;
3030 case Hexagon::C2_cmpeqi:
3031 case Hexagon::C2_cmpgti:
3032 case Hexagon::C2_cmpgtui:
3033 // P0 = cmp.eq(Rs,#u2)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003034 DstReg = MI.getOperand(0).getReg();
3035 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003036 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3037 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003038 isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() &&
3039 ((isUInt<5>(MI.getOperand(2).getImm())) ||
3040 (MI.getOperand(2).getImm() == -1)))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003041 return HexagonII::HCG_A;
3042 break;
3043 case Hexagon::A2_tfr:
3044 // Rd = Rs
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003045 DstReg = MI.getOperand(0).getReg();
3046 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003047 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
3048 return HexagonII::HCG_A;
3049 break;
3050 case Hexagon::A2_tfrsi:
3051 // Rd = #u6
3052 // Do not test for #u6 size since the const is getting extended
3053 // regardless and compound could be formed.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003054 DstReg = MI.getOperand(0).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003055 if (isIntRegForSubInst(DstReg))
3056 return HexagonII::HCG_A;
3057 break;
3058 case Hexagon::S2_tstbit_i:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003059 DstReg = MI.getOperand(0).getReg();
3060 Src1Reg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003061 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3062 (Hexagon::P0 == DstReg || Hexagon::P1 == DstReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003063 MI.getOperand(2).isImm() &&
3064 isIntRegForSubInst(Src1Reg) && (MI.getOperand(2).getImm() == 0))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003065 return HexagonII::HCG_A;
3066 break;
3067 // The fact that .new form is used pretty much guarantees
3068 // that predicate register will match. Nevertheless,
3069 // there could be some false positives without additional
3070 // checking.
3071 case Hexagon::J2_jumptnew:
3072 case Hexagon::J2_jumpfnew:
3073 case Hexagon::J2_jumptnewpt:
3074 case Hexagon::J2_jumpfnewpt:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003075 Src1Reg = MI.getOperand(0).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003076 if (Hexagon::PredRegsRegClass.contains(Src1Reg) &&
3077 (Hexagon::P0 == Src1Reg || Hexagon::P1 == Src1Reg))
3078 return HexagonII::HCG_B;
3079 break;
3080 // Transfer and jump:
3081 // Rd=#U6 ; jump #r9:2
3082 // Rd=Rs ; jump #r9:2
3083 // Do not test for jump range here.
3084 case Hexagon::J2_jump:
3085 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
Krzysztof Parzyszek5a7bef92016-08-19 17:20:57 +00003086 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003087 return HexagonII::HCG_C;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003088 }
3089
3090 return HexagonII::HCG_None;
3091}
3092
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003093// Returns -1 when there is no opcode found.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003094unsigned HexagonInstrInfo::getCompoundOpcode(const MachineInstr &GA,
3095 const MachineInstr &GB) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003096 assert(getCompoundCandidateGroup(GA) == HexagonII::HCG_A);
3097 assert(getCompoundCandidateGroup(GB) == HexagonII::HCG_B);
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003098 if ((GA.getOpcode() != Hexagon::C2_cmpeqi) ||
3099 (GB.getOpcode() != Hexagon::J2_jumptnew))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003100 return -1;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003101 unsigned DestReg = GA.getOperand(0).getReg();
3102 if (!GB.readsRegister(DestReg))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003103 return -1;
3104 if (DestReg == Hexagon::P0)
3105 return Hexagon::J4_cmpeqi_tp0_jump_nt;
3106 if (DestReg == Hexagon::P1)
3107 return Hexagon::J4_cmpeqi_tp1_jump_nt;
3108 return -1;
3109}
3110
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003111int HexagonInstrInfo::getCondOpcode(int Opc, bool invertPredicate) const {
3112 enum Hexagon::PredSense inPredSense;
3113 inPredSense = invertPredicate ? Hexagon::PredSense_false :
3114 Hexagon::PredSense_true;
3115 int CondOpcode = Hexagon::getPredOpcode(Opc, inPredSense);
3116 if (CondOpcode >= 0) // Valid Conditional opcode/instruction
3117 return CondOpcode;
3118
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003119 llvm_unreachable("Unexpected predicable instruction");
3120}
3121
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003122// Return the cur value instruction for a given store.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003123int HexagonInstrInfo::getDotCurOp(const MachineInstr &MI) const {
3124 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003125 default: llvm_unreachable("Unknown .cur type");
3126 case Hexagon::V6_vL32b_pi:
3127 return Hexagon::V6_vL32b_cur_pi;
3128 case Hexagon::V6_vL32b_ai:
3129 return Hexagon::V6_vL32b_cur_ai;
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00003130 case Hexagon::V6_vL32b_nt_pi:
3131 return Hexagon::V6_vL32b_nt_cur_pi;
3132 case Hexagon::V6_vL32b_nt_ai:
3133 return Hexagon::V6_vL32b_nt_cur_ai;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003134 }
3135 return 0;
3136}
3137
Krzysztof Parzyszek0a8043e2017-05-03 15:28:56 +00003138// Return the regular version of the .cur instruction.
3139int HexagonInstrInfo::getNonDotCurOp(const MachineInstr &MI) const {
3140 switch (MI.getOpcode()) {
3141 default: llvm_unreachable("Unknown .cur type");
3142 case Hexagon::V6_vL32b_cur_pi:
3143 return Hexagon::V6_vL32b_pi;
3144 case Hexagon::V6_vL32b_cur_ai:
3145 return Hexagon::V6_vL32b_ai;
Krzysztof Parzyszekc86e2ef2017-07-11 16:39:33 +00003146 case Hexagon::V6_vL32b_nt_cur_pi:
3147 return Hexagon::V6_vL32b_nt_pi;
3148 case Hexagon::V6_vL32b_nt_cur_ai:
3149 return Hexagon::V6_vL32b_nt_ai;
Krzysztof Parzyszek0a8043e2017-05-03 15:28:56 +00003150 }
3151 return 0;
3152}
3153
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003154// The diagram below shows the steps involved in the conversion of a predicated
3155// store instruction to its .new predicated new-value form.
3156//
Krzysztof Parzyszek0a8043e2017-05-03 15:28:56 +00003157// Note: It doesn't include conditional new-value stores as they can't be
3158// converted to .new predicate.
3159//
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003160// p.new NV store [ if(p0.new)memw(R0+#0)=R2.new ]
3161// ^ ^
3162// / \ (not OK. it will cause new-value store to be
3163// / X conditional on p0.new while R2 producer is
3164// / \ on p0)
3165// / \.
3166// p.new store p.old NV store
3167// [if(p0.new)memw(R0+#0)=R2] [if(p0)memw(R0+#0)=R2.new]
3168// ^ ^
3169// \ /
3170// \ /
3171// \ /
3172// p.old store
3173// [if (p0)memw(R0+#0)=R2]
3174//
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003175// The following set of instructions further explains the scenario where
3176// conditional new-value store becomes invalid when promoted to .new predicate
3177// form.
3178//
3179// { 1) if (p0) r0 = add(r1, r2)
3180// 2) p0 = cmp.eq(r3, #0) }
3181//
3182// 3) if (p0) memb(r1+#0) = r0 --> this instruction can't be grouped with
3183// the first two instructions because in instr 1, r0 is conditional on old value
3184// of p0 but its use in instr 3 is conditional on p0 modified by instr 2 which
3185// is not valid for new-value stores.
3186// Predicated new value stores (i.e. if (p0) memw(..)=r0.new) are excluded
3187// from the "Conditional Store" list. Because a predicated new value store
3188// would NOT be promoted to a double dot new store. See diagram below:
3189// This function returns yes for those stores that are predicated but not
3190// yet promoted to predicate dot new instructions.
3191//
3192// +---------------------+
3193// /-----| if (p0) memw(..)=r0 |---------\~
3194// || +---------------------+ ||
3195// promote || /\ /\ || promote
3196// || /||\ /||\ ||
3197// \||/ demote || \||/
3198// \/ || || \/
3199// +-------------------------+ || +-------------------------+
3200// | if (p0.new) memw(..)=r0 | || | if (p0) memw(..)=r0.new |
3201// +-------------------------+ || +-------------------------+
3202// || || ||
3203// || demote \||/
3204// promote || \/ NOT possible
3205// || || /\~
3206// \||/ || /||\~
3207// \/ || ||
3208// +-----------------------------+
3209// | if (p0.new) memw(..)=r0.new |
3210// +-----------------------------+
3211// Double Dot New Store
3212//
3213// Returns the most basic instruction for the .new predicated instructions and
3214// new-value stores.
3215// For example, all of the following instructions will be converted back to the
3216// same instruction:
3217// 1) if (p0.new) memw(R0+#0) = R1.new --->
3218// 2) if (p0) memw(R0+#0)= R1.new -------> if (p0) memw(R0+#0) = R1
3219// 3) if (p0.new) memw(R0+#0) = R1 --->
3220//
3221// To understand the translation of instruction 1 to its original form, consider
3222// a packet with 3 instructions.
3223// { p0 = cmp.eq(R0,R1)
3224// if (p0.new) R2 = add(R3, R4)
3225// R5 = add (R3, R1)
3226// }
3227// if (p0) memw(R5+#0) = R2 <--- trying to include it in the previous packet
3228//
3229// This instruction can be part of the previous packet only if both p0 and R2
3230// are promoted to .new values. This promotion happens in steps, first
3231// predicate register is promoted to .new and in the next iteration R2 is
3232// promoted. Therefore, in case of dependence check failure (due to R5) during
3233// next iteration, it should be converted back to its most basic form.
3234
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003235// Return the new value instruction for a given store.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003236int HexagonInstrInfo::getDotNewOp(const MachineInstr &MI) const {
3237 int NVOpcode = Hexagon::getNewValueOpcode(MI.getOpcode());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003238 if (NVOpcode >= 0) // Valid new-value store instruction.
3239 return NVOpcode;
3240
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003241 switch (MI.getOpcode()) {
Krzysztof Parzyszeka72fad92017-02-10 15:33:13 +00003242 default:
Eugene Zelenko3b873362017-09-28 22:27:31 +00003243 report_fatal_error(std::string("Unknown .new type: ") +
3244 std::to_string(MI.getOpcode()));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003245 case Hexagon::S4_storerb_ur:
3246 return Hexagon::S4_storerbnew_ur;
3247
3248 case Hexagon::S2_storerb_pci:
3249 return Hexagon::S2_storerb_pci;
3250
3251 case Hexagon::S2_storeri_pci:
3252 return Hexagon::S2_storeri_pci;
3253
3254 case Hexagon::S2_storerh_pci:
3255 return Hexagon::S2_storerh_pci;
3256
3257 case Hexagon::S2_storerd_pci:
3258 return Hexagon::S2_storerd_pci;
3259
3260 case Hexagon::S2_storerf_pci:
3261 return Hexagon::S2_storerf_pci;
3262
3263 case Hexagon::V6_vS32b_ai:
3264 return Hexagon::V6_vS32b_new_ai;
3265
3266 case Hexagon::V6_vS32b_pi:
3267 return Hexagon::V6_vS32b_new_pi;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003268 }
3269 return 0;
3270}
3271
3272// Returns the opcode to use when converting MI, which is a conditional jump,
3273// into a conditional instruction which uses the .new value of the predicate.
3274// We also use branch probabilities to add a hint to the jump.
Krzysztof Parzyszek3cf16572017-06-01 18:02:40 +00003275// If MBPI is null, all edges will be treated as equally likely for the
3276// purposes of establishing a predication hint.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003277int HexagonInstrInfo::getDotNewPredJumpOp(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003278 const MachineBranchProbabilityInfo *MBPI) const {
3279 // We assume that block can have at most two successors.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003280 const MachineBasicBlock *Src = MI.getParent();
3281 const MachineOperand &BrTarget = MI.getOperand(1);
Krzysztof Parzyszeke720feb2017-03-02 21:49:49 +00003282 bool Taken = false;
3283 const BranchProbability OneHalf(1, 2);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003284
Krzysztof Parzyszek3cf16572017-06-01 18:02:40 +00003285 auto getEdgeProbability = [MBPI] (const MachineBasicBlock *Src,
3286 const MachineBasicBlock *Dst) {
3287 if (MBPI)
3288 return MBPI->getEdgeProbability(Src, Dst);
3289 return BranchProbability(1, Src->succ_size());
3290 };
3291
Krzysztof Parzyszeke720feb2017-03-02 21:49:49 +00003292 if (BrTarget.isMBB()) {
3293 const MachineBasicBlock *Dst = BrTarget.getMBB();
Krzysztof Parzyszek3cf16572017-06-01 18:02:40 +00003294 Taken = getEdgeProbability(Src, Dst) >= OneHalf;
Krzysztof Parzyszeke720feb2017-03-02 21:49:49 +00003295 } else {
3296 // The branch target is not a basic block (most likely a function).
3297 // Since BPI only gives probabilities for targets that are basic blocks,
3298 // try to identify another target of this branch (potentially a fall-
3299 // -through) and check the probability of that target.
3300 //
3301 // The only handled branch combinations are:
3302 // - one conditional branch,
3303 // - one conditional branch followed by one unconditional branch.
3304 // Otherwise, assume not-taken.
3305 assert(MI.isConditionalBranch());
3306 const MachineBasicBlock &B = *MI.getParent();
3307 bool SawCond = false, Bad = false;
3308 for (const MachineInstr &I : B) {
3309 if (!I.isBranch())
3310 continue;
3311 if (I.isConditionalBranch()) {
3312 SawCond = true;
3313 if (&I != &MI) {
3314 Bad = true;
3315 break;
3316 }
3317 }
3318 if (I.isUnconditionalBranch() && !SawCond) {
3319 Bad = true;
3320 break;
3321 }
3322 }
3323 if (!Bad) {
3324 MachineBasicBlock::const_instr_iterator It(MI);
3325 MachineBasicBlock::const_instr_iterator NextIt = std::next(It);
3326 if (NextIt == B.instr_end()) {
3327 // If this branch is the last, look for the fall-through block.
3328 for (const MachineBasicBlock *SB : B.successors()) {
3329 if (!B.isLayoutSuccessor(SB))
3330 continue;
Krzysztof Parzyszek3cf16572017-06-01 18:02:40 +00003331 Taken = getEdgeProbability(Src, SB) < OneHalf;
Krzysztof Parzyszeke720feb2017-03-02 21:49:49 +00003332 break;
3333 }
3334 } else {
3335 assert(NextIt->isUnconditionalBranch());
3336 // Find the first MBB operand and assume it's the target.
3337 const MachineBasicBlock *BT = nullptr;
3338 for (const MachineOperand &Op : NextIt->operands()) {
3339 if (!Op.isMBB())
3340 continue;
3341 BT = Op.getMBB();
3342 break;
3343 }
Krzysztof Parzyszek3cf16572017-06-01 18:02:40 +00003344 Taken = BT && getEdgeProbability(Src, BT) < OneHalf;
Krzysztof Parzyszeke720feb2017-03-02 21:49:49 +00003345 }
3346 } // if (!Bad)
3347 }
3348
3349 // The Taken flag should be set to something reasonable by this point.
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003350
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003351 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003352 case Hexagon::J2_jumpt:
Krzysztof Parzyszeke720feb2017-03-02 21:49:49 +00003353 return Taken ? Hexagon::J2_jumptnewpt : Hexagon::J2_jumptnew;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003354 case Hexagon::J2_jumpf:
Krzysztof Parzyszeke720feb2017-03-02 21:49:49 +00003355 return Taken ? Hexagon::J2_jumpfnewpt : Hexagon::J2_jumpfnew;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003356
3357 default:
3358 llvm_unreachable("Unexpected jump instruction.");
3359 }
3360}
3361
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003362// Return .new predicate version for an instruction.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003363int HexagonInstrInfo::getDotNewPredOp(const MachineInstr &MI,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003364 const MachineBranchProbabilityInfo *MBPI) const {
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003365 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003366 // Condtional Jumps
3367 case Hexagon::J2_jumpt:
3368 case Hexagon::J2_jumpf:
3369 return getDotNewPredJumpOp(MI, MBPI);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003370 }
Krzysztof Parzyszeke720feb2017-03-02 21:49:49 +00003371
3372 int NewOpcode = Hexagon::getPredNewOpcode(MI.getOpcode());
3373 if (NewOpcode >= 0)
3374 return NewOpcode;
Krzysztof Parzyszek066e8b52017-06-02 14:07:06 +00003375 return 0;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003376}
3377
Krzysztof Parzyszek143158b2017-03-06 17:03:16 +00003378int HexagonInstrInfo::getDotOldOp(const MachineInstr &MI) const {
3379 int NewOp = MI.getOpcode();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003380 if (isPredicated(NewOp) && isPredicatedNew(NewOp)) { // Get predicate old form
3381 NewOp = Hexagon::getPredOldOpcode(NewOp);
Krzysztof Parzyszek143158b2017-03-06 17:03:16 +00003382 // All Hexagon architectures have prediction bits on dot-new branches,
3383 // but only Hexagon V60+ has prediction bits on dot-old ones. Make sure
3384 // to pick the right opcode when converting back to dot-old.
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +00003385 if (!Subtarget.getFeatureBits()[Hexagon::ArchV60]) {
Krzysztof Parzyszek143158b2017-03-06 17:03:16 +00003386 switch (NewOp) {
3387 case Hexagon::J2_jumptpt:
3388 NewOp = Hexagon::J2_jumpt;
3389 break;
3390 case Hexagon::J2_jumpfpt:
3391 NewOp = Hexagon::J2_jumpf;
3392 break;
3393 case Hexagon::J2_jumprtpt:
3394 NewOp = Hexagon::J2_jumprt;
3395 break;
3396 case Hexagon::J2_jumprfpt:
3397 NewOp = Hexagon::J2_jumprf;
3398 break;
3399 }
3400 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003401 assert(NewOp >= 0 &&
3402 "Couldn't change predicate new instruction to its old form.");
3403 }
3404
3405 if (isNewValueStore(NewOp)) { // Convert into non-new-value format
3406 NewOp = Hexagon::getNonNVStore(NewOp);
3407 assert(NewOp >= 0 && "Couldn't change new-value store to its old form.");
3408 }
Krzysztof Parzyszek19635bd2017-05-03 15:30:46 +00003409
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +00003410 if (Subtarget.hasV60TOps())
Krzysztof Parzyszek19635bd2017-05-03 15:30:46 +00003411 return NewOp;
3412
3413 // Subtargets prior to V60 didn't support 'taken' forms of predicated jumps.
3414 switch (NewOp) {
3415 case Hexagon::J2_jumpfpt:
3416 return Hexagon::J2_jumpf;
3417 case Hexagon::J2_jumptpt:
3418 return Hexagon::J2_jumpt;
3419 case Hexagon::J2_jumprfpt:
3420 return Hexagon::J2_jumprf;
3421 case Hexagon::J2_jumprtpt:
3422 return Hexagon::J2_jumprt;
3423 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003424 return NewOp;
3425}
3426
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003427// See if instruction could potentially be a duplex candidate.
3428// If so, return its group. Zero otherwise.
3429HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup(
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003430 const MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003431 unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +00003432 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003433
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003434 switch (MI.getOpcode()) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003435 default:
3436 return HexagonII::HSIG_None;
3437 //
3438 // Group L1:
3439 //
3440 // Rd = memw(Rs+#u4:2)
3441 // Rd = memub(Rs+#u4:0)
3442 case Hexagon::L2_loadri_io:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003443 DstReg = MI.getOperand(0).getReg();
3444 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003445 // Special case this one from Group L2.
3446 // Rd = memw(r29+#u5:2)
3447 if (isIntRegForSubInst(DstReg)) {
3448 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
3449 HRI.getStackRegister() == SrcReg &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003450 MI.getOperand(2).isImm() &&
3451 isShiftedUInt<5,2>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003452 return HexagonII::HSIG_L2;
3453 // Rd = memw(Rs+#u4:2)
3454 if (isIntRegForSubInst(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003455 (MI.getOperand(2).isImm() &&
3456 isShiftedUInt<4,2>(MI.getOperand(2).getImm())))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003457 return HexagonII::HSIG_L1;
3458 }
3459 break;
3460 case Hexagon::L2_loadrub_io:
3461 // Rd = memub(Rs+#u4:0)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003462 DstReg = MI.getOperand(0).getReg();
3463 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003464 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003465 MI.getOperand(2).isImm() && isUInt<4>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003466 return HexagonII::HSIG_L1;
3467 break;
3468 //
3469 // Group L2:
3470 //
3471 // Rd = memh/memuh(Rs+#u3:1)
3472 // Rd = memb(Rs+#u3:0)
3473 // Rd = memw(r29+#u5:2) - Handled above.
3474 // Rdd = memd(r29+#u5:3)
3475 // deallocframe
3476 // [if ([!]p0[.new])] dealloc_return
3477 // [if ([!]p0[.new])] jumpr r31
3478 case Hexagon::L2_loadrh_io:
3479 case Hexagon::L2_loadruh_io:
3480 // Rd = memh/memuh(Rs+#u3:1)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003481 DstReg = MI.getOperand(0).getReg();
3482 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003483 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003484 MI.getOperand(2).isImm() &&
3485 isShiftedUInt<3,1>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003486 return HexagonII::HSIG_L2;
3487 break;
3488 case Hexagon::L2_loadrb_io:
3489 // Rd = memb(Rs+#u3:0)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003490 DstReg = MI.getOperand(0).getReg();
3491 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003492 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003493 MI.getOperand(2).isImm() &&
3494 isUInt<3>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003495 return HexagonII::HSIG_L2;
3496 break;
3497 case Hexagon::L2_loadrd_io:
3498 // Rdd = memd(r29+#u5:3)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003499 DstReg = MI.getOperand(0).getReg();
3500 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003501 if (isDblRegForSubInst(DstReg, HRI) &&
3502 Hexagon::IntRegsRegClass.contains(SrcReg) &&
3503 HRI.getStackRegister() == SrcReg &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003504 MI.getOperand(2).isImm() &&
3505 isShiftedUInt<5,3>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003506 return HexagonII::HSIG_L2;
3507 break;
3508 // dealloc_return is not documented in Hexagon Manual, but marked
3509 // with A_SUBINSN attribute in iset_v4classic.py.
3510 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
Krzysztof Parzyszek5a7bef92016-08-19 17:20:57 +00003511 case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003512 case Hexagon::L4_return:
3513 case Hexagon::L2_deallocframe:
3514 return HexagonII::HSIG_L2;
3515 case Hexagon::EH_RETURN_JMPR:
Krzysztof Parzyszekbe976d42016-08-12 11:12:02 +00003516 case Hexagon::PS_jmpret:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003517 // jumpr r31
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +00003518 // Actual form JMPR %pc<imp-def>, %r31<imp-use>, %r0<imp-use,internal>.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003519 DstReg = MI.getOperand(0).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003520 if (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg))
3521 return HexagonII::HSIG_L2;
3522 break;
Krzysztof Parzyszekbe976d42016-08-12 11:12:02 +00003523 case Hexagon::PS_jmprett:
3524 case Hexagon::PS_jmpretf:
3525 case Hexagon::PS_jmprettnewpt:
3526 case Hexagon::PS_jmpretfnewpt:
3527 case Hexagon::PS_jmprettnew:
3528 case Hexagon::PS_jmpretfnew:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003529 DstReg = MI.getOperand(1).getReg();
3530 SrcReg = MI.getOperand(0).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003531 // [if ([!]p0[.new])] jumpr r31
3532 if ((Hexagon::PredRegsRegClass.contains(SrcReg) &&
3533 (Hexagon::P0 == SrcReg)) &&
3534 (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg)))
3535 return HexagonII::HSIG_L2;
Krzysztof Parzyszekfb4c4172016-08-19 19:29:15 +00003536 break;
Eugene Zelenko3b873362017-09-28 22:27:31 +00003537 case Hexagon::L4_return_t:
3538 case Hexagon::L4_return_f:
3539 case Hexagon::L4_return_tnew_pnt:
3540 case Hexagon::L4_return_fnew_pnt:
3541 case Hexagon::L4_return_tnew_pt:
3542 case Hexagon::L4_return_fnew_pt:
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003543 // [if ([!]p0[.new])] dealloc_return
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003544 SrcReg = MI.getOperand(0).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003545 if (Hexagon::PredRegsRegClass.contains(SrcReg) && (Hexagon::P0 == SrcReg))
3546 return HexagonII::HSIG_L2;
3547 break;
3548 //
3549 // Group S1:
3550 //
3551 // memw(Rs+#u4:2) = Rt
3552 // memb(Rs+#u4:0) = Rt
3553 case Hexagon::S2_storeri_io:
3554 // Special case this one from Group S2.
3555 // memw(r29+#u5:2) = Rt
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003556 Src1Reg = MI.getOperand(0).getReg();
3557 Src2Reg = MI.getOperand(2).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003558 if (Hexagon::IntRegsRegClass.contains(Src1Reg) &&
3559 isIntRegForSubInst(Src2Reg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003560 HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() &&
3561 isShiftedUInt<5,2>(MI.getOperand(1).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003562 return HexagonII::HSIG_S2;
3563 // memw(Rs+#u4:2) = Rt
3564 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003565 MI.getOperand(1).isImm() &&
3566 isShiftedUInt<4,2>(MI.getOperand(1).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003567 return HexagonII::HSIG_S1;
3568 break;
3569 case Hexagon::S2_storerb_io:
3570 // memb(Rs+#u4:0) = Rt
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003571 Src1Reg = MI.getOperand(0).getReg();
3572 Src2Reg = MI.getOperand(2).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003573 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003574 MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003575 return HexagonII::HSIG_S1;
3576 break;
3577 //
3578 // Group S2:
3579 //
3580 // memh(Rs+#u3:1) = Rt
3581 // memw(r29+#u5:2) = Rt
3582 // memd(r29+#s6:3) = Rtt
3583 // memw(Rs+#u4:2) = #U1
3584 // memb(Rs+#u4) = #U1
3585 // allocframe(#u5:3)
3586 case Hexagon::S2_storerh_io:
3587 // memh(Rs+#u3:1) = Rt
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003588 Src1Reg = MI.getOperand(0).getReg();
3589 Src2Reg = MI.getOperand(2).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003590 if (isIntRegForSubInst(Src1Reg) && isIntRegForSubInst(Src2Reg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003591 MI.getOperand(1).isImm() &&
3592 isShiftedUInt<3,1>(MI.getOperand(1).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003593 return HexagonII::HSIG_S1;
3594 break;
3595 case Hexagon::S2_storerd_io:
3596 // memd(r29+#s6:3) = Rtt
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003597 Src1Reg = MI.getOperand(0).getReg();
3598 Src2Reg = MI.getOperand(2).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003599 if (isDblRegForSubInst(Src2Reg, HRI) &&
3600 Hexagon::IntRegsRegClass.contains(Src1Reg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003601 HRI.getStackRegister() == Src1Reg && MI.getOperand(1).isImm() &&
3602 isShiftedInt<6,3>(MI.getOperand(1).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003603 return HexagonII::HSIG_S2;
3604 break;
3605 case Hexagon::S4_storeiri_io:
3606 // memw(Rs+#u4:2) = #U1
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003607 Src1Reg = MI.getOperand(0).getReg();
3608 if (isIntRegForSubInst(Src1Reg) && MI.getOperand(1).isImm() &&
3609 isShiftedUInt<4,2>(MI.getOperand(1).getImm()) &&
3610 MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003611 return HexagonII::HSIG_S2;
3612 break;
3613 case Hexagon::S4_storeirb_io:
3614 // memb(Rs+#u4) = #U1
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003615 Src1Reg = MI.getOperand(0).getReg();
Krzysztof Parzyszekf2a4f8f2016-06-15 21:05:04 +00003616 if (isIntRegForSubInst(Src1Reg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003617 MI.getOperand(1).isImm() && isUInt<4>(MI.getOperand(1).getImm()) &&
3618 MI.getOperand(2).isImm() && isUInt<1>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003619 return HexagonII::HSIG_S2;
3620 break;
3621 case Hexagon::S2_allocframe:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003622 if (MI.getOperand(0).isImm() &&
3623 isShiftedUInt<5,3>(MI.getOperand(0).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003624 return HexagonII::HSIG_S1;
3625 break;
3626 //
3627 // Group A:
3628 //
3629 // Rx = add(Rx,#s7)
3630 // Rd = Rs
3631 // Rd = #u6
3632 // Rd = #-1
3633 // if ([!]P0[.new]) Rd = #0
3634 // Rd = add(r29,#u6:2)
3635 // Rx = add(Rx,Rs)
3636 // P0 = cmp.eq(Rs,#u2)
3637 // Rdd = combine(#0,Rs)
3638 // Rdd = combine(Rs,#0)
3639 // Rdd = combine(#u2,#U2)
3640 // Rd = add(Rs,#1)
3641 // Rd = add(Rs,#-1)
3642 // Rd = sxth/sxtb/zxtb/zxth(Rs)
3643 // Rd = and(Rs,#1)
3644 case Hexagon::A2_addi:
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003645 DstReg = MI.getOperand(0).getReg();
3646 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003647 if (isIntRegForSubInst(DstReg)) {
3648 // Rd = add(r29,#u6:2)
3649 if (Hexagon::IntRegsRegClass.contains(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003650 HRI.getStackRegister() == SrcReg && MI.getOperand(2).isImm() &&
3651 isShiftedUInt<6,2>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003652 return HexagonII::HSIG_A;
3653 // Rx = add(Rx,#s7)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003654 if ((DstReg == SrcReg) && MI.getOperand(2).isImm() &&
3655 isInt<7>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003656 return HexagonII::HSIG_A;
3657 // Rd = add(Rs,#1)
3658 // Rd = add(Rs,#-1)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003659 if (isIntRegForSubInst(SrcReg) && MI.getOperand(2).isImm() &&
3660 ((MI.getOperand(2).getImm() == 1) ||
3661 (MI.getOperand(2).getImm() == -1)))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003662 return HexagonII::HSIG_A;
3663 }
3664 break;
3665 case Hexagon::A2_add:
3666 // Rx = add(Rx,Rs)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003667 DstReg = MI.getOperand(0).getReg();
3668 Src1Reg = MI.getOperand(1).getReg();
3669 Src2Reg = MI.getOperand(2).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003670 if (isIntRegForSubInst(DstReg) && (DstReg == Src1Reg) &&
3671 isIntRegForSubInst(Src2Reg))
3672 return HexagonII::HSIG_A;
3673 break;
3674 case Hexagon::A2_andir:
3675 // Same as zxtb.
3676 // Rd16=and(Rs16,#255)
3677 // Rd16=and(Rs16,#1)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003678 DstReg = MI.getOperand(0).getReg();
3679 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003680 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003681 MI.getOperand(2).isImm() &&
3682 ((MI.getOperand(2).getImm() == 1) ||
3683 (MI.getOperand(2).getImm() == 255)))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003684 return HexagonII::HSIG_A;
3685 break;
3686 case Hexagon::A2_tfr:
3687 // Rd = Rs
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003688 DstReg = MI.getOperand(0).getReg();
3689 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003690 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
3691 return HexagonII::HSIG_A;
3692 break;
3693 case Hexagon::A2_tfrsi:
3694 // Rd = #u6
3695 // Do not test for #u6 size since the const is getting extended
3696 // regardless and compound could be formed.
3697 // Rd = #-1
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003698 DstReg = MI.getOperand(0).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003699 if (isIntRegForSubInst(DstReg))
3700 return HexagonII::HSIG_A;
3701 break;
3702 case Hexagon::C2_cmoveit:
3703 case Hexagon::C2_cmovenewit:
3704 case Hexagon::C2_cmoveif:
3705 case Hexagon::C2_cmovenewif:
3706 // if ([!]P0[.new]) Rd = #0
3707 // Actual form:
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +00003708 // %r16<def> = C2_cmovenewit %p0<internal>, 0, %r16<imp-use,undef>;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003709 DstReg = MI.getOperand(0).getReg();
3710 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003711 if (isIntRegForSubInst(DstReg) &&
3712 Hexagon::PredRegsRegClass.contains(SrcReg) && Hexagon::P0 == SrcReg &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003713 MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0)
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003714 return HexagonII::HSIG_A;
3715 break;
3716 case Hexagon::C2_cmpeqi:
3717 // P0 = cmp.eq(Rs,#u2)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003718 DstReg = MI.getOperand(0).getReg();
3719 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003720 if (Hexagon::PredRegsRegClass.contains(DstReg) &&
3721 Hexagon::P0 == DstReg && isIntRegForSubInst(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003722 MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm()))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003723 return HexagonII::HSIG_A;
3724 break;
3725 case Hexagon::A2_combineii:
3726 case Hexagon::A4_combineii:
3727 // Rdd = combine(#u2,#U2)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003728 DstReg = MI.getOperand(0).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003729 if (isDblRegForSubInst(DstReg, HRI) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003730 ((MI.getOperand(1).isImm() && isUInt<2>(MI.getOperand(1).getImm())) ||
3731 (MI.getOperand(1).isGlobal() &&
3732 isUInt<2>(MI.getOperand(1).getOffset()))) &&
3733 ((MI.getOperand(2).isImm() && isUInt<2>(MI.getOperand(2).getImm())) ||
3734 (MI.getOperand(2).isGlobal() &&
3735 isUInt<2>(MI.getOperand(2).getOffset()))))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003736 return HexagonII::HSIG_A;
3737 break;
3738 case Hexagon::A4_combineri:
3739 // Rdd = combine(Rs,#0)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003740 DstReg = MI.getOperand(0).getReg();
3741 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003742 if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003743 ((MI.getOperand(2).isImm() && MI.getOperand(2).getImm() == 0) ||
3744 (MI.getOperand(2).isGlobal() && MI.getOperand(2).getOffset() == 0)))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003745 return HexagonII::HSIG_A;
3746 break;
3747 case Hexagon::A4_combineir:
3748 // Rdd = combine(#0,Rs)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003749 DstReg = MI.getOperand(0).getReg();
3750 SrcReg = MI.getOperand(2).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003751 if (isDblRegForSubInst(DstReg, HRI) && isIntRegForSubInst(SrcReg) &&
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003752 ((MI.getOperand(1).isImm() && MI.getOperand(1).getImm() == 0) ||
3753 (MI.getOperand(1).isGlobal() && MI.getOperand(1).getOffset() == 0)))
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003754 return HexagonII::HSIG_A;
3755 break;
3756 case Hexagon::A2_sxtb:
3757 case Hexagon::A2_sxth:
3758 case Hexagon::A2_zxtb:
3759 case Hexagon::A2_zxth:
3760 // Rd = sxth/sxtb/zxtb/zxth(Rs)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003761 DstReg = MI.getOperand(0).getReg();
3762 SrcReg = MI.getOperand(1).getReg();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003763 if (isIntRegForSubInst(DstReg) && isIntRegForSubInst(SrcReg))
3764 return HexagonII::HSIG_A;
3765 break;
3766 }
3767
3768 return HexagonII::HSIG_None;
3769}
3770
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003771short HexagonInstrInfo::getEquivalentHWInstr(const MachineInstr &MI) const {
3772 return Hexagon::getRealHWInstr(MI.getOpcode(), Hexagon::InstrType_Real);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003773}
3774
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003775unsigned HexagonInstrInfo::getInstrTimingClassLatency(
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003776 const InstrItineraryData *ItinData, const MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003777 // Default to one cycle for no itinerary. However, an "empty" itinerary may
3778 // still have a MinLatency property, which getStageLatency checks.
3779 if (!ItinData)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003780 return getInstrLatency(ItinData, MI);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003781
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003782 if (MI.isTransient())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003783 return 0;
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00003784 return ItinData->getStageLatency(MI.getDesc().getSchedClass());
3785}
3786
3787/// getOperandLatency - Compute and return the use operand latency of a given
3788/// pair of def and use.
3789/// In most cases, the static scheduling itinerary was enough to determine the
3790/// operand latency. But it may not be possible for instructions with variable
3791/// number of defs / uses.
3792///
3793/// This is a raw interface to the itinerary that may be directly overriden by
3794/// a target. Use computeOperandLatency to get the best estimate of latency.
3795int HexagonInstrInfo::getOperandLatency(const InstrItineraryData *ItinData,
3796 const MachineInstr &DefMI,
3797 unsigned DefIdx,
3798 const MachineInstr &UseMI,
3799 unsigned UseIdx) const {
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +00003800 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00003801
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00003802 // Get DefIdx and UseIdx for super registers.
3803 MachineOperand DefMO = DefMI.getOperand(DefIdx);
3804
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00003805 if (HRI.isPhysicalRegister(DefMO.getReg())) {
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00003806 if (DefMO.isImplicit()) {
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00003807 for (MCSuperRegIterator SR(DefMO.getReg(), &HRI); SR.isValid(); ++SR) {
3808 int Idx = DefMI.findRegisterDefOperandIdx(*SR, false, false, &HRI);
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00003809 if (Idx != -1) {
3810 DefIdx = Idx;
3811 break;
3812 }
3813 }
3814 }
3815
3816 MachineOperand UseMO = UseMI.getOperand(UseIdx);
3817 if (UseMO.isImplicit()) {
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00003818 for (MCSuperRegIterator SR(UseMO.getReg(), &HRI); SR.isValid(); ++SR) {
3819 int Idx = UseMI.findRegisterUseOperandIdx(*SR, false, &HRI);
Krzysztof Parzyszek2af50372017-05-03 20:10:36 +00003820 if (Idx != -1) {
3821 UseIdx = Idx;
3822 break;
3823 }
3824 }
3825 }
3826 }
3827
3828 return TargetInstrInfo::getOperandLatency(ItinData, DefMI, DefIdx,
3829 UseMI, UseIdx);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003830}
3831
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003832// inverts the predication logic.
3833// p -> NotP
3834// NotP -> P
3835bool HexagonInstrInfo::getInvertedPredSense(
3836 SmallVectorImpl<MachineOperand> &Cond) const {
3837 if (Cond.empty())
3838 return false;
3839 unsigned Opc = getInvertedPredicatedOpcode(Cond[0].getImm());
3840 Cond[0].setImm(Opc);
3841 return true;
3842}
3843
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003844unsigned HexagonInstrInfo::getInvertedPredicatedOpcode(const int Opc) const {
3845 int InvPredOpcode;
3846 InvPredOpcode = isPredicatedTrue(Opc) ? Hexagon::getFalsePredOpcode(Opc)
3847 : Hexagon::getTruePredOpcode(Opc);
3848 if (InvPredOpcode >= 0) // Valid instruction with the inverted predicate.
3849 return InvPredOpcode;
3850
3851 llvm_unreachable("Unexpected predicated instruction");
3852}
3853
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003854// Returns the max value that doesn't need to be extended.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003855int HexagonInstrInfo::getMaxValue(const MachineInstr &MI) const {
3856 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003857 unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
3858 & HexagonII::ExtentSignedMask;
3859 unsigned bits = (F >> HexagonII::ExtentBitsPos)
3860 & HexagonII::ExtentBitsMask;
3861
3862 if (isSigned) // if value is signed
3863 return ~(-1U << (bits - 1));
3864 else
3865 return ~(-1U << bits);
3866}
3867
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003868unsigned HexagonInstrInfo::getMemAccessSize(const MachineInstr &MI) const {
Krzysztof Parzyszek473d02d2017-09-14 12:06:40 +00003869 using namespace HexagonII;
Eugene Zelenko3b873362017-09-28 22:27:31 +00003870
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003871 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszek473d02d2017-09-14 12:06:40 +00003872 unsigned S = (F >> MemAccessSizePos) & MemAccesSizeMask;
3873 unsigned Size = getMemAccessSizeInBytes(MemAccessSize(S));
3874 if (Size != 0)
3875 return Size;
3876
3877 // Handle vector access sizes.
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +00003878 const HexagonRegisterInfo &HRI = *Subtarget.getRegisterInfo();
Krzysztof Parzyszek473d02d2017-09-14 12:06:40 +00003879 switch (S) {
Krzysztof Parzyszek55772972017-09-15 15:46:05 +00003880 case HexagonII::HVXVectorAccess:
3881 return HRI.getSpillSize(Hexagon::HvxVRRegClass);
Krzysztof Parzyszek473d02d2017-09-14 12:06:40 +00003882 default:
3883 llvm_unreachable("Unexpected instruction");
3884 }
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003885}
3886
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003887// Returns the min value that doesn't need to be extended.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003888int HexagonInstrInfo::getMinValue(const MachineInstr &MI) const {
3889 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003890 unsigned isSigned = (F >> HexagonII::ExtentSignedPos)
3891 & HexagonII::ExtentSignedMask;
3892 unsigned bits = (F >> HexagonII::ExtentBitsPos)
3893 & HexagonII::ExtentBitsMask;
3894
3895 if (isSigned) // if value is signed
3896 return -1U << (bits - 1);
3897 else
3898 return 0;
3899}
3900
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003901// Returns opcode of the non-extended equivalent instruction.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003902short HexagonInstrInfo::getNonExtOpcode(const MachineInstr &MI) const {
Jyotsna Verma84256432013-03-01 17:37:13 +00003903 // Check if the instruction has a register form that uses register in place
3904 // of the extended operand, if so return that as the non-extended form.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003905 short NonExtOpcode = Hexagon::getRegForm(MI.getOpcode());
Jyotsna Verma84256432013-03-01 17:37:13 +00003906 if (NonExtOpcode >= 0)
3907 return NonExtOpcode;
3908
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003909 if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {
Alp Tokercb402912014-01-24 17:20:08 +00003910 // Check addressing mode and retrieve non-ext equivalent instruction.
Jyotsna Verma84256432013-03-01 17:37:13 +00003911 switch (getAddrMode(MI)) {
Eugene Zelenko3b873362017-09-28 22:27:31 +00003912 case HexagonII::Absolute:
Krzysztof Parzyszek7ae3ae92017-10-05 20:01:38 +00003913 return Hexagon::changeAddrMode_abs_io(MI.getOpcode());
Eugene Zelenko3b873362017-09-28 22:27:31 +00003914 case HexagonII::BaseImmOffset:
Krzysztof Parzyszek7ae3ae92017-10-05 20:01:38 +00003915 return Hexagon::changeAddrMode_io_rr(MI.getOpcode());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003916 case HexagonII::BaseLongOffset:
Krzysztof Parzyszek7ae3ae92017-10-05 20:01:38 +00003917 return Hexagon::changeAddrMode_ur_rr(MI.getOpcode());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003918
Jyotsna Verma84256432013-03-01 17:37:13 +00003919 default:
3920 return -1;
3921 }
3922 }
3923 return -1;
3924}
Jyotsna Verma5ed51812013-05-01 21:37:34 +00003925
Ahmed Bougachac88bf542015-06-11 19:30:37 +00003926bool HexagonInstrInfo::getPredReg(ArrayRef<MachineOperand> Cond,
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003927 unsigned &PredReg, unsigned &PredRegPos, unsigned &PredRegFlags) const {
Brendon Cahoondf43e682015-05-08 16:16:29 +00003928 if (Cond.empty())
3929 return false;
3930 assert(Cond.size() == 2);
3931 if (isNewValueJump(Cond[0].getImm()) || Cond[1].isMBB()) {
Krzysztof Parzyszekfb4c4172016-08-19 19:29:15 +00003932 DEBUG(dbgs() << "No predregs for new-value jumps/endloop");
3933 return false;
Brendon Cahoondf43e682015-05-08 16:16:29 +00003934 }
3935 PredReg = Cond[1].getReg();
3936 PredRegPos = 1;
3937 // See IfConversion.cpp why we add RegState::Implicit | RegState::Undef
3938 PredRegFlags = 0;
3939 if (Cond[1].isImplicit())
3940 PredRegFlags = RegState::Implicit;
3941 if (Cond[1].isUndef())
3942 PredRegFlags |= RegState::Undef;
3943 return true;
3944}
3945
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003946short HexagonInstrInfo::getPseudoInstrPair(const MachineInstr &MI) const {
3947 return Hexagon::getRealHWInstr(MI.getOpcode(), Hexagon::InstrType_Pseudo);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003948}
3949
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003950short HexagonInstrInfo::getRegForm(const MachineInstr &MI) const {
3951 return Hexagon::getRegForm(MI.getOpcode());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003952}
3953
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003954// Return the number of bytes required to encode the instruction.
3955// Hexagon instructions are fixed length, 4 bytes, unless they
3956// use a constant extender, which requires another 4 bytes.
3957// For debug instructions and prolog labels, return 0.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003958unsigned HexagonInstrInfo::getSize(const MachineInstr &MI) const {
3959 if (MI.isDebugValue() || MI.isPosition())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003960 return 0;
3961
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003962 unsigned Size = MI.getDesc().getSize();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003963 if (!Size)
3964 // Assume the default insn size in case it cannot be determined
3965 // for whatever reason.
3966 Size = HEXAGON_INSTR_SIZE;
3967
3968 if (isConstExtended(MI) || isExtended(MI))
3969 Size += HEXAGON_INSTR_SIZE;
3970
3971 // Try and compute number of instructions in asm.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003972 if (BranchRelaxAsmLarge && MI.getOpcode() == Hexagon::INLINEASM) {
3973 const MachineBasicBlock &MBB = *MI.getParent();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003974 const MachineFunction *MF = MBB.getParent();
3975 const MCAsmInfo *MAI = MF->getTarget().getMCAsmInfo();
3976
3977 // Count the number of register definitions to find the asm string.
3978 unsigned NumDefs = 0;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003979 for (; MI.getOperand(NumDefs).isReg() && MI.getOperand(NumDefs).isDef();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003980 ++NumDefs)
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003981 assert(NumDefs != MI.getNumOperands()-2 && "No asm string?");
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003982
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003983 assert(MI.getOperand(NumDefs).isSymbol() && "No asm string?");
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003984 // Disassemble the AsmStr and approximate number of instructions.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003985 const char *AsmStr = MI.getOperand(NumDefs).getSymbolName();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003986 Size = getInlineAsmLength(AsmStr, *MAI);
3987 }
3988
3989 return Size;
3990}
3991
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003992uint64_t HexagonInstrInfo::getType(const MachineInstr &MI) const {
3993 const uint64_t F = MI.getDesc().TSFlags;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00003994 return (F >> HexagonII::TypePos) & HexagonII::TypeMask;
3995}
3996
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003997unsigned HexagonInstrInfo::getUnits(const MachineInstr &MI) const {
Krzysztof Parzyszek4697dde2017-10-04 18:00:15 +00003998 const InstrItineraryData &II = *Subtarget.getInstrItineraryData();
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00003999 const InstrStage &IS = *II.beginStage(MI.getDesc().getSchedClass());
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004000
4001 return IS.getUnits();
4002}
4003
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004004// Calculate size of the basic block without debug instructions.
4005unsigned HexagonInstrInfo::nonDbgBBSize(const MachineBasicBlock *BB) const {
4006 return nonDbgMICount(BB->instr_begin(), BB->instr_end());
4007}
4008
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004009unsigned HexagonInstrInfo::nonDbgBundleSize(
4010 MachineBasicBlock::const_iterator BundleHead) const {
4011 assert(BundleHead->isBundle() && "Not a bundle header");
Duncan P. N. Exon Smithd84f6002016-02-22 21:30:15 +00004012 auto MII = BundleHead.getInstrIterator();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004013 // Skip the bundle header.
Matthias Braunc8440dd2016-10-25 02:55:17 +00004014 return nonDbgMICount(++MII, getBundleEnd(BundleHead.getInstrIterator()));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004015}
4016
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004017/// immediateExtend - Changes the instruction in place to one using an immediate
4018/// extender.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004019void HexagonInstrInfo::immediateExtend(MachineInstr &MI) const {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004020 assert((isExtendable(MI)||isConstExtended(MI)) &&
4021 "Instruction must be extendable");
4022 // Find which operand is extendable.
4023 short ExtOpNum = getCExtOpNum(MI);
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004024 MachineOperand &MO = MI.getOperand(ExtOpNum);
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004025 // This needs to be something we understand.
4026 assert((MO.isMBB() || MO.isImm()) &&
4027 "Branch with unknown extendable field type");
4028 // Mark given operand as extended.
4029 MO.addTargetFlag(HexagonII::HMOTF_ConstExtended);
4030}
4031
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004032bool HexagonInstrInfo::invertAndChangeJumpTarget(
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004033 MachineInstr &MI, MachineBasicBlock *NewTarget) const {
Francis Visoiu Mistrih25528d62017-12-04 17:18:51 +00004034 DEBUG(dbgs() << "\n[invertAndChangeJumpTarget] to "
4035 << printMBBReference(*NewTarget);
4036 MI.dump(););
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004037 assert(MI.isBranch());
4038 unsigned NewOpcode = getInvertedPredicatedOpcode(MI.getOpcode());
4039 int TargetPos = MI.getNumOperands() - 1;
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004040 // In general branch target is the last operand,
4041 // but some implicit defs added at the end might change it.
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004042 while ((TargetPos > -1) && !MI.getOperand(TargetPos).isMBB())
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004043 --TargetPos;
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004044 assert((TargetPos >= 0) && MI.getOperand(TargetPos).isMBB());
4045 MI.getOperand(TargetPos).setMBB(NewTarget);
4046 if (EnableBranchPrediction && isPredicatedNew(MI)) {
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004047 NewOpcode = reversePrediction(NewOpcode);
4048 }
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004049 MI.setDesc(get(NewOpcode));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004050 return true;
4051}
4052
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004053void HexagonInstrInfo::genAllInsnTimingClasses(MachineFunction &MF) const {
4054 /* +++ The code below is used to generate complete set of Hexagon Insn +++ */
4055 MachineFunction::iterator A = MF.begin();
4056 MachineBasicBlock &B = *A;
4057 MachineBasicBlock::iterator I = B.begin();
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004058 DebugLoc DL = I->getDebugLoc();
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004059 MachineInstr *NewMI;
4060
4061 for (unsigned insn = TargetOpcode::GENERIC_OP_END+1;
4062 insn < Hexagon::INSTRUCTION_LIST_END; ++insn) {
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004063 NewMI = BuildMI(B, I, DL, get(insn));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004064 DEBUG(dbgs() << "\n" << getName(NewMI->getOpcode()) <<
4065 " Class: " << NewMI->getDesc().getSchedClass());
4066 NewMI->eraseFromParent();
4067 }
4068 /* --- The code above is used to generate complete set of Hexagon Insn --- */
4069}
4070
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004071// inverts the predication logic.
4072// p -> NotP
4073// NotP -> P
Krzysztof Parzyszekf0b34a52016-07-29 21:49:42 +00004074bool HexagonInstrInfo::reversePredSense(MachineInstr &MI) const {
4075 DEBUG(dbgs() << "\nTrying to reverse pred. sense of:"; MI.dump());
4076 MI.setDesc(get(getInvertedPredicatedOpcode(MI.getOpcode())));
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004077 return true;
4078}
4079
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004080// Reverse the branch prediction.
4081unsigned HexagonInstrInfo::reversePrediction(unsigned Opcode) const {
4082 int PredRevOpcode = -1;
4083 if (isPredictedTaken(Opcode))
4084 PredRevOpcode = Hexagon::notTakenBranchPrediction(Opcode);
4085 else
4086 PredRevOpcode = Hexagon::takenBranchPrediction(Opcode);
4087 assert(PredRevOpcode > 0);
4088 return PredRevOpcode;
4089}
4090
Krzysztof Parzyszekb9a1c3a2015-11-24 14:55:26 +00004091// TODO: Add more rigorous validation.
4092bool HexagonInstrInfo::validateBranchCond(const ArrayRef<MachineOperand> &Cond)
4093 const {
4094 return Cond.empty() || (Cond[0].isImm() && (Cond.size() != 1));
4095}
4096
Krzysztof Parzyszek7ae3ae92017-10-05 20:01:38 +00004097// Addressing mode relations.
4098short HexagonInstrInfo::changeAddrMode_abs_io(short Opc) const {
4099 return Opc >= 0 ? Hexagon::changeAddrMode_abs_io(Opc) : Opc;
4100}
4101
4102short HexagonInstrInfo::changeAddrMode_io_abs(short Opc) const {
4103 return Opc >= 0 ? Hexagon::changeAddrMode_io_abs(Opc) : Opc;
4104}
4105
4106short HexagonInstrInfo::changeAddrMode_io_rr(short Opc) const {
4107 return Opc >= 0 ? Hexagon::changeAddrMode_io_rr(Opc) : Opc;
4108}
4109
4110short HexagonInstrInfo::changeAddrMode_rr_io(short Opc) const {
4111 return Opc >= 0 ? Hexagon::changeAddrMode_rr_io(Opc) : Opc;
4112}
4113
4114short HexagonInstrInfo::changeAddrMode_rr_ur(short Opc) const {
4115 return Opc >= 0 ? Hexagon::changeAddrMode_rr_ur(Opc) : Opc;
4116}
4117
4118short HexagonInstrInfo::changeAddrMode_ur_rr(short Opc) const {
4119 return Opc >= 0 ? Hexagon::changeAddrMode_ur_rr(Opc) : Opc;
Krzysztof Parzyszekf5cbac92016-04-29 15:49:13 +00004120}