}
}
+bool
+validate_instr_defs(Program* program, std::array<unsigned, 2048>& regs,
+ const std::vector<Assignment>& assignments, const Location& loc,
+ aco_ptr<Instruction>& instr)
+{
+ bool err = false;
+
+ for (unsigned i = 0; i < instr->definitions.size(); i++) {
+ Definition& def = instr->definitions[i];
+ if (!def.isTemp())
+ continue;
+ Temp tmp = def.getTemp();
+ PhysReg reg = assignments[tmp.id()].reg;
+ for (unsigned j = 0; j < tmp.bytes(); j++) {
+ if (regs[reg.reg_b + j])
+ err |=
+ ra_fail(program, loc, assignments[regs[reg.reg_b + j]].defloc,
+ "Assignment of element %d of %%%d already taken by %%%d from instruction", i,
+ tmp.id(), regs[reg.reg_b + j]);
+ regs[reg.reg_b + j] = tmp.id();
+ }
+ if (def.regClass().is_subdword() && def.bytes() < 4) {
+ unsigned written = get_subdword_bytes_written(program, instr, i);
+ /* If written=4, the instruction still might write the upper half. In that case, it's
+ * the lower half that isn't preserved */
+ for (unsigned j = reg.byte() & ~(written - 1); j < written; j++) {
+ unsigned written_reg = reg.reg() * 4u + j;
+ if (regs[written_reg] && regs[written_reg] != def.tempId())
+ err |= ra_fail(program, loc, assignments[regs[written_reg]].defloc,
+ "Assignment of element %d of %%%d overwrites the full register "
+ "taken by %%%d from instruction",
+ i, tmp.id(), regs[written_reg]);
+ }
+ }
+ }
+
+ for (const Definition& def : instr->definitions) {
+ if (!def.isTemp())
+ continue;
+ if (def.isKill()) {
+ for (unsigned j = 0; j < def.getTemp().bytes(); j++)
+ regs[def.physReg().reg_b + j] = 0;
+ }
+ }
+
+ return err;
+}
+
} /* end namespace */
bool
}
}
- for (unsigned i = 0; i < instr->definitions.size(); i++) {
- Definition& def = instr->definitions[i];
- if (!def.isTemp())
- continue;
- Temp tmp = def.getTemp();
- PhysReg reg = assignments[tmp.id()].reg;
- for (unsigned j = 0; j < tmp.bytes(); j++) {
- if (regs[reg.reg_b + j])
- err |= ra_fail(
- program, loc, assignments[regs[reg.reg_b + j]].defloc,
- "Assignment of element %d of %%%d already taken by %%%d from instruction", i,
- tmp.id(), regs[reg.reg_b + j]);
- regs[reg.reg_b + j] = tmp.id();
- }
- if (def.regClass().is_subdword() && def.bytes() < 4) {
- unsigned written = get_subdword_bytes_written(program, instr, i);
- /* If written=4, the instruction still might write the upper half. In that case, it's
- * the lower half that isn't preserved */
- for (unsigned j = reg.byte() & ~(written - 1); j < written; j++) {
- unsigned written_reg = reg.reg() * 4u + j;
- if (regs[written_reg] && regs[written_reg] != def.tempId())
- err |= ra_fail(program, loc, assignments[regs[written_reg]].defloc,
- "Assignment of element %d of %%%d overwrites the full register "
- "taken by %%%d from instruction",
- i, tmp.id(), regs[written_reg]);
- }
- }
- }
+ err |= validate_instr_defs(program, regs, assignments, loc, instr);
- for (const Definition& def : instr->definitions) {
- if (!def.isTemp())
- continue;
- if (def.isKill()) {
- for (unsigned j = 0; j < def.getTemp().bytes(); j++)
- regs[def.physReg().reg_b + j] = 0;
- }
- }
-
- if (instr->opcode != aco_opcode::p_phi && instr->opcode != aco_opcode::p_linear_phi) {
+ if (!is_phi(instr)) {
for (const Operand& op : instr->operands) {
if (!op.isTemp())
continue;