}
};
-bool instr_can_access_subdword(aco_ptr<Instruction>& instr)
+bool instr_can_access_subdword(ra_ctx& ctx, aco_ptr<Instruction>& instr)
{
+ if (ctx.program->chip_class < GFX8)
+ return false;
return instr->isSDWA() || instr->format == Format::PSEUDO;
}
if (rc.is_subdword()) {
/* stride in bytes */
- if(!instr_can_access_subdword(instr))
+ if(!instr_can_access_subdword(ctx, instr))
stride = 4;
else if (rc.bytes() % 4 == 0)
stride = 4;
aco_ptr<Instruction>& instr,
PhysReg reg)
{
- if (rc.is_subdword() && reg.byte() && !instr_can_access_subdword(instr))
+ if (rc.is_subdword() && reg.byte() && !instr_can_access_subdword(ctx, instr))
return false;
if (!rc.is_subdword() && reg.byte())
return false;
}
}
-bool operand_can_use_reg(aco_ptr<Instruction>& instr, unsigned idx, PhysReg reg)
+bool operand_can_use_reg(ra_ctx& ctx, aco_ptr<Instruction>& instr, unsigned idx, PhysReg reg)
{
if (instr->operands[idx].isFixed())
return instr->operands[idx].physReg() == reg;
- if (!instr_can_access_subdword(instr) && reg.byte())
+ if (reg.byte() && !instr_can_access_subdword(ctx, instr))
return false;
switch (instr->format) {
assert(ctx.assignments[operand.tempId()].assigned);
PhysReg reg = ctx.assignments[operand.tempId()].reg;
- if (operand_can_use_reg(instr, i, reg))
+ if (operand_can_use_reg(ctx, instr, i, reg))
operand.setFixed(reg);
else
get_reg_for_operand(ctx, register_file, parallelcopy, instr, operand);
Temp tmp = definition.getTemp();
/* subdword instructions before RDNA write full registers */
if (tmp.regClass().is_subdword() &&
- !instr_can_access_subdword(instr) &&
+ !instr_can_access_subdword(ctx, instr) &&
ctx.program->chip_class <= GFX9) {
assert(tmp.bytes() <= 4);
tmp = Temp(definition.tempId(), v1);
}
#endif
-bool instr_can_access_subdword(aco_ptr<Instruction>& instr)
-{
- return instr->isSDWA() || instr->format == Format::PSEUDO;
-}
-
void validate(Program* program, FILE * output)
{
if (!(debug_flags & DEBUG_VALIDATE))
/* check subdword definitions */
for (unsigned i = 0; i < instr->definitions.size(); i++) {
if (instr->definitions[i].regClass().is_subdword())
- check(instr_can_access_subdword(instr) || instr->definitions[i].bytes() <= 4, "Only SDWA and Pseudo instructions can write subdword registers larger than 4 bytes", instr.get());
+ check(instr->format == Format::PSEUDO || instr->definitions[i].bytes() <= 4, "Only Pseudo instructions can write subdword registers larger than 4 bytes", instr.get());
}
if (instr->isSALU() || instr->isVALU()) {
return true;
}
+bool instr_can_access_subdword(Program* program, aco_ptr<Instruction>& instr)
+{
+ if (program->chip_class < GFX8)
+ return false;
+ return instr->isSDWA() || instr->format == Format::PSEUDO;
+}
+
} /* end namespace */
bool validate_ra(Program *program, const struct radv_nir_compiler_options *options, FILE *output) {
err |= ra_fail(output, loc, assignments.at(op.tempId()).firstloc, "Operand %d has an out-of-bounds register assignment", i);
if (op.physReg() == vcc && !program->needs_vcc)
err |= ra_fail(output, loc, Location(), "Operand %d fixed to vcc but needs_vcc=false", i);
- if (!instr_can_access_subdword(instr) && op.regClass().is_subdword() && op.physReg().byte())
+ if (!instr_can_access_subdword(program, instr) && op.regClass().is_subdword() && op.physReg().byte())
err |= ra_fail(output, loc, assignments.at(op.tempId()).firstloc, "Operand %d must be aligned to a full register", i);
if (!assignments[op.tempId()].firstloc.block)
assignments[op.tempId()].firstloc = loc;
err |= ra_fail(output, loc, assignments.at(def.tempId()).firstloc, "Definition %d has an out-of-bounds register assignment", i);
if (def.physReg() == vcc && !program->needs_vcc)
err |= ra_fail(output, loc, Location(), "Definition %d fixed to vcc but needs_vcc=false", i);
- if (!instr_can_access_subdword(instr) && def.regClass().is_subdword() && def.physReg().byte())
+ if (!instr_can_access_subdword(program, instr) && def.regClass().is_subdword() && def.physReg().byte())
err |= ra_fail(output, loc, assignments.at(def.tempId()).firstloc, "Definition %d must be aligned to a full register", i);
if (!assignments[def.tempId()].firstloc.block)
assignments[def.tempId()].firstloc = loc;
err |= ra_fail(output, loc, assignments.at(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() && !instr_can_access_subdword(instr)) {
+ if (def.regClass().is_subdword() && !instr_can_access_subdword(program, instr)) {
for (unsigned j = tmp.bytes(); j < 4; j++)
if (regs[reg.reg_b + j])
err |= ra_fail(output, loc, assignments.at(regs[reg.reg_b + j]).defloc, "Assignment of element %d of %%%d overwrites the full register taken by %%%d from instruction", i, tmp.id(), regs[reg.reg_b + j]);