aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common.h33
-rw-r--r--src/ejit.c184
-rw-r--r--src/interp.c143
3 files changed, 343 insertions, 17 deletions
diff --git a/src/common.h b/src/common.h
index e9f0b69..1e08961 100644
--- a/src/common.h
+++ b/src/common.h
@@ -6,6 +6,7 @@
enum ejit_opcode {
MOVI,
+ MOVI_F,
MOVR,
MOVR_F,
@@ -46,10 +47,6 @@ enum ejit_opcode {
STI16,
STI32,
STI64,
- STIU8,
- STIU16,
- STIU32,
- STIU64,
STIF,
STID,
@@ -57,13 +54,16 @@ enum ejit_opcode {
STXI16,
STXI32,
STXI64,
- STXIU8,
- STXIU16,
- STXIU32,
- STXIU64,
STXIF,
STXID,
+ STXR8,
+ STXR16,
+ STXR32,
+ STXR64,
+ STXRF,
+ STXRD,
+
EXTR8,
EXTR16,
EXTR32,
@@ -88,17 +88,32 @@ enum ejit_opcode {
DIVR_U,
DIVR_F,
- NEGR,
+ REMR,
+ REMR_U,
+
COMR,
+ NEGR,
+ NEGR_F,
LSHI,
LSHR,
RSHI,
+ RSHI_U,
RSHR,
+ RSHR_U,
ANDR,
ANDI,
+ ORR,
+ ORI,
+
+ XORR,
+ XORI,
+
+ TRUNCR_D_32,
+ TRUNCR_D_64,
+
EQR,
NER,
GTR,
diff --git a/src/ejit.c b/src/ejit.c
index 4f407aa..02446ea 100644
--- a/src/ejit.c
+++ b/src/ejit.c
@@ -197,6 +197,36 @@ void ejit_retval_f(struct ejit_func *s, struct ejit_fpr r0)
emit_insn_i(s, RETVAL_F, r0.f, 0, 0);
}
+void ejit_sti_8(struct ejit_func *s, struct ejit_gpr r0, void *p)
+{
+ emit_insn_p(s, STI8, r0.r, 0, p);
+}
+
+void ejit_sti_16(struct ejit_func *s, struct ejit_gpr r0, void *p)
+{
+ emit_insn_p(s, STI16, r0.r, 0, p);
+}
+
+void ejit_sti_32(struct ejit_func *s, struct ejit_gpr r0, void *p)
+{
+ emit_insn_p(s, STI32, r0.r, 0, p);
+}
+
+void ejit_sti_64(struct ejit_func *s, struct ejit_gpr r0, void *p)
+{
+ emit_insn_p(s, STI64, r0.r, 0, p);
+}
+
+void ejit_sti_f(struct ejit_func *s, struct ejit_fpr r0, void *p)
+{
+ emit_insn_p(s, STIF, r0.f, 0, p);
+}
+
+void ejit_sti_d(struct ejit_func *s, struct ejit_fpr r0, void *p)
+{
+ emit_insn_p(s, STID, r0.f, 0, p);
+}
+
void ejit_stxi_8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
@@ -233,6 +263,42 @@ void ejit_stxi_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1,
emit_insn_i(s, STXID, r0.f, r1.r, o);
}
+void ejit_stxr_8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
+{
+ emit_insn_r(s, STXR8, r0.r, r1.r, r2.r);
+}
+
+void ejit_stxr_16(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
+{
+ emit_insn_r(s, STXR16, r0.r, r1.r, r2.r);
+}
+
+void ejit_stxr_32(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
+{
+ emit_insn_r(s, STXR32, r0.r, r1.r, r2.r);
+}
+
+void ejit_stxr_64(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
+{
+ emit_insn_r(s, STXR64, r0.r, r1.r, r2.r);
+}
+
+void ejit_stxr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
+{
+ emit_insn_r(s, STXRF, r0.f, r1.r, r2.r);
+}
+
+void ejit_stxr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
+{
+ emit_insn_r(s, STXRD, r0.f, r1.r, r2.r);
+}
+
void ejit_ldi_i8(struct ejit_func *s, struct ejit_gpr r0, void *p)
{
emit_insn_p(s, LDI8, r0.r, 0, p);
@@ -403,6 +469,11 @@ void ejit_ldxr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_gpr r1,
emit_insn_r(s, LDXRD, r0.f, r1.r, r2.r);
}
+void ejit_ret(struct ejit_func *s)
+{
+ emit_insn_i(s, END, 0, 0, 0);
+}
+
void ejit_retr(struct ejit_func *s, struct ejit_gpr r0)
{
emit_insn_r(s, RETR, r0.r, 0, 0);
@@ -500,6 +571,12 @@ void ejit_mulr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
emit_insn_r(s, MULR, r0.r, r1.r, r2.r);
}
+void ejit_mulr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
+ struct ejit_fpr r2)
+{
+ emit_insn_r(s, MULR_F, r0.f, r1.f, r2.f);
+}
+
void ejit_divr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
@@ -518,6 +595,18 @@ void ejit_divr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
emit_insn_r(s, DIVR_F, r0.f, r1.f, r2.f);
}
+void ejit_remr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
+{
+ emit_insn_r(s, REMR, r0.r, r1.r, r2.r);
+}
+
+void ejit_remr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
+{
+ emit_insn_r(s, REMR_U, r0.r, r1.r, r2.r);
+}
+
void ejit_lshi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
@@ -536,12 +625,24 @@ void ejit_rshi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
emit_insn_i(s, RSHI, r0.r, r1.r, o);
}
+void ejit_rshi_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ int64_t o)
+{
+ emit_insn_i(s, RSHI_U, r0.r, r1.r, o);
+}
+
void ejit_rshr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
emit_insn_r(s, RSHR, r0.r, r1.r, r2.r);
}
+void ejit_rshr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
+{
+ emit_insn_r(s, RSHR_U, r0.r, r1.r, r2.r);
+}
+
void ejit_andr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
@@ -554,6 +655,30 @@ void ejit_andi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
emit_insn_i(s, ANDI, r0.r, r1.r, o);
}
+void ejit_orr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
+{
+ emit_insn_r(s, ORR, r0.r, r1.r, r2.r);
+}
+
+void ejit_ori(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ int64_t o)
+{
+ emit_insn_i(s, ORI, r0.r, r1.r, o);
+}
+
+void ejit_xorr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
+{
+ emit_insn_r(s, XORR, r0.r, r1.r, r2.r);
+}
+
+void ejit_xori(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ int64_t o)
+{
+ emit_insn_i(s, XORI, r0.r, r1.r, o);
+}
+
void ejit_comr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
{
emit_insn_i(s, COMR, r0.r, r1.r, 0);
@@ -564,11 +689,21 @@ void ejit_negr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
emit_insn_i(s, NEGR, r0.r, r1.r, 0);
}
+void ejit_negr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1)
+{
+ emit_insn_i(s, NEGR_F, r0.f, r1.f, 0);
+}
+
void ejit_movi(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
{
emit_insn_i(s, MOVI, r0.r, 0, o);
}
+void ejit_movi_f(struct ejit_func *s, struct ejit_fpr r0, double o)
+{
+ emit_insn_f(s, MOVI_F, r0.f, 0, o);
+}
+
void ejit_movr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
{
if (r0.r == r1.r)
@@ -577,6 +712,14 @@ void ejit_movr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
emit_insn_i(s, MOVR, r0.r, r1.r, 0);
}
+void ejit_movr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1)
+{
+ if (r0.f == r1.f)
+ return;
+
+ emit_insn_i(s, MOVR_F, r0.f, r1.f, 0);
+}
+
void ejit_eqr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
@@ -589,6 +732,18 @@ void ejit_eqr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
emit_insn_r(s, EQR_F, r0.r, r1.f, r2.f);
}
+void ejit_ner(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
+ struct ejit_gpr r2)
+{
+ emit_insn_r(s, NER, r0.r, r1.r, r2.r);
+}
+
+void ejit_ner_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
+ struct ejit_fpr r2)
+{
+ emit_insn_r(s, NER_F, r0.r, r1.f, r2.f);
+}
+
void ejit_gtr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
@@ -610,19 +765,19 @@ void ejit_gtr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
void ejit_ltr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, GER, r0.r, r2.r, r1.r);
+ emit_insn_r(s, GTR, r0.r, r2.r, r1.r);
}
void ejit_ltr_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, GER_U, r0.r, r2.r, r1.r);
+ emit_insn_r(s, GTR_U, r0.r, r2.r, r1.r);
}
void ejit_ltr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
struct ejit_fpr r2)
{
- emit_insn_r(s, GER_F, r0.r, r2.f, r1.f);
+ emit_insn_r(s, GTR_F, r0.r, r2.f, r1.f);
}
void ejit_ger(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
@@ -646,19 +801,31 @@ void ejit_ger_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
void ejit_ler(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, GTR, r0.r, r2.r, r1.r);
+ emit_insn_r(s, GER, r0.r, r2.r, r1.r);
}
void ejit_ler_u(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
- emit_insn_r(s, GTR_U, r0.r, r2.r, r1.r);
+ emit_insn_r(s, GER_U, r0.r, r2.r, r1.r);
}
void ejit_ler_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
struct ejit_fpr r2)
{
- emit_insn_r(s, GTR_F, r0.r, r2.f, r1.f);
+ emit_insn_r(s, GER_F, r0.r, r2.f, r1.f);
+}
+
+void ejit_truncr_d_32(struct ejit_func *s, struct ejit_gpr r0,
+ struct ejit_fpr r1)
+{
+ emit_insn_i(s, TRUNCR_D_32, r0.r, r1.f, 0);
+}
+
+void ejit_truncr_d_64(struct ejit_func *s, struct ejit_gpr r0,
+ struct ejit_fpr r1)
+{
+ emit_insn_i(s, TRUNCR_D_64, r0.r, r1.f, 0);
}
struct ejit_reloc ejit_bner(struct ejit_func *s, struct ejit_gpr r0,
@@ -942,12 +1109,13 @@ long ejit_run_interp(struct ejit_func *f, size_t argc,
return ejit_interp(f, argc, args, state, true, NULL).r;
}
-long ejit_run_func(struct ejit_func *f, size_t argc, struct ejit_arg args[argc])
+int64_t ejit_run_func(struct ejit_func *f, size_t argc,
+ struct ejit_arg args[argc])
{
assert(f->size && "trying to run a function that hasn't been compiled");
assert(f->rtype == EJIT_VOID || ejit_int_type(f->rtype));
if (f->arena)
- return ((ejit_escape_t)f->arena)(argc, args);
+ return (int64_t)((ejit_escape_t)f->arena)(argc, args);
struct interp_state state = create_interp_state();
long r = ejit_interp(f, argc, args, &state, true, NULL).r;
diff --git a/src/interp.c b/src/interp.c
index 30a7672..a86b754 100644
--- a/src/interp.c
+++ b/src/interp.c
@@ -10,6 +10,7 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
{
static void *labels[OPCODE_COUNT] = {
[MOVI] = &&MOVI,
+ [MOVI_F] = &&MOVI_F,
[MOVR] = &&MOVR,
[MOVR_F] = &&MOVR_F,
@@ -31,21 +32,34 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
[SUBI] = &&SUBI,
[MULR] = &&MULR,
+ [MULR_F] = &&MULR_F,
[DIVR] = &&DIVR,
[DIVR_U] = &&DIVR_U,
[DIVR_F] = &&DIVR_F,
+ [REMR] = &&REMR,
+ [REMR_U] = &&REMR_U,
+
[LSHI] = &&LSHI,
[LSHR] = &&LSHR,
[RSHI] = &&RSHI,
[RSHR] = &&RSHR,
+ [RSHI_U] = &&RSHI_U,
+ [RSHR_U] = &&RSHR_U,
[ANDR] = &&ANDR,
[ANDI] = &&ANDI,
+ [ORR] = &&ORR,
+ [ORI] = &&ORI,
+
+ [XORR] = &&XORR,
+ [XORI] = &&XORI,
+
[COMR] = &&COMR,
[NEGR] = &&NEGR,
+ [NEGR_F] = &&NEGR_F,
[EQR] = &&EQR,
[EQR_F] = &&EQR_F,
@@ -61,6 +75,13 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
[GER_U] = &&GER_U,
[GER_F] = &&GER_F,
+ [STI8] = &&STI8,
+ [STI16] = &&STI16,
+ [STI32] = &&STI32,
+ [STI64] = &&STI64,
+ [STIF] = &&STIF,
+ [STID] = &&STID,
+
[STXI8] = &&STXI8,
[STXI16] = &&STXI16,
[STXI32] = &&STXI32,
@@ -68,6 +89,13 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
[STXIF] = &&STXIF,
[STXID] = &&STXID,
+ [STXR8] = &&STXR8,
+ [STXR16] = &&STXR16,
+ [STXR32] = &&STXR32,
+ [STXR64] = &&STXR64,
+ [STXRF] = &&STXRF,
+ [STXRD] = &&STXRD,
+
[LDI8] = &&LDI8,
[LDI16] = &&LDI16,
[LDI32] = &&LDI32,
@@ -101,6 +129,9 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
[LDXRF] = &&LDXRF,
[LDXRD] = &&LDXRD,
+ [TRUNCR_D_32] = &&TRUNCR_D_32,
+ [TRUNCR_D_64] = &&TRUNCR_D_64,
+
[BNER] = &&BNER,
[BNEI] = &&BNEI,
[BNER_F] = &&BNER_F,
@@ -202,6 +233,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
gpr[i.r0] = i.o;
DISPATCH();
+ DO(MOVI_F);
+ fpr[i.r0] = i.d;
+ DISPATCH();
+
DO(MOVR);
gpr[i.r0] = gpr[i.r1];
DISPATCH();
@@ -266,6 +301,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
gpr[i.r0] = gpr[i.r1] * gpr[i.r2];
DISPATCH();
+ DO(MULR_F);
+ fpr[i.r0] = fpr[i.r1] * fpr[i.r2];
+ DISPATCH();
+
DO(DIVR);
gpr[i.r0] = gpr[i.r1] / gpr[i.r2];
DISPATCH();
@@ -274,6 +313,14 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
gpr[i.r0] = (uint64_t)gpr[i.r1] / (uint64_t)gpr[i.r2];
DISPATCH();
+ DO(REMR);
+ gpr[i.r0] = gpr[i.r1] % gpr[i.r2];
+ DISPATCH();
+
+ DO(REMR_U);
+ gpr[i.r0] = (uint64_t)gpr[i.r1] % (uint64_t)gpr[i.r2];
+ DISPATCH();
+
DO(DIVR_F);
fpr[i.r0] = fpr[i.r1] / fpr[i.r2];
DISPATCH();
@@ -294,6 +341,14 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
gpr[i.r0] = gpr[i.r1] >> gpr[i.r2];
DISPATCH();
+ DO(RSHI_U);
+ gpr[i.r0] = (uint64_t)gpr[i.r1] >> i.o;
+ DISPATCH();
+
+ DO(RSHR_U);
+ gpr[i.r0] = (uint64_t)gpr[i.r1] >> gpr[i.r2];
+ DISPATCH();
+
DO(ANDR);
gpr[i.r0] = gpr[i.r1] & gpr[i.r2];
DISPATCH();
@@ -302,6 +357,22 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
gpr[i.r0] = gpr[i.r1] & i.o;
DISPATCH();
+ DO(ORR);
+ gpr[i.r0] = gpr[i.r1] | gpr[i.r2];
+ DISPATCH();
+
+ DO(ORI);
+ gpr[i.r0] = gpr[i.r1] | i.o;
+ DISPATCH();
+
+ DO(XORR);
+ gpr[i.r0] = gpr[i.r1] ^ gpr[i.r2];
+ DISPATCH();
+
+ DO(XORI);
+ gpr[i.r0] = gpr[i.r1] ^ i.o;
+ DISPATCH();
+
DO(COMR);
gpr[i.r0] = ~gpr[i.r1];
DISPATCH();
@@ -310,6 +381,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
gpr[i.r0] = -gpr[i.r1];
DISPATCH();
+ DO(NEGR_F);
+ fpr[i.r0] = -fpr[i.r1];
+ DISPATCH();
+
DO(EQR);
gpr[i.r0] = gpr[i.r1] == gpr[i.r2];
DISPATCH();
@@ -350,6 +425,36 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
gpr[i.r0] = fpr[i.r1] >= fpr[i.r2];
DISPATCH();
+ DO(STI8);
+ int8_t *addr = (int8_t *)(i.p);
+ *addr = gpr[i.r0];
+ DISPATCH();
+
+ DO(STI16);
+ int16_t *addr = (int16_t *)(i.p);
+ *addr = gpr[i.r0];
+ DISPATCH();
+
+ DO(STI32);
+ int32_t *addr = (int32_t *)(i.p);
+ *addr = gpr[i.r0];
+ DISPATCH();
+
+ DO(STI64);
+ int64_t *addr = (int64_t *)(i.p);
+ *addr = gpr[i.r0];
+ DISPATCH();
+
+ DO(STIF);
+ float *addr = (float *)(i.p);
+ *addr = fpr[i.r0];
+ DISPATCH();
+
+ DO(STID);
+ double *addr = (double *)(i.p);
+ *addr = fpr[i.r0];
+ DISPATCH();
+
DO(STXI8);
int8_t *addr = (int8_t *)(gpr[i.r1] + i.o);
*addr = gpr[i.r0];
@@ -380,6 +485,36 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
*addr = fpr[i.r0];
DISPATCH();
+ DO(STXR8);
+ int8_t *addr = (int8_t *)(gpr[i.r1] + gpr[i.r2]);
+ *addr = gpr[i.r0];
+ DISPATCH();
+
+ DO(STXR16);
+ int16_t *addr = (int16_t *)(gpr[i.r1] + gpr[i.r2]);
+ *addr = gpr[i.r0];
+ DISPATCH();
+
+ DO(STXR32);
+ int32_t *addr = (int32_t *)(gpr[i.r1] + gpr[i.r2]);
+ *addr = gpr[i.r0];
+ DISPATCH();
+
+ DO(STXR64);
+ int64_t *addr = (int64_t *)(gpr[i.r1] + gpr[i.r2]);
+ *addr = gpr[i.r0];
+ DISPATCH();
+
+ DO(STXRF);
+ float *addr = (float *)(gpr[i.r1] + gpr[i.r2]);
+ *addr = fpr[i.r0];
+ DISPATCH();
+
+ DO(STXRD);
+ double *addr = (double *)(gpr[i.r1] + gpr[i.r2]);
+ *addr = fpr[i.r0];
+ DISPATCH();
+
DO(LDI8);
int8_t *addr = (int8_t *)i.p;
gpr[i.r0] = *addr;
@@ -530,6 +665,14 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
fpr[i.r0] = *addr;
DISPATCH();
+ DO(TRUNCR_D_32);
+ gpr[i.r0] = (int32_t)fpr[i.r1];
+ DISPATCH();
+
+ DO(TRUNCR_D_64);
+ gpr[i.r0] = (int64_t)fpr[i.r1];
+ DISPATCH();
+
DO(BNER);
if (gpr[i.r1] != gpr[i.r2])
JUMP(i.r0);