HexagonMCChecker.cpp revision 296417
1234353Sdim//===----- HexagonMCChecker.cpp - Instruction bundle checking -------------===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim// 10218885Sdim// This implements the checking of insns inside a bundle according to the 11218885Sdim// packet constraint rules of the Hexagon ISA. 12218885Sdim// 13218885Sdim//===----------------------------------------------------------------------===// 14218885Sdim 15218885Sdim#include "HexagonMCChecker.h" 16218885Sdim 17218885Sdim#include "HexagonBaseInfo.h" 18221345Sdim 19218885Sdim#include "llvm/ADT/SmallVector.h" 20218885Sdim#include "llvm/MC/MCInstrDesc.h" 21218885Sdim#include "llvm/MC/MCInstrInfo.h" 22218885Sdim#include "llvm/Support/CommandLine.h" 23218885Sdim#include "llvm/Support/Debug.h" 24221345Sdim#include "llvm/Support/raw_ostream.h" 25218885Sdim 26218885Sdimusing namespace llvm; 27218885Sdim 28218885Sdimstatic cl::opt<bool> RelaxNVChecks("relax-nv-checks", cl::init(false), 29218885Sdim cl::ZeroOrMore, cl::Hidden, cl::desc("Relax checks of new-value validity")); 30218885Sdim 31218885Sdimconst HexagonMCChecker::PredSense 32218885Sdim HexagonMCChecker::Unconditional(Hexagon::NoRegister, false); 33218885Sdim 34218885Sdimvoid HexagonMCChecker::init() { 35218885Sdim // Initialize read-only registers set. 36218885Sdim ReadOnly.insert(Hexagon::PC); 37218885Sdim 38218885Sdim // Figure out the loop-registers definitions. 39218885Sdim if (HexagonMCInstrInfo::isInnerLoop(MCB)) { 40218885Sdim Defs[Hexagon::SA0].insert(Unconditional); // FIXME: define or change SA0? 41218885Sdim Defs[Hexagon::LC0].insert(Unconditional); 42218885Sdim } 43218885Sdim if (HexagonMCInstrInfo::isOuterLoop(MCB)) { 44218885Sdim Defs[Hexagon::SA1].insert(Unconditional); // FIXME: define or change SA0? 45218885Sdim Defs[Hexagon::LC1].insert(Unconditional); 46218885Sdim } 47218885Sdim 48218885Sdim if (HexagonMCInstrInfo::isBundle(MCB)) 49218885Sdim // Unfurl a bundle. 50218885Sdim for (auto const&I : HexagonMCInstrInfo::bundleInstructions(MCB)) { 51218885Sdim init(*I.getInst()); 52218885Sdim } 53218885Sdim else 54243830Sdim init(MCB); 55243830Sdim} 56218885Sdim 57218885Sdimvoid HexagonMCChecker::init(MCInst const& MCI) { 58221345Sdim const MCInstrDesc& MCID = HexagonMCInstrInfo::getDesc(MCII, MCI); 59218885Sdim unsigned PredReg = Hexagon::NoRegister; 60218885Sdim bool isTrue = false; 61218885Sdim 62218885Sdim // Get used registers. 63218885Sdim for (unsigned i = MCID.getNumDefs(); i < MCID.getNumOperands(); ++i) 64243830Sdim if (MCI.getOperand(i).isReg()) { 65218885Sdim unsigned R = MCI.getOperand(i).getReg(); 66221345Sdim 67218885Sdim if (HexagonMCInstrInfo::isPredicated(MCII, MCI) && isPredicateRegister(R)) { 68218885Sdim // Note an used predicate register. 69218885Sdim PredReg = R; 70218885Sdim isTrue = HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI); 71218885Sdim 72218885Sdim // Note use of new predicate register. 73218885Sdim if (HexagonMCInstrInfo::isPredicatedNew(MCII, MCI)) 74218885Sdim NewPreds.insert(PredReg); 75218885Sdim } 76218885Sdim else 77218885Sdim // Note register use. Super-registers are not tracked directly, 78218885Sdim // but their components. 79218885Sdim for(MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid()); 80218885Sdim SRI.isValid(); 81218885Sdim ++SRI) 82218885Sdim if (!MCSubRegIterator(*SRI, &RI).isValid()) 83218885Sdim // Skip super-registers used indirectly. 84218885Sdim Uses.insert(*SRI); 85218885Sdim } 86218885Sdim 87218885Sdim // Get implicit register definitions. 88218885Sdim if (const MCPhysReg *ImpDef = MCID.getImplicitDefs()) 89218885Sdim for (; *ImpDef; ++ImpDef) { 90218885Sdim unsigned R = *ImpDef; 91218885Sdim 92218885Sdim if (Hexagon::R31 != R && MCID.isCall()) 93218885Sdim // Any register other than the LR and the PC are actually volatile ones 94218885Sdim // as defined by the ABI, not modified implicitly by the call insn. 95218885Sdim continue; 96218885Sdim if (Hexagon::PC == R) 97218885Sdim // Branches are the only insns that can change the PC, 98218885Sdim // otherwise a read-only register. 99218885Sdim continue; 100218885Sdim 101218885Sdim if (Hexagon::USR_OVF == R) 102218885Sdim // Many insns change the USR implicitly, but only one or another flag. 103218885Sdim // The instruction table models the USR.OVF flag, which can be implicitly 104218885Sdim // modified more than once, but cannot be modified in the same packet 105218885Sdim // with an instruction that modifies is explicitly. Deal with such situ- 106218885Sdim // ations individually. 107218885Sdim SoftDefs.insert(R); 108218885Sdim else if (isPredicateRegister(R) && 109218885Sdim HexagonMCInstrInfo::isPredicateLate(MCII, MCI)) 110218885Sdim // Include implicit late predicates. 111218885Sdim LatePreds.insert(R); 112218885Sdim else 113218885Sdim Defs[R].insert(PredSense(PredReg, isTrue)); 114218885Sdim } 115218885Sdim 116218885Sdim // Figure out explicit register definitions. 117218885Sdim for (unsigned i = 0; i < MCID.getNumDefs(); ++i) { 118218885Sdim unsigned R = MCI.getOperand(i).getReg(), 119218885Sdim S = Hexagon::NoRegister; 120218885Sdim 121218885Sdim // Note register definitions, direct ones as well as indirect side-effects. 122218885Sdim // Super-registers are not tracked directly, but their components. 123218885Sdim for(MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid()); 124218885Sdim SRI.isValid(); 125218885Sdim ++SRI) { 126218885Sdim if (MCSubRegIterator(*SRI, &RI).isValid()) 127218885Sdim // Skip super-registers defined indirectly. 128218885Sdim continue; 129218885Sdim 130218885Sdim if (R == *SRI) { 131218885Sdim if (S == R) 132218885Sdim // Avoid scoring the defined register multiple times. 133218885Sdim continue; 134218885Sdim else 135218885Sdim // Note that the defined register has already been scored. 136218885Sdim S = R; 137218885Sdim } 138218885Sdim 139218885Sdim if (Hexagon::P3_0 != R && Hexagon::P3_0 == *SRI) 140243830Sdim // P3:0 is a special case, since multiple predicate register definitions 141243830Sdim // in a packet is allowed as the equivalent of their logical "and". 142243830Sdim // Only an explicit definition of P3:0 is noted as such; if a 143243830Sdim // side-effect, then note as a soft definition. 144243830Sdim SoftDefs.insert(*SRI); 145243830Sdim else if (HexagonMCInstrInfo::isPredicateLate(MCII, MCI) && isPredicateRegister(*SRI)) 146243830Sdim // Some insns produce predicates too late to be used in the same packet. 147243830Sdim LatePreds.insert(*SRI); 148243830Sdim else if (i == 0 && llvm::HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCVI_VM_CUR_LD) 149243830Sdim // Current loads should be used in the same packet. 150243830Sdim // TODO: relies on the impossibility of a current and a temporary loads 151243830Sdim // in the same packet. 152243830Sdim CurDefs.insert(*SRI), Defs[*SRI].insert(PredSense(PredReg, isTrue)); 153243830Sdim else if (i == 0 && llvm::HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeCVI_VM_TMP_LD) 154243830Sdim // Temporary loads should be used in the same packet, but don't commit 155243830Sdim // results, so it should be disregarded if another insn changes the same 156243830Sdim // register. 157243830Sdim // TODO: relies on the impossibility of a current and a temporary loads 158243830Sdim // in the same packet. 159243830Sdim TmpDefs.insert(*SRI); 160243830Sdim else if (i <= 1 && llvm::HexagonMCInstrInfo::hasNewValue2(MCII, MCI) ) 161243830Sdim // vshuff(Vx, Vy, Rx) <- Vx(0) and Vy(1) are both source and 162243830Sdim // destination registers with this instruction. same for vdeal(Vx,Vy,Rx) 163243830Sdim Uses.insert(*SRI); 164243830Sdim else 165243830Sdim Defs[*SRI].insert(PredSense(PredReg, isTrue)); 166243830Sdim } 167243830Sdim } 168243830Sdim 169243830Sdim // Figure out register definitions that produce new values. 170243830Sdim if (HexagonMCInstrInfo::hasNewValue(MCII, MCI)) { 171243830Sdim unsigned R = HexagonMCInstrInfo::getNewValueOperand(MCII, MCI).getReg(); 172243830Sdim 173243830Sdim if (HexagonMCInstrInfo::isCompound(MCII, MCI)) 174243830Sdim compoundRegisterMap(R); // Compound insns have a limited register range. 175243830Sdim 176243830Sdim for(MCRegAliasIterator SRI(R, &RI, !MCSubRegIterator(R, &RI).isValid()); 177243830Sdim SRI.isValid(); 178243830Sdim ++SRI) 179243830Sdim if (!MCSubRegIterator(*SRI, &RI).isValid()) 180243830Sdim // No super-registers defined indirectly. 181243830Sdim NewDefs[*SRI].push_back(NewSense::Def(PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI), 182243830Sdim HexagonMCInstrInfo::isFloat(MCII, MCI))); 183243830Sdim 184218885Sdim // For fairly unique 2-dot-new producers, example: 185219077Sdim // vdeal(V1, V9, R0) V1.new and V9.new can be used by consumers. 186224145Sdim if (HexagonMCInstrInfo::hasNewValue2(MCII, MCI)) { 187224145Sdim unsigned R2 = HexagonMCInstrInfo::getNewValueOperand2(MCII, MCI).getReg(); 188234353Sdim 189218885Sdim for(MCRegAliasIterator SRI(R2, &RI, !MCSubRegIterator(R2, &RI).isValid()); 190224145Sdim SRI.isValid(); 191219077Sdim ++SRI) 192219077Sdim if (!MCSubRegIterator(*SRI, &RI).isValid()) 193219077Sdim NewDefs[*SRI].push_back(NewSense::Def(PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI), 194219077Sdim HexagonMCInstrInfo::isFloat(MCII, MCI))); 195218885Sdim } 196218885Sdim } 197218885Sdim 198243830Sdim // Figure out definitions of new predicate registers. 199243830Sdim if (HexagonMCInstrInfo::isPredicatedNew(MCII, MCI)) 200243830Sdim for (unsigned i = MCID.getNumDefs(); i < MCID.getNumOperands(); ++i) 201243830Sdim if (MCI.getOperand(i).isReg()) { 202243830Sdim unsigned P = MCI.getOperand(i).getReg(); 203243830Sdim 204243830Sdim if (isPredicateRegister(P)) 205243830Sdim NewPreds.insert(P); 206243830Sdim } 207243830Sdim 208243830Sdim // Figure out uses of new values. 209243830Sdim if (HexagonMCInstrInfo::isNewValue(MCII, MCI)) { 210243830Sdim unsigned N = HexagonMCInstrInfo::getNewValueOperand(MCII, MCI).getReg(); 211218885Sdim 212221345Sdim if (!MCSubRegIterator(N, &RI).isValid()) { 213218885Sdim // Super-registers cannot use new values. 214218885Sdim if (MCID.isBranch()) 215218885Sdim NewUses[N] = NewSense::Jmp(llvm::HexagonMCInstrInfo::getType(MCII, MCI) == HexagonII::TypeNV); 216218885Sdim else 217218885Sdim NewUses[N] = NewSense::Use(PredReg, HexagonMCInstrInfo::isPredicatedTrue(MCII, MCI)); 218218885Sdim } 219218885Sdim } 220221345Sdim} 221218885Sdim 222218885SdimHexagonMCChecker::HexagonMCChecker(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst &mcb, MCInst &mcbdx, 223218885Sdim MCRegisterInfo const &ri) 224218885Sdim : MCB(mcb), MCBDX(mcbdx), RI(ri), MCII(MCII), STI(STI), 225218885Sdim bLoadErrInfo(false) { 226218885Sdim init(); 227218885Sdim} 228218885Sdim 229221345Sdimbool HexagonMCChecker::check() { 230218885Sdim bool chkB = checkBranches(); 231221345Sdim bool chkP = checkPredicates(); 232218885Sdim bool chkNV = checkNewValues(); 233243830Sdim bool chkR = checkRegisters(); 234243830Sdim bool chkS = checkSolo(); 235243830Sdim bool chkSh = checkShuffle(); 236243830Sdim bool chkSl = checkSlots(); 237243830Sdim bool chk = chkB && chkP && chkNV && chkR && chkS && chkSh && chkSl; 238243830Sdim 239221345Sdim return chk; 240221345Sdim} 241221345Sdim 242218885Sdimbool HexagonMCChecker::checkSlots() 243218885Sdim 244218885Sdim{ 245218885Sdim unsigned slotsUsed = 0; 246218885Sdim for (auto HMI: HexagonMCInstrInfo::bundleInstructions(MCBDX)) { 247243830Sdim MCInst const& MCI = *HMI.getInst(); 248243830Sdim if (HexagonMCInstrInfo::isImmext(MCI)) 249218885Sdim continue; 250218885Sdim if (HexagonMCInstrInfo::isDuplex(MCII, MCI)) 251218885Sdim slotsUsed += 2; 252218885Sdim else 253218885Sdim ++slotsUsed; 254218885Sdim } 255221345Sdim 256221345Sdim if (slotsUsed > HEXAGON_PACKET_SIZE) { 257221345Sdim HexagonMCErrInfo errInfo; 258221345Sdim errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_NOSLOTS); 259218885Sdim addErrInfo(errInfo); 260218885Sdim return false; 261221345Sdim } 262218885Sdim return true; 263218885Sdim} 264218885Sdim 265218885Sdim// Check legal use of branches. 266218885Sdimbool HexagonMCChecker::checkBranches() { 267218885Sdim HexagonMCErrInfo errInfo; 268218885Sdim if (HexagonMCInstrInfo::isBundle(MCB)) { 269218885Sdim bool hasConditional = false; 270218885Sdim unsigned Branches = 0, Returns = 0, NewIndirectBranches = 0, 271218885Sdim NewValueBranches = 0, Conditional = HEXAGON_PRESHUFFLE_PACKET_SIZE, 272218885Sdim Unconditional = HEXAGON_PRESHUFFLE_PACKET_SIZE; 273218885Sdim 274218885Sdim for (unsigned i = HexagonMCInstrInfo::bundleInstructionsOffset; 275218885Sdim i < MCB.size(); ++i) { 276218885Sdim MCInst const &MCI = *MCB.begin()[i].getInst(); 277218885Sdim 278218885Sdim if (HexagonMCInstrInfo::isImmext(MCI)) 279218885Sdim continue; 280218885Sdim if (HexagonMCInstrInfo::getDesc(MCII, MCI).isBranch() || 281218885Sdim HexagonMCInstrInfo::getDesc(MCII, MCI).isCall()) { 282218885Sdim ++Branches; 283218885Sdim if (HexagonMCInstrInfo::getDesc(MCII, MCI).isIndirectBranch() && 284218885Sdim HexagonMCInstrInfo::isPredicatedNew(MCII, MCI)) 285218885Sdim ++NewIndirectBranches; 286224145Sdim if (HexagonMCInstrInfo::isNewValue(MCII, MCI)) 287224145Sdim ++NewValueBranches; 288239462Sdim 289239462Sdim if (HexagonMCInstrInfo::isPredicated(MCII, MCI) || 290239462Sdim HexagonMCInstrInfo::isPredicatedNew(MCII, MCI)) { 291218885Sdim hasConditional = true; 292234353Sdim Conditional = i; // Record the position of the conditional branch. 293218885Sdim } else { 294218885Sdim Unconditional = i; // Record the position of the unconditional branch. 295218885Sdim } 296218885Sdim } 297218885Sdim if (HexagonMCInstrInfo::getDesc(MCII, MCI).isReturn() && 298218885Sdim HexagonMCInstrInfo::getDesc(MCII, MCI).mayLoad()) 299234353Sdim ++Returns; 300218885Sdim } 301218885Sdim 302218885Sdim if (Branches) // FIXME: should "Defs.count(Hexagon::PC)" be here too? 303218885Sdim if (HexagonMCInstrInfo::isInnerLoop(MCB) || 304218885Sdim HexagonMCInstrInfo::isOuterLoop(MCB)) { 305218885Sdim // Error out if there's any branch in a loop-end packet. 306218885Sdim errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_ENDLOOP, Hexagon::PC); 307218885Sdim addErrInfo(errInfo); 308218885Sdim return false; 309218885Sdim } 310218885Sdim if (Branches > 1) 311218885Sdim if (!hasConditional || Conditional > Unconditional) { 312218885Sdim // Error out if more than one unconditional branch or 313218885Sdim // the conditional branch appears after the unconditional one. 314218885Sdim errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_BRANCHES); 315218885Sdim addErrInfo(errInfo); 316218885Sdim return false; 317218885Sdim } 318218885Sdim } 319218885Sdim 320218885Sdim return true; 321218885Sdim} 322218885Sdim 323218885Sdim// Check legal use of predicate registers. 324218885Sdimbool HexagonMCChecker::checkPredicates() { 325218885Sdim HexagonMCErrInfo errInfo; 326218885Sdim // Check for proper use of new predicate registers. 327218885Sdim for (const auto& I : NewPreds) { 328218885Sdim unsigned P = I; 329218885Sdim 330218885Sdim if (!Defs.count(P) || LatePreds.count(P)) { 331221345Sdim // Error out if the new predicate register is not defined, 332218885Sdim // or defined "late" 333218885Sdim // (e.g., "{ if (p3.new)... ; p3 = sp1loop0(#r7:2, Rs) }"). 334218885Sdim errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_NEWP, P); 335218885Sdim addErrInfo(errInfo); 336218885Sdim return false; 337218885Sdim } 338218885Sdim } 339218885Sdim 340218885Sdim // Check for proper use of auto-anded of predicate registers. 341218885Sdim for (const auto& I : LatePreds) { 342218885Sdim unsigned P = I; 343224145Sdim 344234353Sdim if (LatePreds.count(P) > 1 || Defs.count(P)) { 345218885Sdim // Error out if predicate register defined "late" multiple times or 346218885Sdim // defined late and regularly defined 347218885Sdim // (e.g., "{ p3 = sp1loop0(...); p3 = cmp.eq(...) }". 348218885Sdim errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, P); 349218885Sdim addErrInfo(errInfo); 350218885Sdim return false; 351224145Sdim } 352218885Sdim } 353218885Sdim 354218885Sdim return true; 355218885Sdim} 356218885Sdim 357218885Sdim// Check legal use of new values. 358218885Sdimbool HexagonMCChecker::checkNewValues() { 359218885Sdim HexagonMCErrInfo errInfo; 360218885Sdim memset(&errInfo, 0, sizeof(errInfo)); 361224145Sdim for (auto& I : NewUses) { 362218885Sdim unsigned R = I.first; 363218885Sdim NewSense &US = I.second; 364218885Sdim 365218885Sdim if (!hasValidNewValueDef(US, NewDefs[R])) { 366218885Sdim errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_NEWV, R); 367218885Sdim addErrInfo(errInfo); 368218885Sdim return false; 369218885Sdim } 370218885Sdim } 371218885Sdim 372218885Sdim return true; 373218885Sdim} 374218885Sdim 375218885Sdim// Check for legal register uses and definitions. 376218885Sdimbool HexagonMCChecker::checkRegisters() { 377218885Sdim HexagonMCErrInfo errInfo; 378218885Sdim // Check for proper register definitions. 379218885Sdim for (const auto& I : Defs) { 380218885Sdim unsigned R = I.first; 381218885Sdim 382218885Sdim if (ReadOnly.count(R)) { 383221345Sdim // Error out for definitions of read-only registers. 384243830Sdim errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_READONLY, R); 385243830Sdim addErrInfo(errInfo); 386218885Sdim return false; 387218885Sdim } 388218885Sdim if (isLoopRegister(R) && Defs.count(R) > 1 && 389218885Sdim (HexagonMCInstrInfo::isInnerLoop(MCB) || 390218885Sdim HexagonMCInstrInfo::isOuterLoop(MCB))) { 391218885Sdim // Error out for definitions of loop registers at the end of a loop. 392218885Sdim errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_LOOP, R); 393218885Sdim addErrInfo(errInfo); 394218885Sdim return false; 395218885Sdim } 396218885Sdim if (SoftDefs.count(R)) { 397218885Sdim // Error out for explicit changes to registers also weakly defined 398218885Sdim // (e.g., "{ usr = r0; r0 = sfadd(...) }"). 399218885Sdim unsigned UsrR = Hexagon::USR; // Silence warning about mixed types in ?:. 400 unsigned BadR = RI.isSubRegister(Hexagon::USR, R) ? UsrR : R; 401 errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, BadR); 402 addErrInfo(errInfo); 403 return false; 404 } 405 if (!isPredicateRegister(R) && Defs[R].size() > 1) { 406 // Check for multiple register definitions. 407 PredSet &PM = Defs[R]; 408 409 // Check for multiple unconditional register definitions. 410 if (PM.count(Unconditional)) { 411 // Error out on an unconditional change when there are any other 412 // changes, conditional or not. 413 unsigned UsrR = Hexagon::USR; 414 unsigned BadR = RI.isSubRegister(Hexagon::USR, R) ? UsrR : R; 415 errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, BadR); 416 addErrInfo(errInfo); 417 return false; 418 } 419 // Check for multiple conditional register definitions. 420 for (const auto& J : PM) { 421 PredSense P = J; 422 423 // Check for multiple uses of the same condition. 424 if (PM.count(P) > 1) { 425 // Error out on conditional changes based on the same predicate 426 // (e.g., "{ if (!p0) r0 =...; if (!p0) r0 =... }"). 427 errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, R); 428 addErrInfo(errInfo); 429 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 436 // (e.g., "{ if (p0) r0 =...; if (!p0) r0 =... }; if (!p0) r0 =... }"). 437 errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_REGISTERS, R); 438 addErrInfo(errInfo); 439 return false; 440 } 441 } 442 } 443 } 444 445 // Check for use of current definitions. 446 for (const auto& I : CurDefs) { 447 unsigned R = I; 448 449 if (!Uses.count(R)) { 450 // Warn on an unused current definition. 451 errInfo.setWarning(HexagonMCErrInfo::CHECK_WARN_CURRENT, R); 452 addErrInfo(errInfo); 453 return true; 454 } 455 } 456 457 // Check for use of temporary definitions. 458 for (const auto& I : TmpDefs) { 459 unsigned R = I; 460 461 if (!Uses.count(R)) { 462 // special case for vhist 463 bool vHistFound = false; 464 for (auto const&HMI : HexagonMCInstrInfo::bundleInstructions(MCB)) { 465 if(llvm::HexagonMCInstrInfo::getType(MCII, *HMI.getInst()) == HexagonII::TypeCVI_HIST) { 466 vHistFound = true; // vhist() implicitly uses ALL REGxx.tmp 467 break; 468 } 469 } 470 // Warn on an unused temporary definition. 471 if (vHistFound == false) { 472 errInfo.setWarning(HexagonMCErrInfo::CHECK_WARN_TEMPORARY, R); 473 addErrInfo(errInfo); 474 return true; 475 } 476 } 477 } 478 479 return true; 480} 481 482// Check for legal use of solo insns. 483bool HexagonMCChecker::checkSolo() { 484 HexagonMCErrInfo errInfo; 485 if (HexagonMCInstrInfo::isBundle(MCB) && 486 HexagonMCInstrInfo::bundleSize(MCB) > 1) { 487 for (auto const&I : HexagonMCInstrInfo::bundleInstructions(MCB)) { 488 if (llvm::HexagonMCInstrInfo::isSolo(MCII, *I.getInst())) { 489 errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_SOLO); 490 addErrInfo(errInfo); 491 return false; 492 } 493 } 494 } 495 496 return true; 497} 498 499bool HexagonMCChecker::checkShuffle() { 500 HexagonMCErrInfo errInfo; 501 // Branch info is lost when duplexing. The unduplexed insns must be 502 // checked and only branch errors matter for this case. 503 HexagonMCShuffler MCS(MCII, STI, MCB); 504 if (!MCS.check()) { 505 if (MCS.getError() == HexagonShuffler::SHUFFLE_ERROR_BRANCHES) { 506 errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_SHUFFLE); 507 errInfo.setShuffleError(MCS.getError()); 508 addErrInfo(errInfo); 509 return false; 510 } 511 } 512 HexagonMCShuffler MCSDX(MCII, STI, MCBDX); 513 if (!MCSDX.check()) { 514 errInfo.setError(HexagonMCErrInfo::CHECK_ERROR_SHUFFLE); 515 errInfo.setShuffleError(MCSDX.getError()); 516 addErrInfo(errInfo); 517 return false; 518 } 519 return true; 520} 521 522void HexagonMCChecker::compoundRegisterMap(unsigned& Register) { 523 switch (Register) { 524 default: 525 break; 526 case Hexagon::R15: 527 Register = Hexagon::R23; 528 break; 529 case Hexagon::R14: 530 Register = Hexagon::R22; 531 break; 532 case Hexagon::R13: 533 Register = Hexagon::R21; 534 break; 535 case Hexagon::R12: 536 Register = Hexagon::R20; 537 break; 538 case Hexagon::R11: 539 Register = Hexagon::R19; 540 break; 541 case Hexagon::R10: 542 Register = Hexagon::R18; 543 break; 544 case Hexagon::R9: 545 Register = Hexagon::R17; 546 break; 547 case Hexagon::R8: 548 Register = Hexagon::R16; 549 break; 550 } 551} 552 553bool HexagonMCChecker::hasValidNewValueDef(const NewSense &Use, 554 const NewSenseList &Defs) const { 555 bool Strict = !RelaxNVChecks; 556 557 for (unsigned i = 0, n = Defs.size(); i < n; ++i) { 558 const NewSense &Def = Defs[i]; 559 // NVJ cannot use a new FP value [7.6.1] 560 if (Use.IsNVJ && (Def.IsFloat || Def.PredReg != 0)) 561 continue; 562 // If the definition was not predicated, then it does not matter if 563 // the use is. 564 if (Def.PredReg == 0) 565 return true; 566 // With the strict checks, both the definition and the use must be 567 // predicated on the same register and condition. 568 if (Strict) { 569 if (Def.PredReg == Use.PredReg && Def.Cond == Use.Cond) 570 return true; 571 } else { 572 // With the relaxed checks, if the definition was predicated, the only 573 // detectable violation is if the use is predicated on the opposing 574 // condition, otherwise, it's ok. 575 if (Def.PredReg != Use.PredReg || Def.Cond == Use.Cond) 576 return true; 577 } 578 } 579 return false; 580} 581 582