From e6f548018089d2d36215b8117e68393d35772648 Mon Sep 17 00:00:00 2001 From: Danylo Piliaiev Date: Thu, 6 Jan 2022 16:24:20 +0200 Subject: [PATCH] ir3: Add cat7 sleep instruction Has short and long variants, long seem to be ~20 times longer. The exact difference between it and a bunch of nops is unknown. The emission of this instruction were not observed in the wild. Signed-off-by: Danylo Piliaiev Part-of: --- src/freedreno/ir3/instr-a3xx.h | 1 + src/freedreno/ir3/ir3_lexer.l | 1 + src/freedreno/ir3/ir3_parser.y | 2 ++ src/freedreno/ir3/tests/disasm.c | 1 + src/freedreno/isa/ir3-cat7.xml | 31 +++++++++++++++++++++++++++++++ 5 files changed, 36 insertions(+) diff --git a/src/freedreno/ir3/instr-a3xx.h b/src/freedreno/ir3/instr-a3xx.h index cc298458d1f..57e90aa58ce 100644 --- a/src/freedreno/ir3/instr-a3xx.h +++ b/src/freedreno/ir3/instr-a3xx.h @@ -361,6 +361,7 @@ typedef enum { /* category 7: */ OPC_BAR = _OPC(7, 0), OPC_FENCE = _OPC(7, 1), + OPC_SLEEP = _OPC(7, 2), OPC_ICINV = _OPC(7, 3), OPC_DCCLN = _OPC(7, 4), OPC_DCINV = _OPC(7, 5), diff --git a/src/freedreno/ir3/ir3_lexer.l b/src/freedreno/ir3/ir3_lexer.l index bb969b03c29..7bd6cdfe1a2 100644 --- a/src/freedreno/ir3/ir3_lexer.l +++ b/src/freedreno/ir3/ir3_lexer.l @@ -382,6 +382,7 @@ static int parse_reg(const char *str) /* category 7: */ "bar" return TOKEN(T_OP_BAR); "fence" return TOKEN(T_OP_FENCE); +"sleep.l" return TOKEN(T_OP_SLEEP); "icinv" return TOKEN(T_OP_ICINV); "dccln.all" return TOKEN(T_OP_DCCLN); "dcinv.all" return TOKEN(T_OP_DCINV); diff --git a/src/freedreno/ir3/ir3_parser.y b/src/freedreno/ir3/ir3_parser.y index e0d06d2bcbe..929989115a9 100644 --- a/src/freedreno/ir3/ir3_parser.y +++ b/src/freedreno/ir3/ir3_parser.y @@ -621,6 +621,7 @@ static void print_token(FILE *file, int type, YYSTYPE value) /* category 7: */ %token T_OP_BAR %token T_OP_FENCE +%token T_OP_SLEEP %token T_OP_ICINV %token T_OP_DCCLN %token T_OP_DCINV @@ -1295,6 +1296,7 @@ cat7_data_cache: T_OP_DCCLN { new_instr(OPC_DCCLN); } cat7_instr: cat7_barrier | cat7_data_cache +| T_OP_SLEEP { new_instr(OPC_SLEEP); } | T_OP_ICINV { new_instr(OPC_ICINV); } raw_instr: T_RAW {new_instr(OPC_META_RAW)->raw.value = $1;} diff --git a/src/freedreno/ir3/tests/disasm.c b/src/freedreno/ir3/tests/disasm.c index 277f827716b..c40302c577d 100644 --- a/src/freedreno/ir3/tests/disasm.c +++ b/src/freedreno/ir3/tests/disasm.c @@ -418,6 +418,7 @@ static const struct test { INSTR_6XX(e0fa0000_00000000, "fence.g.l.r.w"), INSTR_6XX(e09a0000_00000000, "fence.r.w"), INSTR_6XX(f0420000_00000000, "(sy)bar.g"), + INSTR_6XX(e1080000_00000000, "sleep.l"), INSTR_6XX(e2080000_00000000, "dccln.all"), INSTR_6XX(ffffffff_ffffffff, "raw 0xFFFFFFFFFFFFFFFF"), diff --git a/src/freedreno/isa/ir3-cat7.xml b/src/freedreno/isa/ir3-cat7.xml index f3fd1b8f097..7b32155fda2 100644 --- a/src/freedreno/isa/ir3-cat7.xml +++ b/src/freedreno/isa/ir3-cat7.xml @@ -80,6 +80,37 @@ SOFTWARE. + + + + Short sleep + + + + + Long sleep, around 20x longer than short + + + + + + + Short/Long Sleep + TODO: how is it different from a bunch of nops? + + + {SY}{JP}{NAME}{DURATION} + + xxxxxx + + xxx + 0010 + + + 1 + + + Seem to be Instruction Cache Invalidate, supported by the fact