handle_operands(copy_operations, &ctx, program->gfx_level, pi);
break;
}
+ case aco_opcode::p_start_linear_vgpr: {
+ if (instr->operands.empty())
+ break;
+
+ Definition def(instr->definitions[0].physReg(),
+ RegClass::get(RegType::vgpr, instr->definitions[0].bytes()));
+
+ std::map<PhysReg, copy_operation> copy_operations;
+ copy_operations[def.physReg()] = {instr->operands[0], def,
+ instr->operands[0].bytes()};
+ handle_operands(copy_operations, &ctx, program->gfx_level, pi);
+ break;
+ }
case aco_opcode::p_exit_early_if: {
/* don't bother with an early exit near the end of the program */
if ((block->instructions.size() - 1 - instr_idx) <= 4 &&
opcode("p_spill")
opcode("p_reload")
-# start/end linear vgprs
+# Start/end linear vgprs. p_start_linear_vgpr can take an operand to copy from, into the linear vgpr
opcode("p_start_linear_vgpr")
opcode("p_end_linear_vgpr")
case aco_opcode::p_create_vector:
case aco_opcode::p_split_vector:
case aco_opcode::p_parallelcopy:
- case aco_opcode::p_wqm: break;
+ case aco_opcode::p_wqm:
+ case aco_opcode::p_start_linear_vgpr: break;
default: return;
}
definition->setFixed(reg);
}
} else if (instr->opcode == aco_opcode::p_wqm ||
- instr->opcode == aco_opcode::p_parallelcopy) {
+ instr->opcode == aco_opcode::p_parallelcopy ||
+ (instr->opcode == aco_opcode::p_start_linear_vgpr &&
+ !instr->operands.empty())) {
PhysReg reg = instr->operands[i].physReg();
if (instr->operands[i].isTemp() &&
instr->operands[i].getTemp().type() == definition->getTemp().type() &&
instr->operands[i].isUndefined(),
"Operands of p_dual_src_export_gfx11 must be VGPRs or undef", instr.get());
}
+ } else if (instr->opcode == aco_opcode::p_start_linear_vgpr) {
+ check(instr->definitions.size() == 1, "Must have one definition", instr.get());
+ check(instr->operands.size() <= 1, "Must have one or zero operands", instr.get());
+ if (!instr->definitions.empty())
+ check(instr->definitions[0].regClass().is_linear_vgpr(),
+ "Definition must be linear VGPR", instr.get());
+ if (!instr->definitions.empty() && !instr->operands.empty())
+ check(instr->definitions[0].bytes() == instr->operands[0].bytes(),
+ "Operand size must match definition", instr.get());
}
break;
}