aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common.h24
-rw-r--r--src/ejit.c158
-rw-r--r--src/interp.c220
3 files changed, 338 insertions, 64 deletions
diff --git a/src/common.h b/src/common.h
index 1e08961..c646288 100644
--- a/src/common.h
+++ b/src/common.h
@@ -7,8 +7,10 @@
enum ejit_opcode {
MOVI,
MOVI_F,
+ MOVI_D,
MOVR,
MOVR_F,
+ MOVR_D,
LDI8,
LDI16,
@@ -73,20 +75,25 @@ enum ejit_opcode {
ADDR,
ADDR_F,
+ ADDR_D,
ADDI,
ABSR_F,
+ ABSR_D,
SUBR,
SUBR_F,
+ SUBR_D,
SUBI,
MULR,
MULR_F,
+ MULR_D,
DIVR,
DIVR_U,
DIVR_F,
+ DIVR_D,
REMR,
REMR_U,
@@ -94,6 +101,7 @@ enum ejit_opcode {
COMR,
NEGR,
NEGR_F,
+ NEGR_D,
LSHI,
LSHR,
@@ -113,6 +121,8 @@ enum ejit_opcode {
TRUNCR_D_32,
TRUNCR_D_64,
+ TRUNCR_F_32,
+ TRUNCR_F_64,
EQR,
NER,
@@ -125,20 +135,27 @@ enum ejit_opcode {
NER_F,
GTR_F,
GER_F,
+ EQR_D,
+ NER_D,
+ GTR_D,
+ GER_D,
BNER,
BNEI,
BNER_F,
+ BNER_D,
BEQR,
BEQI,
BEQR_F,
+ BEQR_D,
BGER,
BGER_U,
BGEI,
BGEI_U,
BGER_F,
+ BGER_D,
BLEI,
BLEI_U,
@@ -148,12 +165,11 @@ enum ejit_opcode {
BGTI,
BGTI_U,
BGTR_F,
+ BGTR_D,
BLTI,
BLTI_U,
- BLTGTR_F,
-
JMP,
JMPR,
@@ -179,10 +195,13 @@ enum ejit_opcode {
RETR,
RETI,
RETR_F,
+ RETR_D,
RETI_F,
+ RETI_D,
RETVAL,
RETVAL_F,
+ RETVAL_D,
START,
END,
@@ -203,6 +222,7 @@ struct ejit_insn {
void *p;
int64_t o;
double d;
+ float f;
};
};
diff --git a/src/ejit.c b/src/ejit.c
index 02446ea..c6b8f72 100644
--- a/src/ejit.c
+++ b/src/ejit.c
@@ -27,6 +27,13 @@ static void emit_insn_p(struct ejit_func *f, enum ejit_opcode op, size_t r0,
}
static void emit_insn_f(struct ejit_func *f, enum ejit_opcode op, size_t r0,
+ size_t r1, float d)
+{
+ struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .f = d};
+ vec_append(&f->insns, &i);
+}
+
+static void emit_insn_d(struct ejit_func *f, enum ejit_opcode op, size_t r0,
size_t r1, double d)
{
struct ejit_insn i = {.op = op, .r0 = r0, .r1 = r1, .d = d};
@@ -484,16 +491,26 @@ void ejit_retr_f(struct ejit_func *s, struct ejit_fpr r0)
emit_insn_r(s, RETR_F, r0.f, 0, 0);
}
+void ejit_retr_d(struct ejit_func *s, struct ejit_fpr r0)
+{
+ emit_insn_r(s, RETR_D, r0.f, 0, 0);
+}
+
void ejit_reti(struct ejit_func *s, int64_t i)
{
emit_insn_i(s, RETI, 0, 0, i);
}
-void ejit_reti_f(struct ejit_func *s, double f)
+void ejit_reti_f(struct ejit_func *s, float f)
{
emit_insn_f(s, RETI_F, 0, 0, f);
}
+void ejit_reti_d(struct ejit_func *s, double f)
+{
+ emit_insn_d(s, RETI_F, 0, 0, f);
+}
+
void ejit_extr_8(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
{
emit_insn_i(s, EXTR8, r0.r, r1.r, 0);
@@ -536,6 +553,12 @@ void ejit_addr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
emit_insn_r(s, ADDR_F, r0.f, r1.f, r2.f);
}
+void ejit_addr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
+ struct ejit_fpr r2)
+{
+ emit_insn_r(s, ADDR_D, r0.f, r1.f, r2.f);
+}
+
void ejit_addi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
int64_t o)
{
@@ -547,6 +570,11 @@ void ejit_absr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1)
emit_insn_i(s, ABSR_F, r0.f, r1.f, 0);
}
+void ejit_absr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1)
+{
+ emit_insn_i(s, ABSR_D, r0.f, r1.f, 0);
+}
+
void ejit_subr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
@@ -559,6 +587,12 @@ void ejit_subr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
emit_insn_r(s, SUBR_F, r0.f, r1.f, r2.f);
}
+void ejit_subr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
+ struct ejit_fpr r2)
+{
+ emit_insn_r(s, SUBR_D, r0.f, r1.f, r2.f);
+}
+
void ejit_subi(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
long o)
{
@@ -577,6 +611,12 @@ void ejit_mulr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
emit_insn_r(s, MULR_F, r0.f, r1.f, r2.f);
}
+void ejit_mulr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
+ struct ejit_fpr r2)
+{
+ emit_insn_r(s, MULR_D, 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)
{
@@ -595,6 +635,12 @@ 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_divr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1,
+ struct ejit_fpr r2)
+{
+ emit_insn_r(s, DIVR_D, 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)
{
@@ -694,16 +740,26 @@ 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_negr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1)
+{
+ emit_insn_i(s, NEGR_D, 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)
+void ejit_movi_f(struct ejit_func *s, struct ejit_fpr r0, float o)
{
emit_insn_f(s, MOVI_F, r0.f, 0, o);
}
+void ejit_movi_d(struct ejit_func *s, struct ejit_fpr r0, double o)
+{
+ emit_insn_d(s, MOVI_D, r0.f, 0, o);
+}
+
void ejit_movr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1)
{
if (r0.r == r1.r)
@@ -720,6 +776,14 @@ void ejit_movr_f(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1)
emit_insn_i(s, MOVR_F, r0.f, r1.f, 0);
}
+void ejit_movr_d(struct ejit_func *s, struct ejit_fpr r0, struct ejit_fpr r1)
+{
+ if (r0.f == r1.f)
+ return;
+
+ emit_insn_i(s, MOVR_D, r0.f, r1.f, 0);
+}
+
void ejit_eqr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
@@ -732,6 +796,12 @@ 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_eqr_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
+ struct ejit_fpr r2)
+{
+ emit_insn_r(s, EQR_D, 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)
{
@@ -744,6 +814,12 @@ void ejit_ner_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
emit_insn_r(s, NER_F, r0.r, r1.f, r2.f);
}
+void ejit_ner_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
+ struct ejit_fpr r2)
+{
+ emit_insn_r(s, NER_D, 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)
{
@@ -762,6 +838,12 @@ void ejit_gtr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
emit_insn_r(s, GTR_F, r0.r, r1.f, r2.f);
}
+void ejit_gtr_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
+ struct ejit_fpr r2)
+{
+ emit_insn_r(s, GTR_D, r0.r, r1.f, r2.f);
+}
+
void ejit_ltr(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
@@ -780,6 +862,12 @@ void ejit_ltr_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
emit_insn_r(s, GTR_F, r0.r, r2.f, r1.f);
}
+void ejit_ltr_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
+ struct ejit_fpr r2)
+{
+ emit_insn_r(s, GTR_D, r0.r, r2.f, r1.f);
+}
+
void ejit_ger(struct ejit_func *s, struct ejit_gpr r0, struct ejit_gpr r1,
struct ejit_gpr r2)
{
@@ -816,6 +904,12 @@ void ejit_ler_f(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
emit_insn_r(s, GER_F, r0.r, r2.f, r1.f);
}
+void ejit_ler_d(struct ejit_func *s, struct ejit_gpr r0, struct ejit_fpr r1,
+ struct ejit_fpr r2)
+{
+ emit_insn_r(s, GER_D, r0.r, r2.f, r1.f);
+}
+
void ejit_truncr_d_32(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_fpr r1)
{
@@ -828,6 +922,18 @@ void ejit_truncr_d_64(struct ejit_func *s, struct ejit_gpr r0,
emit_insn_i(s, TRUNCR_D_64, r0.r, r1.f, 0);
}
+void ejit_truncr_f_32(struct ejit_func *s, struct ejit_gpr r0,
+ struct ejit_fpr r1)
+{
+ emit_insn_i(s, TRUNCR_F_32, r0.r, r1.f, 0);
+}
+
+void ejit_truncr_f_64(struct ejit_func *s, struct ejit_gpr r0,
+ struct ejit_fpr r1)
+{
+ emit_insn_i(s, TRUNCR_F_64, r0.r, r1.f, 0);
+}
+
struct ejit_reloc ejit_bner(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
@@ -851,6 +957,14 @@ struct ejit_reloc ejit_bner_f(struct ejit_func *s, struct ejit_fpr r0,
return (struct ejit_reloc){.insn = addr};
}
+struct ejit_reloc ejit_bner_d(struct ejit_func *s, struct ejit_fpr r0,
+ struct ejit_fpr r1)
+{
+ size_t addr = vec_len(&s->insns);
+ emit_insn_r(s, BNER_D, 0, r0.f, r1.f);
+ return (struct ejit_reloc){.insn = addr};
+}
+
struct ejit_reloc ejit_beqr(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
@@ -874,6 +988,14 @@ struct ejit_reloc ejit_beqr_f(struct ejit_func *s, struct ejit_fpr r0,
return (struct ejit_reloc){.insn = addr};
}
+struct ejit_reloc ejit_beqr_d(struct ejit_func *s, struct ejit_fpr r0,
+ struct ejit_fpr r1)
+{
+ size_t addr = vec_len(&s->insns);
+ emit_insn_r(s, BEQR_D, 0, r0.f, r1.f);
+ return (struct ejit_reloc){.insn = addr};
+}
+
struct ejit_reloc ejit_bger(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
@@ -937,6 +1059,14 @@ struct ejit_reloc ejit_bler_f(struct ejit_func *s, struct ejit_fpr r0,
return (struct ejit_reloc){.insn = addr};
}
+struct ejit_reloc ejit_bler_d(struct ejit_func *s, struct ejit_fpr r0,
+ struct ejit_fpr r1)
+{
+ size_t addr = vec_len(&s->insns);
+ emit_insn_r(s, BGER_D, 0, r1.f, r0.f);
+ return (struct ejit_reloc){.insn = addr};
+}
+
struct ejit_reloc ejit_blei(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
{
size_t addr = vec_len(&s->insns);
@@ -991,6 +1121,14 @@ struct ejit_reloc ejit_bgtr_f(struct ejit_func *s, struct ejit_fpr r0,
return (struct ejit_reloc){.insn = addr};
}
+struct ejit_reloc ejit_bgtr_d(struct ejit_func *s, struct ejit_fpr r0,
+ struct ejit_fpr r1)
+{
+ size_t addr = vec_len(&s->insns);
+ emit_insn_r(s, BGTR_D, 0, r0.f, r1.f);
+ return (struct ejit_reloc){.insn = addr};
+}
+
struct ejit_reloc ejit_bltr(struct ejit_func *s, struct ejit_gpr r0,
struct ejit_gpr r1)
{
@@ -1015,26 +1153,26 @@ struct ejit_reloc ejit_bltr_f(struct ejit_func *s, struct ejit_fpr r0,
return (struct ejit_reloc){.insn = addr};
}
-struct ejit_reloc ejit_blti(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
+struct ejit_reloc ejit_bltr_d(struct ejit_func *s, struct ejit_fpr r0,
+ struct ejit_fpr r1)
{
size_t addr = vec_len(&s->insns);
- emit_insn_i(s, BLTI, 0, r0.r, o);
+ emit_insn_r(s, BGTR_D, 0, r1.f, r0.f);
return (struct ejit_reloc){.insn = addr};
}
-struct ejit_reloc ejit_blti_u(struct ejit_func *s, struct ejit_gpr r0,
- int64_t o)
+struct ejit_reloc ejit_blti(struct ejit_func *s, struct ejit_gpr r0, int64_t o)
{
size_t addr = vec_len(&s->insns);
- emit_insn_i(s, BLTI_U, 0, r0.r, o);
+ emit_insn_i(s, BLTI, 0, r0.r, o);
return (struct ejit_reloc){.insn = addr};
}
-struct ejit_reloc ejit_bltgtr_f(struct ejit_func *s, struct ejit_fpr r0,
- struct ejit_fpr r1)
+struct ejit_reloc ejit_blti_u(struct ejit_func *s, struct ejit_gpr r0,
+ int64_t o)
{
size_t addr = vec_len(&s->insns);
- emit_insn_r(s, BLTGTR_F, 0, r0.f, r1.f);
+ emit_insn_i(s, BLTI_U, 0, r0.r, o);
return (struct ejit_reloc){.insn = addr};
}
diff --git a/src/interp.c b/src/interp.c
index 8462112..293da46 100644
--- a/src/interp.c
+++ b/src/interp.c
@@ -11,8 +11,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
static void *labels[OPCODE_COUNT] = {
[MOVI] = &&MOVI,
[MOVI_F] = &&MOVI_F,
+ [MOVI_D] = &&MOVI_D,
[MOVR] = &&MOVR,
[MOVR_F] = &&MOVR_F,
+ [MOVR_D] = &&MOVR_D,
[EXTR8] = &&EXTR8,
[EXTR16] = &&EXTR16,
@@ -23,20 +25,25 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
[ADDR] = &&ADDR,
[ADDR_F] = &&ADDR_F,
+ [ADDR_D] = &&ADDR_D,
[ADDI] = &&ADDI,
[ABSR_F] = &&ABSR_F,
+ [ABSR_D] = &&ABSR_D,
[SUBR] = &&SUBR,
[SUBR_F] = &&SUBR_F,
+ [SUBR_D] = &&SUBR_D,
[SUBI] = &&SUBI,
[MULR] = &&MULR,
[MULR_F] = &&MULR_F,
+ [MULR_D] = &&MULR_D,
[DIVR] = &&DIVR,
[DIVR_U] = &&DIVR_U,
[DIVR_F] = &&DIVR_F,
+ [DIVR_D] = &&DIVR_D,
[REMR] = &&REMR,
[REMR_U] = &&REMR_U,
@@ -60,20 +67,25 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
[COMR] = &&COMR,
[NEGR] = &&NEGR,
[NEGR_F] = &&NEGR_F,
+ [NEGR_D] = &&NEGR_D,
[EQR] = &&EQR,
[EQR_F] = &&EQR_F,
+ [EQR_D] = &&EQR_D,
[NER] = &&NER,
[NER_F] = &&NER_F,
+ [NER_D] = &&NER_D,
[GTR] = &&GTR,
[GTR_U] = &&GTR_U,
[GTR_F] = &&GTR_F,
+ [GTR_D] = &&GTR_D,
[GER] = &&GER,
[GER_U] = &&GER_U,
[GER_F] = &&GER_F,
+ [GER_D] = &&GER_D,
[STI8] = &&STI8,
[STI16] = &&STI16,
@@ -131,20 +143,25 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
[TRUNCR_D_32] = &&TRUNCR_D_32,
[TRUNCR_D_64] = &&TRUNCR_D_64,
+ [TRUNCR_F_32] = &&TRUNCR_F_32,
+ [TRUNCR_F_64] = &&TRUNCR_F_64,
[BNER] = &&BNER,
[BNEI] = &&BNEI,
[BNER_F] = &&BNER_F,
+ [BNER_D] = &&BNER_D,
[BEQR] = &&BEQR,
[BEQI] = &&BEQI,
[BEQR_F] = &&BEQR_F,
+ [BEQR_D] = &&BEQR_D,
[BGER] = &&BGER,
[BGER_U] = &&BGER_U,
[BGEI] = &&BGEI,
[BGEI_U] = &&BGEI_U,
[BGER_F] = &&BGER_F,
+ [BGER_D] = &&BGER_D,
[BLEI] = &&BLEI,
[BLEI_U] = &&BLEI_U,
@@ -154,12 +171,11 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
[BGTI] = &&BGTI,
[BGTI_U] = &&BGTI_U,
[BGTR_F] = &&BGTR_F,
+ [BGTR_D] = &&BGTR_D,
[BLTI] = &&BLTI,
[BLTI_U] = &&BLTI_U,
- [BLTGTR_F] = &&BLTGTR_F,
-
[JMP] = &&JMP,
[JMPR] = &&JMPR,
@@ -172,9 +188,12 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
[RETI] = &&RETI,
[RETR_F] = &&RETR_F,
[RETI_F] = &&RETI_F,
+ [RETR_D] = &&RETR_D,
+ [RETI_D] = &&RETI_D,
[RETVAL] = &&RETVAL,
[RETVAL_F] = &&RETVAL_F,
+ [RETVAL_D] = &&RETVAL_D,
[ARG] = &&ARG,
[ARG_I] = &&ARG_I,
@@ -205,8 +224,12 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
vec_reserve(&state->gprs, prev_gprs + f->gpr);
vec_reserve(&state->fprs, prev_fprs + f->fpr);
+ union fpr {
+ double d;
+ float f;
+ };
long *gpr = ((long *)state->gprs.buf) + prev_gprs;
- double *fpr = ((double *)state->fprs.buf) + prev_fprs;
+ union fpr *fpr = ((union fpr *)state->fprs.buf) + prev_fprs;
struct ejit_insn *insns = f->insns.buf;
@@ -234,7 +257,11 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(MOVI_F);
- fpr[i.r0] = i.d;
+ fpr[i.r0].f = i.f;
+ DISPATCH();
+
+ DO(MOVI_D);
+ fpr[i.r0].d = i.d;
DISPATCH();
DO(MOVR);
@@ -242,7 +269,11 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(MOVR_F);
- fpr[i.r0] = fpr[i.r1];
+ fpr[i.r0].f = fpr[i.r1].f;
+ DISPATCH();
+
+ DO(MOVR_D);
+ fpr[i.r0].d = fpr[i.r1].d;
DISPATCH();
DO(EXTR8);
@@ -274,7 +305,11 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(ADDR_F);
- fpr[i.r0] = fpr[i.r1] + fpr[i.r2];
+ fpr[i.r0].f = fpr[i.r1].f + fpr[i.r2].f;
+ DISPATCH();
+
+ DO(ADDR_D);
+ fpr[i.r0].d = fpr[i.r1].d + fpr[i.r2].d;
DISPATCH();
DO(ADDI);
@@ -282,7 +317,11 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(ABSR_F);
- fpr[i.r0] = fabs(fpr[i.r1]);
+ fpr[i.r0].f = fabs(fpr[i.r1].f);
+ DISPATCH();
+
+ DO(ABSR_D);
+ fpr[i.r0].d = fabs(fpr[i.r1].d);
DISPATCH();
DO(SUBR);
@@ -290,7 +329,11 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(SUBR_F);
- fpr[i.r0] = fpr[i.r1] - fpr[i.r2];
+ fpr[i.r0].f = fpr[i.r1].f - fpr[i.r2].f;
+ DISPATCH();
+
+ DO(SUBR_D);
+ fpr[i.r0].d = fpr[i.r1].d - fpr[i.r2].d;
DISPATCH();
DO(SUBI);
@@ -302,7 +345,11 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(MULR_F);
- fpr[i.r0] = fpr[i.r1] * fpr[i.r2];
+ fpr[i.r0].f = fpr[i.r1].f * fpr[i.r2].f;
+ DISPATCH();
+
+ DO(MULR_D);
+ fpr[i.r0].d = fpr[i.r1].d * fpr[i.r2].d;
DISPATCH();
DO(DIVR);
@@ -322,7 +369,11 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(DIVR_F);
- fpr[i.r0] = fpr[i.r1] / fpr[i.r2];
+ fpr[i.r0].f = fpr[i.r1].f / fpr[i.r2].f;
+ DISPATCH();
+
+ DO(DIVR_D);
+ fpr[i.r0].d = fpr[i.r1].d / fpr[i.r2].d;
DISPATCH();
DO(LSHI);
@@ -382,7 +433,11 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(NEGR_F);
- fpr[i.r0] = -fpr[i.r1];
+ fpr[i.r0].f = -fpr[i.r1].f;
+ DISPATCH();
+
+ DO(NEGR_D);
+ fpr[i.r0].d = -fpr[i.r1].d;
DISPATCH();
DO(EQR);
@@ -390,7 +445,11 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(EQR_F);
- gpr[i.r0] = fpr[i.r1] == fpr[i.r2];
+ gpr[i.r0] = fpr[i.r1].f == fpr[i.r2].f;
+ DISPATCH();
+
+ DO(EQR_D);
+ gpr[i.r0] = fpr[i.r1].d == fpr[i.r2].d;
DISPATCH();
DO(NER);
@@ -398,7 +457,11 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(NER_F);
- gpr[i.r0] = fpr[i.r1] != fpr[i.r2];
+ gpr[i.r0] = fpr[i.r1].f != fpr[i.r2].f;
+ DISPATCH();
+
+ DO(NER_D);
+ gpr[i.r0] = fpr[i.r1].d != fpr[i.r2].d;
DISPATCH();
DO(GTR);
@@ -410,7 +473,11 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(GTR_F);
- gpr[i.r0] = fpr[i.r1] > fpr[i.r2];
+ gpr[i.r0] = fpr[i.r1].f > fpr[i.r2].f;
+ DISPATCH();
+
+ DO(GTR_D);
+ gpr[i.r0] = fpr[i.r1].d > fpr[i.r2].d;
DISPATCH();
DO(GER);
@@ -422,7 +489,11 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(GER_F);
- gpr[i.r0] = fpr[i.r1] >= fpr[i.r2];
+ gpr[i.r0] = fpr[i.r1].f >= fpr[i.r2].f;
+ DISPATCH();
+
+ DO(GER_D);
+ gpr[i.r0] = fpr[i.r1].d >= fpr[i.r2].d;
DISPATCH();
DO(STI8);
@@ -447,12 +518,12 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DO(STIF);
float *addr = (float *)(i.p);
- *addr = fpr[i.r0];
+ *addr = fpr[i.r0].f;
DISPATCH();
DO(STID);
double *addr = (double *)(i.p);
- *addr = fpr[i.r0];
+ *addr = fpr[i.r0].d;
DISPATCH();
DO(STXI8);
@@ -477,12 +548,12 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DO(STXIF);
float *addr = (float *)(gpr[i.r1] + i.o);
- *addr = fpr[i.r0];
+ *addr = fpr[i.r0].f;
DISPATCH();
DO(STXID);
double *addr = (double *)(gpr[i.r1] + i.o);
- *addr = fpr[i.r0];
+ *addr = fpr[i.r0].d;
DISPATCH();
DO(STXR8);
@@ -507,12 +578,12 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DO(STXRF);
float *addr = (float *)(gpr[i.r1] + gpr[i.r2]);
- *addr = fpr[i.r0];
+ *addr = fpr[i.r0].f;
DISPATCH();
DO(STXRD);
double *addr = (double *)(gpr[i.r1] + gpr[i.r2]);
- *addr = fpr[i.r0];
+ *addr = fpr[i.r0].d;
DISPATCH();
DO(LDI8);
@@ -557,12 +628,12 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DO(LDIF);
float *addr = (float *)i.p;
- fpr[i.r0] = *addr;
+ fpr[i.r0].f = *addr;
DISPATCH();
DO(LDID);
double *addr = (double *)i.p;
- fpr[i.r0] = *addr;
+ fpr[i.r0].d = *addr;
DISPATCH();
DO(LDXI8);
@@ -607,12 +678,12 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DO(LDXIF);
float *addr = (float *)(gpr[i.r1] + i.o);
- fpr[i.r0] = *addr;
+ fpr[i.r0].f = *addr;
DISPATCH();
DO(LDXID);
double *addr = (double *)(gpr[i.r1] + i.o);
- fpr[i.r0] = *addr;
+ fpr[i.r0].d = *addr;
DISPATCH();
DO(LDXR8);
@@ -657,20 +728,28 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DO(LDXRF);
float *addr = (float *)(gpr[i.r1] + gpr[i.r2]);
- fpr[i.r0] = *addr;
+ fpr[i.r0].f = *addr;
DISPATCH();
DO(LDXRD);
double *addr = (double *)(gpr[i.r1] + gpr[i.r2]);
- fpr[i.r0] = *addr;
+ fpr[i.r0].d = *addr;
DISPATCH();
DO(TRUNCR_D_32);
- gpr[i.r0] = (int32_t)fpr[i.r1];
+ gpr[i.r0] = (int32_t)fpr[i.r1].d;
DISPATCH();
DO(TRUNCR_D_64);
- gpr[i.r0] = (int64_t)fpr[i.r1];
+ gpr[i.r0] = (int64_t)fpr[i.r1].d;
+ DISPATCH();
+
+ DO(TRUNCR_F_32);
+ gpr[i.r0] = (int32_t)fpr[i.r1].f;
+ DISPATCH();
+
+ DO(TRUNCR_F_64);
+ gpr[i.r0] = (int64_t)fpr[i.r1].f;
DISPATCH();
DO(BNER);
@@ -686,7 +765,13 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(BNER_F);
- if (fpr[i.r1] != fpr[i.r2])
+ if (fpr[i.r1].f != fpr[i.r2].f)
+ JUMP(i.r0);
+
+ DISPATCH();
+
+ DO(BNER_D);
+ if (fpr[i.r1].d != fpr[i.r2].d)
JUMP(i.r0);
DISPATCH();
@@ -704,7 +789,13 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(BEQR_F);
- if (fpr[i.r1] == fpr[i.r2])
+ if (fpr[i.r1].f == fpr[i.r2].f)
+ JUMP(i.r0);
+
+ DISPATCH();
+
+ DO(BEQR_D);
+ if (fpr[i.r1].d == fpr[i.r2].d)
JUMP(i.r0);
DISPATCH();
@@ -734,7 +825,13 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(BGTR_F);
- if (fpr[i.r1] > fpr[i.r2])
+ if (fpr[i.r1].f > fpr[i.r2].f)
+ JUMP(i.r0);
+
+ DISPATCH();
+
+ DO(BGTR_D);
+ if (fpr[i.r1].d > fpr[i.r2].d)
JUMP(i.r0);
DISPATCH();
@@ -776,31 +873,25 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(BGER_F);
- if (fpr[i.r1] >= fpr[i.r2])
+ if (fpr[i.r1].f >= fpr[i.r2].f)
JUMP(i.r0);
DISPATCH();
- DO(BLEI);
- if (gpr[i.r1] <= i.o)
+ DO(BGER_D);
+ if (fpr[i.r1].d >= fpr[i.r2].d)
JUMP(i.r0);
DISPATCH();
- DO(BLEI_U);
- if ((uint64_t)gpr[i.r1] <= (uint64_t)i.o)
+ DO(BLEI);
+ if (gpr[i.r1] <= i.o)
JUMP(i.r0);
DISPATCH();
- DO(BLTGTR_F);
- double f0 = fpr[i.r1];
- double f1 = fpr[i.r2];
-
- if (isnan(f0) || isnan(f1))
- JUMP(++pc);
-
- if (!(f0 >= f1) || !(f0 <= f1))
+ DO(BLEI_U);
+ if ((uint64_t)gpr[i.r1] <= (uint64_t)i.o)
JUMP(i.r0);
DISPATCH();
@@ -842,7 +933,11 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(RETVAL_F);
- fpr[i.r0] = retval_f;
+ fpr[i.r0].f = retval_f;
+ DISPATCH();
+
+ DO(RETVAL_D);
+ fpr[i.r0].d = retval_f;
DISPATCH();
DO(PARAM);
@@ -851,9 +946,10 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DO(PARAM_F);
if (i.r1 == EJIT_FLOAT)
- fpr[i.r2] = args[i.r0].f;
+ fpr[i.r2].f = args[i.r0].f;
else
- fpr[i.r2] = args[i.r0].d;
+ fpr[i.r2].d = args[i.r0].d;
+
DISPATCH();
DO(ARG);
@@ -867,12 +963,22 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(ARG_F);
- struct ejit_arg a = ejit_build_arg_f(i.r1, fpr[i.r2]);
+ struct ejit_arg a;
+ if (i.r1 == EJIT_DOUBLE)
+ a = ejit_build_arg_f(i.r1, fpr[i.r2].d);
+ else
+ a = ejit_build_arg_f(i.r1, fpr[i.r2].f);
+
vec_append(&state->args, &a);
DISPATCH();
DO(ARG_FI);
- struct ejit_arg a = ejit_build_arg_f(i.r1, i.d);
+ struct ejit_arg a;
+ if (i.r1 == EJIT_DOUBLE)
+ a = ejit_build_arg_f(i.r1, i.d);
+ else
+ a = ejit_build_arg_f(i.r1, i.f);
+
vec_append(&state->args, &a);
DISPATCH();
@@ -885,7 +991,7 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
retval = ejit_run_interp(f, argc, args, state);
gpr = ((long *)state->gprs.buf) + prev_gprs;
- fpr = ((double *)state->fprs.buf) + prev_fprs;
+ fpr = ((union fpr *)state->fprs.buf) + prev_fprs;
vec_shrink(&state->args, prev_argc);
DISPATCH();
@@ -927,11 +1033,21 @@ union interp_ret ejit_interp(struct ejit_func *f, size_t argc,
DISPATCH();
DO(RETR_F);
- retval_f = fpr[i.r0];
+ retval_f = fpr[i.r0].f;
+ goto out_float;
+ DISPATCH();
+
+ DO(RETR_D);
+ retval_f = fpr[i.r0].d;
goto out_float;
DISPATCH();
DO(RETI_F);
+ retval_f = i.f;
+ goto out_float;
+ DISPATCH();
+
+ DO(RETI_D);
retval_f = i.d;
goto out_float;
DISPATCH();