summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConnor Abbott <cwabbott0@gmail.com>2020-08-17 20:29:20 +0200
committerMarge Bot <eric+marge@anholt.net>2020-08-18 16:17:31 +0000
commitb2b19234d81fe8fa47ad735c08049e1a6c0d2ce9 (patch)
treea22ec1fc724b657ae9c4ebfa674933326069adf7
parenta2c14ac070b6703d3e395707ab7938aca4fe4fdb (diff)
freedreno/afuc: Add iret
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6368>
-rw-r--r--src/freedreno/afuc/afuc.h5
-rw-r--r--src/freedreno/afuc/asm.c4
-rw-r--r--src/freedreno/afuc/disasm.c7
-rw-r--r--src/freedreno/afuc/lexer.l1
-rw-r--r--src/freedreno/afuc/parser.y2
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
@@ -153,6 +153,11 @@ typedef union PACKED {
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;
} waitin;
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 <tok> T_OP_BRNE
%token <tok> T_OP_BREQ
%token <tok> T_OP_RET
+%token <tok> T_OP_IRET
%token <tok> T_OP_CALL
%token <tok> T_OP_JUMP
%token <tok> 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); }