/src/keystone/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCChecker.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===----- 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 | | |
19 | | #include "llvm/ADT/SmallVector.h" |
20 | | #include "llvm/MC/MCInstrDesc.h" |
21 | | #include "llvm/MC/MCInstrInfo.h" |
22 | | #include "llvm/Support/Debug.h" |
23 | | #include "llvm/Support/raw_ostream.h" |
24 | | |
25 | | using namespace llvm_ks; |
26 | | |
27 | | static bool RelaxNVChecks = false; |
28 | | |
29 | | const HexagonMCChecker::PredSense |
30 | | HexagonMCChecker::Unconditional(Hexagon::NoRegister, false); |
31 | | |
32 | 3.25k | void HexagonMCChecker::init() { |
33 | | // Initialize read-only registers set. |
34 | 3.25k | ReadOnly.insert(Hexagon::PC); |
35 | | |
36 | | // Figure out the loop-registers definitions. |
37 | 3.25k | if (HexagonMCInstrInfo::isInnerLoop(MCB)) { |
38 | 0 | Defs[Hexagon::SA0].insert(Unconditional); // FIXME: define or change SA0? |
39 | 0 | Defs[Hexagon::LC0].insert(Unconditional); |
40 | 0 | } |
41 | 3.25k | if (HexagonMCInstrInfo::isOuterLoop(MCB)) { |
42 | 0 | Defs[Hexagon::SA1].insert(Unconditional); // FIXME: define or change SA0? |
43 | 0 | Defs[Hexagon::LC1].insert(Unconditional); |
44 | 0 | } |
45 | | |
46 | 3.25k | if (HexagonMCInstrInfo::isBundle(MCB)) |
47 | | // Unfurl a bundle. |
48 | 6.70k | for (auto const&I : HexagonMCInstrInfo::bundleInstructions(MCB)) { |
49 | 6.70k | init(*I.getInst()); |
50 | 6.70k | } |
51 | 0 | else |
52 | 0 | init(MCB); |
53 | 3.25k | } |
54 | | |
55 | 6.70k | void HexagonMCChecker::init(MCInst const& MCI) { |
56 | 6.70k | const MCInstrDesc& MCID = HexagonMCInstrInfo::getDesc(MCII, MCI); |
57 | 6.70k | unsigned PredReg = Hexagon::NoRegister; |
58 | 6.70k | bool isTrue = false; |
59 | | |
60 | | // Get used registers. |
61 | 12.9k | for (unsigned i = MCID.getNumDefs(); i < MCID.getNumOperands(); ++i) |
62 | 6.24k | if (MCI.getOperand(i).isReg()) { |
63 | 783 | unsigned R = MCI.getOperand(i).getReg(); |
64 | | |
65 | 783 | if (HexagonMCInstrInfo::isPredicated(MCII, MCI) && isPredicateRegister(R)) { |
66 | | // Note an used predicate register. |
67 | 12 | PredReg = R; |
68 | 12 | isTrue = HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI); |
69 | | |
70 | | // Note use of new predicate register. |
71 | 12 | if (HexagonMCInstrInfo::isPredicatedNew(MCII, MCI)) |
72 | 0 | NewPreds.insert(PredReg); |
73 | 12 | } |
74 | 771 | else |
75 | | // Note register use. Super-registers are not tracked directly, |
76 | | // but their components. |
77 | 771 | for(MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid()); |
78 | 2.31k | SRI.isValid(); |
79 | 1.54k | ++SRI) |
80 | 1.54k | if (!MCSubRegIterator(*SRI, &RI).isValid()) |
81 | | // Skip super-registers used indirectly. |
82 | 825 | Uses.insert(*SRI); |
83 | 783 | } |
84 | | |
85 | | // Get implicit register definitions. |
86 | 6.70k | if (const MCPhysReg *ImpDef = MCID.getImplicitDefs()) |
87 | 10.4k | for (; *ImpDef; ++ImpDef) { |
88 | 8.44k | unsigned R = *ImpDef; |
89 | | |
90 | 8.44k | if (Hexagon::R31 != R && MCID.isCall()) |
91 | | // Any register other than the LR and the PC are actually volatile ones |
92 | | // as defined by the ABI, not modified implicitly by the call insn. |
93 | 6.48k | continue; |
94 | 1.96k | if (Hexagon::PC == R) |
95 | | // Branches are the only insns that can change the PC, |
96 | | // otherwise a read-only register. |
97 | 1.64k | continue; |
98 | | |
99 | 312 | if (Hexagon::USR_OVF == R) |
100 | | // Many insns change the USR implicitly, but only one or another flag. |
101 | | // The instruction table models the USR.OVF flag, which can be implicitly |
102 | | // modified more than once, but cannot be modified in the same packet |
103 | | // with an instruction that modifies is explicitly. Deal with such situ- |
104 | | // ations individually. |
105 | 0 | SoftDefs.insert(R); |
106 | 312 | else if (isPredicateRegister(R) && |
107 | 312 | HexagonMCInstrInfo::isPredicateLate(MCII, MCI)) |
108 | | // Include implicit late predicates. |
109 | 0 | LatePreds.insert(R); |
110 | 312 | else |
111 | 312 | Defs[R].insert(PredSense(PredReg, isTrue)); |
112 | 312 | } |
113 | | |
114 | | // Figure out explicit register definitions. |
115 | 9.13k | for (unsigned i = 0; i < MCID.getNumDefs(); ++i) { |
116 | 2.43k | unsigned R = MCI.getOperand(i).getReg(), |
117 | 2.43k | S = Hexagon::NoRegister; |
118 | | |
119 | | // Note register definitions, direct ones as well as indirect side-effects. |
120 | | // Super-registers are not tracked directly, but their components. |
121 | 2.43k | for(MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid()); |
122 | 7.30k | SRI.isValid(); |
123 | 4.87k | ++SRI) { |
124 | 4.87k | if (MCSubRegIterator(*SRI, &RI).isValid()) |
125 | | // Skip super-registers defined indirectly. |
126 | 2.05k | continue; |
127 | | |
128 | 2.82k | if (R == *SRI) { |
129 | 2.41k | if (S == R) |
130 | | // Avoid scoring the defined register multiple times. |
131 | 0 | continue; |
132 | 2.41k | else |
133 | | // Note that the defined register has already been scored. |
134 | 2.41k | S = R; |
135 | 2.41k | } |
136 | | |
137 | 2.82k | if (Hexagon::P3_0 != R && Hexagon::P3_0 == *SRI) |
138 | | // P3:0 is a special case, since multiple predicate register definitions |
139 | | // in a packet is allowed as the equivalent of their logical "and". |
140 | | // Only an explicit definition of P3:0 is noted as such; if a |
141 | | // side-effect, then note as a soft definition. |
142 | 357 | SoftDefs.insert(*SRI); |
143 | 2.46k | else if (HexagonMCInstrInfo::isPredicateLate(MCII, MCI) && isPredicateRegister(*SRI)) |
144 | | // Some insns produce predicates too late to be used in the same packet. |
145 | 0 | LatePreds.insert(*SRI); |
146 | 2.46k | else if (i == 0 && llvm_ks::HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCVI_VM_CUR_LD) |
147 | | // Current loads should be used in the same packet. |
148 | | // TODO: relies on the impossibility of a current and a temporary loads |
149 | | // in the same packet. |
150 | 0 | CurDefs.insert(*SRI), Defs[*SRI].insert(PredSense(PredReg, isTrue)); |
151 | 2.46k | else if (i == 0 && llvm_ks::HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCVI_VM_TMP_LD) |
152 | | // Temporary loads should be used in the same packet, but don't commit |
153 | | // results, so it should be disregarded if another insn changes the same |
154 | | // register. |
155 | | // TODO: relies on the impossibility of a current and a temporary loads |
156 | | // in the same packet. |
157 | 0 | TmpDefs.insert(*SRI); |
158 | 2.46k | else if (i <= 1 && llvm_ks::HexagonMCInstrInfo::hasNewValue2(MCII, MCI) ) |
159 | | // vshuff(Vx, Vy, Rx) <- Vx(0) and Vy(1) are both source and |
160 | | // destination registers with this instruction. same for vdeal(Vx,Vy,Rx) |
161 | 0 | Uses.insert(*SRI); |
162 | 2.46k | else |
163 | 2.46k | Defs[*SRI].insert(PredSense(PredReg, isTrue)); |
164 | 2.82k | } |
165 | 2.43k | } |
166 | | |
167 | | // Figure out register definitions that produce new values. |
168 | 6.70k | if (HexagonMCInstrInfo::hasNewValue(MCII, MCI)) { |
169 | 1.76k | unsigned R = HexagonMCInstrInfo::getNewValueOperand(MCII, MCI).getReg(); |
170 | | |
171 | 1.76k | if (HexagonMCInstrInfo::isCompound(MCII, MCI)) |
172 | 0 | compoundRegisterMap(R); // Compound insns have a limited register range. |
173 | | |
174 | 1.76k | for(MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid()); |
175 | 5.28k | SRI.isValid(); |
176 | 3.52k | ++SRI) |
177 | 3.52k | if (!MCSubRegIterator(*SRI, &RI).isValid()) |
178 | | // No super-registers defined indirectly. |
179 | 1.76k | NewDefs[*SRI].push_back(NewSense::Def(PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI), |
180 | 1.76k | HexagonMCInstrInfo::isFloat(MCII, MCI))); |
181 | | |
182 | | // For fairly unique 2-dot-new producers, example: |
183 | | // vdeal(V1, V9, R0) V1.new and V9.new can be used by consumers. |
184 | 1.76k | if (HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) { |
185 | 0 | unsigned R2 = HexagonMCInstrInfo::getNewValueOperand2(MCII, MCI).getReg(); |
186 | |
|
187 | 0 | for(MCRegAliasIterator SRI(R2, &RI, !MCSubRegIterator(R2, &RI).isValid()); |
188 | 0 | SRI.isValid(); |
189 | 0 | ++SRI) |
190 | 0 | if (!MCSubRegIterator(*SRI, &RI).isValid()) |
191 | 0 | NewDefs[*SRI].push_back(NewSense::Def(PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI), |
192 | 0 | HexagonMCInstrInfo::isFloat(MCII, MCI))); |
193 | 0 | } |
194 | 1.76k | } |
195 | | |
196 | | // Figure out definitions of new predicate registers. |
197 | 6.70k | if (HexagonMCInstrInfo::isPredicatedNew(MCII, MCI)) |
198 | 0 | for (unsigned i = MCID.getNumDefs(); i < MCID.getNumOperands(); ++i) |
199 | 0 | if (MCI.getOperand(i).isReg()) { |
200 | 0 | unsigned P = MCI.getOperand(i).getReg(); |
201 | |
|
202 | 0 | if (isPredicateRegister(P)) |
203 | 0 | NewPreds.insert(P); |
204 | 0 | } |
205 | | |
206 | | // Figure out uses of new values. |
207 | 6.70k | if (HexagonMCInstrInfo::isNewValue(MCII, MCI)) { |
208 | 0 | unsigned N = HexagonMCInstrInfo::getNewValueOperand(MCII, MCI).getReg(); |
209 | |
|
210 | 0 | if (!MCSubRegIterator(N, &RI).isValid()) { |
211 | | // Super-registers cannot use new values. |
212 | 0 | if (MCID.isBranch()) |
213 | 0 | NewUses[N] = NewSense::Jmp(llvm_ks::HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNV); |
214 | 0 | else |
215 | 0 | NewUses[N] = NewSense::Use(PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI)); |
216 | 0 | } |
217 | 0 | } |
218 | 6.70k | } |
219 | | |
220 | | HexagonMCChecker::HexagonMCChecker(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &mcb, MCInst &mcbdx, |
221 | | MCRegisterInfo const &ri) |
222 | 3.25k | : MCB(mcb), MCBDX(mcbdx), RI(ri), MCII(MCII), STI(STI), |
223 | 3.25k | bLoadErrInfo(false) { |
224 | 3.25k | init(); |
225 | 3.25k | } |
226 | | |
227 | 3.25k | bool HexagonMCChecker::check() { |
228 | 3.25k | bool chkB = checkBranches(); |
229 | 3.25k | bool chkP = checkPredicates(); |
230 | 3.25k | bool chkNV = checkNewValues(); |
231 | 3.25k | bool chkR = checkRegisters(); |
232 | 3.25k | bool chkS = checkSolo(); |
233 | 3.25k | bool chkSh = checkShuffle(); |
234 | 3.25k | bool chkSl = checkSlots(); |
235 | 3.25k | bool chk = chkB && chkP && chkNV && chkR && chkS && chkSh && chkSl; |
236 | | |
237 | 3.25k | return chk; |
238 | 3.25k | } |
239 | | |
240 | | bool HexagonMCChecker::checkSlots() |
241 | | |
242 | 3.25k | { |
243 | 3.25k | unsigned slotsUsed = 0; |
244 | 6.68k | for (auto HMI: HexagonMCInstrInfo::bundleInstructions(MCBDX)) { |
245 | 6.68k | MCInst const& MCI = *HMI.getInst(); |
246 | 6.68k | if (HexagonMCInstrInfo::isImmext(MCI)) |
247 | 1.79k | continue; |
248 | 4.89k | if (HexagonMCInstrInfo::isDuplex(MCII, MCI)) |
249 | 0 | slotsUsed += 2; |
250 | 4.89k | else |
251 | 4.89k | ++slotsUsed; |
252 | 4.89k | } |
253 | | |
254 | 3.25k | if (slotsUsed > HEXAGON_PACKET_SIZE) { |
255 | 41 | HexagonMCErrInfo errInfo; |
256 | 41 | errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_NOSLOTS); |
257 | 41 | addErrInfo(errInfo); |
258 | 41 | return false; |
259 | 41 | } |
260 | 3.21k | return true; |
261 | 3.25k | } |
262 | | |
263 | | // Check legal use of branches. |
264 | 3.25k | bool HexagonMCChecker::checkBranches() { |
265 | 3.25k | HexagonMCErrInfo errInfo; |
266 | 3.25k | if (HexagonMCInstrInfo::isBundle(MCB)) { |
267 | 3.25k | bool hasConditional = false; |
268 | 3.25k | unsigned Branches = 0, Returns = 0, NewIndirectBranches = 0, |
269 | 3.25k | NewValueBranches = 0, Conditional = HEXAGON_PRESHUFFLE_PACKET_SIZE, |
270 | 3.25k | Unconditional = HEXAGON_PRESHUFFLE_PACKET_SIZE; |
271 | | |
272 | 3.25k | for (unsigned i = HexagonMCInstrInfo::bundleInstructionsOffset; |
273 | 9.94k | i < MCB.size(); ++i) { |
274 | 6.68k | MCInst const &MCI = *MCB.begin()[i].getInst(); |
275 | | |
276 | 6.68k | if (HexagonMCInstrInfo::isImmext(MCI)) |
277 | 1.79k | continue; |
278 | 4.89k | if (HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch() || |
279 | 4.89k | HexagonMCInstrInfo::getDesc(MCII, MCI).isCall()) { |
280 | 1.95k | ++Branches; |
281 | 1.95k | if (HexagonMCInstrInfo::getDesc(MCII, MCI).isIndirectBranch() && |
282 | 1.95k | HexagonMCInstrInfo::isPredicatedNew(MCII, MCI)) |
283 | 0 | ++NewIndirectBranches; |
284 | 1.95k | if (HexagonMCInstrInfo::isNewValue(MCII, MCI)) |
285 | 0 | ++NewValueBranches; |
286 | | |
287 | 1.95k | if (HexagonMCInstrInfo::isPredicated(MCII, MCI) || |
288 | 1.95k | HexagonMCInstrInfo::isPredicatedNew(MCII, MCI)) { |
289 | 11 | hasConditional = true; |
290 | 11 | Conditional = i; // Record the position of the conditional branch. |
291 | 1.94k | } else { |
292 | 1.94k | Unconditional = i; // Record the position of the unconditional branch. |
293 | 1.94k | } |
294 | 1.95k | } |
295 | 4.89k | if (HexagonMCInstrInfo::getDesc(MCII, MCI).isReturn() && |
296 | 4.89k | HexagonMCInstrInfo::getDesc(MCII, MCI).mayLoad()) |
297 | 1 | ++Returns; |
298 | 4.89k | } |
299 | | |
300 | 3.25k | if (Branches) // FIXME: should "Defs.count(Hexagon::PC)" be here too? |
301 | 1.84k | if (HexagonMCInstrInfo::isInnerLoop(MCB) || |
302 | 1.84k | HexagonMCInstrInfo::isOuterLoop(MCB)) { |
303 | | // Error out if there's any branch in a loop-end packet. |
304 | 0 | errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_ENDLOOP, Hexagon::PC); |
305 | 0 | addErrInfo(errInfo); |
306 | 0 | return false; |
307 | 0 | } |
308 | 3.25k | if (Branches > 1) |
309 | 17 | if (!hasConditional || Conditional > Unconditional) { |
310 | | // Error out if more than one unconditional branch or |
311 | | // the conditional branch appears after the unconditional one. |
312 | 17 | errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_BRANCHES); |
313 | 17 | addErrInfo(errInfo); |
314 | 17 | return false; |
315 | 17 | } |
316 | 3.25k | } |
317 | | |
318 | 3.24k | return true; |
319 | 3.25k | } |
320 | | |
321 | | // Check legal use of predicate registers. |
322 | 3.25k | bool HexagonMCChecker::checkPredicates() { |
323 | 3.25k | HexagonMCErrInfo errInfo; |
324 | | // Check for proper use of new predicate registers. |
325 | 3.25k | for (const auto& I : NewPreds) { |
326 | 0 | unsigned P = I; |
327 | |
|
328 | 0 | if (!Defs.count(P) || LatePreds.count(P)) { |
329 | | // Error out if the new predicate register is not defined, |
330 | | // or defined "late" |
331 | | // (e.g., "{ if (p3.new)... ; p3 = sp1loop0(#r7:2, Rs) }"). |
332 | 0 | errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_NEWP, P); |
333 | 0 | addErrInfo(errInfo); |
334 | 0 | return false; |
335 | 0 | } |
336 | 0 | } |
337 | | |
338 | | // Check for proper use of auto-anded of predicate registers. |
339 | 3.25k | for (const auto& I : LatePreds) { |
340 | 0 | unsigned P = I; |
341 | |
|
342 | 0 | if (LatePreds.count(P) > 1 || Defs.count(P)) { |
343 | | // Error out if predicate register defined "late" multiple times or |
344 | | // defined late and regularly defined |
345 | | // (e.g., "{ p3 = sp1loop0(...); p3 = cmp.eq(...) }". |
346 | 0 | errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, P); |
347 | 0 | addErrInfo(errInfo); |
348 | 0 | return false; |
349 | 0 | } |
350 | 0 | } |
351 | | |
352 | 3.25k | return true; |
353 | 3.25k | } |
354 | | |
355 | | // Check legal use of new values. |
356 | 3.25k | bool HexagonMCChecker::checkNewValues() { |
357 | 3.25k | HexagonMCErrInfo errInfo; |
358 | 3.25k | memset(&errInfo, 0, sizeof(errInfo)); |
359 | 3.25k | for (auto& I : NewUses) { |
360 | 0 | unsigned R = I.first; |
361 | 0 | NewSense &US = I.second; |
362 | |
|
363 | 0 | if (!hasValidNewValueDef(US, NewDefs[R])) { |
364 | 0 | errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_NEWV, R); |
365 | 0 | addErrInfo(errInfo); |
366 | 0 | return false; |
367 | 0 | } |
368 | 0 | } |
369 | | |
370 | 3.25k | return true; |
371 | 3.25k | } |
372 | | |
373 | | // Check for legal register uses and definitions. |
374 | 3.25k | bool HexagonMCChecker::checkRegisters() { |
375 | 3.25k | HexagonMCErrInfo errInfo; |
376 | | // Check for proper register definitions. |
377 | 3.25k | for (const auto& I : Defs) { |
378 | 1.16k | unsigned R = I.first; |
379 | | |
380 | 1.16k | if (ReadOnly.count(R)) { |
381 | | // Error out for definitions of read-only registers. |
382 | 271 | errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_READONLY, R); |
383 | 271 | addErrInfo(errInfo); |
384 | 271 | return false; |
385 | 271 | } |
386 | 897 | if (isLoopRegister(R) && Defs.count(R) > 1 && |
387 | 897 | (HexagonMCInstrInfo::isInnerLoop(MCB) || |
388 | 0 | HexagonMCInstrInfo::isOuterLoop(MCB))) { |
389 | | // Error out for definitions of loop registers at the end of a loop. |
390 | 0 | errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_LOOP, R); |
391 | 0 | addErrInfo(errInfo); |
392 | 0 | return false; |
393 | 0 | } |
394 | 897 | if (SoftDefs.count(R)) { |
395 | | // Error out for explicit changes to registers also weakly defined |
396 | | // (e.g., "{ usr = r0; r0 = sfadd(...) }"). |
397 | 0 | unsigned UsrR = Hexagon::USR; // Silence warning about mixed types in ?:. |
398 | 0 | unsigned BadR = RI.isSubRegister(Hexagon::USR, R) ? UsrR : R; |
399 | 0 | errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, BadR); |
400 | 0 | addErrInfo(errInfo); |
401 | 0 | return false; |
402 | 0 | } |
403 | 897 | if (!isPredicateRegister(R) && Defs[R].size() > 1) { |
404 | | // Check for multiple register definitions. |
405 | 40 | PredSet &PM = Defs[R]; |
406 | | |
407 | | // Check for multiple unconditional register definitions. |
408 | 40 | if (PM.count(Unconditional)) { |
409 | | // Error out on an unconditional change when there are any other |
410 | | // changes, conditional or not. |
411 | 40 | unsigned UsrR = Hexagon::USR; |
412 | 40 | unsigned BadR = RI.isSubRegister(Hexagon::USR, R) ? UsrR : R; |
413 | 40 | errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, BadR); |
414 | 40 | addErrInfo(errInfo); |
415 | 40 | return false; |
416 | 40 | } |
417 | | // Check for multiple conditional register definitions. |
418 | 0 | for (const auto& J : PM) { |
419 | 0 | PredSense P = J; |
420 | | |
421 | | // Check for multiple uses of the same condition. |
422 | 0 | if (PM.count(P) > 1) { |
423 | | // Error out on conditional changes based on the same predicate |
424 | | // (e.g., "{ if (!p0) r0 =...; if (!p0) r0 =... }"). |
425 | 0 | errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, R); |
426 | 0 | addErrInfo(errInfo); |
427 | 0 | return false; |
428 | 0 | } |
429 | | // Check for the use of the complementary condition. |
430 | 0 | P.second = !P.second; |
431 | 0 | if (PM.count(P) && PM.size() > 2) { |
432 | | // Error out on conditional changes based on the same predicate |
433 | | // multiple times |
434 | | // (e.g., "{ if (p0) r0 =...; if (!p0) r0 =... }; if (!p0) r0 =... }"). |
435 | 0 | errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, R); |
436 | 0 | addErrInfo(errInfo); |
437 | 0 | return false; |
438 | 0 | } |
439 | 0 | } |
440 | 0 | } |
441 | 897 | } |
442 | | |
443 | | // Check for use of current definitions. |
444 | 2.94k | for (const auto& I : CurDefs) { |
445 | 0 | unsigned R = I; |
446 | |
|
447 | 0 | if (!Uses.count(R)) { |
448 | | // Warn on an unused current definition. |
449 | 0 | errInfo.setWarning(HexagonMCErrInfo::CHECK_WARN_CURRENT, R); |
450 | 0 | addErrInfo(errInfo); |
451 | 0 | return true; |
452 | 0 | } |
453 | 0 | } |
454 | | |
455 | | // Check for use of temporary definitions. |
456 | 2.94k | for (const auto& I : TmpDefs) { |
457 | 0 | unsigned R = I; |
458 | |
|
459 | 0 | if (!Uses.count(R)) { |
460 | | // special case for vhist |
461 | 0 | bool vHistFound = false; |
462 | 0 | for (auto const&HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) { |
463 | 0 | if(llvm_ks::HexagonMCInstrInfo::getType(MCII, *HMI.getInst()) == HexagonII::TypeCVI_HIST) { |
464 | 0 | vHistFound = true; // vhist() implicitly uses ALL REGxx.tmp |
465 | 0 | break; |
466 | 0 | } |
467 | 0 | } |
468 | | // Warn on an unused temporary definition. |
469 | 0 | if (vHistFound == false) { |
470 | 0 | errInfo.setWarning(HexagonMCErrInfo::CHECK_WARN_TEMPORARY, R); |
471 | 0 | addErrInfo(errInfo); |
472 | 0 | return true; |
473 | 0 | } |
474 | 0 | } |
475 | 0 | } |
476 | | |
477 | 2.94k | return true; |
478 | 2.94k | } |
479 | | |
480 | | // Check for legal use of solo insns. |
481 | 3.25k | bool HexagonMCChecker::checkSolo() { |
482 | 3.25k | HexagonMCErrInfo errInfo; |
483 | 3.25k | if (HexagonMCInstrInfo::isBundle(MCB) && |
484 | 3.25k | HexagonMCInstrInfo::bundleSize(MCB) > 1) { |
485 | 3.78k | for (auto const&I : HexagonMCInstrInfo::bundleInstructions(MCB)) { |
486 | 3.78k | if (llvm_ks::HexagonMCInstrInfo::isSolo(MCII, *I.getInst())) { |
487 | 0 | errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_SOLO); |
488 | 0 | addErrInfo(errInfo); |
489 | 0 | return false; |
490 | 0 | } |
491 | 3.78k | } |
492 | 315 | } |
493 | | |
494 | 3.25k | return true; |
495 | 3.25k | } |
496 | | |
497 | 3.25k | bool HexagonMCChecker::checkShuffle() { |
498 | 3.25k | HexagonMCErrInfo errInfo; |
499 | | // Branch info is lost when duplexing. The unduplexed insns must be |
500 | | // checked and only branch errors matter for this case. |
501 | 3.25k | HexagonMCShuffler MCS(MCII, STI, MCB); |
502 | 3.25k | if (!MCS.check()) { |
503 | 42 | if (MCS.getError() == HexagonShuffler::SHUFFLE_ERROR_BRANCHES) { |
504 | 13 | errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_SHUFFLE); |
505 | 13 | errInfo.setShuffleError(MCS.getError()); |
506 | 13 | addErrInfo(errInfo); |
507 | 13 | return false; |
508 | 13 | } |
509 | 42 | } |
510 | 3.24k | HexagonMCShuffler MCSDX(MCII, STI, MCBDX); |
511 | 3.24k | if (!MCSDX.check()) { |
512 | 29 | errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_SHUFFLE); |
513 | 29 | errInfo.setShuffleError(MCSDX.getError()); |
514 | 29 | addErrInfo(errInfo); |
515 | 29 | return false; |
516 | 29 | } |
517 | 3.21k | return true; |
518 | 3.24k | } |
519 | | |
520 | 0 | void HexagonMCChecker::compoundRegisterMap(unsigned& Register) { |
521 | 0 | switch (Register) { |
522 | 0 | default: |
523 | 0 | break; |
524 | 0 | case Hexagon::R15: |
525 | 0 | Register = Hexagon::R23; |
526 | 0 | break; |
527 | 0 | case Hexagon::R14: |
528 | 0 | Register = Hexagon::R22; |
529 | 0 | break; |
530 | 0 | case Hexagon::R13: |
531 | 0 | Register = Hexagon::R21; |
532 | 0 | break; |
533 | 0 | case Hexagon::R12: |
534 | 0 | Register = Hexagon::R20; |
535 | 0 | break; |
536 | 0 | case Hexagon::R11: |
537 | 0 | Register = Hexagon::R19; |
538 | 0 | break; |
539 | 0 | case Hexagon::R10: |
540 | 0 | Register = Hexagon::R18; |
541 | 0 | break; |
542 | 0 | case Hexagon::R9: |
543 | 0 | Register = Hexagon::R17; |
544 | 0 | break; |
545 | 0 | case Hexagon::R8: |
546 | 0 | Register = Hexagon::R16; |
547 | 0 | break; |
548 | 0 | } |
549 | 0 | } |
550 | | |
551 | | bool HexagonMCChecker::hasValidNewValueDef(const NewSense &Use, |
552 | 0 | const NewSenseList &Defs) const { |
553 | 0 | bool Strict = !RelaxNVChecks; |
554 | |
|
555 | 0 | for (unsigned i = 0, n = Defs.size(); i < n; ++i) { |
556 | 0 | const NewSense &Def = Defs[i]; |
557 | | // NVJ cannot use a new FP value [7.6.1] |
558 | 0 | if (Use.IsNVJ && (Def.IsFloat || Def.PredReg != 0)) |
559 | 0 | continue; |
560 | | // If the definition was not predicated, then it does not matter if |
561 | | // the use is. |
562 | 0 | if (Def.PredReg == 0) |
563 | 0 | return true; |
564 | | // With the strict checks, both the definition and the use must be |
565 | | // predicated on the same register and condition. |
566 | 0 | if (Strict) { |
567 | 0 | if (Def.PredReg == Use.PredReg && Def.Cond == Use.Cond) |
568 | 0 | return true; |
569 | 0 | } else { |
570 | | // With the relaxed checks, if the definition was predicated, the only |
571 | | // detectable violation is if the use is predicated on the opposing |
572 | | // condition, otherwise, it's ok. |
573 | 0 | if (Def.PredReg != Use.PredReg || Def.Cond == Use.Cond) |
574 | 0 | return true; |
575 | 0 | } |
576 | 0 | } |
577 | 0 | return false; |
578 | 0 | } |
579 | | |