From e53c605adf9ee2af242d00e8db69289048e44909 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Mon, 27 Oct 2025 14:34:55 -0700 Subject: [PATCH] ir3: Add mova.r encoding Signed-off-by: Rob Clark Part-of: --- src/freedreno/ir3/instr-a3xx.h | 2 ++ src/freedreno/ir3/ir3.h | 1 + src/freedreno/ir3/ir3_parser.y | 12 +++++++ src/freedreno/ir3/ir3_print.c | 5 +++ src/freedreno/ir3/tests/disasm.c | 1 + src/freedreno/isa/encode.c | 9 +++++- src/freedreno/isa/ir3-cat1.xml | 55 ++++++++++++++++++++++++++++---- 7 files changed, 78 insertions(+), 7 deletions(-) diff --git a/src/freedreno/ir3/instr-a3xx.h b/src/freedreno/ir3/instr-a3xx.h index d387113a74d..b70451d050d 100644 --- a/src/freedreno/ir3/instr-a3xx.h +++ b/src/freedreno/ir3/instr-a3xx.h @@ -101,6 +101,8 @@ typedef enum { OPC_MOV_RELCONST = _OPC(1, 44), OPC_MOVS_IMMED = _OPC(1, 45), OPC_MOVS_A0 = _OPC(1, 46), + OPC_MOVA_R_IMMED = _OPC(1, 47), + OPC_MOVA_R_GPR = _OPC(1, 48), /* Macros that expand to an if statement + move */ OPC_BALLOT_MACRO = _OPC(1, 50), diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index a82e0eabea7..ea49efd2655 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -447,6 +447,7 @@ struct ir3_instruction { round_t round; reduce_op_t reduce_op; bool sat; + uint16_t r[2]; } cat1; struct { enum { diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index d0e1ffa7512..ea4e8b7aed3 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -722,6 +722,17 @@ cat1_mova: T_OP_MOVA cat1_mova_flags T_A0 ',' { new_dst((61 << 3), IR3_REG_HALF); } mova_src +cat1_mova_dst_flags: +| T_SAT { instr->cat1.sat = true; } + +cat1_mova_r: T_OP_MOVA cat1_mova_flags '.' 'r' { new_instr(OPC_MOV); } cat1_mova_dst_flags T_A0 ',' mova_src ',' integer ',' integer { + instr->cat1.src_type = TYPE_S16; + instr->cat1.dst_type = TYPE_S16; + new_dst((61 << 3), IR3_REG_HALF); + instr->cat1.r[0] = $11; + instr->cat1.r[1] = $13; + } + cat1_swz: T_OP_SWZ '.' T_CAT1_TYPE_TYPE { parse_type_type(new_instr(OPC_SWZ), $3); } dst_reg ',' dst_reg ',' src_reg ',' src_reg cat1_gat: T_OP_GAT '.' T_CAT1_TYPE_TYPE { parse_type_type(new_instr(OPC_GAT), $3); } dst_reg ',' src_reg ',' src_reg ',' src_reg ',' src_reg @@ -737,6 +748,7 @@ cat1_movs: T_OP_MOVS '.' T_CAT1_TYPE_TYPE { parse_type_type(new_instr(OPC_MOVS), cat1_instr: cat1_movmsk | cat1_mova1 | cat1_mova +| cat1_mova_r | cat1_swz | cat1_gat | cat1_sct diff --git a/src/freedreno/ir3/ir3_print.c b/src/freedreno/ir3/ir3_print.c index fe308cf8cf5..99cd3a97d47 100644 --- a/src/freedreno/ir3/ir3_print.c +++ b/src/freedreno/ir3/ir3_print.c @@ -485,6 +485,11 @@ print_instr(struct log_stream *stream, struct ir3_instruction *instr, int lvl) first = false; } + if ((opc_cat(instr->opc) == 1) && (instr->cat1.r[0] || instr->cat1.r[1])) { + mesa_log_stream_printf(stream, ", %u, %u", + instr->cat1.r[0], instr->cat1.r[1]); + } + if (is_tex(instr) && !(instr->flags & IR3_INSTR_S2EN) && !is_tex_shuffle(instr)) { if (!!(instr->flags & IR3_INSTR_B) && !!(instr->flags & IR3_INSTR_A1EN)) { diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c index 65fd17954fb..c0a8f9616e5 100644 --- a/src/freedreno/ir3/tests/disasm.c +++ b/src/freedreno/ir3/tests/disasm.c @@ -98,6 +98,7 @@ static const struct test { INSTR_6XX(201108f4_00000000, "mova.u a0.x, (r)hr0.x"), INSTR_6XX(204888f5_00000000, "mova1.u a1.x, 0"), + INSTR_8XX(20130cf4_008000c0, "mova.u.r (sat)a0.x, hr48.x, 0, 1"), INSTR_7XX(2004c005_00000405, "cov.f32u32 r1.y, (last)r1.y"), diff --git a/src/freedreno/isa/encode.c b/src/freedreno/isa/encode.c index 7f975c84cd9..ee9bb6eeeec 100644 --- a/src/freedreno/isa/encode.c +++ b/src/freedreno/isa/encode.c @@ -66,7 +66,14 @@ __instruction_case(struct encode_state *s, const struct ir3_instruction *instr) */ if (instr->opc == OPC_MOV) { struct ir3_register *src = instr->srcs[0]; - if (src->flags & IR3_REG_IMMED) { + if ((instr->dsts[0]->num == regid(REG_A0, 0)) && + (instr->cat1.r[0] || instr->cat1.r[1])) { + if (src->flags & IR3_REG_IMMED) { + return OPC_MOVA_R_IMMED; + } else { + return OPC_MOVA_R_GPR; + } + } else if (src->flags & IR3_REG_IMMED) { return OPC_MOV_IMMED; } if (src->flags & IR3_REG_RELATIV) { if (src->flags & IR3_REG_CONST) { diff --git a/src/freedreno/isa/ir3-cat1.xml b/src/freedreno/isa/ir3-cat1.xml index f9c4fe7320e..55f9e364347 100644 --- a/src/freedreno/isa/ir3-cat1.xml +++ b/src/freedreno/isa/ir3-cat1.xml @@ -114,7 +114,15 @@ SOFTWARE. - + + + {SRC_R} + + + 00 + + + ({DST} == 0xf4 /* a0.x */) && ({SRC_TYPE} == 4 /* s16 */) && ({DST_TYPE} == 4) @@ -148,15 +156,50 @@ SOFTWARE. {SY}{SS}{JP}{REPEAT}{UL}mov.{SRC_TYPE}{DST_TYPE} {ROUND}{DM}{DST_HALF}{DST}, {SRC} - - {SRC_R} - - - 00 + + + + + + + ({SRC_TYPE} == 4 /* s16 */) && ({DST_TYPE} == 4) + + {SY}{SS}{JP}{REPEAT}{UL}mova{U}.r {ROUND}{DM}a0.x, {SRC}, {R0}, {R1} + + + error + + + 11110100 + + 1 + + src->cat1.r[0] + src->cat1.r[1] + + + + + + 10 + + extract_reg_uim(src->srcs[0]) + + + + + + + + + + 000000 + + 00