aco: add GFX11.5+ opcodes

Signed-off-by: Rhys Perry <pendingchaos02@gmail.com>
Reviewed-by: Georg Lehmann <dadschoorse@gmail.com>
Acked-by: Daniel Schürmann <daniel@schuermann.dev>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/29162>
This commit is contained in:
Rhys Perry
2024-03-11 14:16:53 +00:00
committed by Marge Bot
parent 97698e564a
commit 74aa6437d6
5 changed files with 315 additions and 117 deletions
+17 -15
View File
@@ -926,7 +926,8 @@ emit_vop3a_instruction(isel_context* ctx, nir_alu_instr* instr, aco_opcode op, T
if (dst.size() == 1)
bld.vop2(aco_opcode::v_mul_f32, Definition(dst), Operand::c32(0x3f800000u), tmp);
else
bld.vop3(aco_opcode::v_mul_f64, Definition(dst), Operand::c64(0x3FF0000000000000), tmp);
bld.vop3(aco_opcode::v_mul_f64_e64, Definition(dst), Operand::c64(0x3FF0000000000000),
tmp);
} else if (num_sources == 3) {
bld.vop3(op, Definition(dst), src[0], src[1], src[2]);
} else {
@@ -1297,7 +1298,7 @@ emit_floor_f64(isel_context* ctx, Builder& bld, Definition dst, Temp val)
Temp isnan = bld.vopc(aco_opcode::v_cmp_neq_f64, bld.def(bld.lm), src0, src0);
Temp fract = bld.vop1(aco_opcode::v_fract_f64, bld.def(v2), src0);
Temp min = bld.vop3(aco_opcode::v_min_f64, bld.def(v2), fract, min_val);
Temp min = bld.vop3(aco_opcode::v_min_f64_e64, bld.def(v2), fract, min_val);
Temp then_lo = bld.tmp(v1), then_hi = bld.tmp(v1);
bld.pseudo(aco_opcode::p_split_vector, Definition(then_lo), Definition(then_hi), src0);
@@ -1309,7 +1310,7 @@ emit_floor_f64(isel_context* ctx, Builder& bld, Definition dst, Temp val)
Temp v = bld.pseudo(aco_opcode::p_create_vector, bld.def(v2), dst0, dst1);
Instruction* add = bld.vop3(aco_opcode::v_add_f64, Definition(dst), src0, v);
Instruction* add = bld.vop3(aco_opcode::v_add_f64_e64, Definition(dst), src0, v);
add->valu().neg[1] = true;
return add->definitions[0].getTemp();
@@ -1723,7 +1724,7 @@ visit_alu_instr(isel_context* ctx, nir_alu_instr* instr)
emit_vop2_instruction(ctx, instr, aco_opcode::v_lshlrev_b32, dst, false, true, false,
false, 2);
} else if (dst.regClass() == v2 && ctx->program->gfx_level >= GFX8) {
bld.vop3(aco_opcode::v_lshlrev_b64, Definition(dst), get_alu_src(ctx, instr->src[1]),
bld.vop3(aco_opcode::v_lshlrev_b64_e64, Definition(dst), get_alu_src(ctx, instr->src[1]),
get_alu_src(ctx, instr->src[0]));
} else if (dst.regClass() == v2) {
emit_vop3a_instruction(ctx, instr, aco_opcode::v_lshl_b64, dst);
@@ -2337,7 +2338,7 @@ visit_alu_instr(isel_context* ctx, nir_alu_instr* instr)
} else if (dst.regClass() == v1) {
emit_vop2_instruction(ctx, instr, aco_opcode::v_mul_f32, dst, true);
} else if (dst.regClass() == v2) {
emit_vop3a_instruction(ctx, instr, aco_opcode::v_mul_f64, dst);
emit_vop3a_instruction(ctx, instr, aco_opcode::v_mul_f64_e64, dst);
} else {
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
@@ -2359,7 +2360,7 @@ visit_alu_instr(isel_context* ctx, nir_alu_instr* instr)
} else if (dst.regClass() == v1) {
emit_vop2_instruction(ctx, instr, aco_opcode::v_add_f32, dst, true);
} else if (dst.regClass() == v2) {
emit_vop3a_instruction(ctx, instr, aco_opcode::v_add_f64, dst);
emit_vop3a_instruction(ctx, instr, aco_opcode::v_add_f64_e64, dst);
} else {
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
}
@@ -2387,7 +2388,7 @@ visit_alu_instr(isel_context* ctx, nir_alu_instr* instr)
else
emit_vop2_instruction(ctx, instr, aco_opcode::v_subrev_f32, dst, true);
} else if (dst.regClass() == v2) {
Instruction* add = bld.vop3(aco_opcode::v_add_f64, Definition(dst), as_vgpr(ctx, src0),
Instruction* add = bld.vop3(aco_opcode::v_add_f64_e64, Definition(dst), as_vgpr(ctx, src0),
as_vgpr(ctx, src1));
add->valu().neg[1] = true;
} else {
@@ -2443,7 +2444,7 @@ visit_alu_instr(isel_context* ctx, nir_alu_instr* instr)
emit_vop2_instruction(ctx, instr, aco_opcode::v_max_f32, dst, true, false,
ctx->block->fp_mode.must_flush_denorms32);
} else if (dst.regClass() == v2) {
emit_vop3a_instruction(ctx, instr, aco_opcode::v_max_f64, dst,
emit_vop3a_instruction(ctx, instr, aco_opcode::v_max_f64_e64, dst,
ctx->block->fp_mode.must_flush_denorms16_64);
} else {
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
@@ -2460,7 +2461,7 @@ visit_alu_instr(isel_context* ctx, nir_alu_instr* instr)
emit_vop2_instruction(ctx, instr, aco_opcode::v_min_f32, dst, true, false,
ctx->block->fp_mode.must_flush_denorms32);
} else if (dst.regClass() == v2) {
emit_vop3a_instruction(ctx, instr, aco_opcode::v_min_f64, dst,
emit_vop3a_instruction(ctx, instr, aco_opcode::v_min_f64_e64, dst,
ctx->block->fp_mode.must_flush_denorms16_64);
} else {
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
@@ -2561,7 +2562,7 @@ visit_alu_instr(isel_context* ctx, nir_alu_instr* instr)
as_vgpr(ctx, src));
} else if (dst.regClass() == v2) {
if (ctx->block->fp_mode.must_flush_denorms16_64)
src = bld.vop3(aco_opcode::v_mul_f64, bld.def(v2), Operand::c64(0x3FF0000000000000),
src = bld.vop3(aco_opcode::v_mul_f64_e64, bld.def(v2), Operand::c64(0x3FF0000000000000),
as_vgpr(ctx, src));
Temp upper = bld.tmp(v1), lower = bld.tmp(v1);
bld.pseudo(aco_opcode::p_split_vector, Definition(lower), Definition(upper), src);
@@ -2597,7 +2598,7 @@ visit_alu_instr(isel_context* ctx, nir_alu_instr* instr)
mul->valu().abs[1] = true;
} else if (dst.regClass() == v2) {
if (ctx->block->fp_mode.must_flush_denorms16_64)
src = bld.vop3(aco_opcode::v_mul_f64, bld.def(v2), Operand::c64(0x3FF0000000000000),
src = bld.vop3(aco_opcode::v_mul_f64_e64, bld.def(v2), Operand::c64(0x3FF0000000000000),
as_vgpr(ctx, src));
Temp upper = bld.tmp(v1), lower = bld.tmp(v1);
bld.pseudo(aco_opcode::p_split_vector, Definition(lower), Definition(upper), src);
@@ -2633,7 +2634,8 @@ visit_alu_instr(isel_context* ctx, nir_alu_instr* instr)
* operands */
// TODO: confirm that this holds under any circumstances
} else if (dst.regClass() == v2) {
Instruction* add = bld.vop3(aco_opcode::v_add_f64, Definition(dst), src, Operand::zero());
Instruction* add =
bld.vop3(aco_opcode::v_add_f64_e64, Definition(dst), src, Operand::zero());
add->valu().clamp = true;
} else {
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
@@ -2739,7 +2741,7 @@ visit_alu_instr(isel_context* ctx, nir_alu_instr* instr)
bld.copy(bld.def(v1), Operand::c32(0x3ff00000u)), cond);
add = bld.pseudo(aco_opcode::p_create_vector, bld.def(v2),
bld.copy(bld.def(v1), Operand::zero()), add);
bld.vop3(aco_opcode::v_add_f64, Definition(dst), trunc, add);
bld.vop3(aco_opcode::v_add_f64_e64, Definition(dst), trunc, add);
}
} else {
isel_err(&instr->instr, "Unimplemented NIR instr bit size");
@@ -2779,10 +2781,10 @@ visit_alu_instr(isel_context* ctx, nir_alu_instr* instr)
bld.vop3(aco_opcode::v_bfi_b32, bld.def(v1), bitmask,
bld.copy(bld.def(v1), Operand::c32(0x43300000u)), as_vgpr(ctx, src0_hi));
Temp tmp =
bld.vop3(aco_opcode::v_add_f64, bld.def(v2), src0,
bld.vop3(aco_opcode::v_add_f64_e64, bld.def(v2), src0,
bld.pseudo(aco_opcode::p_create_vector, bld.def(v2), Operand::zero(), bfi));
Instruction* sub =
bld.vop3(aco_opcode::v_add_f64, bld.def(v2), tmp,
bld.vop3(aco_opcode::v_add_f64_e64, bld.def(v2), tmp,
bld.pseudo(aco_opcode::p_create_vector, bld.def(v2), Operand::zero(), bfi));
sub->valu().neg[1] = true;
tmp = sub->definitions[0].getTemp();