|
|
|
|
@@ -317,6 +317,29 @@ pgf_jit_predicate(PgfReader* rdr, PgfAbstr* abstr,
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
pgf_jit_compile_slide(PgfReader* rdr, int es_arg, size_t a, size_t b)
|
|
|
|
|
{
|
|
|
|
|
if (a == b) {
|
|
|
|
|
jit_prepare(2);
|
|
|
|
|
jit_movi_i(JIT_V1, a);
|
|
|
|
|
jit_pusharg_p(JIT_V1);
|
|
|
|
|
jit_getarg_p(JIT_V1, es_arg);
|
|
|
|
|
jit_ldxi_p(JIT_V1, JIT_V1, offsetof(PgfEvalState,stack));
|
|
|
|
|
jit_pusharg_p(JIT_V1);
|
|
|
|
|
jit_finish(gu_buf_trim_n);
|
|
|
|
|
} else {
|
|
|
|
|
jit_prepare(3);
|
|
|
|
|
jit_movi_i(JIT_V1, b);
|
|
|
|
|
jit_pusharg_p(JIT_V1);
|
|
|
|
|
jit_movi_i(JIT_V1, a);
|
|
|
|
|
jit_pusharg_p(JIT_V1);
|
|
|
|
|
jit_getarg_p(JIT_V1, es_arg);
|
|
|
|
|
jit_pusharg_p(JIT_V1);
|
|
|
|
|
jit_finish(pgf_evaluate_slide);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
|
|
|
|
|
PgfAbsFun* absfun)
|
|
|
|
|
@@ -371,7 +394,9 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
|
|
|
|
|
gu_printf(out, err, " ");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
uint8_t opcode = pgf_read_tag(rdr);
|
|
|
|
|
uint8_t tag = pgf_read_tag(rdr);
|
|
|
|
|
uint8_t opcode = tag >> 3;
|
|
|
|
|
uint8_t mod = tag & 0x07;
|
|
|
|
|
switch (opcode) {
|
|
|
|
|
case PGF_INSTR_ENTER: {
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
@@ -383,40 +408,11 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
|
|
|
|
|
closure_arg = jit_arg_p();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_EVAL_ARG_VAR: {
|
|
|
|
|
size_t index = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "EVAL_ARG_VAR %d\n", index);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
jit_getarg_p(JIT_V0, es_arg);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack));
|
|
|
|
|
jit_prepare(1);
|
|
|
|
|
jit_pusharg_p(JIT_V0);
|
|
|
|
|
jit_finish(gu_buf_last);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_RET, -index*sizeof(PgfClosure*));
|
|
|
|
|
jit_prepare(2);
|
|
|
|
|
jit_pusharg_p(JIT_V0);
|
|
|
|
|
jit_getarg_p(JIT_V2, es_arg);
|
|
|
|
|
jit_pusharg_p(JIT_V2);
|
|
|
|
|
jit_ldr_p(JIT_V0, JIT_V0);
|
|
|
|
|
jit_finishr(JIT_V0);
|
|
|
|
|
jit_retval_p(JIT_V1);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_V1, offsetof(PgfValue, absfun));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_EVAL_FREE_VAR: {
|
|
|
|
|
size_t index = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "EVAL_FREE_VAR %d\n", index);
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_CASE: {
|
|
|
|
|
PgfCId id = pgf_read_cid(rdr, rdr->opool);
|
|
|
|
|
int target = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "CASE %s %03d\n", id, target);
|
|
|
|
|
gu_printf(out, err, "CASE %s %03d\n", id, target);
|
|
|
|
|
#endif
|
|
|
|
|
jit_insn *jump=
|
|
|
|
|
jit_bnei_i(jit_forward(), JIT_V0, (int) jit_forward());
|
|
|
|
|
@@ -439,34 +435,41 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
|
|
|
|
|
jit_finish(pgf_evaluate_save_variables);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_CASE_INT: {
|
|
|
|
|
int n = pgf_read_int(rdr);
|
|
|
|
|
int target = pgf_read_int(rdr);
|
|
|
|
|
case PGF_INSTR_CASE_LIT: {
|
|
|
|
|
switch (mod) {
|
|
|
|
|
case 0: {
|
|
|
|
|
int n = pgf_read_int(rdr);
|
|
|
|
|
int target = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "CASE_INT %d %03d\n", n, target);
|
|
|
|
|
gu_printf(out, err, "CASE_LIT %d %03d\n", n, target);
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_CASE_STR: {
|
|
|
|
|
GuString s = pgf_read_string(rdr);
|
|
|
|
|
int target = pgf_read_int(rdr);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 1: {
|
|
|
|
|
GuString s = pgf_read_string(rdr);
|
|
|
|
|
int target = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "CASE_STR %s %03d\n", s, target);
|
|
|
|
|
gu_printf(out, err, "CASE_LIT %s %03d\n", s, target);
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_CASE_FLT: {
|
|
|
|
|
double d = pgf_read_double(rdr);
|
|
|
|
|
int target = pgf_read_int(rdr);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 2: {
|
|
|
|
|
double d = pgf_read_double(rdr);
|
|
|
|
|
int target = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "CASE_FLT %f %03d\n", d, target);
|
|
|
|
|
gu_printf(out, err, "CASE_LIT %f %03d\n", d, target);
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
gu_impossible();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_ALLOC: {
|
|
|
|
|
size_t size = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "ALLOC %d\n", size);
|
|
|
|
|
gu_printf(out, err, "ALLOC %d\n", size);
|
|
|
|
|
#endif
|
|
|
|
|
jit_prepare(2);
|
|
|
|
|
jit_movi_ui(JIT_V0, size*sizeof(void*));
|
|
|
|
|
@@ -483,7 +486,7 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
|
|
|
|
|
case PGF_INSTR_PUT_CONSTR: {
|
|
|
|
|
PgfCId id = pgf_read_cid(rdr, rdr->tmp_pool);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "PUT_CONSTR %s\n", id);
|
|
|
|
|
gu_printf(out, err, "PUT_CONSTR %s\n", id);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
jit_movi_p(JIT_V0, pgf_evaluate_value);
|
|
|
|
|
@@ -502,7 +505,7 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
|
|
|
|
|
case PGF_INSTR_PUT_FUN: {
|
|
|
|
|
PgfCId id = pgf_read_cid(rdr, rdr->tmp_pool);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "PUT_FUN %s\n", id);
|
|
|
|
|
gu_printf(out, err, "PUT_FUN %s\n", id);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
PgfCallPatch patch;
|
|
|
|
|
@@ -518,7 +521,7 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
|
|
|
|
|
case PGF_INSTR_PUT_CLOSURE: {
|
|
|
|
|
size_t target = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "PUT_CLOSURE %03d\n", target);
|
|
|
|
|
gu_printf(out, err, "PUT_CLOSURE %03d\n", target);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
PgfSegmentPatch patch;
|
|
|
|
|
@@ -531,62 +534,72 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
|
|
|
|
|
gu_buf_push(rdr->jit_state->segment_patches, PgfSegmentPatch, patch);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_PUT_INT: {
|
|
|
|
|
size_t n = pgf_read_int(rdr);
|
|
|
|
|
case PGF_INSTR_PUT_LIT: {
|
|
|
|
|
switch (mod) {
|
|
|
|
|
case 0: {
|
|
|
|
|
size_t n = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "PUT_INT %d\n", n);
|
|
|
|
|
gu_printf(out, err, "PUT_LIT %d\n", n);
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 1: {
|
|
|
|
|
GuString s = pgf_read_string(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "PUT_LIT \"%s\"\n", s);
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 2: {
|
|
|
|
|
double d = pgf_read_double(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "PUT_LIT %f\n", d);
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
gu_impossible();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_PUT_STR: {
|
|
|
|
|
size_t addr = pgf_read_int(rdr);
|
|
|
|
|
case PGF_INSTR_SET: {
|
|
|
|
|
switch (mod) {
|
|
|
|
|
case 0: {
|
|
|
|
|
size_t offset = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "PUT_STR %d\n", addr);
|
|
|
|
|
gu_printf(out, err, "SET hp(%d)\n", offset);
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_PUT_FLT: {
|
|
|
|
|
size_t addr = pgf_read_int(rdr);
|
|
|
|
|
jit_addi_p(JIT_V0, JIT_V1, offset*sizeof(void*));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 1: {
|
|
|
|
|
size_t index = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "PUT_FLT %d\n", addr);
|
|
|
|
|
gu_printf(out, err, "SET stk(%d)\n", index);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
jit_getarg_p(JIT_V0, es_arg);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack));
|
|
|
|
|
jit_prepare(1);
|
|
|
|
|
jit_pusharg_p(JIT_V0);
|
|
|
|
|
jit_finish(gu_buf_last);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_RET, -index*sizeof(PgfClosure*));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 2: {
|
|
|
|
|
size_t index = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "SET env(%d)\n", index);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
jit_getarg_p(JIT_V0, closure_arg);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_V0, sizeof(PgfClosure)+index*sizeof(PgfClosure*));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
gu_impossible();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_SET_VALUE: {
|
|
|
|
|
size_t offset = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "SET_VALUE %d\n", offset);
|
|
|
|
|
#endif
|
|
|
|
|
jit_addi_p(JIT_V0, JIT_V1, offset*sizeof(void*));
|
|
|
|
|
jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0);
|
|
|
|
|
curr_offset++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_SET_ARG_VAR: {
|
|
|
|
|
size_t index = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "SET_ARG_VAR %d\n", index);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
jit_getarg_p(JIT_V0, es_arg);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack));
|
|
|
|
|
jit_prepare(1);
|
|
|
|
|
jit_pusharg_p(JIT_V0);
|
|
|
|
|
jit_finish(gu_buf_last);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_RET, -index*sizeof(PgfClosure*));
|
|
|
|
|
jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0);
|
|
|
|
|
curr_offset++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_SET_FREE_VAR: {
|
|
|
|
|
size_t index = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "SET_FREE_VAR %d\n", index);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
jit_getarg_p(JIT_V0, closure_arg);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_V0, sizeof(PgfClosure)+index*sizeof(PgfClosure*));
|
|
|
|
|
jit_stxi_p(curr_offset*sizeof(void*), JIT_V1, JIT_V0);
|
|
|
|
|
curr_offset++;
|
|
|
|
|
break;
|
|
|
|
|
@@ -600,76 +613,174 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
|
|
|
|
|
curr_offset++;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_PUSH_VALUE: {
|
|
|
|
|
size_t offset = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "PUSH_VALUE %d\n", offset);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
case PGF_INSTR_PUSH: {
|
|
|
|
|
jit_getarg_p(JIT_V0, es_arg);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack));
|
|
|
|
|
jit_prepare(1);
|
|
|
|
|
jit_pusharg_p(JIT_V0);
|
|
|
|
|
jit_finish(gu_buf_extend);
|
|
|
|
|
if (offset == 0) {
|
|
|
|
|
jit_str_p(JIT_RET, JIT_V1);
|
|
|
|
|
} else {
|
|
|
|
|
jit_addi_p(JIT_V0, JIT_V1, offset*sizeof(void*));
|
|
|
|
|
|
|
|
|
|
switch (mod) {
|
|
|
|
|
case 0: {
|
|
|
|
|
size_t offset = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "PUSH hp(%d)\n", offset);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (offset == 0) {
|
|
|
|
|
jit_str_p(JIT_RET, JIT_V1);
|
|
|
|
|
} else {
|
|
|
|
|
jit_addi_p(JIT_V0, JIT_V1, offset*sizeof(void*));
|
|
|
|
|
jit_str_p(JIT_RET, JIT_V0);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 1: {
|
|
|
|
|
size_t index = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "PUSH stk(%d)\n", index);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_RET, -(index+1)*sizeof(PgfClosure*));
|
|
|
|
|
jit_str_p(JIT_RET, JIT_V0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 2: {
|
|
|
|
|
size_t index = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "PUSH env(%d)\n", index);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
jit_getarg_p(JIT_V0, closure_arg);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_V0, sizeof(PgfClosure)+index*sizeof(PgfClosure*));
|
|
|
|
|
jit_str_p(JIT_RET, JIT_V0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
gu_impossible();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_PUSH_ARG_VAR: {
|
|
|
|
|
size_t index = pgf_read_int(rdr);
|
|
|
|
|
case PGF_INSTR_EVAL: {
|
|
|
|
|
switch (mod & 0x3) {
|
|
|
|
|
case 0: {
|
|
|
|
|
size_t offset = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "PUSH_ARG_VAR %d\n", index);
|
|
|
|
|
gu_printf(out, err, "EVAL hp(%d)", offset);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
jit_getarg_p(JIT_V0, es_arg);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack));
|
|
|
|
|
jit_prepare(1);
|
|
|
|
|
jit_pusharg_p(JIT_V0);
|
|
|
|
|
jit_finish(gu_buf_extend);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_RET, -(index+1)*sizeof(PgfClosure*));
|
|
|
|
|
jit_str_p(JIT_RET, JIT_V0);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_PUSH_FREE_VAR: {
|
|
|
|
|
size_t index = pgf_read_int(rdr);
|
|
|
|
|
jit_addi_p(JIT_V0, JIT_V1, offset*sizeof(void*));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 1: {
|
|
|
|
|
size_t index = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "PUSH_FREE_VAR %d\n", index);
|
|
|
|
|
gu_printf(out, err, "EVAL stk(%d)", index);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
jit_getarg_p(JIT_V0, es_arg);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack));
|
|
|
|
|
jit_prepare(1);
|
|
|
|
|
jit_pusharg_p(JIT_V0);
|
|
|
|
|
jit_finish(gu_buf_extend);
|
|
|
|
|
jit_getarg_p(JIT_V0, closure_arg);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_V0, sizeof(PgfClosure)+index*sizeof(PgfClosure*));
|
|
|
|
|
jit_str_p(JIT_RET, JIT_V0);
|
|
|
|
|
jit_getarg_p(JIT_V0, es_arg);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfEvalState,stack));
|
|
|
|
|
jit_prepare(1);
|
|
|
|
|
jit_pusharg_p(JIT_V0);
|
|
|
|
|
jit_finish(gu_buf_last);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_RET, -index*sizeof(PgfClosure*));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 2: {
|
|
|
|
|
size_t index = pgf_read_int(rdr);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "EVAL env(%d)", index);
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
gu_impossible();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (mod >> 2) {
|
|
|
|
|
case 0: {
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
jit_prepare(2);
|
|
|
|
|
jit_pusharg_p(JIT_V0);
|
|
|
|
|
jit_getarg_p(JIT_V2, es_arg);
|
|
|
|
|
jit_pusharg_p(JIT_V2);
|
|
|
|
|
jit_ldr_p(JIT_V0, JIT_V0);
|
|
|
|
|
jit_finishr(JIT_V0);
|
|
|
|
|
jit_retval_p(JIT_V1);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_V1, offsetof(PgfValue, absfun));
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 1: {
|
|
|
|
|
size_t a = pgf_read_int(rdr);
|
|
|
|
|
size_t b = pgf_read_int(rdr);
|
|
|
|
|
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, " tail(%d,%d)\n", a, b);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
pgf_jit_compile_slide(rdr, es_arg, a, b);
|
|
|
|
|
jit_setarg_p(JIT_V0, closure_arg);
|
|
|
|
|
jit_ldr_p(JIT_RET, JIT_V0);
|
|
|
|
|
jit_tail_finishr(JIT_RET);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
gu_impossible();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_TAIL_CALL: {
|
|
|
|
|
case PGF_INSTR_CALL: {
|
|
|
|
|
PgfCId id = pgf_read_cid(rdr, rdr->tmp_pool);
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "TAIL_CALL %s\n", id);
|
|
|
|
|
gu_printf(out, err, "CALL %s", id);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
jit_getarg_p(JIT_V0, es_arg);
|
|
|
|
|
jit_getarg_p(JIT_V1, closure_arg);
|
|
|
|
|
jit_prepare(2);
|
|
|
|
|
jit_pusharg_p(JIT_V1);
|
|
|
|
|
jit_pusharg_p(JIT_V0);
|
|
|
|
|
switch (mod >> 2) {
|
|
|
|
|
case 0: {
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "\n");
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
PgfCallPatch patch;
|
|
|
|
|
patch.cid = id;
|
|
|
|
|
patch.ref = jit_movi_p(JIT_V0, jit_forward());
|
|
|
|
|
gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfAbsFun,function));
|
|
|
|
|
jit_getarg_p(JIT_V0, es_arg);
|
|
|
|
|
jit_getarg_p(JIT_V1, closure_arg);
|
|
|
|
|
jit_prepare(2);
|
|
|
|
|
jit_pusharg_p(JIT_V1);
|
|
|
|
|
jit_pusharg_p(JIT_V0);
|
|
|
|
|
|
|
|
|
|
jit_finishr(JIT_V0);
|
|
|
|
|
jit_retval_p(JIT_V1);
|
|
|
|
|
PgfCallPatch patch;
|
|
|
|
|
patch.cid = id;
|
|
|
|
|
patch.ref = jit_movi_p(JIT_V0, jit_forward());
|
|
|
|
|
gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch);
|
|
|
|
|
jit_ldxi_p(JIT_V0, JIT_V0, offsetof(PgfAbsFun,function));
|
|
|
|
|
|
|
|
|
|
jit_finishr(JIT_V0);
|
|
|
|
|
jit_retval_p(JIT_V1);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 1: {
|
|
|
|
|
size_t a = pgf_read_int(rdr);
|
|
|
|
|
size_t b = pgf_read_int(rdr);
|
|
|
|
|
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, " tail(%d,%d)\n", a, b);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
pgf_jit_compile_slide(rdr, es_arg, a, b);
|
|
|
|
|
|
|
|
|
|
PgfCallPatch patch;
|
|
|
|
|
patch.cid = id;
|
|
|
|
|
patch.ref = jit_movi_p(JIT_V0, jit_forward());
|
|
|
|
|
gu_buf_push(rdr->jit_state->call_patches, PgfCallPatch, patch);
|
|
|
|
|
jit_ldxi_p(JIT_RET, JIT_V0, offsetof(PgfAbsFun,function));
|
|
|
|
|
jit_tail_finishr(JIT_RET);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
gu_impossible();
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case PGF_INSTR_FAIL:
|
|
|
|
|
@@ -692,7 +803,7 @@ pgf_jit_function(PgfReader* rdr, PgfAbstr* abstr,
|
|
|
|
|
size_t count = pgf_read_int(rdr);
|
|
|
|
|
|
|
|
|
|
#ifdef PGF_JIT_DEBUG
|
|
|
|
|
gu_printf(out, err, "RET %d\n", count);
|
|
|
|
|
gu_printf(out, err, "RET %d\n", count);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (count > 0) {
|
|
|
|
|
|