Lines Matching defs:operands

64  *     propagates reg->reg operands of the same type, inline constants
486 if (instr->operands.size() && instr->operands[0].isLiteral() && ctx.program->chip_class < GFX10)
526 if (temp.bytes() != instr->operands[index].bytes())
537 if (temp.bytes() > instr->operands[index].bytes())
544 int decrease = instr->operands[index].bytes() - temp.bytes();
559 instr->operands[index].setTemp(temp);
586 instr.reset(create_instruction<VOP3_instruction>(tmp->opcode, format, tmp->operands.size(),
588 std::copy(tmp->operands.cbegin(), tmp->operands.cend(), instr->operands.begin());
661 check_vop3_operands(opt_ctx& ctx, unsigned num_operands, Operand* operands)
670 Operand op = operands[i];
712 Operand op = instr->operands[op_index];
737 if (add_instr->operands[i].isConstant()) {
738 *offset = add_instr->operands[i].constantValue();
739 } else if (add_instr->operands[i].isTemp() &&
740 ctx.info[add_instr->operands[i].tempId()].is_constant_or_literal(32)) {
741 *offset = ctx.info[add_instr->operands[i].tempId()].val;
745 if (!add_instr->operands[!i].isTemp())
752 *base = add_instr->operands[!i].getTemp();
764 return instr->operands[index].bytes() * 8u;
792 unsigned size = instr->operands[2].constantValue() / 8;
793 unsigned offset = instr->operands[1].constantValue() * size;
794 bool sext = instr->operands[3].constantEquals(1);
796 } else if (instr->opcode == aco_opcode::p_insert && instr->operands[1].constantEquals(0)) {
797 return instr->operands[2].constantEquals(8) ? SubdwordSel::ubyte : SubdwordSel::uword;
806 if (instr->opcode == aco_opcode::p_extract && instr->operands[3].constantEquals(0) &&
807 instr->operands[1].constantEquals(0)) {
808 return instr->operands[2].constantEquals(8) ? SubdwordSel::ubyte : SubdwordSel::uword;
810 unsigned size = instr->operands[2].constantValue() / 8;
811 unsigned offset = instr->operands[1].constantValue() * size;
824 Temp tmp = info.instr->operands[0].getTemp();
853 Temp tmp = info.instr->operands[0].getTemp();
857 instr->operands[idx].set16bit(false);
858 instr->operands[idx].set24bit(false);
871 } else if (instr->opcode == aco_opcode::v_lshlrev_b32 && instr->operands[0].isConstant() &&
873 ((sel.size() == 2 && instr->operands[0].constantValue() >= 16u) ||
874 (sel.size() == 1 && instr->operands[0].constantValue() >= 24u))) {
894 for (unsigned i = 0; i < instr->operands.size(); i++) {
895 Operand op = instr->operands[i];
899 if (info.is_extract() && (info.instr->operands[0].getTemp().type() == RegType::vgpr ||
967 for (Operand& op : instr->operands)
970 perfwarn(ctx.program, all_const, "All instruction operands are constant", instr.get());
979 for (unsigned i = 0; i < instr->operands.size(); i++) {
980 if (!instr->operands[i].isTemp())
983 ssa_info info = ctx.info[instr->operands[i].tempId()];
986 instr->operands[i] = Operand(instr->operands[i].regClass());
988 while (info.is_temp() && info.temp.regClass() == instr->operands[i].getTemp().regClass()) {
989 instr->operands[i].setTemp(ctx.info[instr->operands[i].tempId()].temp);
1005 !instr->operands[i].isFixed() && alu_can_accept_constant(instr->opcode, i)) {
1006 instr->operands[i] = get_constant_op(ctx, info, bits);
1015 instr->operands[i].setTemp(info.temp);
1020 instr->operands.size() == 1) {
1022 instr->operands[i].setTemp(info.temp);
1029 instr->opcode != aco_opcode::v_cndmask_b32 || instr->operands[i].getTemp().bytes() == 4;
1039 instr->operands[i].setTemp(info.temp);
1042 instr->operands[i].setTemp(info.temp);
1047 instr->operands[i].setTemp(info.temp);
1058 instr->operands[i] = Operand(info.temp);
1078 instr->operands[i] = op;
1081 instr->operands[i] = instr->operands[0];
1082 instr->operands[0] = op;
1086 instr->operands[i] = op;
1112 instr->operands[1] = Operand(v1);
1117 instr->operands[2] = Operand::c32(0);
1125 instr->operands[1].setTemp(base);
1132 instr->operands[i].setTemp(base);
1147 base.regClass() == instr->operands[i].regClass() &&
1164 instr->operands[i].setTemp(base);
1170 instr->operands[i].setTemp(base);
1183 bool prevent_overflow = smem.operands[0].size() > 2 || smem.prevent_overflow;
1188 instr->operands[i] = Operand::c32(info.val);
1193 bool soe = smem.operands.size() >= (!smem.definitions.empty() ? 3 : 4);
1194 if (soe && (!ctx.info[smem.operands.back().tempId()].is_constant_or_literal(32) ||
1195 ctx.info[smem.operands.back().tempId()].val != 0)) {
1199 smem.operands[1] = Operand::c32(offset);
1200 smem.operands.back() = Operand(base);
1203 smem.opcode, Format::SMEM, smem.operands.size() + 1, smem.definitions.size());
1204 new_instr->operands[0] = smem.operands[0];
1205 new_instr->operands[1] = Operand::c32(offset);
1207 new_instr->operands[2] = smem.operands[2];
1208 new_instr->operands.back() = Operand(base);
1223 if (ctx.info[instr->operands[0].tempId()].is_scc_invert()) {
1227 instr->operands[0].setTemp(ctx.info[instr->operands[0].tempId()].temp);
1243 unsigned ops = instr->opcode == aco_opcode::v_cndmask_b32 ? 2 : instr->operands.size();
1245 canonicalized = is_op_canonicalized(ctx, instr->operands[i]);
1264 bool copy_prop = instr->operands.size() == 1 && instr->operands[0].isTemp() &&
1265 instr->operands[0].regClass() == instr->definitions[0].regClass();
1267 ctx.info[instr->definitions[0].tempId()].set_temp(instr->operands[0].getTemp());
1271 /* expand vector operands */
1274 for (const Operand& op : instr->operands) {
1275 /* ensure that any expanded operands are properly aligned */
1280 for (const Operand& vec_op : vec->operands)
1287 /* combine expanded operands to new vector */
1288 if (ops.size() != instr->operands.size()) {
1289 assert(ops.size() > instr->operands.size());
1297 instr->operands[i] = ops[i];
1302 assert(instr->operands[i] == ops[i]);
1309 ssa_info& info = ctx.info[instr->operands[0].tempId()];
1323 Instruction* vec = ctx.info[instr->operands[0].tempId()].instr;
1329 while (vec_offset < split_offset && vec_index < vec->operands.size())
1330 vec_offset += vec->operands[vec_index++].bytes();
1333 vec->operands[vec_index].bytes() != instr->definitions[i].bytes())
1336 Operand vec_op = vec->operands[vec_index];
1350 ssa_info& info = ctx.info[instr->operands[0].tempId()];
1351 const unsigned index = instr->operands[1].constantValue();
1359 for (const Operand& op : vec->operands) {
1366 instr->operands[0] = op;
1373 instr->operands[0] =
1376 } else if (index == 0 && instr->operands[0].size() == instr->definitions[0].size()) {
1377 ctx.info[instr->definitions[0].tempId()].set_temp(instr->operands[0].getTemp());
1380 if (instr->operands[0].bytes() != instr->definitions[0].bytes())
1385 instr->operands.pop_back();
1389 if (instr->operands[0].isTemp() && ctx.info[instr->operands[0].tempId()].is_vec() &&
1390 instr->operands[0].regClass() != instr->definitions[0].regClass()) {
1394 Instruction* vec = ctx.info[instr->operands[0].tempId()].instr;
1398 aco_opcode::p_create_vector, Format::PSEUDO, vec->operands.size(), 1));
1400 std::copy(vec->operands.begin(), vec->operands.end(), instr->operands.begin());
1401 for (unsigned i = 0; i < vec->operands.size(); i++) {
1402 Operand& op = instr->operands[i];
1416 } else if (instr->operands[0].isConstant()) {
1418 ctx.program->chip_class, instr->operands[0].constantValue64());
1419 } else if (instr->operands[0].isTemp()) {
1420 ctx.info[instr->definitions[0].tempId()].set_temp(instr->operands[0].getTemp());
1421 if (ctx.info[instr->operands[0].tempId()].is_canonicalized())
1424 assert(instr->operands[0].isFixed());
1448 if (instr->operands[!i].isConstant() && instr->operands[i].isTemp()) {
1450 (instr->operands[!i].constantEquals(fp16 ? 0x3c00 : 0x3f800000) || /* 1.0 */
1451 instr->operands[!i].constantEquals(fp16 ? 0xbc00 : 0xbf800000u))) { /* -1.0 */
1452 bool neg1 = instr->operands[!i].constantEquals(fp16 ? 0xbc00 : 0xbf800000u);
1461 Temp other = instr->operands[i].getTemp();
1472 } else if (instr->operands[!i].constantValue() ==
1474 ctx.info[instr->operands[i].tempId()].set_omod2(instr.get());
1475 } else if (instr->operands[!i].constantValue() ==
1477 ctx.info[instr->operands[i].tempId()].set_omod4(instr.get());
1478 } else if (instr->operands[!i].constantValue() ==
1480 ctx.info[instr->operands[i].tempId()].set_omod5(instr.get());
1481 } else if (instr->operands[!i].constantValue() == 0u &&
1509 if (instr->operands[i].constantEquals(0))
1511 else if (instr->operands[i].constantEquals(is_fp16 ? 0x3c00 : 0x3f800000)) /* 1.0 */
1516 if (found_zero && found_one && instr->operands[idx].isTemp())
1517 ctx.info[instr->operands[idx].tempId()].set_clamp(instr.get());
1521 if (instr->operands[0].constantEquals(0) && instr->operands[1].constantEquals(0xFFFFFFFF))
1522 ctx.info[instr->definitions[0].tempId()].set_vcc(instr->operands[2].getTemp());
1523 else if (instr->operands[0].constantEquals(0) &&
1524 instr->operands[1].constantEquals(0x3f800000u))
1525 ctx.info[instr->definitions[0].tempId()].set_b2f(instr->operands[2].getTemp());
1526 else if (instr->operands[0].constantEquals(0) && instr->operands[1].constantEquals(1))
1527 ctx.info[instr->definitions[0].tempId()].set_b2i(instr->operands[2].getTemp());
1529 ctx.info[instr->operands[2].tempId()].set_vcc_hint();
1533 instr->operands[0].constantEquals(0) && instr->operands[1].isTemp() &&
1534 ctx.info[instr->operands[1].tempId()].is_vcc())
1536 ctx.info[instr->operands[1].tempId()].temp);
1540 bool all_same_temp = instr->operands[0].isTemp();
1543 all_same_temp = instr->definitions[0].regClass() == instr->operands[0].regClass();
1544 for (unsigned i = 1; all_same_temp && (i < instr->operands.size()); i++) {
1545 if (!instr->operands[i].isTemp() ||
1546 instr->operands[i].tempId() != instr->operands[0].tempId())
1550 ctx.info[instr->definitions[0].tempId()].set_temp(instr->operands[0].getTemp());
1552 bool all_undef = instr->operands[0].isUndefined();
1553 for (unsigned i = 1; all_undef && (i < instr->operands.size()); i++) {
1554 if (!instr->operands[i].isUndefined())
1572 if (ctx.info[instr->operands[0].tempId()].is_uniform_bool()) {
1575 ctx.info[instr->operands[0].tempId()].temp);
1576 } else if (ctx.info[instr->operands[0].tempId()].is_uniform_bitwise()) {
1579 ctx.info[instr->operands[0].tempId()].instr->definitions[1].getTemp());
1585 if (fixed_to_exec(instr->operands[1]) && instr->operands[0].isTemp()) {
1586 if (ctx.info[instr->operands[0].tempId()].is_uniform_bool()) {
1590 ctx.info[instr->operands[0].tempId()].temp);
1592 ctx.info[instr->operands[0].tempId()].temp);
1594 } else if (ctx.info[instr->operands[0].tempId()].is_uniform_bitwise()) {
1598 ctx.info[instr->operands[0].tempId()].instr->definitions[1].getTemp());
1600 ctx.info[instr->operands[0].tempId()].instr->definitions[1].getTemp());
1607 ctx.info[instr->definitions[0].tempId()].set_temp(instr->operands[0].getTemp());
1609 } else if (ctx.info[instr->operands[0].tempId()].is_vopc()) {
1610 Instruction* vopc_instr = ctx.info[instr->operands[0].tempId()].instr;
1626 if (std::all_of(instr->operands.begin(), instr->operands.end(),
1659 if (instr->operands[0].constantEquals((unsigned)-1) && instr->operands[1].constantEquals(0)) {
1661 ctx.info[instr->definitions[0].tempId()].set_uniform_bool(instr->operands[2].getTemp());
1663 if (instr->operands[2].isTemp() && ctx.info[instr->operands[2].tempId()].is_scc_invert()) {
1664 /* Flip the operands to get rid of the scc_invert instruction */
1665 std::swap(instr->operands[0], instr->operands[1]);
1666 instr->operands[2].setTemp(ctx.info[instr->operands[2].tempId()].temp);
1670 if (instr->operands[0].isTemp() && ctx.info[instr->operands[0].tempId()].is_scc_invert()) {
1671 ctx.info[instr->definitions[0].tempId()].set_temp(instr->operands[0].getTemp());
1677 if (instr->operands[0].constantEquals(0x3f800000u))
1683 if (instr->operands[0].regClass() == v1 && parse_insert(instr.get()))
1684 ctx.info[instr->operands[0].tempId()].set_insert(instr.get());
1689 if (instr->operands[0].bytes() == 4) {
1690 if (instr->operands[0].regClass() == v1)
1691 ctx.info[instr->operands[0].tempId()].set_insert(instr.get());
1727 for (const Operand& op : instr->operands) {
1773 op_instr[i] = follow_operand(ctx, instr->operands[i], true);
1784 if (!op_instr[i]->operands[0].isTemp() || !op_instr[i]->operands[1].isTemp())
1799 Temp op0 = op_instr[i]->operands[0].getTemp();
1800 Temp op1 = op_instr[i]->operands[1].getTemp();
1839 new_instr->operands[0] = Operand(op[0]);
1840 new_instr->operands[1] = Operand(op[1]);
1864 Instruction* nan_test = follow_operand(ctx, instr->operands[0], true);
1865 Instruction* cmp = follow_operand(ctx, instr->operands[1], true);
1879 if (!nan_test->operands[0].isTemp() || !nan_test->operands[1].isTemp())
1881 if (!cmp->operands[0].isTemp() || !cmp->operands[1].isTemp())
1884 unsigned prop_cmp0 = original_temp_id(ctx, cmp->operands[0].getTemp());
1885 unsigned prop_cmp1 = original_temp_id(ctx, cmp->operands[1].getTemp());
1886 unsigned prop_nan0 = original_temp_id(ctx, nan_test->operands[0].getTemp());
1887 unsigned prop_nan1 = original_temp_id(ctx, nan_test->operands[1].getTemp());
1893 ctx.uses[cmp->operands[0].tempId()]++;
1894 ctx.uses[cmp->operands[1].tempId()]++;
1914 new_instr->operands[0] = cmp->operands[0];
1915 new_instr->operands[1] = cmp->operands[1];
1965 Instruction* nan_test = follow_operand(ctx, instr->operands[0], true);
1966 Instruction* cmp = follow_operand(ctx, instr->operands[1], true);
1983 if (!nan_test->operands[0].isTemp() || !nan_test->operands[1].isTemp())
1985 if (!cmp->operands[0].isTemp() && !cmp->operands[1].isTemp())
1988 unsigned prop_nan0 = original_temp_id(ctx, nan_test->operands[0].getTemp());
1989 unsigned prop_nan1 = original_temp_id(ctx, nan_test->operands[1].getTemp());
2002 if (cmp->operands[i].isTemp() &&
2003 original_temp_id(ctx, cmp->operands[i].getTemp()) == prop_nan0) {
2012 if (!is_operand_constant(ctx, cmp->operands[constant_operand], bit_size, &constant_value))
2017 if (cmp->operands[0].isTemp())
2018 ctx.uses[cmp->operands[0].tempId()]++;
2019 if (cmp->operands[1].isTemp())
2020 ctx.uses[cmp->operands[1].tempId()]++;
2040 new_instr->operands[0] = cmp->operands[0];
2041 new_instr->operands[1] = cmp->operands[1];
2056 if (!instr->operands[0].isFixed() || instr->operands[0].physReg() != exec)
2061 Instruction* cmp = follow_operand(ctx, instr->operands[1]);
2069 if (cmp->operands[0].isTemp())
2070 ctx.uses[cmp->operands[0].tempId()]++;
2071 if (cmp->operands[1].isTemp())
2072 ctx.uses[cmp->operands[1].tempId()]++;
2114 new_instr->operands[0] = cmp->operands[0];
2115 new_instr->operands[1] = cmp->operands[1];
2130 const char* shuffle_str, Operand operands[3], bool neg[3], bool abs[3],
2138 Instruction* op2_instr = follow_operand(ctx, op1_instr->operands[swap]);
2141 if (fixed_to_exec(op2_instr->operands[0]) || fixed_to_exec(op2_instr->operands[1]))
2156 /* get operands and modifiers and check inbetween modifiers */
2182 operands[shuffle[0]] = op1_instr->operands[!swap];
2189 operands[shuffle[i + 1]] = op2_instr->operands[i];
2196 /* check operands */
2197 if (!check_vop3_operands(ctx, 3, operands))
2205 Operand operands[3], bool neg[3], bool abs[3], uint8_t opsel, bool clamp,
2214 new_instr->operands[0] = operands[0];
2215 new_instr->operands[1] = operands[1];
2216 new_instr->operands[2] = operands[2];
2231 Operand operands[3];
2234 if (match_op3_for_vop3(ctx, instr->opcode, op2, instr.get(), swap, shuffle, operands, neg,
2236 ctx.uses[instr->operands[swap].tempId()]--;
2237 create_vop3_for_op3(ctx, new_op, instr, operands, neg, abs, opsel, clamp, omod);
2271 Instruction* extins = follow_operand(ctx, instr->operands[i]);
2276 Operand operands[3];
2279 (extins->operands[1].constantValue() + 1) * extins->operands[2].constantValue() == 32) {
2281 operands[1] =
2282 Operand::c32(extins->operands[1].constantValue() * extins->operands[2].constantValue());
2286 extins->operands[3].constantEquals(0))) &&
2287 extins->operands[1].constantEquals(0)) {
2289 operands[1] = Operand::c32(extins->operands[2].constantEquals(8) ? 0xffu : 0xffffu);
2294 operands[0] = extins->operands[0];
2295 operands[2] = instr->operands[!i];
2297 if (!check_vop3_operands(ctx, 3, operands))
2306 ctx.uses[instr->operands[i].tempId()]--;
2307 create_vop3_for_op3(ctx, op, instr, operands, neg, abs, opsel, clamp, omod);
2324 Operand operands[3];
2328 if (match_op3_for_vop3(ctx, instr->opcode, opposite, instr.get(), swap, "012", operands, neg,
2331 ctx.uses[instr->operands[swap].tempId()]--;
2334 create_vop3_for_op3(ctx, minmax3, instr, operands, neg, abs, opsel, clamp, omod);
2351 if (!instr->operands[0].isTemp())
2356 Instruction* op2_instr = follow_operand(ctx, instr->operands[0]);
2372 ctx.uses[instr->operands[0].tempId()]--;
2399 Instruction* op2_instr = follow_operand(ctx, instr->operands[i]);
2403 if (ctx.uses[op2_instr->definitions[1].tempId()] || fixed_to_exec(op2_instr->operands[0]))
2406 if (instr->operands[!i].isLiteral() && op2_instr->operands[0].isLiteral() &&
2407 instr->operands[!i].constantValue() != op2_instr->operands[0].constantValue())
2410 ctx.uses[instr->operands[i].tempId()]--;
2411 instr->operands[0] = instr->operands[!i];
2412 instr->operands[1] = op2_instr->operands[0];
2436 Instruction* op2_instr = follow_operand(ctx, instr->operands[i], true);
2440 if (!op2_instr->operands[1].isConstant() || fixed_to_exec(op2_instr->operands[0]))
2443 uint32_t shift = op2_instr->operands[1].constantValue();
2447 if (instr->operands[!i].isLiteral() && op2_instr->operands[0].isLiteral() &&
2448 instr->operands[!i].constantValue() != op2_instr->operands[0].constantValue())
2451 ctx.uses[instr->operands[i].tempId()]--;
2452 instr->operands[1] = instr->operands[!i];
2453 instr->operands[0] = op2_instr->operands[0];
2474 if (instr->operands[i].isTemp() && ctx.info[instr->operands[i].tempId()].is_b2i() &&
2475 ctx.uses[instr->operands[i].tempId()] == 1) {
2478 if (instr->operands[!i].isTemp() &&
2479 instr->operands[!i].getTemp().type() == RegType::vgpr) {
2482 (instr->operands[!i].isConstant() && !instr->operands[!i].isLiteral())) {
2488 ctx.uses[instr->operands[i].tempId()]--;
2501 new_instr->operands[0] = Operand::zero();
2502 new_instr->operands[1] = instr->operands[!i];
2503 new_instr->operands[2] = Operand(ctx.info[instr->operands[i].tempId()].temp);
2520 Instruction* op_instr = follow_operand(ctx, instr->operands[i]);
2522 !op_instr->usesModifiers() && op_instr->operands[0].isTemp() &&
2523 op_instr->operands[0].getTemp().type() == RegType::vgpr &&
2524 op_instr->operands[1].constantEquals(0)) {
2527 ctx.uses[instr->operands[i].tempId()]--;
2528 new_instr->operands[0] = op_instr->operands[0];
2529 new_instr->operands[1] = instr->operands[!i];
2588 Operand operands[3];
2591 if (match_op3_for_vop3(ctx, instr->opcode, other_op, instr.get(), swap, "012", operands, neg,
2603 if (operands[i].isConstant()) {
2604 val = operands[i].constantValue();
2605 } else if (operands[i].isTemp() &&
2606 ctx.info[operands[i].tempId()].is_constant_or_literal(32)) {
2607 val = ctx.info[operands[i].tempId()].val;
2684 ctx.uses[instr->operands[swap].tempId()]--;
2685 create_vop3_for_op3(ctx, med, instr, operands, neg, abs, opsel, clamp, omod);
2705 for (unsigned i = 0; i < instr->operands.size(); i++) {
2706 if (instr->operands[i].isLiteral())
2708 if (!instr->operands[i].isTemp())
2710 if (instr->operands[i].getTemp().type() == RegType::sgpr) {
2711 if (instr->operands[i].tempId() != sgpr_ids[0])
2712 sgpr_ids[!!sgpr_ids[0]] = instr->operands[i].tempId();
2714 ssa_info& info = ctx.info[instr->operands[i].tempId()];
2717 if (info.is_extract() && info.instr->operands[0].getTemp().type() == RegType::sgpr)
2736 uint16_t uses = ctx.uses[instr->operands[i].tempId()];
2739 sgpr_info_id = instr->operands[i].tempId();
2753 Temp sgpr = info.is_extract() ? info.instr->operands[0].getTemp() : info.temp;
2768 instr->operands[sgpr_idx] = Operand(sgpr);
2770 instr->operands[sgpr_idx] = instr->operands[0];
2771 instr->operands[0] = Operand(sgpr);
2777 instr->operands[sgpr_idx] = Operand(sgpr);
2916 if (!ctx.info[extract->operands[0].tempId()].is_usedef() ||
2917 ctx.uses[extract->operands[0].tempId()] > 1)
2921 Instruction* ds = ctx.info[extract->operands[0].tempId()].instr;
2925 unsigned extract_idx = extract->operands[1].constantValue();
2926 unsigned bits_extracted = extract->operands[2].constantValue();
2927 unsigned sign_ext = extract->operands[3].constantValue();
2968 Instruction* op_instr = follow_operand(ctx, instr->operands[i], true);
2970 op_instr->operands[0].constantEquals(0) && op_instr->operands[1].constantEquals(0) &&
2974 if (instr->operands[!i].isTemp() &&
2975 instr->operands[!i].getTemp().type() == RegType::vgpr) {
2979 (instr->operands[!i].isConstant() && !instr->operands[!i].isLiteral())) {
2986 ctx.uses[instr->operands[i].tempId()]--;
2987 if (ctx.uses[instr->operands[i].tempId()])
2988 ctx.uses[op_instr->operands[2].tempId()]++;
2990 new_instr->operands[0] = Operand::zero();
2991 new_instr->operands[1] = instr->operands[!i];
2992 new_instr->operands[2] = Operand(op_instr->operands[2]);
3019 /* Don't allow 24-bit operands on subtraction because
3025 Instruction* op_instr = follow_operand(ctx, instr->operands[i]);
3035 if (op_instr->operands[shift_op_idx].isConstant() &&
3036 ((allow_24bit && op_instr->operands[!shift_op_idx].is24bit()) ||
3037 op_instr->operands[!shift_op_idx].is16bit())) {
3038 uint32_t multiplier = 1 << (op_instr->operands[shift_op_idx].constantValue() % 32u);
3045 op_instr->operands[!shift_op_idx],
3047 instr->operands[!i],
3052 ctx.uses[instr->operands[i].tempId()]--;
3058 new_instr->operands[op_idx] = ops[op_idx];
3072 /* propagate swizzles which apply to a result down to the instruction's operands:
3098 if (instr->opcode == aco_opcode::v_pk_mul_f16 && instr->operands[1].constantEquals(0x3C00) &&
3099 vop3p->clamp && instr->operands[0].isTemp() && ctx.uses[instr->operands[0].tempId()] == 1) {
3101 ssa_info& info = ctx.info[instr->operands[0].tempId()];
3103 VOP3P_instruction* candidate = &ctx.info[instr->operands[0].tempId()].instr->vop3p();
3116 assert(instr->operands.size() == 2);
3118 Operand& op = instr->operands[i];
3124 info.instr->operands[1].constantEquals(0xBC00)) {
3125 Operand ops[2] = {instr->operands[!i], info.instr->operands[0]};
3132 instr->operands[i] = fneg->operands[0];
3148 ctx.uses[fneg->operands[0].tempId()]++;
3165 if (!instr->operands[i].isTemp() || !ctx.info[instr->operands[i].tempId()].is_vop3p())
3167 ssa_info& info = ctx.info[instr->operands[i].tempId()];
3177 Operand op[3] = {info.instr->operands[0], info.instr->operands[1], instr->operands[1 - i]};
3178 if (ctx.uses[instr->operands[i].tempId()] >= uses || !check_vop3_operands(ctx, 3, op))
3189 uses = ctx.uses[instr->operands[i].tempId()];
3196 Operand op[3] = {mul_instr->operands[0], mul_instr->operands[1], instr->operands[add_op_idx]};
3212 fma->operands[i] = op[i];
3216 fma->operands[2] = op[2];
3246 for (unsigned i = 0; i < instr->operands.size(); i++) {
3247 Operand& op = instr->operands[i];
3260 (info.instr->operands[0].getTemp().type() == RegType::vgpr ||
3261 instr->operands[i].getTemp().type() == RegType::sgpr) &&
3264 ctx.uses[instr->operands[i].tempId()]--;
3265 instr->operands[i].setTemp(info.instr->operands[0].getTemp());
3301 ctx.uses[instr->operands[1].tempId()] == 1) {
3309 if (mul_instr->operands[0].isLiteral())
3323 instr->operands[0] = mul_instr->operands[0];
3324 instr->operands[1] = mul_instr->operands[1];
3366 if (!instr->operands[i].isTemp() || !ctx.info[instr->operands[i].tempId()].is_mul())
3369 ssa_info& info = ctx.info[instr->operands[i].tempId()];
3377 Operand op[3] = {info.instr->operands[0], info.instr->operands[1], instr->operands[1 - i]};
3379 ctx.uses[instr->operands[i].tempId()] >= uses)
3384 uses = ctx.uses[instr->operands[i].tempId()];
3389 Operand op[3] = {mul_instr->operands[0], mul_instr->operands[1],
3390 instr->operands[add_op_idx]};
3446 mad->operands[i] = op[i];
3464 if (instr->operands[i].isTemp() && ctx.info[instr->operands[i].tempId()].is_b2f() &&
3465 ctx.uses[instr->operands[i].tempId()] == 1 && instr->operands[!i].isTemp() &&
3466 instr->operands[!i].getTemp().type() == RegType::vgpr) {
3467 ctx.uses[instr->operands[i].tempId()]--;
3468 ctx.uses[ctx.info[instr->operands[i].tempId()].temp.id()]++;
3472 new_instr->operands[0] = Operand::zero();
3473 new_instr->operands[1] = instr->operands[!i];
3474 new_instr->operands[2] = Operand(ctx.info[instr->operands[i].tempId()].temp);
3580 for (Operand& op : instr->operands) {
3599 for (Operand& op : instr->operands) {
3624 assert(instr->operands[0].regClass() == s1);
3625 assert(instr->operands[1].regClass() == s1);
3653 if (num_used == 1 && ctx.info[instr->operands[0].tempId()].is_vec() &&
3654 ctx.uses[instr->operands[0].tempId()] == 1) {
3655 Instruction* vec = ctx.info[instr->operands[0].tempId()].instr;
3659 for (Operand& vec_op : vec->operands) {
3666 if (off != instr->operands[0].bytes() && op.bytes() == instr->definitions[idx].bytes()) {
3667 ctx.uses[instr->operands[0].tempId()]--;
3668 for (Operand& vec_op : vec->operands) {
3677 extract->operands[0] = op;
3686 instr->operands[0].bytes() % instr->definitions[idx].bytes() == 0 &&
3690 extract->operands[0] = instr->operands[0];
3691 extract->operands[1] =
3704 if (instr->operands[0].isTemp())
3705 ctx.uses[instr->operands[0].tempId()]--;
3706 if (instr->operands[1].isTemp())
3707 ctx.uses[instr->operands[1].tempId()]--;
3726 for (unsigned i = 0; i < instr->operands.size(); i++) {
3727 if (instr->operands[i].isConstant() && i > 0) {
3731 if (!instr->operands[i].isTemp())
3734 /* if one of the operands is sgpr, we cannot add a literal somewhere else on pre-GFX10
3735 * or operands other than the 1st */
3736 if (instr->operands[i].getTemp().type() == RegType::sgpr &&
3738 if (!sgpr_used && ctx.info[instr->operands[i].tempId()].is_literal(bits)) {
3739 literal_uses = ctx.uses[instr->operands[i].tempId()];
3746 } else if (!sgpr_used && ctx.info[instr->operands[i].tempId()].is_literal(bits) &&
3747 ctx.uses[instr->operands[i].tempId()] < literal_uses) {
3748 literal_uses = ctx.uses[instr->operands[i].tempId()];
3761 ctx.uses[instr->operands[literal_idx].tempId()]--;
3771 if (instr->isBranch() && instr->operands.size() && instr->operands[0].isTemp() &&
3772 instr->operands[0].isFixed() && instr->operands[0].physReg() == scc) {
3773 ctx.info[instr->operands[0].tempId()].set_scc_needed();
3777 instr->operands[2].isTemp()) {
3778 ctx.info[instr->operands[2].tempId()].set_scc_needed();
3779 } else if (instr->opcode == aco_opcode::p_wqm && instr->operands[0].isTemp() &&
3782 ctx.info[instr->operands[0].tempId()].set_scc_needed();
3811 for (unsigned i = 0; i < instr->operands.size(); i++) {
3812 if (!instr->operands[i].isTemp())
3814 ssa_info info = ctx.info[instr->operands[i].tempId()];
3824 std::swap(instr->operands[0], instr->operands[1]);
3829 ctx.uses[info.instr->operands[0].tempId()]++;
3830 instr->operands[0].setTemp(info.instr->operands[0].getTemp());
3853 num_operands = instr->operands.size();
3855 else if (instr->isVALU() && instr->operands.size() >= 3)
3864 Operand op = instr->operands[i];
3911 if (instr->operands[i].isTemp() && instr->operands[i].tempId() == literal_id)
3912 ctx.uses[instr->operands[i].tempId()]--;
3928 (ctx.uses[instr->operands[info->literal_idx].tempId()] == 0 || info->literal_idx == 2)) {
3943 new_mad->operands[0] = instr->operands[0];
3944 new_mad->operands[1] = instr->operands[1];
3946 new_mad->operands[0] = instr->operands[1 - info->literal_idx];
3947 new_mad->operands[1] = instr->operands[2];
3949 new_mad->operands[2] =
3950 Operand::c32(ctx.info[instr->operands[info->literal_idx].tempId()].val);
3959 for (unsigned i = 0; i < instr->operands.size(); i++) {
3960 Operand op = instr->operands[i];
3967 instr->operands[i] = literal;