JIT: push alternate target-register handling into inlined code
This change streamlines generated code slightly. New release checklist item: double-check by building with TEST_ALTERNATE_TARGET_REGISTER.
This commit is contained in:
parent
335711bc3f
commit
91a5347d5b
|
@ -225,6 +225,7 @@
|
|||
(test-bin 8 'unsafe-list-ref (cons 5 (cons 8 9)) 1)
|
||||
(test-bin 9 'unsafe-list-ref (cons 5 (cons 8 (cons 9 10))) 2)
|
||||
(test-bin (cons 5 9) 'unsafe-list-tail (cons 5 9) 0)
|
||||
(test-bin 3 'unsafe-list-tail 3 0)
|
||||
(test-bin 9 'unsafe-list-tail (cons 5 9) 1)
|
||||
(test-bin 8 'unsafe-list-tail (cons 5 (cons 9 8)) 2)
|
||||
|
||||
|
|
|
@ -1856,6 +1856,30 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef TEST_ALTERNATE_TARGET_REGISTER
|
||||
# define IS_SKIP_TYPE(t) 0
|
||||
if ((target == JIT_R0)
|
||||
&& !is_tail
|
||||
&& !for_branch
|
||||
&& !jitter->unbox
|
||||
&& !IS_SKIP_TYPE(SCHEME_TYPE(obj))
|
||||
&& !SAME_TYPE(SCHEME_TYPE(obj), scheme_toplevel_type)
|
||||
&& !SAME_TYPE(SCHEME_TYPE(obj), scheme_local_type)
|
||||
&& !SAME_TYPE(SCHEME_TYPE(obj), scheme_local_unbox_type)
|
||||
&& (SCHEME_TYPE(obj) < _scheme_values_types_)) {
|
||||
scheme_generate(obj, jitter, is_tail, wcm_may_replace, multi_ok, JIT_R1, for_branch);
|
||||
CHECK_LIMIT();
|
||||
jit_movr_p(JIT_R0, JIT_R1);
|
||||
return 1;
|
||||
} else if ((target == JIT_R1)
|
||||
&& IS_SKIP_TYPE(SCHEME_TYPE(obj))) {
|
||||
scheme_generate(obj, jitter, is_tail, wcm_may_replace, multi_ok, JIT_R0, for_branch);
|
||||
CHECK_LIMIT();
|
||||
jit_movr_p(JIT_R1, JIT_R0);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
orig_target = target;
|
||||
result_ignored = (target < 0);
|
||||
if (target < 0) target = JIT_R0;
|
||||
|
@ -2437,11 +2461,9 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
|
|||
|
||||
LOG_IT(("app %d\n", app->num_args));
|
||||
|
||||
r = scheme_generate_inlined_nary(jitter, app, is_tail, multi_ok, NULL, 1, result_ignored);
|
||||
r = scheme_generate_inlined_nary(jitter, app, is_tail, multi_ok, NULL, 1, result_ignored, target);
|
||||
CHECK_LIMIT();
|
||||
if (r) {
|
||||
if (target != JIT_R0)
|
||||
jit_movr_p(target, JIT_R0);
|
||||
if (for_branch) finish_branch(jitter, target, for_branch);
|
||||
return r;
|
||||
}
|
||||
|
@ -2462,11 +2484,9 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
|
|||
Scheme_Object *args[2];
|
||||
int r;
|
||||
|
||||
r = scheme_generate_inlined_unary(jitter, app, is_tail, multi_ok, NULL, 1, 0, result_ignored);
|
||||
r = scheme_generate_inlined_unary(jitter, app, is_tail, multi_ok, NULL, 1, 0, result_ignored, target);
|
||||
CHECK_LIMIT();
|
||||
if (r) {
|
||||
if (target != JIT_R0)
|
||||
jit_movr_p(target, JIT_R0);
|
||||
if (for_branch) finish_branch(jitter, target, for_branch);
|
||||
return r;
|
||||
}
|
||||
|
@ -2492,11 +2512,9 @@ int scheme_generate(Scheme_Object *obj, mz_jit_state *jitter, int is_tail, int w
|
|||
Scheme_Object *args[3];
|
||||
int r;
|
||||
|
||||
r = scheme_generate_inlined_binary(jitter, app, is_tail, multi_ok, NULL, 1, 0, result_ignored);
|
||||
r = scheme_generate_inlined_binary(jitter, app, is_tail, multi_ok, NULL, 1, 0, result_ignored, target);
|
||||
CHECK_LIMIT();
|
||||
if (r) {
|
||||
if (target != JIT_R0)
|
||||
jit_movr_p(target, JIT_R0);
|
||||
if (for_branch) finish_branch(jitter, target, for_branch);
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -1218,17 +1218,20 @@ int scheme_inlined_unary_prim(Scheme_Object *o, Scheme_Object *_app, mz_jit_stat
|
|||
int scheme_inlined_binary_prim(Scheme_Object *o, Scheme_Object *_app, mz_jit_state *jitter);
|
||||
int scheme_inlined_nary_prim(Scheme_Object *o, Scheme_Object *_app, mz_jit_state *jitter);
|
||||
int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, int is_tail, int multi_ok,
|
||||
Branch_Info *for_branch, int branch_short, int need_sync, int result_ignored);
|
||||
Branch_Info *for_branch, int branch_short, int need_sync, int result_ignored,
|
||||
int dest);
|
||||
int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, int is_tail, int multi_ok,
|
||||
Branch_Info *for_branch, int branch_short, int need_sync, int result_ignored);
|
||||
Branch_Info *for_branch, int branch_short, int need_sync, int result_ignored,
|
||||
int dest);
|
||||
int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int is_tail, int multi_ok,
|
||||
Branch_Info *for_branch, int branch_short, int result_ignored);
|
||||
Branch_Info *for_branch, int branch_short, int result_ignored,
|
||||
int dest);
|
||||
int scheme_generate_inlined_test(mz_jit_state *jitter, Scheme_Object *obj, int branch_short,
|
||||
Branch_Info *for_branch, int need_sync);
|
||||
int scheme_generate_cons_alloc(mz_jit_state *jitter, int rev, int inline_retry);
|
||||
int scheme_generate_cons_alloc(mz_jit_state *jitter, int rev, int inline_retry, int dest);
|
||||
int scheme_generate_struct_alloc(mz_jit_state *jitter, int num_args,
|
||||
int inline_slow, int pop_and_jump,
|
||||
int is_tail, int multi_ok);
|
||||
int is_tail, int multi_ok, int dest);
|
||||
|
||||
/**********************************************************************/
|
||||
/* jitalloc */
|
||||
|
@ -1258,12 +1261,14 @@ int scheme_can_unbox_directly(Scheme_Object *obj);
|
|||
int scheme_generate_unboxing(mz_jit_state *jitter, int target);
|
||||
int scheme_generate_pop_unboxed(mz_jit_state *jitter);
|
||||
int scheme_generate_nary_arith(mz_jit_state *jitter, Scheme_App_Rec *app,
|
||||
int arith, int cmp, Branch_Info *for_branch, int branch_short);
|
||||
int scheme_generate_alloc_double(mz_jit_state *jitter, int inline_retry);
|
||||
int arith, int cmp, Branch_Info *for_branch, int branch_short,
|
||||
int dest);
|
||||
int scheme_generate_alloc_double(mz_jit_state *jitter, int inline_retry, int dest);
|
||||
int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Object *rand, Scheme_Object *rand2,
|
||||
int orig_args, int arith, int cmp, int v,
|
||||
Branch_Info *for_branch, int branch_short,
|
||||
int unsafe_fx, int unsafe_fl, GC_CAN_IGNORE jit_insn *overflow_refslow);
|
||||
int unsafe_fx, int unsafe_fl, GC_CAN_IGNORE jit_insn *overflow_refslow,
|
||||
int dest);
|
||||
|
||||
/**********************************************************************/
|
||||
/* jitcall */
|
||||
|
|
|
@ -250,8 +250,9 @@ int scheme_can_unbox_directly(Scheme_Object *obj)
|
|||
|
||||
static jit_insn *generate_arith_slow_path(mz_jit_state *jitter, Scheme_Object *rator,
|
||||
jit_insn **_ref, jit_insn **_ref4,
|
||||
Branch_Info *for_branch,
|
||||
int orig_args, int reversed, int arith, int use_v, int v)
|
||||
Branch_Info *for_branch, int branch_short,
|
||||
int orig_args, int reversed, int arith, int use_v, int v,
|
||||
int dest)
|
||||
/* *_ref4 is place to set for where to jump (for true case, if for_branch) after completing;
|
||||
*_ref is place to set for where to jump for false if for_branch, result if !for_branch;
|
||||
result is place to jump to start slow path if fixnum attempt fails */
|
||||
|
@ -266,15 +267,17 @@ static jit_insn *generate_arith_slow_path(mz_jit_state *jitter, Scheme_Object *r
|
|||
CHECK_LIMIT();
|
||||
ref4 = jit_patchable_movi_p(JIT_V1, jit_forward());
|
||||
mz_set_local_p(JIT_V1, JIT_LOCAL2);
|
||||
} else
|
||||
ref = jit_patchable_movi_p(JIT_V1, jit_forward());
|
||||
} else {
|
||||
ref4 = NULL;
|
||||
ref = jit_patchable_movi_p(JIT_V1, jit_forward());
|
||||
ref = NULL;
|
||||
}
|
||||
|
||||
if (orig_args == 1) {
|
||||
if (for_branch) {
|
||||
(void)jit_jmpi(sjc.call_original_unary_arith_for_branch_code);
|
||||
} else {
|
||||
(void)jit_jmpi(sjc.call_original_unary_arith_code);
|
||||
(void)jit_calli(sjc.call_original_unary_arith_code);
|
||||
}
|
||||
} else {
|
||||
if (use_v) {
|
||||
|
@ -290,13 +293,20 @@ static jit_insn *generate_arith_slow_path(mz_jit_state *jitter, Scheme_Object *r
|
|||
}
|
||||
} else {
|
||||
if (reversed) {
|
||||
(void)jit_jmpi(sjc.call_original_binary_rev_arith_code);
|
||||
(void)jit_calli(sjc.call_original_binary_rev_arith_code);
|
||||
} else {
|
||||
(void)jit_jmpi(sjc.call_original_binary_arith_code);
|
||||
(void)jit_calli(sjc.call_original_binary_arith_code);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!for_branch) {
|
||||
jit_movr_p(dest, JIT_R0);
|
||||
__START_SHORT_JUMPS__(branch_short);
|
||||
ref = jit_jmpi(jit_forward());
|
||||
__END_SHORT_JUMPS__(branch_short);
|
||||
}
|
||||
|
||||
*_ref = ref;
|
||||
*_ref4 = ref4;
|
||||
|
||||
|
@ -386,15 +396,15 @@ int scheme_generate_unboxing(mz_jit_state *jitter, int target)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int scheme_generate_alloc_double(mz_jit_state *jitter, int inline_retry)
|
||||
int scheme_generate_alloc_double(mz_jit_state *jitter, int inline_retry, int dest)
|
||||
/* value should be in JIT_FPR0; R0-R2 not saved; V1 used */
|
||||
{
|
||||
#ifdef INLINE_FP_OPS
|
||||
# ifdef CAN_INLINE_ALLOC
|
||||
scheme_inline_alloc(jitter, sizeof(Scheme_Double), scheme_double_type, 0, 0, 1, inline_retry);
|
||||
CHECK_LIMIT();
|
||||
jit_addi_p(JIT_R0, JIT_V1, OBJHEAD_SIZE);
|
||||
(void)jit_stxi_d_fppop(&((Scheme_Double *)0x0)->double_val, JIT_R0, JIT_FPR0);
|
||||
jit_addi_p(dest, JIT_V1, OBJHEAD_SIZE);
|
||||
(void)jit_stxi_d_fppop(&((Scheme_Double *)0x0)->double_val, dest, JIT_FPR0);
|
||||
# else
|
||||
(void)mz_tl_sti_d_fppop(tl_scheme_jit_save_fp, JIT_FPR0, JIT_R0);
|
||||
JIT_UPDATE_THREAD_RSPTR_IF_NEEDED();
|
||||
|
@ -403,7 +413,7 @@ int scheme_generate_alloc_double(mz_jit_state *jitter, int inline_retry)
|
|||
GC_CAN_IGNORE jit_insn *refr;
|
||||
(void)mz_finish_lwe(ts_malloc_double, refr);
|
||||
}
|
||||
jit_retval(JIT_R0);
|
||||
jit_retval(dest);
|
||||
# endif
|
||||
#endif
|
||||
return 1;
|
||||
|
@ -412,7 +422,8 @@ int scheme_generate_alloc_double(mz_jit_state *jitter, int inline_retry)
|
|||
static int generate_double_arith(mz_jit_state *jitter, Scheme_Object *rator,
|
||||
int arith, int cmp, int reversed, int two_args, int second_const,
|
||||
jit_insn **_refd, jit_insn **_refdt, Branch_Info *for_branch,
|
||||
int branch_short, int unsafe_fl, int unboxed, int unboxed_result)
|
||||
int branch_short, int unsafe_fl, int unboxed, int unboxed_result,
|
||||
int dest)
|
||||
/* Unless unboxed, first arg is in JIT_R1, second in JIT_R0.
|
||||
If unboxed in push/pop mode, first arg is pushed before second.
|
||||
If unboxed in direct mode, first arg is in JIT_FPR0+depth
|
||||
|
@ -446,7 +457,7 @@ static int generate_double_arith(mz_jit_state *jitter, Scheme_Object *rator,
|
|||
|
||||
if (!two_args && !second_const && ((arith == ARITH_MUL) || ((arith == ARITH_DIV) && reversed))) {
|
||||
/* Special case: multiplication by exact 0 */
|
||||
(void)jit_movi_p(JIT_R0, scheme_make_integer(0));
|
||||
(void)jit_movi_p(dest, scheme_make_integer(0));
|
||||
} else {
|
||||
/* Yes, they're doubles. First arg is in JIT_R1, second is in JIT_R0.
|
||||
Put the first arg in fpr0 and second (if any) into fpr1. To work
|
||||
|
@ -551,6 +562,7 @@ static int generate_double_arith(mz_jit_state *jitter, Scheme_Object *rator,
|
|||
__END_TINY_JUMPS__(1);
|
||||
if (!unboxed) {
|
||||
/* we've already set JIT_R0 */
|
||||
jit_movr_p(dest, JIT_R0);
|
||||
no_alloc = 1;
|
||||
}
|
||||
}
|
||||
|
@ -562,6 +574,7 @@ static int generate_double_arith(mz_jit_state *jitter, Scheme_Object *rator,
|
|||
/* no work to do, because argument is already inexact;
|
||||
no need to allocate, because argument is never unboxed,
|
||||
and it therefore already resides in R0 */
|
||||
jit_movr_p(dest, JIT_R0);
|
||||
no_alloc = 1;
|
||||
break;
|
||||
case ARITH_INEX_EX: /* inexact->exact */
|
||||
|
@ -590,7 +603,7 @@ static int generate_double_arith(mz_jit_state *jitter, Scheme_Object *rator,
|
|||
jit_roundr_d_l_fppop(JIT_R1, fpr2); /* slow path won't be needed */
|
||||
#endif
|
||||
}
|
||||
jit_fixnum_l(JIT_R0, JIT_R1);
|
||||
jit_fixnum_l(dest, JIT_R1);
|
||||
no_alloc = 1;
|
||||
break;
|
||||
case ARITH_SQRT:
|
||||
|
@ -659,7 +672,7 @@ static int generate_double_arith(mz_jit_state *jitter, Scheme_Object *rator,
|
|||
|
||||
if (!no_alloc) {
|
||||
mz_rs_sync(); /* needed if arguments were unboxed */
|
||||
scheme_generate_alloc_double(jitter, 0);
|
||||
scheme_generate_alloc_double(jitter, 0, dest);
|
||||
CHECK_LIMIT();
|
||||
#if defined(MZ_USE_JIT_I386)
|
||||
if (need_post_pop)
|
||||
|
@ -792,7 +805,8 @@ static void generate_modulo_setup(mz_jit_state *jitter, int branch_short, int a1
|
|||
int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Object *rand, Scheme_Object *rand2,
|
||||
int orig_args, int arith, int cmp, int v,
|
||||
Branch_Info *for_branch, int branch_short,
|
||||
int unsafe_fx, int unsafe_fl, GC_CAN_IGNORE jit_insn *overflow_refslow)
|
||||
int unsafe_fx, int unsafe_fl, GC_CAN_IGNORE jit_insn *overflow_refslow,
|
||||
int dest)
|
||||
/* needs de-sync */
|
||||
/* Operation codes are defined in jit.h.
|
||||
Either arith is non-zero or it's a cmp; the value of each determines the operation:
|
||||
|
@ -981,7 +995,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
generate_double_arith(jitter, rator, arith, cmp, reversed, !!rand2, 0,
|
||||
&refd, &refdt, for_branch, branch_short,
|
||||
(arith == ARITH_INEX_EX) ? (unsafe_fl > 0) : 1,
|
||||
args_unboxed, jitter->unbox);
|
||||
args_unboxed, jitter->unbox, dest);
|
||||
CHECK_LIMIT();
|
||||
ref3 = NULL;
|
||||
ref = NULL;
|
||||
|
@ -992,10 +1006,10 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
if (args_unboxed) {
|
||||
(void)jit_calli(sjc.box_flonum_from_reg_code);
|
||||
}
|
||||
generate_arith_slow_path(jitter, rator, &ref, &ref4, for_branch, orig_args, reversed, arith, 0, 0);
|
||||
generate_arith_slow_path(jitter, rator, &ref, &ref4, for_branch, branch_short, orig_args, reversed, arith, 0, 0, dest);
|
||||
/* assert: !ref4, since not for_branch */
|
||||
jit_patch_movi(ref, (_jit.x.pc));
|
||||
__START_SHORT_JUMPS__(branch_short);
|
||||
mz_patch_ucbranch(ref);
|
||||
mz_patch_ucbranch(refdt);
|
||||
__END_SHORT_JUMPS__(branch_short);
|
||||
}
|
||||
|
@ -1160,7 +1174,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
/* Maybe they're both doubles... */
|
||||
if (unsafe_fl) mz_rs_sync();
|
||||
generate_double_arith(jitter, rator, arith, cmp, reversed, 1, 0, &refd, &refdt,
|
||||
for_branch, branch_short, unsafe_fl, 0, unbox);
|
||||
for_branch, branch_short, unsafe_fl, 0, unbox, dest);
|
||||
CHECK_LIMIT();
|
||||
}
|
||||
|
||||
|
@ -1172,7 +1186,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
}
|
||||
|
||||
/* Slow path */
|
||||
refslow = generate_arith_slow_path(jitter, rator, &ref, &ref4, for_branch, orig_args, reversed, arith, 0, 0);
|
||||
refslow = generate_arith_slow_path(jitter, rator, &ref, &ref4, for_branch, branch_short, orig_args, reversed, arith, 0, 0, dest);
|
||||
|
||||
if (has_fixnum_fast) {
|
||||
__START_TINY_JUMPS_IF_COMPACT__(1);
|
||||
|
@ -1210,7 +1224,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
/* Maybe they're both doubles... */
|
||||
if (unsafe_fl) mz_rs_sync();
|
||||
generate_double_arith(jitter, rator, arith, cmp, reversed, 1, 0, &refd, &refdt,
|
||||
for_branch, branch_short, unsafe_fl, 0, unbox);
|
||||
for_branch, branch_short, unsafe_fl, 0, unbox, dest);
|
||||
CHECK_LIMIT();
|
||||
}
|
||||
|
||||
|
@ -1222,7 +1236,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
}
|
||||
|
||||
/* Slow path */
|
||||
refslow = generate_arith_slow_path(jitter, rator, &ref, &ref4, for_branch, orig_args, reversed, arith, 0, 0);
|
||||
refslow = generate_arith_slow_path(jitter, rator, &ref, &ref4, for_branch, branch_short, orig_args, reversed, arith, 0, 0, dest);
|
||||
|
||||
if (has_fixnum_fast) {
|
||||
/* Fixnum branch: */
|
||||
|
@ -1258,7 +1272,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
&& ((arith != ARITH_DIV) || v || reversed))) {
|
||||
/* Maybe it's a double... */
|
||||
generate_double_arith(jitter, rator, arith, cmp, reversed, 0, v, &refd, &refdt,
|
||||
for_branch, branch_short, unsafe_fl, 0, unbox);
|
||||
for_branch, branch_short, unsafe_fl, 0, unbox, dest);
|
||||
CHECK_LIMIT();
|
||||
}
|
||||
|
||||
|
@ -1270,7 +1284,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
}
|
||||
|
||||
/* Slow path */
|
||||
refslow = generate_arith_slow_path(jitter, rator, &ref, &ref4, for_branch, orig_args, reversed, arith, 1, v);
|
||||
refslow = generate_arith_slow_path(jitter, rator, &ref, &ref4, for_branch, branch_short, orig_args, reversed, arith, 1, v, dest);
|
||||
|
||||
if (has_fixnum_fast) {
|
||||
__START_TINY_JUMPS_IF_COMPACT__(1);
|
||||
|
@ -1304,10 +1318,10 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
if (arith == ARITH_ADD) {
|
||||
jit_andi_ul(JIT_R2, JIT_R1, (~0x1));
|
||||
if (unsafe_fx && !overflow_refslow)
|
||||
jit_addr_l(JIT_R0, JIT_R2, JIT_R0);
|
||||
jit_addr_l(dest, JIT_R2, JIT_R0);
|
||||
else {
|
||||
(void)jit_boaddr_l(refslow, JIT_R2, JIT_R0);
|
||||
jit_movr_p(JIT_R0, JIT_R2);
|
||||
jit_movr_p(dest, JIT_R2);
|
||||
}
|
||||
} else if (arith == ARITH_SUB) {
|
||||
if (reversed) {
|
||||
|
@ -1323,7 +1337,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
else
|
||||
(void)jit_bosubr_l(refslow, JIT_R2, JIT_R0);
|
||||
}
|
||||
jit_ori_ul(JIT_R0, JIT_R2, 0x1);
|
||||
jit_ori_ul(dest, JIT_R2, 0x1);
|
||||
} else if (arith == ARITH_MUL) {
|
||||
jit_andi_ul(JIT_R2, JIT_R1, (~0x1));
|
||||
jit_rshi_l(JIT_V1, JIT_R0, 0x1);
|
||||
|
@ -1331,7 +1345,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
jit_mulr_l(JIT_V1, JIT_V1, JIT_R2);
|
||||
else
|
||||
(void)jit_bomulr_l(refslow, JIT_V1, JIT_R2);
|
||||
jit_ori_ul(JIT_R0, JIT_V1, 0x1);
|
||||
jit_ori_ul(dest, JIT_V1, 0x1);
|
||||
} else if ((arith == ARITH_DIV) || (arith == ARITH_QUOT) || (arith == ARITH_REM) || (arith == ARITH_MOD)) {
|
||||
if (reversed) {
|
||||
jit_rshi_l(JIT_V1, JIT_R0, 0x1);
|
||||
|
@ -1403,17 +1417,17 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
__END_INNER_TINY__(branch_short);
|
||||
}
|
||||
}
|
||||
jit_fixnum_l(JIT_R0, JIT_R0);
|
||||
jit_fixnum_l(dest, JIT_R0);
|
||||
} else if (arith == ARITH_AND) {
|
||||
/* and */
|
||||
jit_andr_ul(JIT_R0, JIT_R1, JIT_R0);
|
||||
jit_andr_ul(dest, JIT_R1, JIT_R0);
|
||||
} else if (arith == ARITH_IOR) {
|
||||
/* ior */
|
||||
jit_orr_ul(JIT_R0, JIT_R1, JIT_R0);
|
||||
jit_orr_ul(dest, JIT_R1, JIT_R0);
|
||||
} else if (arith == ARITH_XOR) {
|
||||
/* xor */
|
||||
jit_andi_ul(JIT_R0, JIT_R0, (~0x1));
|
||||
jit_xorr_ul(JIT_R0, JIT_R1, JIT_R0);
|
||||
jit_xorr_ul(dest, JIT_R1, JIT_R0);
|
||||
} else if ((arith == ARITH_LSH) || (arith == ARITH_RSH)) {
|
||||
/* arithmetic-shift
|
||||
This is a lot of code, but if you're using
|
||||
|
@ -1452,7 +1466,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
#else
|
||||
jit_rshr_l(JIT_R2, v1, JIT_V1);
|
||||
#endif
|
||||
jit_ori_l(JIT_R0, JIT_R2, 0x1);
|
||||
jit_ori_l(dest, JIT_R2, 0x1);
|
||||
if (!unsafe_fx || overflow_refslow)
|
||||
refc = jit_jmpi(jit_forward());
|
||||
else
|
||||
|
@ -1483,7 +1497,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
if (!unsafe_fx || overflow_refslow)
|
||||
(void)jit_bner_p(refslow, JIT_V1, v1);
|
||||
/* No overflow. */
|
||||
jit_ori_l(JIT_R0, JIT_R2, 0x1);
|
||||
jit_ori_l(dest, JIT_R2, 0x1);
|
||||
}
|
||||
|
||||
if (refc)
|
||||
|
@ -1495,6 +1509,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
refc = jit_bltr_l(jit_forward(), JIT_R0, JIT_R1);
|
||||
jit_movr_l(JIT_R0, JIT_R1);
|
||||
mz_patch_branch(refc);
|
||||
jit_movr_p(dest, JIT_R0);
|
||||
__END_INNER_TINY__(branch_short);
|
||||
} else if (arith == ARITH_MAX) {
|
||||
/* max */
|
||||
|
@ -1503,17 +1518,18 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
refc = jit_bgtr_l(jit_forward(), JIT_R0, JIT_R1);
|
||||
jit_movr_l(JIT_R0, JIT_R1);
|
||||
mz_patch_branch(refc);
|
||||
jit_movr_p(dest, JIT_R0);
|
||||
__END_INNER_TINY__(branch_short);
|
||||
}
|
||||
} else {
|
||||
/* Non-constant arg is in JIT_R0 */
|
||||
if (arith == ARITH_ADD) {
|
||||
if (unsafe_fx && !overflow_refslow)
|
||||
jit_addi_l(JIT_R0, JIT_R0, v << 1);
|
||||
jit_addi_l(dest, JIT_R0, v << 1);
|
||||
else {
|
||||
jit_movr_p(JIT_R2, JIT_R0);
|
||||
(void)jit_boaddi_l(refslow, JIT_R2, v << 1);
|
||||
jit_movr_p(JIT_R0, JIT_R2);
|
||||
jit_movr_p(dest, JIT_R2);
|
||||
}
|
||||
} else if (arith == ARITH_SUB) {
|
||||
if (reversed) {
|
||||
|
@ -1522,21 +1538,22 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
jit_subr_l(JIT_R2, JIT_R2, JIT_R0);
|
||||
else
|
||||
(void)jit_bosubr_l(refslow, JIT_R2, JIT_R0);
|
||||
jit_addi_ul(JIT_R0, JIT_R2, 0x1);
|
||||
jit_addi_ul(dest, JIT_R2, 0x1);
|
||||
} else {
|
||||
if (unsafe_fx && !overflow_refslow)
|
||||
jit_subi_l(JIT_R0, JIT_R0, v << 1);
|
||||
jit_subi_l(dest, JIT_R0, v << 1);
|
||||
else {
|
||||
jit_movr_p(JIT_R2, JIT_R0);
|
||||
(void)jit_bosubi_l(refslow, JIT_R2, v << 1);
|
||||
jit_movr_p(JIT_R0, JIT_R2);
|
||||
jit_movr_p(dest, JIT_R2);
|
||||
}
|
||||
}
|
||||
} else if (arith == ARITH_MUL) {
|
||||
if (v == 1) {
|
||||
/* R0 already is the answer */
|
||||
jit_movr_p(dest, JIT_R0);
|
||||
} else if (v == 0) {
|
||||
(void)jit_movi_p(JIT_R0, scheme_make_integer(0));
|
||||
(void)jit_movi_p(dest, scheme_make_integer(0));
|
||||
} else {
|
||||
(void)jit_movi_l(JIT_R2, ((intptr_t)scheme_make_integer(v) & (~0x1)));
|
||||
jit_rshi_l(JIT_V1, JIT_R0, 0x1);
|
||||
|
@ -1546,20 +1563,20 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
(void)jit_movi_p(JIT_R1, scheme_make_integer(v)); /* for slow path */
|
||||
(void)jit_bomulr_l(refslow, JIT_V1, JIT_R2);
|
||||
}
|
||||
jit_ori_ul(JIT_R0, JIT_V1, 0x1);
|
||||
jit_ori_ul(dest, JIT_V1, 0x1);
|
||||
}
|
||||
} else {
|
||||
if (arith == ARITH_AND) {
|
||||
/* and */
|
||||
intptr_t l = (intptr_t)scheme_make_integer(v);
|
||||
jit_andi_ul(JIT_R0, JIT_R0, l);
|
||||
jit_andi_ul(dest, JIT_R0, l);
|
||||
} else if (arith == ARITH_IOR) {
|
||||
/* ior */
|
||||
intptr_t l = (intptr_t)scheme_make_integer(v);
|
||||
jit_ori_ul(JIT_R0, JIT_R0, l);
|
||||
jit_ori_ul(dest, JIT_R0, l);
|
||||
} else if (arith == ARITH_XOR) {
|
||||
/* xor */
|
||||
jit_xori_ul(JIT_R0, JIT_R0, v << 1);
|
||||
jit_xori_ul(dest, JIT_R0, v << 1);
|
||||
} else if ((arith == ARITH_LSH) || (arith == ARITH_RSH)) {
|
||||
/* arithmetic-shift */
|
||||
/* We only get here when v is between -MAX_TRY_SHIFT and MAX_TRY_SHIFT, inclusive */
|
||||
|
@ -1568,7 +1585,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
if (arith != ARITH_RSH)
|
||||
amt = -amt;
|
||||
jit_rshi_l(JIT_R0, JIT_R0, amt);
|
||||
jit_ori_l(JIT_R0, JIT_R0, 0x1);
|
||||
jit_ori_l(dest, JIT_R0, 0x1);
|
||||
} else {
|
||||
jit_andi_l(JIT_R0, JIT_R0, (~0x1));
|
||||
jit_lshi_l(JIT_R2, JIT_R0, v);
|
||||
|
@ -1579,11 +1596,11 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
(void)jit_bner_p(refslow, JIT_V1, JIT_R0);
|
||||
}
|
||||
/* No overflow. */
|
||||
jit_ori_l(JIT_R0, JIT_R2, 0x1);
|
||||
jit_ori_l(dest, JIT_R2, 0x1);
|
||||
}
|
||||
} else if (arith == ARITH_NOT) {
|
||||
jit_notr_ul(JIT_R0, JIT_R0);
|
||||
jit_ori_ul(JIT_R0, JIT_R0, 0x1);
|
||||
jit_ori_ul(dest, JIT_R0, 0x1);
|
||||
} else if (arith == ARITH_MIN) {
|
||||
/* min */
|
||||
GC_CAN_IGNORE jit_insn *refc;
|
||||
|
@ -1591,6 +1608,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
refc = jit_blti_l(jit_forward(), JIT_R0, (intptr_t)scheme_make_integer(v));
|
||||
jit_movi_l(JIT_R0, (intptr_t)scheme_make_integer(v));
|
||||
mz_patch_branch(refc);
|
||||
jit_movr_p(dest, JIT_R0);
|
||||
__END_INNER_TINY__(branch_short);
|
||||
} else if (arith == ARITH_MAX) {
|
||||
/* max */
|
||||
|
@ -1599,6 +1617,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
refc = jit_bgti_l(jit_forward(), JIT_R0, (intptr_t)scheme_make_integer(v));
|
||||
jit_movi_l(JIT_R0, (intptr_t)scheme_make_integer(v));
|
||||
mz_patch_branch(refc);
|
||||
jit_movr_p(dest, JIT_R0);
|
||||
__END_INNER_TINY__(branch_short);
|
||||
} else if (arith == ARITH_ABS) {
|
||||
/* abs */
|
||||
|
@ -1614,6 +1633,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
jit_ori_l(JIT_R0, JIT_R0, 0x1);
|
||||
__START_INNER_TINY__(branch_short);
|
||||
mz_patch_branch(refc);
|
||||
jit_movr_p(dest, JIT_R0);
|
||||
__END_INNER_TINY__(branch_short);
|
||||
CHECK_LIMIT();
|
||||
} else if (arith == ARITH_EX_INEX) {
|
||||
|
@ -1626,7 +1646,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
if (!unbox) {
|
||||
mz_rs_sync(); /* needed for unsafe op before allocation */
|
||||
__END_SHORT_JUMPS__(branch_short);
|
||||
scheme_generate_alloc_double(jitter, 0);
|
||||
scheme_generate_alloc_double(jitter, 0, dest);
|
||||
__START_SHORT_JUMPS__(branch_short);
|
||||
} else {
|
||||
jitter->unbox_depth++;
|
||||
|
@ -1635,13 +1655,14 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
} else if (arith == ARITH_INEX_EX) {
|
||||
/* inexact->exact */
|
||||
/* no work to do, since fixnum is already exact */
|
||||
jit_movr_p(dest, JIT_R0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (refdt)
|
||||
mz_patch_ucbranch(refdt);
|
||||
if (!unsafe_fx && !unsafe_fl)
|
||||
jit_patch_movi(ref, (_jit.x.pc));
|
||||
mz_patch_ucbranch(ref);
|
||||
ref3 = NULL;
|
||||
} else {
|
||||
/* If second is constant, first arg is in JIT_R0. */
|
||||
|
@ -1769,7 +1790,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
if (refdt)
|
||||
mz_patch_ucbranch(refdt);
|
||||
|
||||
(void)jit_movi_p(JIT_R0, scheme_true);
|
||||
(void)jit_movi_p(dest, scheme_true);
|
||||
__START_INNER_TINY__(branch_short);
|
||||
ref2 = jit_jmpi(jit_forward());
|
||||
__END_INNER_TINY__(branch_short);
|
||||
|
@ -1777,18 +1798,18 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
|||
mz_patch_branch(ref3);
|
||||
if (refd)
|
||||
mz_patch_branch(refd);
|
||||
(void)jit_movi_p(JIT_R0, scheme_false);
|
||||
(void)jit_movi_p(dest, scheme_false);
|
||||
__START_INNER_TINY__(branch_short);
|
||||
mz_patch_ucbranch(ref2);
|
||||
__END_INNER_TINY__(branch_short);
|
||||
if (!unsafe_fx && !unsafe_fl)
|
||||
jit_patch_movi(ref, (_jit.x.pc));
|
||||
mz_patch_ucbranch(ref);
|
||||
}
|
||||
}
|
||||
|
||||
__END_SHORT_JUMPS__(branch_short);
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#define MAX_NON_SIMPLE_ARGS 5
|
||||
|
@ -1847,7 +1868,8 @@ static void patch_nary_branches(mz_jit_state *jitter, Branch_Info *for_nary_bran
|
|||
}
|
||||
|
||||
int scheme_generate_nary_arith(mz_jit_state *jitter, Scheme_App_Rec *app,
|
||||
int arith, int cmp, Branch_Info *for_branch, int branch_short)
|
||||
int arith, int cmp, Branch_Info *for_branch, int branch_short,
|
||||
int dest)
|
||||
{
|
||||
int c, i, non_simple_c = 0, stack_c, use_fx = 1, trigger_arg = 0;
|
||||
Scheme_Object *non_simples[1+MAX_NON_SIMPLE_ARGS], **alt_args, *v;
|
||||
|
@ -1997,7 +2019,8 @@ int scheme_generate_nary_arith(mz_jit_state *jitter, Scheme_App_Rec *app,
|
|||
if (!arith) init_nary_branches(&for_nary_branch, nary_addrs);
|
||||
__END_SHORT_JUMPS__(c < 100);
|
||||
scheme_generate_arith(jitter, NULL, NULL, scheme_void, 2, arith, cmp, 0,
|
||||
!arith ? &for_nary_branch : NULL, c < 100, 0, 1, NULL);
|
||||
!arith ? &for_nary_branch : NULL, c < 100, 0, 1, NULL,
|
||||
JIT_R0);
|
||||
__START_SHORT_JUMPS__(c < 100);
|
||||
if (!arith) patch_nary_branches(jitter, &for_nary_branch, reffalse);
|
||||
CHECK_LIMIT();
|
||||
|
@ -2037,7 +2060,8 @@ int scheme_generate_nary_arith(mz_jit_state *jitter, Scheme_App_Rec *app,
|
|||
if (!arith) init_nary_branches(&for_nary_branch, nary_addrs);
|
||||
__END_SHORT_JUMPS__(c < 100);
|
||||
scheme_generate_arith(jitter, NULL, NULL, scheme_void, 2, arith, cmp, 0,
|
||||
!arith ? &for_nary_branch : NULL, c < 100, 1, 0, refslow);
|
||||
!arith ? &for_nary_branch : NULL, c < 100, 1, 0, refslow,
|
||||
JIT_R0);
|
||||
__START_SHORT_JUMPS__(c < 100);
|
||||
if (!arith) patch_nary_branches(jitter, &for_nary_branch, reffalse);
|
||||
CHECK_LIMIT();
|
||||
|
@ -2077,6 +2101,9 @@ int scheme_generate_nary_arith(mz_jit_state *jitter, Scheme_App_Rec *app,
|
|||
CHECK_LIMIT();
|
||||
}
|
||||
|
||||
if (!for_branch && !jitter->unbox)
|
||||
jit_movr_p(dest, JIT_R0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -599,8 +599,9 @@ static int common2(mz_jit_state *jitter, void *_data)
|
|||
GC_CAN_IGNORE jit_insn *ref, *ref2;
|
||||
|
||||
/* *** call_original_unary_arith_code *** */
|
||||
/* R0 is arg, R2 is code pointer, V1 is return address (for false);
|
||||
if for branch, LOCAL2 is target address for true */
|
||||
/* R0 is arg, R2 is code pointer;
|
||||
if for branch, V1 is return address for false,
|
||||
LOCAL2 is target address for true */
|
||||
for (i = 0; i < 3; i++) {
|
||||
int argc, j;
|
||||
void *code;
|
||||
|
@ -626,6 +627,9 @@ static int common2(mz_jit_state *jitter, void *_data)
|
|||
sjc.call_original_binary_rev_arith_for_branch_code = code;
|
||||
argc = 2;
|
||||
}
|
||||
if (!j) {
|
||||
mz_prolog(JIT_V1);
|
||||
}
|
||||
jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(argc));
|
||||
CHECK_RUNSTACK_OVERFLOW();
|
||||
if (i == 2) {
|
||||
|
@ -638,10 +642,6 @@ static int common2(mz_jit_state *jitter, void *_data)
|
|||
jit_str_p(JIT_RUNSTACK, JIT_R0);
|
||||
}
|
||||
jit_movi_i(JIT_R1, argc);
|
||||
if (!j) {
|
||||
/* For stack-trace reporting, stuff return address into LOCAL2 */
|
||||
mz_set_local_p(JIT_V1, JIT_LOCAL2);
|
||||
}
|
||||
JIT_UPDATE_THREAD_RSPTR();
|
||||
mz_prepare_direct_prim(2);
|
||||
{
|
||||
|
@ -656,7 +656,7 @@ static int common2(mz_jit_state *jitter, void *_data)
|
|||
jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(argc));
|
||||
JIT_UPDATE_THREAD_RSPTR();
|
||||
if (!j) {
|
||||
jit_jmpr(JIT_V1);
|
||||
mz_epilog(JIT_V1);
|
||||
} else {
|
||||
/* In for_branch mode, V1 is target for false, LOCAL2 is target for true */
|
||||
mz_get_local_p(JIT_R1, JIT_LOCAL2);
|
||||
|
@ -669,7 +669,10 @@ static int common2(mz_jit_state *jitter, void *_data)
|
|||
}
|
||||
CHECK_LIMIT();
|
||||
|
||||
scheme_jit_register_sub_func(jitter, code, scheme_void);
|
||||
if (!j)
|
||||
scheme_jit_register_sub_func(jitter, code, scheme_false);
|
||||
else
|
||||
scheme_jit_register_sub_func(jitter, code, scheme_void);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1682,7 +1685,7 @@ static int common4(mz_jit_state *jitter, void *_data)
|
|||
jit_movi_i(JIT_R1, 3);
|
||||
if (i == 2) {
|
||||
/* need to box flonum */
|
||||
scheme_generate_alloc_double(jitter, 1);
|
||||
scheme_generate_alloc_double(jitter, 1, JIT_R0);
|
||||
jit_stxi_p(WORDS_TO_BYTES(2), JIT_RUNSTACK, JIT_R0);
|
||||
}
|
||||
}
|
||||
|
@ -2103,7 +2106,7 @@ static int common4c(mz_jit_state *jitter, void *_data)
|
|||
} else
|
||||
num_args = 0;
|
||||
|
||||
scheme_generate_struct_alloc(jitter, num_args, 1, 1, ii == 2, ii == 1);
|
||||
scheme_generate_struct_alloc(jitter, num_args, 1, 1, ii == 2, ii == 1, JIT_R0);
|
||||
|
||||
CHECK_LIMIT();
|
||||
|
||||
|
@ -2165,7 +2168,7 @@ static int common5(mz_jit_state *jitter, void *_data)
|
|||
jit_ldxr_p(JIT_R1, JIT_RUNSTACK, JIT_R2);
|
||||
mz_set_local_p(JIT_R2, JIT_LOCAL3);
|
||||
|
||||
scheme_generate_cons_alloc(jitter, 1, 1);
|
||||
scheme_generate_cons_alloc(jitter, 1, 1, JIT_R0);
|
||||
CHECK_LIMIT();
|
||||
|
||||
mz_get_local_p(JIT_R2, JIT_LOCAL3);
|
||||
|
@ -2190,7 +2193,7 @@ static int common5(mz_jit_state *jitter, void *_data)
|
|||
|
||||
jit_movr_p(JIT_R1, JIT_FP);
|
||||
jit_ldxr_d_fppush(JIT_FPR0, JIT_R1, JIT_R0);
|
||||
scheme_generate_alloc_double(jitter, 1);
|
||||
scheme_generate_alloc_double(jitter, 1, JIT_R0);
|
||||
CHECK_LIMIT();
|
||||
|
||||
mz_epilog(JIT_R2);
|
||||
|
@ -2209,7 +2212,7 @@ static int common5(mz_jit_state *jitter, void *_data)
|
|||
jit_movr_d(JIT_FPR0, JIT_FPR2);
|
||||
#endif
|
||||
|
||||
scheme_generate_alloc_double(jitter, 1);
|
||||
scheme_generate_alloc_double(jitter, 1, JIT_R0);
|
||||
CHECK_LIMIT();
|
||||
|
||||
mz_epilog(JIT_R2);
|
||||
|
@ -2281,7 +2284,7 @@ static int common5(mz_jit_state *jitter, void *_data)
|
|||
jit_stxi_p(WORDS_TO_BYTES(a1), JIT_RUNSTACK, JIT_V1);
|
||||
|
||||
if (i != 0) {
|
||||
scheme_generate_alloc_double(jitter, 1);
|
||||
scheme_generate_alloc_double(jitter, 1, JIT_R0);
|
||||
CHECK_LIMIT();
|
||||
if (i == 1) {
|
||||
jit_ldxi_p(JIT_V1, JIT_RUNSTACK, WORDS_TO_BYTES(a0));
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -231,7 +231,7 @@ struct jit_local_state {
|
|||
#define jit_movi_i(d, is) MOVEIri((d), (is))
|
||||
#define jit_movi_p(d, is) (LISri((d), _HI((is))),ORIrri((d),(d),_LO((is))),_jit.x.pc)
|
||||
|
||||
#define jit_movr_i(d, rs) MRrr((d), (rs))
|
||||
#define jit_movr_i(d, rs) (((d) == (rs)) ? 0 : MRrr((d), (rs)))
|
||||
#define jit_muli_i(d, rs, is) jit_chk_ims ((is), MULLIrri((d), (rs), (is)), MULLWrrr((d), (rs), JIT_AUX))
|
||||
#define jit_muli_ui(d, rs, is) jit_chk_imu15((is), MULLIrri((d), (rs), (is)), MULLWrrr((d), (rs), JIT_AUX))
|
||||
#define jit_mulr_i(d, s1, s2) MULLWrrr((d), (s1), (s2))
|
||||
|
|
Loading…
Reference in New Issue
Block a user