+#if HAVE_COMPUTED_GOTOS && !(PRVMSLOWINTERPRETER || PRVMTIMEPROFILING)
+ // NOTE: Due to otherwise duplicate labels, only ONE interpreter path may
+ // ever hit this!
+# define USE_COMPUTED_GOTOS 1
+#endif
+
+#if USE_COMPUTED_GOTOS
+ // Must exactly match opcode_e enum in pr_comp.h
+ const static void *dispatchtable[] = {
+ &&handle_OP_DONE,
+ &&handle_OP_MUL_F,
+ &&handle_OP_MUL_V,
+ &&handle_OP_MUL_FV,
+ &&handle_OP_MUL_VF,
+ &&handle_OP_DIV_F,
+ &&handle_OP_ADD_F,
+ &&handle_OP_ADD_V,
+ &&handle_OP_SUB_F,
+ &&handle_OP_SUB_V,
+
+ &&handle_OP_EQ_F,
+ &&handle_OP_EQ_V,
+ &&handle_OP_EQ_S,
+ &&handle_OP_EQ_E,
+ &&handle_OP_EQ_FNC,
+
+ &&handle_OP_NE_F,
+ &&handle_OP_NE_V,
+ &&handle_OP_NE_S,
+ &&handle_OP_NE_E,
+ &&handle_OP_NE_FNC,
+
+ &&handle_OP_LE,
+ &&handle_OP_GE,
+ &&handle_OP_LT,
+ &&handle_OP_GT,
+
+ &&handle_OP_LOAD_F,
+ &&handle_OP_LOAD_V,
+ &&handle_OP_LOAD_S,
+ &&handle_OP_LOAD_ENT,
+ &&handle_OP_LOAD_FLD,
+ &&handle_OP_LOAD_FNC,
+
+ &&handle_OP_ADDRESS,
+
+ &&handle_OP_STORE_F,
+ &&handle_OP_STORE_V,
+ &&handle_OP_STORE_S,
+ &&handle_OP_STORE_ENT,
+ &&handle_OP_STORE_FLD,
+ &&handle_OP_STORE_FNC,
+
+ &&handle_OP_STOREP_F,
+ &&handle_OP_STOREP_V,
+ &&handle_OP_STOREP_S,
+ &&handle_OP_STOREP_ENT,
+ &&handle_OP_STOREP_FLD,
+ &&handle_OP_STOREP_FNC,
+
+ &&handle_OP_RETURN,
+ &&handle_OP_NOT_F,
+ &&handle_OP_NOT_V,
+ &&handle_OP_NOT_S,
+ &&handle_OP_NOT_ENT,
+ &&handle_OP_NOT_FNC,
+ &&handle_OP_IF,
+ &&handle_OP_IFNOT,
+ &&handle_OP_CALL0,
+ &&handle_OP_CALL1,
+ &&handle_OP_CALL2,
+ &&handle_OP_CALL3,
+ &&handle_OP_CALL4,
+ &&handle_OP_CALL5,
+ &&handle_OP_CALL6,
+ &&handle_OP_CALL7,
+ &&handle_OP_CALL8,
+ &&handle_OP_STATE,
+ &&handle_OP_GOTO,
+ &&handle_OP_AND,
+ &&handle_OP_OR,
+
+ &&handle_OP_BITAND,
+ &&handle_OP_BITOR
+ };
+#define DISPATCH_OPCODE() \
+ goto *dispatchtable[(++st)->op]
+#define HANDLE_OPCODE(opcode) handle_##opcode
+
+ DISPATCH_OPCODE(); // jump to first opcode
+#else // USE_COMPUTED_GOTOS
+#define DISPATCH_OPCODE() break
+#define HANDLE_OPCODE(opcode) case opcode
+
+#if PRVMSLOWINTERPRETER
+ {
+ if (prog->watch_global_type != ev_void)
+ {
+ prvm_eval_t *g = PRVM_GLOBALFIELDVALUE(prog->watch_global);
+ prog->xstatement = st + 1 - cached_statements;
+ PRVM_Watchpoint(prog, 1, "Global watchpoint hit by engine", prog->watch_global_type, &prog->watch_global_value, g);
+ }
+ if (prog->watch_field_type != ev_void && prog->watch_edict < prog->max_edicts)
+ {
+ prvm_eval_t *g = PRVM_EDICTFIELDVALUE(prog->edicts + prog->watch_edict, prog->watch_field);
+ prog->xstatement = st + 1 - cached_statements;
+ PRVM_Watchpoint(prog, 1, "Entityfield watchpoint hit by engine", prog->watch_field_type, &prog->watch_edictfield_value, g);
+ }
+ }
+#endif
+