From 065d2547e706bbeed133af42e38ce9821fc0ffa2 Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Thu, 27 Jul 2023 10:48:39 +0200 Subject: [PATCH] ir3: Add EOLM and EOGM a7xx flags to NOP Apparently the ignored bits have meaning. - EOLM - Is set on a NOP after the last cat6 instruction. Must be set outside of control flow including preambles. Doesn't seem to affect correctness. - EOGM - Is set on a NOP after the last cat5/cat6 instruction. Signed-off-by: Danylo Piliaiev Signed-off-by: Rob Clark Part-of: --- src/freedreno/ir3/ir3.h | 6 ++++++ src/freedreno/ir3/ir3_lexer.l | 2 ++ src/freedreno/ir3/ir3_parser.y | 4 ++++ src/freedreno/ir3/tests/disasm.c | 3 +++ src/freedreno/isa/ir3-cat0.xml | 18 ++++++++++++++++-- 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/src/freedreno/ir3/ir3.h b/src/freedreno/ir3/ir3.h index 569bb844001..f74327ce51b 100644 --- a/src/freedreno/ir3/ir3.h +++ b/src/freedreno/ir3/ir3.h @@ -402,6 +402,12 @@ typedef enum ir3_instruction_flags { * their sources. */ IR3_INSTR_IMM_OFFSET = BIT(21), + + /* a7xx, set on a nop after all cat6 */ + IR3_INSTR_EOLM = BIT(22), + + /* a7xx, set on a nop after all cat5/cat6 */ + IR3_INSTR_EOGM = BIT(23), } ir3_instruction_flags; struct ir3_instruction { diff --git a/src/freedreno/ir3/ir3_lexer.l b/src/freedreno/ir3/ir3_lexer.l index aca583cab0b..22bd21565ff 100644 --- a/src/freedreno/ir3/ir3_lexer.l +++ b/src/freedreno/ir3/ir3_lexer.l @@ -171,6 +171,8 @@ static int parse_reg(const char *str) "(jp)" return TOKEN(T_JP); "(eq)" return TOKEN(T_EQ_FLAG); "(sat)" return TOKEN(T_SAT); +"(eolm)" return TOKEN(T_EOLM); +"(eogm)" return TOKEN(T_EOGM); "(rpt"[0-7]")" ir3_yylval.num = strtol(yytext+4, NULL, 10); return T_RPT; "(nop"[0-7]")" ir3_yylval.num = strtol(yytext+4, NULL, 10); return T_NOP; "("[x]?[y]?[z]?[w]?")" ir3_yylval.num = parse_wrmask(yytext); return T_WRMASK; diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index 83f1d8bf4b9..ef2a44897ad 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -460,6 +460,8 @@ static void print_token(FILE *file, int type, YYSTYPE value) %token T_RPT %token T_UL %token T_NOP +%token T_EOLM +%token T_EOGM /* category 0: */ %token T_OP_NOP @@ -932,6 +934,8 @@ iflag: T_SY { iflags.flags |= IR3_INSTR_SY; } | T_RPT { iflags.repeat = $1; } | T_UL { iflags.flags |= IR3_INSTR_UL; } | T_NOP { iflags.nop = $1; } +| T_EOLM { iflags.flags |= IR3_INSTR_EOLM; } +| T_EOGM { iflags.flags |= IR3_INSTR_EOGM; } iflags: | iflag iflags diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c index b9f0c735dce..08ea74f005b 100644 --- a/src/freedreno/ir3/tests/disasm.c +++ b/src/freedreno/ir3/tests/disasm.c @@ -68,6 +68,9 @@ static const struct test { INSTR_6XX(07020000_00000000, "predf"), INSTR_6XX(07820000_00000000, "prede"), + INSTR_7XX(00000003_00000000, "(eolm)(eogm)nop"), + INSTR_7XX(00000001_00000000, "(eolm)nop"), + /* cat1 */ INSTR_6XX(20244000_00000020, "mov.f32f32 r0.x, c8.x"), INSTR_6XX(20200000_00000020, "mov.f16f16 hr0.x, hc8.x"), diff --git a/src/freedreno/isa/ir3-cat0.xml b/src/freedreno/isa/ir3-cat0.xml index a5e778650db..b826ec3d23e 100644 --- a/src/freedreno/isa/ir3-cat0.xml +++ b/src/freedreno/isa/ir3-cat0.xml @@ -50,15 +50,29 @@ SOFTWARE. src->cat0.inv1 src->cat0.inv2 !!(src->flags & IR3_INSTR_EQ) + !!(src->flags & IR3_INSTR_EOLM) + !!(src->flags & IR3_INSTR_EOGM) - {SY}{SS}{EQ}{JP}{REPEAT}{NAME} + {SY}{SS}{EQ}{JP}{EOLM}{EOGM}{REPEAT}{NAME} - xxxxx + + + Is set on a NOP after the last cat6 instruction. Must be set outside + of control flow including preambles. Doesn't seem to affect correctness. + + + + + Is set on a NOP after the last cat5/cat6 instruction. Must be set outside + of control flow including preambles. Doesn't seem to affect correctness. + + + 000 000 000 000