freedreno/afuc: Add iret
authorConnor Abbott <cwabbott0@gmail.com>
Mon, 17 Aug 2020 18:29:20 +0000 (20:29 +0200)
committerMarge Bot <eric+marge@anholt.net>
Tue, 18 Aug 2020 16:17:31 +0000 (16:17 +0000)
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6368>

src/freedreno/afuc/afuc.h
src/freedreno/afuc/asm.c
src/freedreno/afuc/disasm.c
src/freedreno/afuc/lexer.l
src/freedreno/afuc/parser.y

index a69690a56f29b39526ce7f77173090d078d8a78a..8233db044026f76e044c5166921b470ebd9e1a72 100644 (file)
@@ -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;
index 896a8555cf3d49f875cc7354cff1297acf8e1479..a03a89a31fa33621a0a1bcf5ec88b3e933fcd34c 100644 (file)
@@ -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);
index 5c86f4327dabd8c4ee9f8aaf77df1c6064785827..f687058f615edfe77d550e3ca9baf288d98005cb 100644 (file)
@@ -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);
index 077ae657d3cd514c14eee15023ee6e51a796411b..6b1ec07caded76bf073699eea89a2be26b08b369 100644 (file)
@@ -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);
index 7b2eebd410a8777f6994924efc72c775f1b071ae..657524a1f6ccfa54f301b8f36be3063b259f3060 100644 (file)
@@ -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); }