From dcca95ebeef7ad047b437c7e65bcd2d33784cae4 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Sun, 14 Jul 2024 14:46:40 +0300 Subject: add float + double instead of just double --- src/common.h | 24 ++++++- src/ejit.c | 158 +++++++++++++++++++++++++++++++++++++++--- src/interp.c | 220 +++++++++++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 338 insertions(+), 64 deletions(-) (limited to 'src') 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] = &>R, [GTR_U] = &>R_U, [GTR_F] = &>R_F, + [GTR_D] = &>R_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(); -- cgit v1.2.3