blob: 36e0aee630e93e6058320a0c46cee287ddc14dff [file] [log] [blame]
Colin LeMahieu7cd08922015-11-09 04:07:48 +00001//===----- HexagonMCChecker.cpp - Instruction bundle checking -------------===//
2//
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 implements the checking of insns inside a bundle according to the
11// packet constraint rules of the Hexagon ISA.
12//
13//===----------------------------------------------------------------------===//
14
15#include "HexagonMCChecker.h"
16
17#include "HexagonBaseInfo.h"
18
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +000019#include "llvm/MC/MCContext.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000020#include "llvm/MC/MCInstrDesc.h"
21#include "llvm/MC/MCInstrInfo.h"
22#include "llvm/Support/CommandLine.h"
23#include "llvm/Support/Debug.h"
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +000024#include "llvm/Support/SourceMgr.h"
Colin LeMahieu7cd08922015-11-09 04:07:48 +000025#include "llvm/Support/raw_ostream.h"
26
27using namespace llvm;
28
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +000029static cl::opt<bool>
30 RelaxNVChecks("relax-nv-checks", cl::init(false), cl::ZeroOrMore,
31 cl::Hidden, cl::desc("Relax checks of new-value validity"));
Colin LeMahieu7cd08922015-11-09 04:07:48 +000032
33const HexagonMCChecker::PredSense
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +000034 HexagonMCChecker::Unconditional(Hexagon::NoRegister, false);
Colin LeMahieu7cd08922015-11-09 04:07:48 +000035
36void HexagonMCChecker::init() {
37 // Initialize read-only registers set.
38 ReadOnly.insert(Hexagon::PC);
39
40 // Figure out the loop-registers definitions.
41 if (HexagonMCInstrInfo::isInnerLoop(MCB)) {
42 Defs[Hexagon::SA0].insert(Unconditional); // FIXME: define or change SA0?
43 Defs[Hexagon::LC0].insert(Unconditional);
44 }
45 if (HexagonMCInstrInfo::isOuterLoop(MCB)) {
46 Defs[Hexagon::SA1].insert(Unconditional); // FIXME: define or change SA0?
47 Defs[Hexagon::LC1].insert(Unconditional);
48 }
49
50 if (HexagonMCInstrInfo::isBundle(MCB))
51 // Unfurl a bundle.
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +000052 for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000053 MCInst const &Inst = *I.getInst();
54 if (HexagonMCInstrInfo::isDuplex(MCII, Inst)) {
55 init(*Inst.getOperand(0).getInst());
56 init(*Inst.getOperand(1).getInst());
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +000057 } else
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000058 init(Inst);
Colin LeMahieu7cd08922015-11-09 04:07:48 +000059 }
60 else
61 init(MCB);
62}
63
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000064void HexagonMCChecker::initReg(MCInst const &MCI, unsigned R, unsigned &PredReg,
65 bool &isTrue) {
66 if (HexagonMCInstrInfo::isPredicated(MCII, MCI) && isPredicateRegister(R)) {
67 // Note an used predicate register.
68 PredReg = R;
69 isTrue = HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI);
70
71 // Note use of new predicate register.
72 if (HexagonMCInstrInfo::isPredicatedNew(MCII, MCI))
73 NewPreds.insert(PredReg);
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +000074 } else
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000075 // Note register use. Super-registers are not tracked directly,
76 // but their components.
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +000077 for (MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
78 SRI.isValid(); ++SRI)
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000079 if (!MCSubRegIterator(*SRI, &RI).isValid())
80 // Skip super-registers used indirectly.
81 Uses.insert(*SRI);
82}
83
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +000084void HexagonMCChecker::init(MCInst const &MCI) {
85 const MCInstrDesc &MCID = HexagonMCInstrInfo::getDesc(MCII, MCI);
Colin LeMahieu7cd08922015-11-09 04:07:48 +000086 unsigned PredReg = Hexagon::NoRegister;
87 bool isTrue = false;
88
89 // Get used registers.
90 for (unsigned i = MCID.getNumDefs(); i < MCID.getNumOperands(); ++i)
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +000091 if (MCI.getOperand(i).isReg())
92 initReg(MCI, MCI.getOperand(i).getReg(), PredReg, isTrue);
93 for (unsigned i = 0; i < MCID.getNumImplicitUses(); ++i)
94 initReg(MCI, MCID.getImplicitUses()[i], PredReg, isTrue);
Colin LeMahieu7cd08922015-11-09 04:07:48 +000095
96 // Get implicit register definitions.
Craig Topper5c322792015-12-05 17:34:07 +000097 if (const MCPhysReg *ImpDef = MCID.getImplicitDefs())
98 for (; *ImpDef; ++ImpDef) {
99 unsigned R = *ImpDef;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000100
Craig Topper5c322792015-12-05 17:34:07 +0000101 if (Hexagon::R31 != R && MCID.isCall())
102 // Any register other than the LR and the PC are actually volatile ones
103 // as defined by the ABI, not modified implicitly by the call insn.
104 continue;
105 if (Hexagon::PC == R)
106 // Branches are the only insns that can change the PC,
107 // otherwise a read-only register.
108 continue;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000109
Craig Topper5c322792015-12-05 17:34:07 +0000110 if (Hexagon::USR_OVF == R)
111 // Many insns change the USR implicitly, but only one or another flag.
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000112 // The instruction table models the USR.OVF flag, which can be
113 // implicitly modified more than once, but cannot be modified in the
114 // same packet with an instruction that modifies is explicitly. Deal
115 // with such situ- ations individually.
Craig Topper5c322792015-12-05 17:34:07 +0000116 SoftDefs.insert(R);
117 else if (isPredicateRegister(R) &&
118 HexagonMCInstrInfo::isPredicateLate(MCII, MCI))
119 // Include implicit late predicates.
120 LatePreds.insert(R);
121 else
122 Defs[R].insert(PredSense(PredReg, isTrue));
123 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000124
125 // Figure out explicit register definitions.
126 for (unsigned i = 0; i < MCID.getNumDefs(); ++i) {
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000127 unsigned R = MCI.getOperand(i).getReg(), S = Hexagon::NoRegister;
Krzysztof Parzyszek96bb4fe2016-05-28 01:51:16 +0000128 // USR has subregisters (while C8 does not for technical reasons), so
129 // reset R to USR, since we know how to handle multiple defs of USR,
130 // taking into account its subregisters.
131 if (R == Hexagon::C8)
132 R = Hexagon::USR;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000133
134 // Note register definitions, direct ones as well as indirect side-effects.
135 // Super-registers are not tracked directly, but their components.
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000136 for (MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
137 SRI.isValid(); ++SRI) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000138 if (MCSubRegIterator(*SRI, &RI).isValid())
139 // Skip super-registers defined indirectly.
140 continue;
141
142 if (R == *SRI) {
143 if (S == R)
144 // Avoid scoring the defined register multiple times.
145 continue;
146 else
147 // Note that the defined register has already been scored.
148 S = R;
149 }
150
151 if (Hexagon::P3_0 != R && Hexagon::P3_0 == *SRI)
152 // P3:0 is a special case, since multiple predicate register definitions
153 // in a packet is allowed as the equivalent of their logical "and".
154 // Only an explicit definition of P3:0 is noted as such; if a
155 // side-effect, then note as a soft definition.
156 SoftDefs.insert(*SRI);
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000157 else if (HexagonMCInstrInfo::isPredicateLate(MCII, MCI) &&
158 isPredicateRegister(*SRI))
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000159 // Some insns produce predicates too late to be used in the same packet.
160 LatePreds.insert(*SRI);
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000161 else if (i == 0 && llvm::HexagonMCInstrInfo::getType(MCII, MCI) ==
162 HexagonII::TypeCVI_VM_CUR_LD)
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000163 // Current loads should be used in the same packet.
164 // TODO: relies on the impossibility of a current and a temporary loads
165 // in the same packet.
166 CurDefs.insert(*SRI), Defs[*SRI].insert(PredSense(PredReg, isTrue));
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000167 else if (i == 0 && llvm::HexagonMCInstrInfo::getType(MCII, MCI) ==
168 HexagonII::TypeCVI_VM_TMP_LD)
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000169 // Temporary loads should be used in the same packet, but don't commit
170 // results, so it should be disregarded if another insn changes the same
171 // register.
172 // TODO: relies on the impossibility of a current and a temporary loads
173 // in the same packet.
174 TmpDefs.insert(*SRI);
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000175 else if (i <= 1 && llvm::HexagonMCInstrInfo::hasNewValue2(MCII, MCI))
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000176 // vshuff(Vx, Vy, Rx) <- Vx(0) and Vy(1) are both source and
177 // destination registers with this instruction. same for vdeal(Vx,Vy,Rx)
178 Uses.insert(*SRI);
179 else
180 Defs[*SRI].insert(PredSense(PredReg, isTrue));
181 }
182 }
183
184 // Figure out register definitions that produce new values.
185 if (HexagonMCInstrInfo::hasNewValue(MCII, MCI)) {
186 unsigned R = HexagonMCInstrInfo::getNewValueOperand(MCII, MCI).getReg();
187
188 if (HexagonMCInstrInfo::isCompound(MCII, MCI))
189 compoundRegisterMap(R); // Compound insns have a limited register range.
190
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000191 for (MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid());
192 SRI.isValid(); ++SRI)
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000193 if (!MCSubRegIterator(*SRI, &RI).isValid())
194 // No super-registers defined indirectly.
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000195 NewDefs[*SRI].push_back(NewSense::Def(
196 PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI),
197 HexagonMCInstrInfo::isFloat(MCII, MCI)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000198
199 // For fairly unique 2-dot-new producers, example:
200 // vdeal(V1, V9, R0) V1.new and V9.new can be used by consumers.
201 if (HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) {
202 unsigned R2 = HexagonMCInstrInfo::getNewValueOperand2(MCII, MCI).getReg();
203
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000204 for (MCRegAliasIterator SRI(R2, &RI,
205 !MCSubRegIterator(R2, &RI).isValid());
206 SRI.isValid(); ++SRI)
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000207 if (!MCSubRegIterator(*SRI, &RI).isValid())
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000208 NewDefs[*SRI].push_back(NewSense::Def(
209 PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI),
210 HexagonMCInstrInfo::isFloat(MCII, MCI)));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000211 }
212 }
213
214 // Figure out definitions of new predicate registers.
215 if (HexagonMCInstrInfo::isPredicatedNew(MCII, MCI))
216 for (unsigned i = MCID.getNumDefs(); i < MCID.getNumOperands(); ++i)
217 if (MCI.getOperand(i).isReg()) {
218 unsigned P = MCI.getOperand(i).getReg();
219
220 if (isPredicateRegister(P))
221 NewPreds.insert(P);
222 }
223
224 // Figure out uses of new values.
225 if (HexagonMCInstrInfo::isNewValue(MCII, MCI)) {
226 unsigned N = HexagonMCInstrInfo::getNewValueOperand(MCII, MCI).getReg();
227
228 if (!MCSubRegIterator(N, &RI).isValid()) {
229 // Super-registers cannot use new values.
230 if (MCID.isBranch())
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000231 NewUses[N] = NewSense::Jmp(
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000232 llvm::HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNCJ);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000233 else
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000234 NewUses[N] = NewSense::Use(
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000235 PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI));
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000236 }
237 }
238}
239
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000240HexagonMCChecker::HexagonMCChecker(MCContext &Context, MCInstrInfo const &MCII,
241 MCSubtargetInfo const &STI, MCInst &mcb,
242 MCRegisterInfo const &ri, bool ReportErrors)
243 : Context(Context), MCB(mcb), RI(ri), MCII(MCII), STI(STI),
244 ReportErrors(ReportErrors) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000245 init();
246}
247
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000248bool HexagonMCChecker::check(bool FullCheck) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000249 bool chkB = checkBranches();
250 bool chkP = checkPredicates();
251 bool chkNV = checkNewValues();
252 bool chkR = checkRegisters();
253 bool chkS = checkSolo();
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000254 bool chkSh = true;
255 if (FullCheck)
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000256 chkSh = checkShuffle();
Krzysztof Parzyszek8cdfe8e2017-02-06 19:35:46 +0000257 bool chkSl = true;
258 if (FullCheck)
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000259 chkSl = checkSlots();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000260 bool chk = chkB && chkP && chkNV && chkR && chkS && chkSh && chkSl;
261
262 return chk;
263}
264
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000265bool HexagonMCChecker::checkSlots() {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000266 unsigned slotsUsed = 0;
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000267 for (auto HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) {
268 MCInst const &MCI = *HMI.getInst();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000269 if (HexagonMCInstrInfo::isImmext(MCI))
270 continue;
271 if (HexagonMCInstrInfo::isDuplex(MCII, MCI))
272 slotsUsed += 2;
273 else
274 ++slotsUsed;
275 }
276
277 if (slotsUsed > HEXAGON_PACKET_SIZE) {
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000278 reportError("invalid instruction packet: out of slots");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000279 return false;
280 }
281 return true;
282}
283
284// Check legal use of branches.
285bool HexagonMCChecker::checkBranches() {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000286 if (HexagonMCInstrInfo::isBundle(MCB)) {
287 bool hasConditional = false;
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000288 unsigned Branches = 0, Conditional = HEXAGON_PRESHUFFLE_PACKET_SIZE,
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000289 Unconditional = HEXAGON_PRESHUFFLE_PACKET_SIZE;
290
291 for (unsigned i = HexagonMCInstrInfo::bundleInstructionsOffset;
292 i < MCB.size(); ++i) {
293 MCInst const &MCI = *MCB.begin()[i].getInst();
294
295 if (HexagonMCInstrInfo::isImmext(MCI))
296 continue;
297 if (HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch() ||
298 HexagonMCInstrInfo::getDesc(MCII, MCI).isCall()) {
299 ++Branches;
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000300 if (HexagonMCInstrInfo::isPredicated(MCII, MCI) ||
301 HexagonMCInstrInfo::isPredicatedNew(MCII, MCI)) {
302 hasConditional = true;
303 Conditional = i; // Record the position of the conditional branch.
304 } else {
305 Unconditional = i; // Record the position of the unconditional branch.
306 }
307 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000308 }
309
310 if (Branches) // FIXME: should "Defs.count(Hexagon::PC)" be here too?
311 if (HexagonMCInstrInfo::isInnerLoop(MCB) ||
312 HexagonMCInstrInfo::isOuterLoop(MCB)) {
313 // Error out if there's any branch in a loop-end packet.
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000314 Twine N(HexagonMCInstrInfo::isInnerLoop(MCB) ? '0' : '1');
315 reportError("packet marked with `:endloop" + N + "' " +
316 "cannot contain instructions that modify register " + "`" +
317 llvm::Twine(RI.getName(Hexagon::PC)) + "'");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000318 return false;
319 }
320 if (Branches > 1)
321 if (!hasConditional || Conditional > Unconditional) {
322 // Error out if more than one unconditional branch or
323 // the conditional branch appears after the unconditional one.
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000324 reportError(
325 "unconditional branch cannot precede another branch in packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000326 return false;
327 }
328 }
329
330 return true;
331}
332
333// Check legal use of predicate registers.
334bool HexagonMCChecker::checkPredicates() {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000335 // Check for proper use of new predicate registers.
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000336 for (const auto &I : NewPreds) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000337 unsigned P = I;
338
339 if (!Defs.count(P) || LatePreds.count(P)) {
340 // Error out if the new predicate register is not defined,
341 // or defined "late"
342 // (e.g., "{ if (p3.new)... ; p3 = sp1loop0(#r7:2, Rs) }").
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000343 reportErrorNewValue(P);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000344 return false;
345 }
346 }
347
348 // Check for proper use of auto-anded of predicate registers.
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000349 for (const auto &I : LatePreds) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000350 unsigned P = I;
351
352 if (LatePreds.count(P) > 1 || Defs.count(P)) {
353 // Error out if predicate register defined "late" multiple times or
354 // defined late and regularly defined
355 // (e.g., "{ p3 = sp1loop0(...); p3 = cmp.eq(...) }".
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000356 reportErrorRegisters(P);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000357 return false;
358 }
359 }
360
361 return true;
362}
363
364// Check legal use of new values.
365bool HexagonMCChecker::checkNewValues() {
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000366 for (auto &I : NewUses) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000367 unsigned R = I.first;
368 NewSense &US = I.second;
369
370 if (!hasValidNewValueDef(US, NewDefs[R])) {
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000371 reportErrorNewValue(R);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000372 return false;
373 }
374 }
375
376 return true;
377}
378
379// Check for legal register uses and definitions.
380bool HexagonMCChecker::checkRegisters() {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000381 // Check for proper register definitions.
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000382 for (const auto &I : Defs) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000383 unsigned R = I.first;
384
385 if (ReadOnly.count(R)) {
386 // Error out for definitions of read-only registers.
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000387 reportError("cannot write to read-only register `" +
388 llvm::Twine(RI.getName(R)) + "'");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000389 return false;
390 }
391 if (isLoopRegister(R) && Defs.count(R) > 1 &&
392 (HexagonMCInstrInfo::isInnerLoop(MCB) ||
393 HexagonMCInstrInfo::isOuterLoop(MCB))) {
394 // Error out for definitions of loop registers at the end of a loop.
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000395 reportError("loop-setup and some branch instructions "
396 "cannot be in the same packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000397 return false;
398 }
399 if (SoftDefs.count(R)) {
400 // Error out for explicit changes to registers also weakly defined
401 // (e.g., "{ usr = r0; r0 = sfadd(...) }").
402 unsigned UsrR = Hexagon::USR; // Silence warning about mixed types in ?:.
403 unsigned BadR = RI.isSubRegister(Hexagon::USR, R) ? UsrR : R;
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000404 reportErrorRegisters(BadR);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000405 return false;
406 }
407 if (!isPredicateRegister(R) && Defs[R].size() > 1) {
408 // Check for multiple register definitions.
409 PredSet &PM = Defs[R];
410
411 // Check for multiple unconditional register definitions.
412 if (PM.count(Unconditional)) {
413 // Error out on an unconditional change when there are any other
414 // changes, conditional or not.
415 unsigned UsrR = Hexagon::USR;
416 unsigned BadR = RI.isSubRegister(Hexagon::USR, R) ? UsrR : R;
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000417 reportErrorRegisters(BadR);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000418 return false;
419 }
420 // Check for multiple conditional register definitions.
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000421 for (const auto &J : PM) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000422 PredSense P = J;
423
424 // Check for multiple uses of the same condition.
425 if (PM.count(P) > 1) {
426 // Error out on conditional changes based on the same predicate
427 // (e.g., "{ if (!p0) r0 =...; if (!p0) r0 =... }").
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000428 reportErrorRegisters(R);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000429 return false;
430 }
431 // Check for the use of the complementary condition.
432 P.second = !P.second;
433 if (PM.count(P) && PM.size() > 2) {
434 // Error out on conditional changes based on the same predicate
435 // multiple times
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000436 // (e.g., "{ if (p0) r0 =...; if (!p0) r0 =... }; if (!p0) r0 =...
437 // }").
438 reportErrorRegisters(R);
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000439 return false;
440 }
441 }
442 }
443 }
444
445 // Check for use of current definitions.
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000446 for (const auto &I : CurDefs) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000447 unsigned R = I;
448
449 if (!Uses.count(R)) {
450 // Warn on an unused current definition.
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000451 reportWarning("register `" + llvm::Twine(RI.getName(R)) +
452 "' used with `.cur' "
453 "but not used in the same packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000454 return true;
455 }
456 }
457
458 // Check for use of temporary definitions.
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000459 for (const auto &I : TmpDefs) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000460 unsigned R = I;
461
462 if (!Uses.count(R)) {
463 // special case for vhist
464 bool vHistFound = false;
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000465 for (auto const &HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) {
466 if (llvm::HexagonMCInstrInfo::getType(MCII, *HMI.getInst()) ==
467 HexagonII::TypeCVI_HIST) {
468 vHistFound = true; // vhist() implicitly uses ALL REGxx.tmp
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000469 break;
470 }
471 }
472 // Warn on an unused temporary definition.
473 if (vHistFound == false) {
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000474 reportWarning("register `" + llvm::Twine(RI.getName(R)) +
475 "' used with `.tmp' "
476 "but not used in the same packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000477 return true;
478 }
479 }
480 }
481
482 return true;
483}
484
485// Check for legal use of solo insns.
486bool HexagonMCChecker::checkSolo() {
Krzysztof Parzyszeke96d27a2017-05-01 20:06:01 +0000487 if (HexagonMCInstrInfo::bundleSize(MCB) > 1)
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000488 for (auto const &I : HexagonMCInstrInfo::bundleInstructions(MCB)) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000489 if (llvm::HexagonMCInstrInfo::isSolo(MCII, *I.getInst())) {
Krzysztof Parzyszeke96d27a2017-05-01 20:06:01 +0000490 SMLoc Loc = I.getInst()->getLoc();
491 reportError(Loc, "Instruction is marked `isSolo' and "
492 "cannot have other instructions in "
493 "the same packet");
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000494 return false;
495 }
496 }
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000497
498 return true;
499}
500
501bool HexagonMCChecker::checkShuffle() {
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000502 HexagonMCShuffler MCSDX(Context, ReportErrors, MCII, STI, MCB);
503 return MCSDX.check();
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000504}
505
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000506void HexagonMCChecker::compoundRegisterMap(unsigned &Register) {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000507 switch (Register) {
508 default:
509 break;
510 case Hexagon::R15:
511 Register = Hexagon::R23;
512 break;
513 case Hexagon::R14:
514 Register = Hexagon::R22;
515 break;
516 case Hexagon::R13:
517 Register = Hexagon::R21;
518 break;
519 case Hexagon::R12:
520 Register = Hexagon::R20;
521 break;
522 case Hexagon::R11:
523 Register = Hexagon::R19;
524 break;
525 case Hexagon::R10:
526 Register = Hexagon::R18;
527 break;
528 case Hexagon::R9:
529 Register = Hexagon::R17;
530 break;
531 case Hexagon::R8:
532 Register = Hexagon::R16;
533 break;
534 }
535}
536
537bool HexagonMCChecker::hasValidNewValueDef(const NewSense &Use,
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000538 const NewSenseList &Defs) const {
Colin LeMahieu7cd08922015-11-09 04:07:48 +0000539 bool Strict = !RelaxNVChecks;
540
541 for (unsigned i = 0, n = Defs.size(); i < n; ++i) {
542 const NewSense &Def = Defs[i];
543 // NVJ cannot use a new FP value [7.6.1]
544 if (Use.IsNVJ && (Def.IsFloat || Def.PredReg != 0))
545 continue;
546 // If the definition was not predicated, then it does not matter if
547 // the use is.
548 if (Def.PredReg == 0)
549 return true;
550 // With the strict checks, both the definition and the use must be
551 // predicated on the same register and condition.
552 if (Strict) {
553 if (Def.PredReg == Use.PredReg && Def.Cond == Use.Cond)
554 return true;
555 } else {
556 // With the relaxed checks, if the definition was predicated, the only
557 // detectable violation is if the use is predicated on the opposing
558 // condition, otherwise, it's ok.
559 if (Def.PredReg != Use.PredReg || Def.Cond == Use.Cond)
560 return true;
561 }
562 }
563 return false;
564}
565
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000566void HexagonMCChecker::reportErrorRegisters(unsigned Register) {
567 reportError("register `" + llvm::Twine(RI.getName(Register)) +
568 "' modified more than once");
569}
570
571void HexagonMCChecker::reportErrorNewValue(unsigned Register) {
572 reportError("register `" + llvm::Twine(RI.getName(Register)) +
573 "' used with `.new' "
574 "but not validly modified in the same packet");
575}
576
577void HexagonMCChecker::reportError(llvm::Twine const &Msg) {
Krzysztof Parzyszeke96d27a2017-05-01 20:06:01 +0000578 reportError(MCB.getLoc(), Msg);
579}
580
581void HexagonMCChecker::reportError(SMLoc Loc, llvm::Twine const &Msg) {
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000582 if (ReportErrors)
Krzysztof Parzyszeke96d27a2017-05-01 20:06:01 +0000583 Context.reportError(Loc, Msg);
Krzysztof Parzyszeke12d1e72017-05-01 19:41:43 +0000584}
585
586void HexagonMCChecker::reportWarning(llvm::Twine const &Msg) {
587 if (ReportErrors) {
588 auto SM = Context.getSourceManager();
589 if (SM)
590 SM->PrintMessage(MCB.getLoc(), SourceMgr::DK_Warning, Msg);
591 }
592}