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