// Moves sources [@s,last_source] by @delta. // If @delta < 0, sources [@s - abs(@delta), @s) are erased. void Instruction::moveSources(const int s, const int delta) { if (delta == 0) return; assert(s + delta >= 0); int k; for (k = 0; srcExists(k); ++k) { for (int i = 0; i < 2; ++i) moveSourcesAdjustIndex(src(k).indirect[i], s, delta); } moveSourcesAdjustIndex(predSrc, s, delta); moveSourcesAdjustIndex(flagsSrc, s, delta); if (asTex()) { TexInstruction *tex = asTex(); moveSourcesAdjustIndex(tex->tex.rIndirectSrc, s, delta); moveSourcesAdjustIndex(tex->tex.sIndirectSrc, s, delta); } if (delta > 0) { --k; for (int p = k + delta; k >= s; --k, --p) setSrc(p, src(k)); } else { int p; for (p = s; p < k; ++p) setSrc(p + delta, src(p)); for (; (p + delta) < k; ++p) setSrc(p + delta, NULL); } }
void Instruction::print() const { #define BUFSZ 512 const size_t size = BUFSZ; char buf[BUFSZ]; int s, d; size_t pos = 0; PRINT("%s", colour[TXT_INSN]); if (join) PRINT("join "); if (predSrc >= 0) { const size_t pre = pos; if (getSrc(predSrc)->reg.file == FILE_PREDICATE) { if (cc == CC_NOT_P) PRINT("not"); } else { PRINT("%s", CondCodeStr[cc]); } if (pos > pre) SPACE(); pos += getSrc(predSrc)->print(&buf[pos], BUFSZ - pos); PRINT(" %s", colour[TXT_INSN]); } if (saturate) PRINT("sat "); if (asFlow()) { PRINT("%s", operationStr[op]); if (asFlow()->indirect) PRINT(" ind"); if (asFlow()->absolute) PRINT(" abs"); if (op == OP_CALL && asFlow()->builtin) { PRINT(" %sBUILTIN:%i", colour[TXT_BRA], asFlow()->target.builtin); } else if (op == OP_CALL && asFlow()->target.fn) { PRINT(" %s%s:%i", colour[TXT_BRA], asFlow()->target.fn->getName(), asFlow()->target.fn->getLabel()); } else if (asFlow()->target.bb) PRINT(" %sBB:%i", colour[TXT_BRA], asFlow()->target.bb->getId()); } else { PRINT("%s ", operationStr[op]); if (op == OP_LINTERP || op == OP_PINTERP) PRINT("%s ", interpStr[ipa]); switch (op) { case OP_SUREDP: case OP_ATOM: if (subOp < ARRAY_SIZE(atomSubOpStr)) PRINT("%s ", atomSubOpStr[subOp]); break; case OP_LOAD: case OP_STORE: if (subOp < ARRAY_SIZE(ldstSubOpStr)) PRINT("%s ", ldstSubOpStr[subOp]); break; case OP_SUBFM: if (subOp < ARRAY_SIZE(subfmOpStr)) PRINT("%s ", subfmOpStr[subOp]); break; case OP_SHFL: if (subOp < ARRAY_SIZE(shflOpStr)) PRINT("%s ", shflOpStr[subOp]); break; case OP_PIXLD: if (subOp < ARRAY_SIZE(pixldOpStr)) PRINT("%s ", pixldOpStr[subOp]); break; case OP_RCP: case OP_RSQ: if (subOp < ARRAY_SIZE(rcprsqOpStr)) PRINT("%s ", rcprsqOpStr[subOp]); break; case OP_EMIT: if (subOp < ARRAY_SIZE(emitOpStr)) PRINT("%s ", emitOpStr[subOp]); break; default: if (subOp) PRINT("(SUBOP:%u) ", subOp); break; } if (perPatch) PRINT("patch "); if (asTex()) PRINT("%s %s$r%u $s%u %s", asTex()->tex.target.getName(), colour[TXT_MEM], asTex()->tex.r, asTex()->tex.s, colour[TXT_INSN]); if (postFactor) PRINT("x2^%i ", postFactor); PRINT("%s%s", dnz ? "dnz " : (ftz ? "ftz " : ""), DataTypeStr[dType]); } if (rnd != ROUND_N) PRINT(" %s", RoundModeStr[rnd]); if (defExists(1)) PRINT(" {"); for (d = 0; defExists(d); ++d) { SPACE(); pos += getDef(d)->print(&buf[pos], size - pos); } if (d > 1) PRINT(" %s}", colour[TXT_INSN]); else if (!d && !asFlow()) PRINT(" %s#", colour[TXT_INSN]); if (asCmp()) PRINT(" %s%s", colour[TXT_INSN], CondCodeStr[asCmp()->setCond]); if (sType != dType) PRINT(" %s%s", colour[TXT_INSN], DataTypeStr[sType]); for (s = 0; srcExists(s); ++s) { if (s == predSrc || src(s).usedAsPtr) continue; const size_t pre = pos; SPACE(); pos += src(s).mod.print(&buf[pos], BUFSZ - pos); if (pos > pre + 1) SPACE(); if (src(s).isIndirect(0) || src(s).isIndirect(1)) pos += getSrc(s)->asSym()->print(&buf[pos], BUFSZ - pos, getIndirect(s, 0), getIndirect(s, 1)); else pos += getSrc(s)->print(&buf[pos], BUFSZ - pos, sType); } if (exit) PRINT("%s exit", colour[TXT_INSN]); PRINT("%s", colour[TXT_DEFAULT]); buf[MIN2(pos, BUFSZ - 1)] = 0; INFO("%s (%u)\n", buf, encSize); }