From b2b19234d81fe8fa47ad735c08049e1a6c0d2ce9 Mon Sep 17 00:00:00 2001 From: Connor Abbott Date: Mon, 17 Aug 2020 20:29:20 +0200 Subject: [PATCH] freedreno/afuc: Add iret Part-of: --- src/freedreno/afuc/afuc.h | 5 +++++ src/freedreno/afuc/asm.c | 4 ++++ src/freedreno/afuc/disasm.c | 7 +++++-- src/freedreno/afuc/lexer.l | 1 + src/freedreno/afuc/parser.y | 2 ++ 5 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/freedreno/afuc/afuc.h b/src/freedreno/afuc/afuc.h index a69690a56f2..8233db04402 100644 --- a/src/freedreno/afuc/afuc.h +++ b/src/freedreno/afuc/afuc.h @@ -152,6 +152,11 @@ typedef union PACKED { uint32_t uoff : 26; /* absolute (unsigned) offset */ uint32_t hdr : 6; } call; + struct PACKED { + uint32_t pad : 25; + uint32_t interrupt : 1; /* return from ctxt-switch interrupt handler */ + uint32_t hdr : 6; + } ret; struct PACKED { uint32_t pad : 26; uint32_t hdr : 6; diff --git a/src/freedreno/afuc/asm.c b/src/freedreno/afuc/asm.c index 896a8555cf3..a03a89a31fa 100644 --- a/src/freedreno/afuc/asm.c +++ b/src/freedreno/afuc/asm.c @@ -254,6 +254,10 @@ static void emit_instructions(int outfd) case T_OP_RET: opc = OPC_RET; break; + case T_OP_IRET: + opc = OPC_RET; + instr.ret.interrupt = 1; + break; case T_OP_CALL: opc = OPC_CALL; instr.call.uoff = resolve_label(ai->label); diff --git a/src/freedreno/afuc/disasm.c b/src/freedreno/afuc/disasm.c index 5c86f4327da..f687058f615 100644 --- a/src/freedreno/afuc/disasm.c +++ b/src/freedreno/afuc/disasm.c @@ -656,9 +656,12 @@ static void disasm(uint32_t *buf, int sizedwords) break; case OPC_RET: assert(!rep); - if (instr->pad) + if (instr->ret.pad) printf("[%08x] ; ", instrs[i]); - printf("ret"); + if (instr->ret.interrupt) + printf("iret"); + else + printf("ret"); break; case OPC_WIN: assert(!rep); diff --git a/src/freedreno/afuc/lexer.l b/src/freedreno/afuc/lexer.l index 077ae657d3c..6b1ec07cade 100644 --- a/src/freedreno/afuc/lexer.l +++ b/src/freedreno/afuc/lexer.l @@ -78,6 +78,7 @@ extern YYSTYPE yylval; "brne" return TOKEN(T_OP_BRNE); "breq" return TOKEN(T_OP_BREQ); "ret" return TOKEN(T_OP_RET); +"iret" return TOKEN(T_OP_IRET); "call" return TOKEN(T_OP_CALL); "jump" return TOKEN(T_OP_JUMP); "waitin" return TOKEN(T_OP_WAITIN); diff --git a/src/freedreno/afuc/parser.y b/src/freedreno/afuc/parser.y index 7b2eebd410a..657524a1f6c 100644 --- a/src/freedreno/afuc/parser.y +++ b/src/freedreno/afuc/parser.y @@ -153,6 +153,7 @@ label(const char *str) %token T_OP_BRNE %token T_OP_BREQ %token T_OP_RET +%token T_OP_IRET %token T_OP_CALL %token T_OP_JUMP %token T_OP_WAITIN @@ -248,6 +249,7 @@ other_instr: T_OP_CALL T_LABEL_REF { new_instr($1); label($2); } | T_OP_PREEMPTLEAVE T_LABEL_REF { new_instr($1); label($2); } | T_OP_SETSECURE reg ',' T_LABEL_REF { new_instr($1); src1($2); label($4); } | T_OP_RET { new_instr($1); } +| T_OP_IRET { new_instr($1); } | T_OP_JUMP T_LABEL_REF { new_instr($1); label($2); } | T_OP_WAITIN { new_instr($1); } | T_OP_NOP { new_instr($1); } -- 2.30.2