From 08499369d0164e9a503e16aad39f9b9e1e347e1a Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Fri, 16 Apr 2021 17:13:30 +0200 Subject: [PATCH] ir3: Assemble and disassemble swz/gat/sct Part-of: --- src/freedreno/ir3/instr-a3xx.h | 9 ++ src/freedreno/ir3/ir3_lexer.l | 3 + src/freedreno/ir3/ir3_parser.y | 12 ++ src/freedreno/ir3/tests/disasm.c | 5 + src/freedreno/isa/ir3-cat1.xml | 192 ++++++++++++++++++++++++++----- 5 files changed, 193 insertions(+), 28 deletions(-) diff --git a/src/freedreno/ir3/instr-a3xx.h b/src/freedreno/ir3/instr-a3xx.h index b56983a3b2b..b7f2f95ccda 100644 --- a/src/freedreno/ir3/instr-a3xx.h +++ b/src/freedreno/ir3/instr-a3xx.h @@ -92,8 +92,17 @@ typedef enum { /* category 1: */ OPC_MOV = _OPC(1, 0), + OPC_MOVP = _OPC(1, 1), + /* swz, gat, sct */ OPC_MOVMSK = _OPC(1, 3), + /* Virtual opcodes for instructions differentiated via a "sub-opcode" that + * replaces the repeat field: + */ + OPC_SWZ = _OPC(1, 4), + OPC_GAT = _OPC(1, 5), + OPC_SCT = _OPC(1, 6), + /* Logical opcodes for different variants of mov: */ OPC_MOV_IMMED = _OPC(1, 40), OPC_MOV_CONST = _OPC(1, 41), diff --git a/src/freedreno/ir3/ir3_lexer.l b/src/freedreno/ir3/ir3_lexer.l index 568145af71e..f7d9783c628 100644 --- a/src/freedreno/ir3/ir3_lexer.l +++ b/src/freedreno/ir3/ir3_lexer.l @@ -180,6 +180,9 @@ static int parse_w(const char *str) "mova" return TOKEN(T_OP_MOVA); "mov" return TOKEN(T_OP_MOV); "cov" return TOKEN(T_OP_COV); +"swz" return TOKEN(T_OP_SWZ); +"gat" return TOKEN(T_OP_GAT); +"sct" return TOKEN(T_OP_SCT); ("f16"|"f32"|"u16"|"u32"|"s16"|"s32"|"u8"|"s8"){2} ir3_yylval.str = yytext; return T_CAT1_TYPE_TYPE; diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index fc684a54159..ae23c6a1da0 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -399,6 +399,9 @@ static void print_token(FILE *file, int type, YYSTYPE value) %token T_OP_MOVA %token T_OP_MOV %token T_OP_COV +%token T_OP_SWZ +%token T_OP_GAT +%token T_OP_SCT /* category 2: */ %token T_OP_ADD_F @@ -791,10 +794,19 @@ cat1_mova: T_OP_MOVA T_A0 ',' { new_reg((61 << 3), IR3_REG_HALF); } cat1_src +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 + +cat1_sct: T_OP_SCT '.' T_CAT1_TYPE_TYPE { parse_type_type(new_instr(OPC_SCT), $3); } dst_reg ',' dst_reg ',' dst_reg ',' dst_reg ',' src_reg + /* NOTE: cat1 can also *write* to relative gpr */ cat1_instr: cat1_movmsk | cat1_mova1 | cat1_mova +| cat1_swz +| cat1_gat +| cat1_sct | cat1_opc dst_reg ',' cat1_src | cat1_opc relative_gpr ',' cat1_src diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c index 5d6d052f7fb..6f500f0253e 100644 --- a/src/freedreno/ir3/tests/disasm.c +++ b/src/freedreno/ir3/tests/disasm.c @@ -84,6 +84,11 @@ static const struct test { /* dEQP-VK.subgroups.ballot.compute.compute */ INSTR_6XX(260cc3c0_00000000, "movmsk.w128 r48.x"), /* movmsk.w128 sr48.x */ + INSTR_6XX(240cc004_00030201, "swz.u32u32 r1.x, r0.w, r0.y, r0.z"), + INSTR_6XX(2400c105_04030201, "gat.f16u32 r1.y, hr0.y, hr0.z, hr0.w, hr1.x"), + INSTR_6XX(240c0205_04030201, "sct.u32f16 hr1.y, hr0.z, hr0.w, hr1.x, r0.y"), + INSTR_6XX(2400c205_04030201, "sct.f16u32 r1.y, r0.z, r0.w, r1.x, hr0.y"), + INSTR_6XX(20510005_0000ffff, "mov.s16s16 hr1.y, -1"), INSTR_6XX(20400005_00003900, "mov.f16f16 hr1.y, h(0.625000)"), INSTR_6XX(20400006_00003800, "mov.f16f16 hr1.z, h(0.500000)"), diff --git a/src/freedreno/isa/ir3-cat1.xml b/src/freedreno/isa/ir3-cat1.xml index 671ccd42e2b..2633894a05e 100644 --- a/src/freedreno/isa/ir3-cat1.xml +++ b/src/freedreno/isa/ir3-cat1.xml @@ -68,14 +68,9 @@ SOFTWARE. - - - - 0 - @@ -84,14 +79,40 @@ SOFTWARE. src->regs[1] !!(src->regs[1]->flags & IR3_REG_R) !!(src->flags & IR3_INSTR_UL) - src->cat1.dst_type !!(src->regs[0]->flags & IR3_REG_RELATIV) - src->cat1.src_type src->cat1.round - + + + + ({SRC_TYPE} == 0) /* f16 */ || + ({SRC_TYPE} == 2) /* u16 */ || + ({SRC_TYPE} == 4) /* s16 */ || + ({SRC_TYPE} == 6) /* u8 */ || + ({SRC_TYPE} == 7) /* s8 */ + + + + + ({DST_TYPE} == 0) /* f16 */ || + ({DST_TYPE} == 2) /* u16 */ || + ({DST_TYPE} == 4) /* s16 */ || + ({DST_TYPE} == 6) /* u8 */ || + ({DST_TYPE} == 7) /* s8 */ + + + + + + + src->cat1.dst_type + src->cat1.src_type + + + + ({DST} == 0xf4 /* a0.x */) && ({SRC_TYPE} == 4 /* s16 */) && ({DST_TYPE} == 4) @@ -125,27 +146,12 @@ SOFTWARE. {SY}{SS}{JP}{REPEAT}{UL}mov.{SRC_TYPE}{DST_TYPE} {ROUND}{DST_HALF}{DST}, {SRC} + + + + + 00 - - - ({SRC_TYPE} == 0) /* f16 */ || - ({SRC_TYPE} == 2) /* u16 */ || - ({SRC_TYPE} == 4) /* s16 */ || - ({SRC_TYPE} == 6) /* u8 */ || - ({SRC_TYPE} == 7) /* s8 */ - - - - - ({DST_TYPE} == 0) /* f16 */ || - ({DST_TYPE} == 2) /* u16 */ || - ({DST_TYPE} == 4) /* s16 */ || - ({DST_TYPE} == 6) /* u8 */ || - ({DST_TYPE} == 7) /* s8 */ - - - - + + + {HALF}{REG} + + + + + src + + + + + + {DST_HALF}{REG} + + + + + + src + + + + + + These instructions all expand to a series of mov instructions, + like (rptN) but more flexible. They aren't any faster than the + equivalent sequence of mov/cov, but they guarantee that all + sources are read before any destination is written, so they + behave as-if the moves are executed in parallel. + TODO: when were these added? + + + + + + + + 0 + 0 + 00 + 10 + + + src->regs[0] + + + + + + SWiZzle. Move SRC0 to DST0 and SRC1 to DST1 in parallel. In + particular this can be used to swap two registers. + + + {SY}{SS}{JP}{UL}swz.{SRC_TYPE}{DST_TYPE} {ROUND}{DST0}, {DST1}, {SRC0}, {SRC1} + + + + + + + + 00000000 + + 00 + + + src->regs[2] + src->regs[3] + src->regs[1] + + + + + + GATher. Move SRC0 to DST0, SRC1 to DST0 + 1, SRC2 to DST0 + 2, and SRC3 to DST0 + 3. + + + {SY}{SS}{JP}{UL}gat.{SRC_TYPE}{DST_TYPE} {ROUND}{DST0}, {SRC0}, {SRC1}, {SRC2}, {SRC3} + + + + + + + + + + + 01 + + + src->regs[1] + src->regs[2] + src->regs[3] + src->regs[4] + + + + + + SCaTter. Move SRC0 to DST0, SRC0 + 1 to DST1, SRC0 + 2 to DST2 + 3, and SRC0 + 3 to DST3. + + + {SY}{SS}{JP}{UL}sct.{SRC_TYPE}{DST_TYPE} {ROUND}{DST0}, {DST1}, {DST2}, {DST3}, {SRC0} + + + + + + + + + + + 10 + + + src->regs[4] + src->regs[1] + src->regs[2] + src->regs[3] + + + {SY}{SS}{JP}{UL}movmsk.w{W} {DST} @@ -314,8 +445,13 @@ SOFTWARE. 00000000000000000000000000000000 + + + + 0 011 + 011 00 11