mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-01 08:08:06 +02:00
aco: Allow p_extract to have different definition and operand sizes.
Makes p_extract more flexible and prepares it to be usable for other use cases. No Fossil DB changes. Signed-off-by: Timur Kristóf <timur.kristof@gmail.com> Reviewed-by: Daniel Schürmann <daniel@schuermann.dev> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/11560>
This commit is contained in:
parent
f00d3e2909
commit
f14023666c
2 changed files with 24 additions and 13 deletions
|
|
@ -2129,7 +2129,8 @@ lower_to_hw_instr(Program* program)
|
||||||
bld.sop2(signext ? aco_opcode::s_bfe_i32 : aco_opcode::s_bfe_u32, dst,
|
bld.sop2(signext ? aco_opcode::s_bfe_i32 : aco_opcode::s_bfe_u32, dst,
|
||||||
bld.def(s1, scc), op, Operand::c32((bits << 16) | offset));
|
bld.def(s1, scc), op, Operand::c32((bits << 16) | offset));
|
||||||
}
|
}
|
||||||
} else if (dst.regClass() == v1 || ctx.program->chip_class <= GFX7) {
|
} else if ((dst.regClass() == v1 && op.regClass() == v1) ||
|
||||||
|
ctx.program->chip_class <= GFX7) {
|
||||||
assert(op.physReg().byte() == 0 && dst.physReg().byte() == 0);
|
assert(op.physReg().byte() == 0 && dst.physReg().byte() == 0);
|
||||||
if (offset == (32 - bits) && op.regClass() != s1) {
|
if (offset == (32 - bits) && op.regClass() != s1) {
|
||||||
bld.vop2(signext ? aco_opcode::v_ashrrev_i32 : aco_opcode::v_lshrrev_b32, dst,
|
bld.vop2(signext ? aco_opcode::v_ashrrev_i32 : aco_opcode::v_lshrrev_b32, dst,
|
||||||
|
|
@ -2138,9 +2139,12 @@ lower_to_hw_instr(Program* program)
|
||||||
bld.vop3(signext ? aco_opcode::v_bfe_i32 : aco_opcode::v_bfe_u32, dst, op,
|
bld.vop3(signext ? aco_opcode::v_bfe_i32 : aco_opcode::v_bfe_u32, dst, op,
|
||||||
Operand::c32(offset), Operand::c32(bits));
|
Operand::c32(offset), Operand::c32(bits));
|
||||||
}
|
}
|
||||||
} else if (dst.regClass() == v2b) {
|
} else {
|
||||||
bld.vop1_sdwa(aco_opcode::v_mov_b32, dst, op).instr->sdwa().sel[0] =
|
assert(dst.regClass() == v2b || dst.regClass() == v1b || op.regClass() == v2b ||
|
||||||
SubdwordSel(1, offset / 8, signext);
|
op.regClass() == v1b);
|
||||||
|
SDWA_instruction& sdwa =
|
||||||
|
bld.vop1_sdwa(aco_opcode::v_mov_b32, dst, op).instr->sdwa();
|
||||||
|
sdwa.sel[0] = SubdwordSel(bits / 8, offset / 8, signext);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -466,22 +466,29 @@ validate_ir(Program* program)
|
||||||
instr->operands[0].getTemp().type() == RegType::sgpr,
|
instr->operands[0].getTemp().type() == RegType::sgpr,
|
||||||
"Can't extract/insert VGPR to SGPR", instr.get());
|
"Can't extract/insert VGPR to SGPR", instr.get());
|
||||||
|
|
||||||
if (instr->operands[0].getTemp().type() == RegType::vgpr)
|
if (instr->opcode == aco_opcode::p_insert)
|
||||||
check(instr->operands[0].bytes() == instr->definitions[0].bytes(),
|
check(instr->operands[0].bytes() == instr->definitions[0].bytes(),
|
||||||
"Sizes of operand and definition must match", instr.get());
|
"Sizes of p_insert data operand and definition must match", instr.get());
|
||||||
|
|
||||||
if (instr->definitions[0].getTemp().type() == RegType::sgpr)
|
if (instr->definitions[0].getTemp().type() == RegType::sgpr)
|
||||||
check(instr->definitions.size() >= 2 && instr->definitions[1].isFixed() &&
|
check(instr->definitions.size() >= 2 && instr->definitions[1].isFixed() &&
|
||||||
instr->definitions[1].physReg() == scc,
|
instr->definitions[1].physReg() == scc,
|
||||||
"SGPR extract/insert needs a SCC definition", instr.get());
|
"SGPR extract/insert needs an SCC definition", instr.get());
|
||||||
|
|
||||||
check(instr->operands[2].constantEquals(8) || instr->operands[2].constantEquals(16),
|
unsigned data_bits = instr->operands[0].getTemp().bytes() * 8u;
|
||||||
"Size must be 8 or 16", instr.get());
|
unsigned op_bits = instr->operands[2].constantValue();
|
||||||
check(instr->operands[2].constantValue() < instr->operands[0].getTemp().bytes() * 8u,
|
|
||||||
"Size must be smaller than source", instr.get());
|
|
||||||
|
|
||||||
unsigned comp =
|
if (instr->opcode == aco_opcode::p_insert) {
|
||||||
instr->operands[0].bytes() * 8u / MAX2(instr->operands[2].constantValue(), 1);
|
check(op_bits == 8 || op_bits == 16, "Size must be 8 or 16", instr.get());
|
||||||
|
check(op_bits < data_bits, "Size must be smaller than source", instr.get());
|
||||||
|
} else if (instr->opcode == aco_opcode::p_extract) {
|
||||||
|
check(op_bits == 8 || op_bits == 16 || op_bits == 32,
|
||||||
|
"Size must be 8 or 16 or 32", instr.get());
|
||||||
|
check(data_bits >= op_bits, "Can't extract more bits than what the data has.",
|
||||||
|
instr.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned comp = data_bits / MAX2(op_bits, 1);
|
||||||
check(instr->operands[1].constantValue() < comp, "Index must be in-bounds",
|
check(instr->operands[1].constantValue() < comp, "Index must be in-bounds",
|
||||||
instr.get());
|
instr.get());
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue