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;
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);
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);
"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);
%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
| 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); }