From c6c37b516d6dcdae0546159668f0d92dd6694eb3 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Mon, 10 Jul 2023 15:47:18 -0700 Subject: [PATCH] lima: ppir: fix diassembling atan and combiner codegen definition Fix multiple issues with atan in disassembler: - arg1_en field in combiner unit actually seems to be a bit indicating that one of sources is vector (e.g. for atan_pt2, or multiplication) - atan2 has 2 arguments, not one - properly handle all instruction variants Reviewed-by: Erico Nunes Signed-off-by: Vasily Khoruzhick Part-of: --- src/gallium/drivers/lima/ir/pp/codegen.c | 2 +- src/gallium/drivers/lima/ir/pp/codegen.h | 4 +- src/gallium/drivers/lima/ir/pp/disasm.c | 95 +++++++++++++++++------- 3 files changed, 73 insertions(+), 28 deletions(-) diff --git a/src/gallium/drivers/lima/ir/pp/codegen.c b/src/gallium/drivers/lima/ir/pp/codegen.c index b043bd46bd8..55f8ee6b6b4 100644 --- a/src/gallium/drivers/lima/ir/pp/codegen.c +++ b/src/gallium/drivers/lima/ir/pp/codegen.c @@ -542,7 +542,7 @@ static void ppir_codegen_encode_combine(ppir_node *node, void *code) case ppir_op_cos: { f->scalar.dest_vec = false; - f->scalar.arg1_en = false; + f->scalar.src_vec = false; ppir_dest *dest = &alu->dest; int dest_component = ffs(dest->write_mask) - 1; diff --git a/src/gallium/drivers/lima/ir/pp/codegen.h b/src/gallium/drivers/lima/ir/pp/codegen.h index dbd0c8f654b..055e952f5fc 100644 --- a/src/gallium/drivers/lima/ir/pp/codegen.h +++ b/src/gallium/drivers/lima/ir/pp/codegen.h @@ -308,7 +308,7 @@ typedef enum { typedef union __attribute__((__packed__)) { struct __attribute__((__packed__)) { bool dest_vec : 1; - bool arg1_en : 1; + bool src_vec : 1; ppir_codegen_combine_scalar_op op : 4; bool arg1_absolute : 1; bool arg1_negate : 1; @@ -321,7 +321,7 @@ typedef union __attribute__((__packed__)) { } scalar; struct __attribute__((__packed__)) { bool dest_vec : 1; - bool arg1_en : 1; + bool src_vec : 1; unsigned arg1_swizzle : 8; unsigned arg1_source : 4; unsigned padding_0 : 8; diff --git a/src/gallium/drivers/lima/ir/pp/disasm.c b/src/gallium/drivers/lima/ir/pp/disasm.c index 81d4016a090..7bf62384c15 100644 --- a/src/gallium/drivers/lima/ir/pp/disasm.c +++ b/src/gallium/drivers/lima/ir/pp/disasm.c @@ -609,11 +609,47 @@ static const asm_op combine_ops[] = { CASE(sin, 1), CASE(cos, 1), CASE(atan, 1), - CASE(atan2, 1), + CASE(atan2, 2), }; #undef CASE +static void +print_combine_mul(void *code, unsigned offset, FILE *fp) +{ + (void) offset; + ppir_codegen_field_combine *combine = code; + + fprintf(fp, "mul.s2 "); + fprintf(fp, "$%u", combine->vector.dest); + print_mask(combine->vector.mask, fp); + fprintf(fp, " "); + + print_source_scalar(combine->scalar.arg0_src, NULL, + combine->scalar.arg0_absolute, + combine->scalar.arg0_negate, fp); + fprintf(fp, " "); + + print_vector_source(combine->vector.arg1_source, NULL, + combine->vector.arg1_swizzle, + false, false, fp); +} + +static void +print_combine_atan_pt2(void *code, unsigned offset, FILE *fp) +{ + (void) offset; + ppir_codegen_field_combine *combine = code; + + fprintf(fp, "atan_pt2.s2 "); + print_outmod(combine->scalar.dest_modifier, fp); + print_dest_scalar(combine->scalar.dest, fp); + + print_vector_source(combine->vector.arg1_source, NULL, + combine->vector.arg1_swizzle, + false, false, fp); +} + static void print_combine(void *code, unsigned offset, FILE *fp) { @@ -621,47 +657,56 @@ print_combine(void *code, unsigned offset, FILE *fp) ppir_codegen_field_combine *combine = code; if (combine->scalar.dest_vec && - combine->scalar.arg1_en) { + combine->scalar.src_vec) { /* This particular combination can only be valid for scalar * vector - * multiplies, and the opcode field is reused for something else. + * multiplies, and the opcode field is reused for a vector argument + * and swizzle, destination is vector. */ - fprintf(fp, "mul"); - } else { - asm_op op = combine_ops[combine->scalar.op]; - - if (op.name) - fprintf(fp, "%s", op.name); - else - fprintf(fp, "op%u", combine->scalar.op); + return print_combine_mul(code, offset, fp); + } else if (!combine->scalar.dest_vec && + combine->scalar.src_vec) { + /* This particular combination can only be valid for atan_pt2. + * The opcode field is reused for a vector argument and swizzle, + * and the destination is scalar. + */ + return print_combine_atan_pt2(code, offset, fp); } - if (!combine->scalar.dest_vec) + /* Vector source is only possible for scalar * vec multiplication and + * atan_pt2. It re-uses the same bits as opcode, so if we got there + * something went wrong + */ + assert(!combine->scalar.src_vec); + + asm_op op = combine_ops[combine->scalar.op]; + + if (op.name) { + fprintf(fp, "%s", op.name); + } else { + fprintf(fp, "op%u", combine->scalar.op); + } + + if (!combine->scalar.dest_vec) { print_outmod(combine->scalar.dest_modifier, fp); + } fprintf(fp, ".s2 "); if (combine->scalar.dest_vec) { fprintf(fp, "$%u", combine->vector.dest); print_mask(combine->vector.mask, fp); + fprintf(fp, " "); } else { print_dest_scalar(combine->scalar.dest, fp); } - fprintf(fp, " "); print_source_scalar(combine->scalar.arg0_src, NULL, combine->scalar.arg0_absolute, combine->scalar.arg0_negate, fp); - fprintf(fp, " "); - - if (combine->scalar.arg1_en) { - if (combine->scalar.dest_vec) { - print_vector_source(combine->vector.arg1_source, NULL, - combine->vector.arg1_swizzle, - false, false, fp); - } else { - print_source_scalar(combine->scalar.arg1_src, NULL, - combine->scalar.arg1_absolute, - combine->scalar.arg1_negate, fp); - } + if (op.srcs > 1) { + fprintf(fp, " "); + print_source_scalar(combine->scalar.arg1_src, NULL, + combine->scalar.arg1_absolute, + combine->scalar.arg1_negate, fp); } }