From 9d3102048e6f7fcd2dcad8121089a7d88d101293 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Tue, 28 Oct 2025 18:32:03 -0700 Subject: [PATCH] ir3: Add new cat2 instructions Signed-off-by: Rob Clark Part-of: --- src/freedreno/ir3/instr-a3xx.h | 4 ++++ src/freedreno/ir3/ir3_lexer.l | 3 +++ src/freedreno/ir3/ir3_parser.y | 7 +++++++ src/freedreno/ir3/tests/disasm.c | 1 + src/freedreno/isa/ir3-cat2.xml | 20 ++++++++++++++++++++ 5 files changed, 35 insertions(+) diff --git a/src/freedreno/ir3/instr-a3xx.h b/src/freedreno/ir3/instr-a3xx.h index b70451d050d..787a539eaff 100644 --- a/src/freedreno/ir3/instr-a3xx.h +++ b/src/freedreno/ir3/instr-a3xx.h @@ -153,6 +153,10 @@ typedef enum { /* 32 - invalid */ OPC_CMPV_U = _OPC(2, 33), OPC_CMPV_S = _OPC(2, 34), + OPC_MUL_F_MUL2 = _OPC(2, 35), + OPC_ADD_F_MUL2 = _OPC(2, 36), + OPC_MUL_F_DIV2 = _OPC(2, 37), + OPC_ADD_F_DIV2 = _OPC(2, 38), /* 35-47 - invalid */ OPC_MUL_U24 = _OPC(2, 48), /* 24b mul into 32b result */ OPC_MUL_S24 = _OPC(2, 49), /* 24b mul into 32b result with sign extension */ diff --git a/src/freedreno/ir3/ir3_lexer.l b/src/freedreno/ir3/ir3_lexer.l index d1bf8696fcf..4f344135d2e 100644 --- a/src/freedreno/ir3/ir3_lexer.l +++ b/src/freedreno/ir3/ir3_lexer.l @@ -234,6 +234,9 @@ static int parse_reg(const char *str) "movs" return TOKEN(T_OP_MOVS); ("f16"|"f32"|"u16"|"u32"|"s16"|"s32"|"u8"|"u8_32"|"u64"){2} ir3_yylval.str = yytext; return T_CAT1_TYPE_TYPE; + +".mul2" return TOKEN(T_MUL2); +".div2" return TOKEN(T_DIV2); /* category 2: */ "add.f" return TOKEN(T_OP_ADD_F); "min.f" return TOKEN(T_OP_MIN_F); diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index ea4e8b7aed3..a18f0e57da2 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -177,6 +177,9 @@ static void print_token(FILE *file, int type, YYSTYPE value) %token T_OP_SCT %token T_OP_MOVS +%token T_MUL2 +%token T_DIV2 + /* category 2: */ %token T_OP_ADD_F %token T_OP_MIN_F @@ -777,6 +780,10 @@ cat2_opc_2src_cnd: T_OP_CMPS_F { new_instr(OPC_CMPS_F); } | T_OP_CMPV_F { new_instr(OPC_CMPV_F); } | T_OP_CMPV_U { new_instr(OPC_CMPV_U); } | T_OP_CMPV_S { new_instr(OPC_CMPV_S); } +| T_OP_ADD_F T_DIV2 { new_instr(OPC_ADD_F_DIV2); } +| T_OP_ADD_F T_MUL2 { new_instr(OPC_ADD_F_MUL2); } +| T_OP_MUL_F T_DIV2 { new_instr(OPC_MUL_F_DIV2); } +| T_OP_MUL_F T_MUL2 { new_instr(OPC_MUL_F_MUL2); } cat2_opc_2src: T_OP_ADD_F { new_instr(OPC_ADD_F); } | T_OP_MIN_F { new_instr(OPC_MIN_F); } diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c index 83a58c67f6a..53990a73dd3 100644 --- a/src/freedreno/ir3/tests/disasm.c +++ b/src/freedreno/ir3/tests/disasm.c @@ -128,6 +128,7 @@ static const struct test { INSTR_7XX(42930000_04000406, "cmps.u.ge r0.x, (last)r1.z, (last)r0.x"), INSTR_7XX(429000f5_100600c1, "cmps.u.lt up0.y, r48.y, c1.z"), + INSTR_7XX(4490000c_10534007, "add.f.mul2.lt r3.x, (neg)r1.w, c20.w"), /* cat3 */ INSTR_6XX(66000000_10421041, "sel.f16 hr0.x, hc16.y, hr0.x, hc16.z"), diff --git a/src/freedreno/isa/ir3-cat2.xml b/src/freedreno/isa/ir3-cat2.xml index 9c516fdabde..603980dc056 100644 --- a/src/freedreno/isa/ir3-cat2.xml +++ b/src/freedreno/isa/ir3-cat2.xml @@ -347,6 +347,26 @@ SOFTWARE. 100010 + + + 100011 + + + + + 100100 + + + + + 100101 + + + + + 100110 + + 110000