diff --git a/collects/tests/racket/unsafe.rktl b/collects/tests/racket/unsafe.rktl index 317c3e44b8..489786629b 100644 --- a/collects/tests/racket/unsafe.rktl +++ b/collects/tests/racket/unsafe.rktl @@ -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) diff --git a/src/racket/src/jit.c b/src/racket/src/jit.c index d9ad2c18ed..756b58b40a 100644 --- a/src/racket/src/jit.c +++ b/src/racket/src/jit.c @@ -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; } diff --git a/src/racket/src/jit.h b/src/racket/src/jit.h index 28b7737d81..9213036b28 100644 --- a/src/racket/src/jit.h +++ b/src/racket/src/jit.h @@ -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 */ diff --git a/src/racket/src/jitarith.c b/src/racket/src/jitarith.c index 584f0bce1b..136daa1e10 100644 --- a/src/racket/src/jitarith.c +++ b/src/racket/src/jitarith.c @@ -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; } diff --git a/src/racket/src/jitcommon.c b/src/racket/src/jitcommon.c index d83fe2412b..9ad26f42be 100644 --- a/src/racket/src/jitcommon.c +++ b/src/racket/src/jitcommon.c @@ -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)); diff --git a/src/racket/src/jitinline.c b/src/racket/src/jitinline.c index a9dc086bd3..26097ddc7d 100644 --- a/src/racket/src/jitinline.c +++ b/src/racket/src/jitinline.c @@ -198,7 +198,8 @@ int scheme_inlined_nary_prim(Scheme_Object *o, Scheme_Object *_app, mz_jit_state static int generate_inlined_constant_test(mz_jit_state *jitter, Scheme_App2_Rec *app, Scheme_Object *cnst, Scheme_Object *cnst2, - Branch_Info *for_branch, int branch_short, int need_sync) + Branch_Info *for_branch, int branch_short, int need_sync, + int dest) /* de-sync'd ok */ { GC_CAN_IGNORE jit_insn *ref, *ref2; @@ -234,10 +235,10 @@ static int generate_inlined_constant_test(mz_jit_state *jitter, Scheme_App2_Rec scheme_branch_for_true(jitter, for_branch); CHECK_LIMIT(); } else { - (void)jit_movi_p(JIT_R0, scheme_true); + (void)jit_movi_p(dest, scheme_true); ref2 = jit_jmpi(jit_forward()); mz_patch_branch(ref); - (void)jit_movi_p(JIT_R0, scheme_false); + (void)jit_movi_p(dest, scheme_false); mz_patch_ucbranch(ref2); } @@ -248,7 +249,8 @@ static int generate_inlined_constant_test(mz_jit_state *jitter, Scheme_App2_Rec static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app, Scheme_Type lo_ty, Scheme_Type hi_ty, int can_chaperone, - Branch_Info *for_branch, int branch_short, int need_sync) + Branch_Info *for_branch, int branch_short, int need_sync, + int dest) { GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *ref4, *ref5; int int_ok, reg_valid; @@ -331,7 +333,7 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app scheme_branch_for_true(jitter, for_branch); CHECK_LIMIT(); } else { - (void)jit_movi_p(JIT_R0, scheme_true); + (void)jit_movi_p(dest, scheme_true); ref2 = jit_jmpi(jit_forward()); if (!int_ok) { mz_patch_branch(ref); @@ -343,7 +345,7 @@ static int generate_inlined_type_test(mz_jit_state *jitter, Scheme_App2_Rec *app if (ref5) { mz_patch_branch(ref5); } - (void)jit_movi_p(JIT_R0, scheme_false); + (void)jit_movi_p(dest, scheme_false); mz_patch_ucbranch(ref2); } @@ -367,7 +369,8 @@ static Scheme_Object *extract_struct_constant(mz_jit_state *jitter, Scheme_Objec static int generate_inlined_struct_op(int kind, mz_jit_state *jitter, Scheme_Object *rator, Scheme_Object *rand, Scheme_Object *rand2, Branch_Info *for_branch, int branch_short, - int is_tail, int multi_ok, int result_ignored) + int is_tail, int multi_ok, int result_ignored, + int dest) /* de-sync'd ok; for branch, sync'd before */ { GC_CAN_IGNORE jit_insn *ref, *ref2, *refslow; @@ -482,7 +485,7 @@ static int generate_inlined_struct_op(int kind, mz_jit_state *jitter, (void)jit_calli(sjc.struct_prop_pred_code); } } else if (kind == INLINE_STRUCT_PROC_CONSTR) { - scheme_generate_struct_alloc(jitter, rand2 ? 2 : 1, 0, 0, is_tail, multi_ok); + scheme_generate_struct_alloc(jitter, rand2 ? 2 : 1, 0, 0, is_tail, multi_ok, JIT_R0); CHECK_LIMIT(); } else { scheme_signal_error("internal error: unknown struct-op mode"); @@ -530,6 +533,9 @@ static int generate_inlined_struct_op(int kind, mz_jit_state *jitter, } } + if (!for_branch) + jit_movr_p(dest, JIT_R0); + return 1; } @@ -596,7 +602,7 @@ Scheme_Structure *scheme_jit_allocate_structure(int argc, Scheme_Struct_Type *st static int generate_inlined_nary_struct_op(int kind, mz_jit_state *jitter, Scheme_Object *rator, Scheme_App_Rec *app, Branch_Info *for_branch, int branch_short, - int is_tail, int multi_ok) + int is_tail, int multi_ok, int dest) /* de-sync'd ok; for branch, sync'd before */ { /* generate code to evaluate the arguments */ @@ -607,7 +613,7 @@ static int generate_inlined_nary_struct_op(int kind, mz_jit_state *jitter, jit_movr_l(JIT_R0, JIT_V1); /* move rator to R0 */ /* arguments are now on the runstack, rator is in R0 */ - scheme_generate_struct_alloc(jitter, app->num_args, 0, 0, is_tail, multi_ok); + scheme_generate_struct_alloc(jitter, app->num_args, 0, 0, is_tail, multi_ok, dest); CHECK_LIMIT(); @@ -621,7 +627,7 @@ static int generate_inlined_nary_struct_op(int kind, mz_jit_state *jitter, 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) /* Rator is in R0. For unary case, R1 is argument. For binary case, R1 is first argument, V1 is second argument. @@ -688,13 +694,13 @@ int scheme_generate_struct_alloc(mz_jit_state *jitter, int num_args, scheme_generate_finish_apply(jitter); } CHECK_LIMIT(); - jit_retval(JIT_R0); - VALIDATE_RESULT(JIT_R0); + jit_retval(dest); + VALIDATE_RESULT(dest); if ((num_args == 1) || (num_args == 2)) { jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(num_args)); JIT_UPDATE_THREAD_RSPTR(); } - } else { + } else { if (num_args == 1) { if (is_tail) (void)jit_calli(sjc.struct_constr_unary_tail_code); @@ -720,6 +726,7 @@ int scheme_generate_struct_alloc(mz_jit_state *jitter, int num_args, else (void)jit_calli(sjc.struct_constr_nary_code); } + jit_movr_p(dest, JIT_R0); } if (pop_and_jump) { @@ -786,7 +793,7 @@ int scheme_generate_struct_alloc(mz_jit_state *jitter, int num_args, jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); jit_stxi_p((intptr_t)&(((Scheme_Structure *)0x0)->slots[1]) + OBJHEAD_SIZE, JIT_V1, JIT_R1); } - jit_addi_p(JIT_R0, JIT_V1, OBJHEAD_SIZE); + jit_addi_p(dest, JIT_V1, OBJHEAD_SIZE); #else jit_subi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(1)); CHECK_RUNSTACK_OVERFLOW(); @@ -797,7 +804,7 @@ int scheme_generate_struct_alloc(mz_jit_state *jitter, int num_args, jit_pusharg_i(JIT_V1); jit_pusharg_p(JIT_R2); (void)mz_finish_lwe(alloc_structure, refrts); - jit_retval(JIT_R0); + jit_retval(dest); jit_addi_p(JIT_RUNSTACK, JIT_RUNSTACK, WORDS_TO_BYTES(num_args)); JIT_UPDATE_THREAD_RSPTR(); #endif @@ -807,7 +814,7 @@ int scheme_generate_struct_alloc(mz_jit_state *jitter, int num_args, jit_pusharg_i(JIT_R1); jit_pusharg_p(JIT_R2); (void)mz_finish_lwe(alloc_structure, refrts); - jit_retval(JIT_R0); + jit_retval(dest); } else { #ifdef CAN_INLINE_ALLOC int i; @@ -821,7 +828,7 @@ int scheme_generate_struct_alloc(mz_jit_state *jitter, int num_args, jit_stxi_p((intptr_t)&(((Scheme_Structure *)0x0)->slots[0]) + OBJHEAD_SIZE + WORDS_TO_BYTES(i), JIT_V1, JIT_R1); CHECK_LIMIT(); } - jit_addi_p(JIT_R0, JIT_V1, OBJHEAD_SIZE); + jit_addi_p(dest, JIT_V1, OBJHEAD_SIZE); #else JIT_UPDATE_THREAD_RSPTR(); jit_movi_l(JIT_R1, num_args); @@ -829,7 +836,7 @@ int scheme_generate_struct_alloc(mz_jit_state *jitter, int num_args, jit_pusharg_i(JIT_R1); jit_pusharg_p(JIT_R2); (void)mz_finish_lwe(alloc_structure, refrts); - jit_retval(JIT_R0); + jit_retval(dest); #endif } CHECK_LIMIT(); @@ -853,13 +860,14 @@ static int is_cXr_prim(const char *name) } static int generate_inlined_constant_varref_test(mz_jit_state *jitter, Scheme_Object *obj, - Branch_Info *for_branch, int branch_short, int need_sync) + Branch_Info *for_branch, int branch_short, int need_sync, + int dest) { GC_CAN_IGNORE jit_insn *ref1, *ref2; int pos; if (SCHEME_VARREF_FLAGS(obj) & 0x1) { - (void)jit_movi_p(JIT_R0, scheme_true); + (void)jit_movi_p(dest, scheme_true); return 1; } @@ -894,11 +902,11 @@ static int generate_inlined_constant_varref_test(mz_jit_state *jitter, Scheme_Ob scheme_add_branch_false(for_branch, ref1); scheme_branch_for_true(jitter, for_branch); } else { - (void)jit_movi_p(JIT_R0, scheme_true); + (void)jit_movi_p(dest, scheme_true); ref2 = jit_jmpi(jit_forward()); mz_patch_branch(ref1); - (void)jit_movi_p(JIT_R0, scheme_false); + (void)jit_movi_p(dest, scheme_false); mz_patch_ucbranch(ref2); } @@ -910,10 +918,12 @@ static int generate_inlined_constant_varref_test(mz_jit_state *jitter, Scheme_Ob } static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator, - Scheme_App_Rec *app, Scheme_App2_Rec *app2, Scheme_App3_Rec *app3); + Scheme_App_Rec *app, Scheme_App2_Rec *app2, Scheme_App3_Rec *app3, + int dest); 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) /* de-sync's, unless branch */ { Scheme_Object *rator = app->rator; @@ -923,7 +933,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in k = inlineable_struct_prim(rator, jitter, 1, 1); if (k == INLINE_STRUCT_PROC_PRED) { generate_inlined_struct_op(1, jitter, rator, app->rand, NULL, for_branch, branch_short, is_tail, multi_ok, - result_ignored); + result_ignored, dest); scheme_direct_call_count++; return 1; } else if (((k == INLINE_STRUCT_PROC_GET) @@ -932,7 +942,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in || (k == INLINE_STRUCT_PROC_CONSTR)) && !for_branch) { generate_inlined_struct_op(k, jitter, rator, app->rand, NULL, for_branch, branch_short, is_tail, multi_ok, - result_ignored); + result_ignored, dest); scheme_direct_call_count++; return 1; } @@ -940,7 +950,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in if (SAME_OBJ(rator, scheme_varref_const_p_proc) && SAME_TYPE(SCHEME_TYPE(app->rand), scheme_varref_form_type)) { - generate_inlined_constant_varref_test(jitter, app->rand, for_branch, branch_short, need_sync); + generate_inlined_constant_varref_test(jitter, app->rand, for_branch, branch_short, need_sync, dest); return 1; } @@ -953,94 +963,94 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in scheme_direct_call_count++; if (IS_NAMED_PRIM(rator, "not")) { - generate_inlined_constant_test(jitter, app, scheme_false, NULL, for_branch, branch_short, need_sync); + generate_inlined_constant_test(jitter, app, scheme_false, NULL, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "null?")) { - generate_inlined_constant_test(jitter, app, scheme_null, NULL, for_branch, branch_short, need_sync); + generate_inlined_constant_test(jitter, app, scheme_null, NULL, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "void?")) { - generate_inlined_constant_test(jitter, app, scheme_void, NULL, for_branch, branch_short, need_sync); + generate_inlined_constant_test(jitter, app, scheme_void, NULL, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "pair?")) { - generate_inlined_type_test(jitter, app, scheme_pair_type, scheme_pair_type, 0, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_pair_type, scheme_pair_type, 0, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "mpair?")) { - generate_inlined_type_test(jitter, app, scheme_mutable_pair_type, scheme_mutable_pair_type, 0, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_mutable_pair_type, scheme_mutable_pair_type, 0, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "symbol?")) { - generate_inlined_type_test(jitter, app, scheme_symbol_type, scheme_symbol_type, 0, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_symbol_type, scheme_symbol_type, 0, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "syntax?")) { - generate_inlined_type_test(jitter, app, scheme_stx_type, scheme_stx_type, 0, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_stx_type, scheme_stx_type, 0, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "char?")) { - generate_inlined_type_test(jitter, app, scheme_char_type, scheme_char_type, 0, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_char_type, scheme_char_type, 0, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "boolean?")) { - generate_inlined_constant_test(jitter, app, scheme_false, scheme_true, for_branch, branch_short, need_sync); + generate_inlined_constant_test(jitter, app, scheme_false, scheme_true, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "number?")) { - generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_complex_type, 0, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_complex_type, 0, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "real?")) { - generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_double_type, 0, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_double_type, 0, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "exact-integer?")) { - generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_bignum_type, 0, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_bignum_type, 0, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fixnum?")) { - generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_integer_type, 0, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_integer_type, scheme_integer_type, 0, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "inexact-real?")) { - generate_inlined_type_test(jitter, app, SCHEME_FLOAT_TYPE, scheme_double_type, 0, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, SCHEME_FLOAT_TYPE, scheme_double_type, 0, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "flonum?")) { - generate_inlined_type_test(jitter, app, scheme_double_type, scheme_double_type, 0, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_double_type, scheme_double_type, 0, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "single-flonum?")) { - generate_inlined_type_test(jitter, app, SCHEME_FLOAT_TYPE, SCHEME_FLOAT_TYPE, 0, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, SCHEME_FLOAT_TYPE, SCHEME_FLOAT_TYPE, 0, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "procedure?")) { - generate_inlined_type_test(jitter, app, scheme_prim_type, scheme_proc_chaperone_type, 1, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_prim_type, scheme_proc_chaperone_type, 1, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "chaperone?")) { - generate_inlined_type_test(jitter, app, scheme_proc_chaperone_type, scheme_chaperone_type, -1, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_proc_chaperone_type, scheme_chaperone_type, -1, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "impersonator?")) { - generate_inlined_type_test(jitter, app, scheme_proc_chaperone_type, scheme_chaperone_type, 0, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_proc_chaperone_type, scheme_chaperone_type, 0, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "vector?")) { - generate_inlined_type_test(jitter, app, scheme_vector_type, scheme_vector_type, 1, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_vector_type, scheme_vector_type, 1, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "box?")) { - generate_inlined_type_test(jitter, app, scheme_box_type, scheme_box_type, 1, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_box_type, scheme_box_type, 1, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "string?")) { - generate_inlined_type_test(jitter, app, scheme_char_string_type, scheme_char_string_type, 0, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_char_string_type, scheme_char_string_type, 0, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "bytes?")) { - generate_inlined_type_test(jitter, app, scheme_byte_string_type, scheme_byte_string_type, 0, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_byte_string_type, scheme_byte_string_type, 0, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "path?")) { - generate_inlined_type_test(jitter, app, SCHEME_PLATFORM_PATH_KIND, SCHEME_PLATFORM_PATH_KIND, 0, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, SCHEME_PLATFORM_PATH_KIND, SCHEME_PLATFORM_PATH_KIND, 0, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "eof-object?")) { - generate_inlined_constant_test(jitter, app, scheme_eof, NULL, for_branch, branch_short, need_sync); + generate_inlined_constant_test(jitter, app, scheme_eof, NULL, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "zero?")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, 0, CMP_EQUAL, 0, for_branch, branch_short, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, 0, CMP_EQUAL, 0, for_branch, branch_short, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "negative?")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, 0, CMP_LT, 0, for_branch, branch_short, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, 0, CMP_LT, 0, for_branch, branch_short, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "positive?")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, 0, CMP_GT, 0, for_branch, branch_short, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, 0, CMP_GT, 0, for_branch, branch_short, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "even?")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, 0, CMP_EVENP, 0, for_branch, branch_short, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, 0, CMP_EVENP, 0, for_branch, branch_short, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "odd?")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, 0, CMP_ODDP, 0, for_branch, branch_short, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, 0, CMP_ODDP, 0, for_branch, branch_short, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "list?")) { GC_CAN_IGNORE jit_insn *ref0, *ref1, *ref3, *ref4; @@ -1081,15 +1091,16 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in GC_CAN_IGNORE jit_insn *ref5; (void)jit_calli(sjc.list_p_code); + jit_movr_p(dest, JIT_R0); ref5 = jit_jmpi(jit_forward()); mz_patch_branch(ref1); mz_patch_branch(ref4); - (void)jit_movi_p(JIT_R0, scheme_false); + (void)jit_movi_p(dest, scheme_false); ref1 = jit_jmpi(jit_forward()); mz_patch_branch(ref3); - (void)jit_movi_p(JIT_R0, scheme_true); + (void)jit_movi_p(dest, scheme_true); mz_patch_ucbranch(ref5); mz_patch_ucbranch(ref1); @@ -1155,12 +1166,12 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in scheme_branch_for_true(jitter, for_branch); CHECK_LIMIT(); } else { - (void)jit_movi_p(JIT_R0, scheme_true); + (void)jit_movi_p(dest, scheme_true); ref = jit_jmpi(jit_forward()); mz_patch_branch(ref2); mz_patch_branch(ref3); mz_patch_branch(ref4); - (void)jit_movi_p(JIT_R0, scheme_false); + (void)jit_movi_p(dest, scheme_false); mz_patch_ucbranch(ref); } @@ -1171,7 +1182,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in if (is_cXr_prim(((Scheme_Primitive_Proc *)rator)->name)) { # define MAX_LEVELS 2 GC_CAN_IGNORE jit_insn *reffail = NULL, *ref; - int steps, i; + int steps, i, this_dest; const char *name = ((Scheme_Primitive_Proc *)rator)->name; LOG_IT(("inlined %s\n", ((Scheme_Primitive_Proc *)rator)->name)); @@ -1194,6 +1205,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in jit_movr_p(JIT_R2, JIT_R0); /* save original argument */ } for (i = 0; i < steps; i++) { + this_dest = ((i + 1 < steps) ? JIT_R0 : dest); if (!sjc.skip_checks) { if (!i) { ref = jit_bmci_ul(jit_forward(), JIT_R0, 0x1); @@ -1233,11 +1245,11 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in reffail = NULL; } if (name[steps - i] == 'a') { - (void)jit_ldxi_p(JIT_R0, JIT_R0, &((Scheme_Simple_Object *)0x0)->u.pair_val.car); + (void)jit_ldxi_p(this_dest, JIT_R0, &((Scheme_Simple_Object *)0x0)->u.pair_val.car); } else { - (void)jit_ldxi_p(JIT_R0, JIT_R0, &((Scheme_Simple_Object *)0x0)->u.pair_val.cdr); + (void)jit_ldxi_p(this_dest, JIT_R0, &((Scheme_Simple_Object *)0x0)->u.pair_val.cdr); } - VALIDATE_RESULT(JIT_R0); + VALIDATE_RESULT(this_dest); CHECK_LIMIT(); } __END_TINY_JUMPS__(1); @@ -1273,11 +1285,11 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_patch_branch(ref); (void)mz_bnei_t(reffail, JIT_R0, scheme_mutable_pair_type, JIT_R1); if (name[2] == 'a') { - (void)jit_ldxi_p(JIT_R0, JIT_R0, &((Scheme_Simple_Object *)0x0)->u.pair_val.car); + (void)jit_ldxi_p(dest, JIT_R0, &((Scheme_Simple_Object *)0x0)->u.pair_val.car); } else { - (void)jit_ldxi_p(JIT_R0, JIT_R0, &((Scheme_Simple_Object *)0x0)->u.pair_val.cdr); + (void)jit_ldxi_p(dest, JIT_R0, &((Scheme_Simple_Object *)0x0)->u.pair_val.cdr); } - VALIDATE_RESULT(JIT_R0); + VALIDATE_RESULT(dest); CHECK_LIMIT(); __END_TINY_JUMPS__(1); @@ -1298,9 +1310,9 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_runstack_unskipped(jitter, 1); if (!strcmp(name, "unsafe-car") || !strcmp(name, "unsafe-mcar")) { - (void)jit_ldxi_p(JIT_R0, JIT_R0, &((Scheme_Simple_Object *)0x0)->u.pair_val.car); + (void)jit_ldxi_p(dest, JIT_R0, &((Scheme_Simple_Object *)0x0)->u.pair_val.car); } else { - (void)jit_ldxi_p(JIT_R0, JIT_R0, &((Scheme_Simple_Object *)0x0)->u.pair_val.cdr); + (void)jit_ldxi_p(dest, JIT_R0, &((Scheme_Simple_Object *)0x0)->u.pair_val.cdr); } CHECK_LIMIT(); @@ -1315,6 +1327,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_rs_sync(); (void)jit_calli(sjc.list_length_code); + jit_movr_p(dest, JIT_R0); return 1; } else if (IS_NAMED_PRIM(rator, "vector-length") @@ -1393,7 +1406,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in (void)jit_ldxi_l(JIT_R0, JIT_R0, &SCHEME_VEC_SIZE(0x0)); else (void)jit_ldxi_l(JIT_R0, JIT_R0, &SCHEME_FLVEC_SIZE(0x0)); - jit_fixnum_l(JIT_R0, JIT_R0); + jit_fixnum_l(dest, JIT_R0); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-string-length") @@ -1411,7 +1424,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in (void)jit_ldxi_l(JIT_R0, JIT_R0, &SCHEME_CHAR_STRLEN_VAL(0x0)); else (void)jit_ldxi_l(JIT_R0, JIT_R0, &SCHEME_BYTE_STRLEN_VAL(0x0)); - jit_fixnum_l(JIT_R0, JIT_R0); + jit_fixnum_l(dest, JIT_R0); return 1; } else if (IS_NAMED_PRIM(rator, "unbox")) { @@ -1434,6 +1447,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in reffail = _jit.x.pc; (void)jit_calli(sjc.unbox_code); + jit_movr_p(dest, JIT_R0); __START_TINY_JUMPS__(1); refdone = jit_jmpi(jit_forward()); @@ -1441,7 +1455,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in (void)mz_bnei_t(reffail, JIT_R0, scheme_box_type, JIT_R1); __END_TINY_JUMPS__(1); - (void)jit_ldxi_p(JIT_R0, JIT_R0, &SCHEME_BOX_VAL(0x0)); + (void)jit_ldxi_p(dest, JIT_R0, &SCHEME_BOX_VAL(0x0)); __START_TINY_JUMPS__(1); mz_patch_ucbranch(refdone); @@ -1458,7 +1472,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_runstack_unskipped(jitter, 1); - (void)jit_ldxi_p(JIT_R0, JIT_R0, &SCHEME_BOX_VAL(0x0)); + (void)jit_ldxi_p(dest, JIT_R0, &SCHEME_BOX_VAL(0x0)); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-unbox")) { @@ -1479,14 +1493,13 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in __START_TINY_JUMPS__(1); ref = mz_bnei_t(jit_forward(), JIT_R0, scheme_chaperone_type, JIT_R1); (void)jit_calli(sjc.unbox_code); - jit_retval(JIT_R0); + jit_retval(dest); ref2 = jit_jmpi(jit_forward()); - jit_retval(JIT_R0); mz_patch_branch(ref); CHECK_LIMIT(); __END_TINY_JUMPS__(1); - (void)jit_ldxi_p(JIT_R0, JIT_R0, &SCHEME_BOX_VAL(0x0)); + (void)jit_ldxi_p(dest, JIT_R0, &SCHEME_BOX_VAL(0x0)); __START_TINY_JUMPS__(1); mz_patch_ucbranch(ref2); @@ -1506,6 +1519,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_rs_sync(); (void)jit_calli(sjc.syntax_e_code); + jit_movr_p(dest, JIT_R0); return 1; } else if (IS_NAMED_PRIM(rator, "imag-part") @@ -1549,6 +1563,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in if (name[0] != 'f') { /* can return */ CHECK_LIMIT(); + jit_movr_p(dest, JIT_R0); __START_TINY_JUMPS__(1); refdone = jit_jmpi(jit_forward()); __END_TINY_JUMPS__(1); @@ -1559,28 +1574,28 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_patch_branch(ref); (void)mz_bnei_t(reffail, JIT_R0, scheme_complex_type, JIT_R1); if (name[0] == 'i') { - (void)jit_ldxi_p(JIT_R0, JIT_R0, &((Scheme_Complex *)0x0)->i); + (void)jit_ldxi_p(dest, JIT_R0, &((Scheme_Complex *)0x0)->i); } else if (name[0] == 'r') { - (void)jit_ldxi_p(JIT_R0, JIT_R0, &((Scheme_Complex *)0x0)->r); + (void)jit_ldxi_p(dest, JIT_R0, &((Scheme_Complex *)0x0)->r); } else { /* real part must always be inexact */ (void)jit_ldxi_p(JIT_R1, JIT_R0, &((Scheme_Complex *)0x0)->r); CHECK_LIMIT(); (void)mz_bnei_t(reffail, JIT_R1, scheme_double_type, JIT_R2); if (name[2] == 'i') { - (void)jit_ldxi_p(JIT_R0, JIT_R0, &((Scheme_Complex *)0x0)->i); + (void)jit_ldxi_p(dest, JIT_R0, &((Scheme_Complex *)0x0)->i); } else { - jit_movr_p(JIT_R0, JIT_R1); + jit_movr_p(dest, JIT_R1); } } - VALIDATE_RESULT(JIT_R0); + VALIDATE_RESULT(dest); if (refdone) mz_patch_ucbranch(refdone); CHECK_LIMIT(); __END_TINY_JUMPS__(1); if (jitter->unbox) /* for fl....-part: */ - scheme_generate_unboxing(jitter, JIT_R0); + scheme_generate_unboxing(jitter, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-flimag-part") @@ -1603,45 +1618,45 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_runstack_unskipped(jitter, 1); if (name[9] == 'i') { - (void)jit_ldxi_p(JIT_R0, JIT_R0, &((Scheme_Complex *)0x0)->i); + (void)jit_ldxi_p(dest, JIT_R0, &((Scheme_Complex *)0x0)->i); } else { - (void)jit_ldxi_p(JIT_R0, JIT_R0, &((Scheme_Complex *)0x0)->r); + (void)jit_ldxi_p(dest, JIT_R0, &((Scheme_Complex *)0x0)->r); } CHECK_LIMIT(); if (jitter->unbox) - scheme_generate_unboxing(jitter, JIT_R0); + scheme_generate_unboxing(jitter, dest); return 1; } else if (IS_NAMED_PRIM(rator, "add1")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_ADD, 0, 1, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_ADD, 0, 1, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "sub1")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_SUB, 0, 1, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_SUB, 0, 1, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "-")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_SUB, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_SUB, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "abs")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_ABS, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_ABS, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fxabs")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_ABS, 0, 0, NULL, 1, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_ABS, 0, 0, NULL, 1, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fxabs")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_ABS, 0, 0, NULL, 1, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_ABS, 0, 0, NULL, 1, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-flabs")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_ABS, 0, 0, NULL, 1, 0, 1, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_ABS, 0, 0, NULL, 1, 0, 1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "flabs")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_ABS, 0, 0, NULL, 1, 0, -1, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_ABS, 0, 0, NULL, 1, 0, -1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-flsqrt")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_SQRT, 0, 0, NULL, 1, 0, 1, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_SQRT, 0, 0, NULL, 1, 0, 1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "flsqrt")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_SQRT, 0, 0, NULL, 1, 0, -1, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_SQRT, 0, 0, NULL, 1, 0, -1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "flfloor") || IS_NAMED_PRIM(rator, "flceiling") @@ -1655,41 +1670,41 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in || IS_NAMED_PRIM(rator, "flatan") || IS_NAMED_PRIM(rator, "flexp") || IS_NAMED_PRIM(rator, "fllog")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_FLUNOP, 0, 0, NULL, 1, 0, -1, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_FLUNOP, 0, 0, NULL, 1, 0, -1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "exact->inexact") || IS_NAMED_PRIM(rator, "real->double-flonum")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_EX_INEX, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_EX_INEX, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fx->fl")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_EX_INEX, 0, 0, NULL, 1, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_EX_INEX, 0, 0, NULL, 1, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "->fl") || IS_NAMED_PRIM(rator, "fx->fl")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_EX_INEX, 0, 0, NULL, 1, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_EX_INEX, 0, 0, NULL, 1, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "inexact->exact")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_INEX_EX, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_INEX_EX, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fl->fx")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_INEX_EX, 0, 0, NULL, 1, 0, 1, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_INEX_EX, 0, 0, NULL, 1, 0, 1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fl->exact-integer") || IS_NAMED_PRIM(rator, "fl->fx")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_INEX_EX, 0, 0, NULL, 1, 0, -1, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_INEX_EX, 0, 0, NULL, 1, 0, -1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "bitwise-not")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_NOT, 0, 9, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_NOT, 0, 9, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fxnot")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_NOT, 0, 9, NULL, 1, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_NOT, 0, 9, NULL, 1, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fxnot")) { - scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_NOT, 0, 9, NULL, 1, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand, NULL, 1, ARITH_NOT, 0, 9, NULL, 1, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "vector-immutable") || IS_NAMED_PRIM(rator, "vector")) { - return generate_vector_alloc(jitter, rator, NULL, app, NULL); + return generate_vector_alloc(jitter, rator, NULL, app, NULL, dest); } else if (IS_NAMED_PRIM(rator, "list*") || IS_NAMED_PRIM(rator, "values")) { /* on a single argument, `list*' or `values' is identity */ @@ -1697,6 +1712,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in scheme_generate_non_tail(app->rand, jitter, 0, 1, 0); CHECK_LIMIT(); mz_runstack_unskipped(jitter, 1); + jit_movr_p(dest, JIT_R0); return 1; } else if (IS_NAMED_PRIM(rator, "list")) { mz_runstack_skipped(jitter, 1); @@ -1705,7 +1721,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in mz_rs_sync(); mz_runstack_unskipped(jitter, 1); (void)jit_movi_p(JIT_R1, &scheme_null); - return scheme_generate_cons_alloc(jitter, 0, 0); + return scheme_generate_cons_alloc(jitter, 0, 0, dest); } else if (IS_NAMED_PRIM(rator, "box")) { mz_runstack_skipped(jitter, 1); scheme_generate_non_tail(app->rand, jitter, 0, 1, 0); @@ -1720,7 +1736,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in CHECK_LIMIT(); jit_stxi_p((intptr_t)&SCHEME_BOX_VAL(0x0) + OBJHEAD_SIZE, JIT_V1, JIT_R0); - jit_addi_p(JIT_R0, JIT_V1, OBJHEAD_SIZE); + jit_addi_p(dest, JIT_V1, OBJHEAD_SIZE); #else /* Non-inlined */ JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); @@ -1730,15 +1746,15 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in GC_CAN_IGNORE jit_insn *refr; (void)mz_finish_lwe(ts_scheme_box, refr); } - jit_retval(JIT_R0); + jit_retval(dest); #endif return 1; } else if (IS_NAMED_PRIM(rator, "future?")) { - generate_inlined_type_test(jitter, app, scheme_future_type, scheme_future_type, 1, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_future_type, scheme_future_type, 1, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fsemaphore?")) { - generate_inlined_type_test(jitter, app, scheme_fsemaphore_type, scheme_fsemaphore_type, 1, for_branch, branch_short, need_sync); + generate_inlined_type_test(jitter, app, scheme_fsemaphore_type, scheme_fsemaphore_type, 1, for_branch, branch_short, need_sync, dest); return 1; } else if (IS_NAMED_PRIM(rator, "future") || IS_NAMED_PRIM(rator, "touch") @@ -1772,7 +1788,7 @@ int scheme_generate_inlined_unary(mz_jit_state *jitter, Scheme_App2_Rec *app, in else (void)mz_finish_lwe(((Scheme_Primitive_Proc *)rator)->prim_val, refr); - jit_retval(JIT_R0); + jit_retval(dest); mz_popr_x(); /* remove arg */ @@ -1876,7 +1892,7 @@ static int generate_two_args(Scheme_Object *rand1, Scheme_Object *rand2, mz_jit_ } static int generate_binary_char(mz_jit_state *jitter, Scheme_App3_Rec *app, - Branch_Info *for_branch, int branch_short) + Branch_Info *for_branch, int branch_short, int dest) /* de-sync'd ok */ { Scheme_Object *r1, *r2, *rator = app->rator; @@ -1901,9 +1917,9 @@ static int generate_binary_char(mz_jit_state *jitter, Scheme_App3_Rec *app, (void)jit_movi_p(JIT_R2, ((Scheme_Primitive_Proc *)rator)->prim_val); __END_SHORT_JUMPS__(branch_short); if (direction > 0) { - (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); } __START_SHORT_JUMPS__(branch_short); mz_patch_branch(pref); @@ -1921,9 +1937,9 @@ static int generate_binary_char(mz_jit_state *jitter, Scheme_App3_Rec *app, (void)jit_movi_p(JIT_R2, ((Scheme_Primitive_Proc *)rator)->prim_val); __END_SHORT_JUMPS__(branch_short); if (direction > 0) { - (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); } __START_SHORT_JUMPS__(branch_short); mz_patch_branch(pref); @@ -1957,10 +1973,10 @@ static int generate_binary_char(mz_jit_state *jitter, Scheme_App3_Rec *app, CHECK_LIMIT(); } else { GC_CAN_IGNORE jit_insn *ref2; - (void)jit_movi_p(JIT_R0, scheme_true); + (void)jit_movi_p(dest, scheme_true); ref2 = jit_jmpi(jit_forward()); mz_patch_branch(ref); - (void)jit_movi_p(JIT_R0, scheme_false); + (void)jit_movi_p(dest, scheme_false); mz_patch_ucbranch(ref2); } @@ -1972,7 +1988,7 @@ static int generate_binary_char(mz_jit_state *jitter, Scheme_App3_Rec *app, static int generate_vector_op(mz_jit_state *jitter, int set, int int_ready, int base_offset, int for_fl, int unsafe, int unbox_flonum, int result_ignored, int can_chaperone, - int for_struct, int for_fx, int check_mutable) + int for_struct, int for_fx, int check_mutable, int dest) /* R0 has vector. In set mode, R2 has value; if not unboxed, not unsafe, or can chaperone, RUNSTACK has space for a temporary (intended for R2). If int_ready, R1 has num index (for safe or can-chaperone mode) and V1 has pre-computed @@ -2019,6 +2035,7 @@ static int generate_vector_op(mz_jit_state *jitter, int set, int int_ready, int } CHECK_LIMIT(); if (can_chaperone) { + jit_movr_p(dest, JIT_R0); pref = jit_jmpi(jit_forward()); } else { /* doesn't return */ @@ -2096,10 +2113,10 @@ static int generate_vector_op(mz_jit_state *jitter, int set, int int_ready, int if (can_chaperone) mz_patch_ucbranch(pref); if (!result_ignored) - (void)jit_movi_p(JIT_R0, scheme_void); + (void)jit_movi_p(dest, scheme_void); } else { if (!for_fl) { - jit_ldxr_p(JIT_R0, JIT_R0, JIT_V1); + jit_ldxr_p(dest, JIT_R0, JIT_V1); } else { int fpr0; fpr0 = JIT_FPR_0(jitter->unbox_depth); @@ -2107,7 +2124,7 @@ static int generate_vector_op(mz_jit_state *jitter, int set, int int_ready, int if (unbox_flonum) jitter->unbox_depth++; else - scheme_generate_alloc_double(jitter, 0); + scheme_generate_alloc_double(jitter, 0, dest); } if (can_chaperone) mz_patch_ucbranch(pref); @@ -2116,7 +2133,7 @@ static int generate_vector_op(mz_jit_state *jitter, int set, int int_ready, int return 1; } -static int allocate_rectangular(mz_jit_state *jitter) +static int allocate_rectangular(mz_jit_state *jitter, int dest) { #ifdef CAN_INLINE_ALLOC /* Inlined alloc */ @@ -2125,7 +2142,7 @@ static int allocate_rectangular(mz_jit_state *jitter) jit_stxi_p((intptr_t)&(((Scheme_Complex *)0x0)->r) + OBJHEAD_SIZE, JIT_V1, JIT_R0); jit_stxi_p((intptr_t)&(((Scheme_Complex *)0x0)->i) + OBJHEAD_SIZE, JIT_V1, JIT_R1); - jit_addi_p(JIT_R0, JIT_V1, OBJHEAD_SIZE); + jit_addi_p(dest, JIT_V1, OBJHEAD_SIZE); #else /* Non-inlined alloc */ JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); @@ -2136,14 +2153,15 @@ static int allocate_rectangular(mz_jit_state *jitter) GC_CAN_IGNORE jit_insn *refr; (void)mz_finish_lwe(ts_scheme_make_complex, refr); } - jit_retval(JIT_R0); + jit_retval(dest); #endif return 1; } 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) /* de-sync's; for branch, sync'd before */ { Scheme_Object *rator = app->rator; @@ -2153,7 +2171,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i k = inlineable_struct_prim(rator, jitter, 2, 2); if (k) { generate_inlined_struct_op(k, jitter, rator, app->rand1, app->rand2, for_branch, branch_short, is_tail, multi_ok, - result_ignored); + result_ignored, dest); scheme_direct_call_count++; return 1; } @@ -2223,10 +2241,10 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i scheme_branch_for_true(jitter, for_branch); CHECK_LIMIT(); } else { - (void)jit_movi_p(JIT_R0, scheme_true); + (void)jit_movi_p(dest, scheme_true); ref2 = jit_jmpi(jit_forward()); mz_patch_branch(ref); - (void)jit_movi_p(JIT_R0, scheme_false); + (void)jit_movi_p(dest, scheme_false); mz_patch_ucbranch(ref2); } @@ -2251,10 +2269,10 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i scheme_branch_for_true(jitter, for_branch); CHECK_LIMIT(); } else { - (void)jit_movi_p(JIT_R0, scheme_true); + (void)jit_movi_p(dest, scheme_true); ref2 = jit_jmpi(jit_forward()); mz_patch_branch(ref); - (void)jit_movi_p(JIT_R0, scheme_false); + (void)jit_movi_p(dest, scheme_false); mz_patch_ucbranch(ref2); } @@ -2275,7 +2293,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i jit_pusharg_p(JIT_R0); jit_pusharg_p(JIT_R1); mz_finish_prim_lwe(ts_scheme_equal, refr); - jit_retval(JIT_R0); + jit_retval(dest); CHECK_LIMIT(); __START_SHORT_JUMPS__(branch_short); @@ -2291,11 +2309,11 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i scheme_add_branch_false(for_branch, ref_f); scheme_branch_for_true(jitter, for_branch); } else { - (void)jit_movi_p(JIT_R0, scheme_true); + (void)jit_movi_p(dest, scheme_true); ref_d = jit_jmpi(jit_forward()); mz_patch_branch(ref_f); - (void)jit_movi_p(JIT_R0, scheme_false); + (void)jit_movi_p(dest, scheme_false); mz_patch_ucbranch(ref_d); } @@ -2352,10 +2370,11 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i scheme_branch_for_true(jitter, for_branch); } else { (void)jit_calli(sjc.eqv_code); + jit_movr_p(dest, JIT_R0); ref_d1 = jit_jmpi(jit_forward()); mz_patch_branch(ref_t1); - (void)jit_movi_p(JIT_R0, scheme_true); + (void)jit_movi_p(dest, scheme_true); ref_d2 = jit_jmpi(jit_forward()); mz_patch_branch(ref_f1); @@ -2364,7 +2383,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i mz_patch_branch(ref_f4); mz_patch_branch(ref_f5); - (void)jit_movi_p(JIT_R0, scheme_false); + (void)jit_movi_p(dest, scheme_false); mz_patch_ucbranch(ref_d1); mz_patch_ucbranch(ref_d2); @@ -2374,242 +2393,242 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i return 1; } else if (IS_NAMED_PRIM(rator, "=")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_EQUAL, 0, for_branch, branch_short, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_EQUAL, 0, for_branch, branch_short, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fx=")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_EQUAL, 0, for_branch, branch_short, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_EQUAL, 0, for_branch, branch_short, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fx=")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_EQUAL, 0, for_branch, branch_short, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_EQUAL, 0, for_branch, branch_short, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fl=")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_EQUAL, 0, for_branch, branch_short, 0, 1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_EQUAL, 0, for_branch, branch_short, 0, 1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fl=")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_EQUAL, 0, for_branch, branch_short, 0, -1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_EQUAL, 0, for_branch, branch_short, 0, -1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "<=")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LEQ, 0, for_branch, branch_short, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LEQ, 0, for_branch, branch_short, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fx<=")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LEQ, 0, for_branch, branch_short, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LEQ, 0, for_branch, branch_short, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fx<=")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LEQ, 0, for_branch, branch_short, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LEQ, 0, for_branch, branch_short, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fl<=")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LEQ, 0, for_branch, branch_short, 0, 1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LEQ, 0, for_branch, branch_short, 0, 1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fl<=")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LEQ, 0, for_branch, branch_short, 0, -1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LEQ, 0, for_branch, branch_short, 0, -1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "<")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LT, 0, for_branch, branch_short, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LT, 0, for_branch, branch_short, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fx<")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LT, 0, for_branch, branch_short, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LT, 0, for_branch, branch_short, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fx<")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LT, 0, for_branch, branch_short, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LT, 0, for_branch, branch_short, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fl<")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LT, 0, for_branch, branch_short, 0, 1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LT, 0, for_branch, branch_short, 0, 1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fl<")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LT, 0, for_branch, branch_short, 0, -1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_LT, 0, for_branch, branch_short, 0, -1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, ">=")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GEQ, 0, for_branch, branch_short, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GEQ, 0, for_branch, branch_short, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fx>=")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GEQ, 0, for_branch, branch_short, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GEQ, 0, for_branch, branch_short, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fx>=")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GEQ, 0, for_branch, branch_short, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GEQ, 0, for_branch, branch_short, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fl>=")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GEQ, 0, for_branch, branch_short, 0, 1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GEQ, 0, for_branch, branch_short, 0, 1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fl>=")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GEQ, 0, for_branch, branch_short, 0, -1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GEQ, 0, for_branch, branch_short, 0, -1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, ">")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GT, 0, for_branch, branch_short, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GT, 0, for_branch, branch_short, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fx>")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GT, 0, for_branch, branch_short, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GT, 0, for_branch, branch_short, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fx>")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GT, 0, for_branch, branch_short, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GT, 0, for_branch, branch_short, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fl>")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GT, 0, for_branch, branch_short, 0, 1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GT, 0, for_branch, branch_short, 0, 1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fl>")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GT, 0, for_branch, branch_short, 0, -1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_GT, 0, for_branch, branch_short, 0, -1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "bitwise-bit-set?")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_BIT, 0, for_branch, branch_short, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, CMP_BIT, 0, for_branch, branch_short, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "char=?")) { - generate_binary_char(jitter, app, for_branch, branch_short); + generate_binary_char(jitter, app, for_branch, branch_short, dest); return 1; } else if (!for_branch) { if (IS_NAMED_PRIM(rator, "+")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_ADD, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_ADD, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fx+")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_ADD, 0, 0, NULL, 1, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_ADD, 0, 0, NULL, 1, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fx+")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_ADD, 0, 0, NULL, 1, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_ADD, 0, 0, NULL, 1, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fl+")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_ADD, 0, 0, NULL, 1, 0, 1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_ADD, 0, 0, NULL, 1, 0, 1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fl+")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_ADD, 0, 0, NULL, 1, 0, -1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_ADD, 0, 0, NULL, 1, 0, -1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "-")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_SUB, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_SUB, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fx-")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_SUB, 0, 0, NULL, 1, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_SUB, 0, 0, NULL, 1, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fx-")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_SUB, 0, 0, NULL, 1, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_SUB, 0, 0, NULL, 1, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fl-")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_SUB, 0, 0, NULL, 1, 0, 1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_SUB, 0, 0, NULL, 1, 0, 1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fl-")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_SUB, 0, 0, NULL, 1, 0, -1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_SUB, 0, 0, NULL, 1, 0, -1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "*")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MUL, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MUL, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fx*")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MUL, 0, 0, NULL, 1, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MUL, 0, 0, NULL, 1, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fx*")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MUL, 0, 0, NULL, 1, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MUL, 0, 0, NULL, 1, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fl*")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MUL, 0, 0, NULL, 1, 0, 1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MUL, 0, 0, NULL, 1, 0, 1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fl*")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MUL, 0, 0, NULL, 1, 0, -1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MUL, 0, 0, NULL, 1, 0, -1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "/")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_DIV, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_DIV, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fl/")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_DIV, 0, 0, NULL, 1, 0, 1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_DIV, 0, 0, NULL, 1, 0, 1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fl/")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_DIV, 0, 0, NULL, 1, 0, -1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_DIV, 0, 0, NULL, 1, 0, -1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "quotient")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_QUOT, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_QUOT, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fxquotient")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_QUOT, 0, 0, NULL, 1, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_QUOT, 0, 0, NULL, 1, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fxquotient")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_QUOT, 0, 0, NULL, 1, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_QUOT, 0, 0, NULL, 1, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "remainder")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_REM, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_REM, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "modulo")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MOD, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MOD, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fxremainder")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_REM, 0, 0, NULL, 1, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_REM, 0, 0, NULL, 1, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fxmodulo")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MOD, 0, 0, NULL, 1, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MOD, 0, 0, NULL, 1, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fxremainder")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_REM, 0, 0, NULL, 1, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_REM, 0, 0, NULL, 1, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fxmodulo")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MOD, 0, 0, NULL, 1, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MOD, 0, 0, NULL, 1, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "min")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MIN, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MIN, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "max")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MAX, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MAX, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-flmin")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MIN, 0, 0, NULL, 1, 0, 1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MIN, 0, 0, NULL, 1, 0, 1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-flmax")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MAX, 0, 0, NULL, 1, 0, 1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MAX, 0, 0, NULL, 1, 0, 1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "flmin")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MIN, 0, 0, NULL, 1, 0, -1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MIN, 0, 0, NULL, 1, 0, -1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "flmax")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MAX, 0, 0, NULL, 1, 0, -1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MAX, 0, 0, NULL, 1, 0, -1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fxmin")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MIN, 0, 0, NULL, 1, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MIN, 0, 0, NULL, 1, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fxmax")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MAX, 0, 0, NULL, 1, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MAX, 0, 0, NULL, 1, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fxmin")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MIN, 0, 0, NULL, 1, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MIN, 0, 0, NULL, 1, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fxmax")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MAX, 0, 0, NULL, 1, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_MAX, 0, 0, NULL, 1, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "bitwise-and")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_AND, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_AND, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fxand")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_AND, 0, 0, NULL, 1, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_AND, 0, 0, NULL, 1, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fxand")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_AND, 0, 0, NULL, 1, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_AND, 0, 0, NULL, 1, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "bitwise-ior")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_IOR, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_IOR, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fxior")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_IOR, 0, 0, NULL, 1, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_IOR, 0, 0, NULL, 1, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fxior")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_IOR, 0, 0, NULL, 1, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_IOR, 0, 0, NULL, 1, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "bitwise-xor")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_XOR, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_XOR, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fxxor")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_XOR, 0, 0, NULL, 1, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_XOR, 0, 0, NULL, 1, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fxxor")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_XOR, 0, 0, NULL, 1, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_XOR, 0, 0, NULL, 1, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "arithmetic-shift")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_LSH, 0, 0, NULL, 1, 0, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_LSH, 0, 0, NULL, 1, 0, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fxlshift")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_LSH, 0, 0, NULL, 1, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_LSH, 0, 0, NULL, 1, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fxlshift")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_LSH, 0, 0, NULL, 1, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_LSH, 0, 0, NULL, 1, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-fxrshift")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_RSH, 0, 0, NULL, 1, 1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_RSH, 0, 0, NULL, 1, 1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "fxrshift")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_RSH, 0, 0, NULL, 1, -1, 0, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_RSH, 0, 0, NULL, 1, -1, 0, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "flexpt")) { - scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_EXPT, 0, 0, NULL, 1, 0, -1, NULL); + scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, ARITH_EXPT, 0, 0, NULL, 1, 0, -1, NULL, dest); return 1; } else if (IS_NAMED_PRIM(rator, "vector-ref") || IS_NAMED_PRIM(rator, "unsafe-vector-ref") @@ -2693,12 +2712,14 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i /* vector-ref is relatively simple and worth inlining */ if (can_chaperone) scheme_mz_need_space(jitter, 3); generate_vector_op(jitter, 0, 0, base_offset, 0, unsafe, - 0, 0, can_chaperone, for_struct, for_fx, 0); + 0, 0, can_chaperone, for_struct, for_fx, 0, + dest); CHECK_LIMIT(); } else if (which == 3) { /* flvector-ref is relatively simple and worth inlining */ generate_vector_op(jitter, 0, 0, base_offset, 1, unsafe, - unbox, 0, can_chaperone, for_struct, for_fx, 0); + unbox, 0, can_chaperone, for_struct, for_fx, 0, + dest); CHECK_LIMIT(); } else if (which == 1) { if (unsafe) { @@ -2708,10 +2729,11 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i jit_ldxr_i(JIT_R0, JIT_R0, JIT_R1); (void)jit_movi_p(JIT_R1, scheme_char_constants); jit_lshi_ul(JIT_R0, JIT_R0, JIT_LOG_WORD_SIZE); - jit_ldxr_p(JIT_R0, JIT_R1, JIT_R0); + jit_ldxr_p(dest, JIT_R1, JIT_R0); CHECK_LIMIT(); } else { (void)jit_calli(sjc.string_ref_check_index_code); + jit_movr_p(dest, JIT_R0); } } else { if (unsafe) { @@ -2719,10 +2741,11 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i jit_ldxi_p(JIT_R0, JIT_R0, &SCHEME_CHAR_STR_VAL((Scheme_Object *)0x0)); jit_ldxr_c(JIT_R0, JIT_R0, JIT_R1); jit_extr_uc_ul(JIT_R0, JIT_R0); - jit_fixnum_l(JIT_R0, JIT_R0); + jit_fixnum_l(dest, JIT_R0); CHECK_LIMIT(); } else { (void)jit_calli(sjc.bytes_ref_check_index_code); + jit_movr_p(dest, JIT_R0); } } } else { @@ -2750,12 +2773,14 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i /* vector-ref is relatively simple and worth inlining */ if (can_chaperone) scheme_mz_need_space(jitter, 3); generate_vector_op(jitter, 0, 1, base_offset, 0, unsafe, - 0, 0, can_chaperone, for_struct, for_fx, 0); + 0, 0, can_chaperone, for_struct, for_fx, 0, + dest); CHECK_LIMIT(); } else if (which == 3) { /* flvector-ref is relatively simple and worth inlining */ generate_vector_op(jitter, 0, 1, base_offset, 1, unsafe, - unbox, 0, can_chaperone, for_struct, for_fx, 0); + unbox, 0, can_chaperone, for_struct, for_fx, 0, + dest); CHECK_LIMIT(); } else if (which == 1) { if (unsafe) { @@ -2763,19 +2788,21 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i jit_ldxr_i(JIT_R0, JIT_R0, JIT_V1); (void)jit_movi_p(JIT_R1, scheme_char_constants); jit_lshi_ul(JIT_R0, JIT_R0, JIT_LOG_WORD_SIZE); - jit_ldxr_p(JIT_R0, JIT_R1, JIT_R0); + jit_ldxr_p(dest, JIT_R1, JIT_R0); CHECK_LIMIT(); } else { (void)jit_calli(sjc.string_ref_code); + jit_movr_p(dest, JIT_R0); } } else { if (unsafe) { jit_ldxi_p(JIT_R0, JIT_R0, &SCHEME_CHAR_STR_VAL((Scheme_Object *)0x0)); jit_ldxr_c(JIT_R0, JIT_R0, JIT_V1); jit_extr_uc_ul(JIT_R0, JIT_R0); - jit_fixnum_l(JIT_R0, JIT_R0); + jit_fixnum_l(dest, JIT_R0); } else { (void)jit_calli(sjc.bytes_ref_code); + jit_movr_p(dest, JIT_R0); } } @@ -2819,7 +2846,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i jitter->unbox_depth++; else { mz_rs_sync(); - scheme_generate_alloc_double(jitter, 0); + scheme_generate_alloc_double(jitter, 0, dest); } return 1; @@ -2840,7 +2867,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i else jit_ldxr_s(JIT_R0, JIT_R0, JIT_R1); - jit_fixnum_l(JIT_R0, JIT_R0); + jit_fixnum_l(dest, JIT_R0); return 1; } else if (IS_NAMED_PRIM(rator, "list-ref") @@ -2852,6 +2879,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i (void)jit_calli(sjc.list_ref_code); else (void)jit_calli(sjc.list_tail_code); + jit_movr_p(dest, JIT_R0); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-list-ref") @@ -2859,16 +2887,20 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i if (SCHEME_INTP(app->rand2)) { intptr_t v = SCHEME_INT_VAL(app->rand2); if ((v >= 0) && (v <= 10)) { + int is_ref; mz_runstack_skipped(jitter, 2); scheme_generate_non_tail(app->rand1, jitter, 0, 1, 0); CHECK_LIMIT(); mz_runstack_unskipped(jitter, 2); + is_ref = IS_NAMED_PRIM(rator, "unsafe-list-ref"); + if (!v && !is_ref) jit_movr_p(dest, JIT_R0); while (v--) { - jit_ldxi_p(JIT_R0, JIT_R0, (intptr_t)&SCHEME_CDR(0x0)); + int this_dest = ((is_ref || (v > 0)) ? JIT_R0 : dest); + jit_ldxi_p(this_dest, JIT_R0, (intptr_t)&SCHEME_CDR(0x0)); } - if (IS_NAMED_PRIM(rator, "unsafe-list-ref")) - jit_ldxi_p(JIT_R0, JIT_R0, (intptr_t)&SCHEME_CAR(0x0)); + if (is_ref) + jit_ldxi_p(dest, JIT_R0, (intptr_t)&SCHEME_CAR(0x0)); return 1; } @@ -2880,6 +2912,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i (void)jit_calli(sjc.list_ref_code); else (void)jit_calli(sjc.list_tail_code); + jit_movr_p(dest, JIT_R0); return 1; } else if (IS_NAMED_PRIM(rator, "set-mcar!") @@ -2915,7 +2948,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i (void)jit_stxi_p(&((Scheme_Simple_Object *)0x0)->u.pair_val.cdr, JIT_R0, JIT_R1); if (!result_ignored) - (void)jit_movi_p(JIT_R0, scheme_void); + (void)jit_movi_p(dest, scheme_void); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-set-mcar!") @@ -2934,7 +2967,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i (void)jit_stxi_p(&((Scheme_Simple_Object *)0x0)->u.pair_val.cdr, JIT_R0, JIT_R1); if (!result_ignored) - (void)jit_movi_p(JIT_R0, scheme_void); + (void)jit_movi_p(dest, scheme_void); return 1; } else if (IS_NAMED_PRIM(rator, "set-box!") @@ -2974,7 +3007,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i __END_TINY_JUMPS__(1); if (!result_ignored) - (void)jit_movi_p(JIT_R0, scheme_void); + (void)jit_movi_p(dest, scheme_void); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-set-box*!")) { @@ -2985,7 +3018,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i (void)jit_stxi_p(&SCHEME_BOX_VAL(0x0), JIT_R0, JIT_R1); if (!result_ignored) - (void)jit_movi_p(JIT_R0, scheme_void); + (void)jit_movi_p(dest, scheme_void); return 1; } else if (IS_NAMED_PRIM(rator, "cons") @@ -2997,7 +3030,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i CHECK_LIMIT(); mz_rs_sync(); - return scheme_generate_cons_alloc(jitter, dir == -1, 0); + return scheme_generate_cons_alloc(jitter, dir == -1, 0, dest); } else if (IS_NAMED_PRIM(rator, "mcons")) { LOG_IT(("inlined mcons\n")); @@ -3012,7 +3045,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i jit_stxi_p((intptr_t)&SCHEME_MCAR(0x0) + OBJHEAD_SIZE, JIT_V1, JIT_R0); jit_stxi_p((intptr_t)&SCHEME_MCDR(0x0) + OBJHEAD_SIZE, JIT_V1, JIT_R1); - jit_addi_p(JIT_R0, JIT_V1, OBJHEAD_SIZE); + jit_addi_p(dest, JIT_V1, OBJHEAD_SIZE); #else /* Non-inlined alloc */ JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); @@ -3023,7 +3056,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i GC_CAN_IGNORE jit_insn *refr; (void)mz_finish_lwe(ts_scheme_make_mutable_pair, refr); } - jit_retval(JIT_R0); + jit_retval(dest); #endif return 1; @@ -3041,7 +3074,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i CHECK_LIMIT(); mz_rs_sync(); - scheme_generate_cons_alloc(jitter, 1, 0); + scheme_generate_cons_alloc(jitter, 1, 0, JIT_R0); CHECK_LIMIT(); jit_ldr_p(JIT_R1, JIT_RUNSTACK); @@ -3049,10 +3082,10 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i mz_runstack_popped(jitter, 1); CHECK_LIMIT(); - return scheme_generate_cons_alloc(jitter, 1, 0); + return scheme_generate_cons_alloc(jitter, 1, 0, dest); } else if (IS_NAMED_PRIM(rator, "vector-immutable") || IS_NAMED_PRIM(rator, "vector")) { - return generate_vector_alloc(jitter, rator, NULL, NULL, app); + return generate_vector_alloc(jitter, rator, NULL, NULL, app, dest); } else if (IS_NAMED_PRIM(rator, "make-rectangular")) { GC_CAN_IGNORE jit_insn *ref, *ref2, *ref3, *ref4, *refslow, *refdone; @@ -3072,7 +3105,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i /* (slow path) */ refslow = _jit.x.pc; (void)jit_calli(sjc.make_rectangular_code); - jit_retval(JIT_R0); + jit_retval(dest); CHECK_LIMIT(); refdone = jit_jmpi(jit_forward()); /* (end of slow path) */ @@ -3103,7 +3136,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i __END_SHORT_JUMPS__(1); - allocate_rectangular(jitter); + allocate_rectangular(jitter, dest); __START_SHORT_JUMPS__(1); mz_patch_ucbranch(refdone); @@ -3130,7 +3163,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i __END_TINY_JUMPS__(1); CHECK_LIMIT(); - allocate_rectangular(jitter); + allocate_rectangular(jitter, dest); return 1; } else if (IS_NAMED_PRIM(rator, "unsafe-make-flrectangular")) { @@ -3139,7 +3172,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i generate_two_args(app->rand1, app->rand2, jitter, 1, 2); CHECK_LIMIT(); - allocate_rectangular(jitter); + allocate_rectangular(jitter, dest); return 1; } else if (IS_NAMED_PRIM(rator, "procedure-arity-includes?")) { @@ -3150,6 +3183,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i mz_rs_sync(); (void)jit_calli(sjc.proc_arity_includes_code); + jit_movr_p(dest, JIT_R0); return 1; } else if (IS_NAMED_PRIM(rator, "values")) { @@ -3168,6 +3202,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i jit_movi_l(JIT_V1, 2); (void)jit_calli(sjc.values_code); + jit_movr_p(dest, JIT_R0); mz_rs_inc(2); /* no sync */ mz_runstack_popped(jitter, 2); @@ -3189,7 +3224,7 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i jit_pusharg_p(JIT_R1); jit_pusharg_p(JIT_R0); mz_finish_prim_lwe(cont_mark_set_first_try_fast, refr); - jit_retval(JIT_R0); + jit_retval(dest); CHECK_LIMIT(); return 1; @@ -3207,7 +3242,8 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i } 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) /* de-sync's; for branch, sync'd before */ { Scheme_Object *rator = app->args[0]; @@ -3216,7 +3252,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int int k; k = inlineable_struct_prim(rator, jitter, app->num_args, app->num_args); if (k) { - generate_inlined_nary_struct_op(k, jitter, rator, app, for_branch, branch_short, is_tail, multi_ok); + generate_inlined_nary_struct_op(k, jitter, rator, app, for_branch, branch_short, is_tail, multi_ok, dest); scheme_direct_call_count++; return 1; } @@ -3236,29 +3272,28 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int scheme_direct_call_count++; if (IS_NAMED_PRIM(rator, "=")) { - scheme_generate_nary_arith(jitter, app, 0, CMP_EQUAL, for_branch, branch_short); + scheme_generate_nary_arith(jitter, app, 0, CMP_EQUAL, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "<")) { - scheme_generate_nary_arith(jitter, app, 0, CMP_LT, for_branch, branch_short); + scheme_generate_nary_arith(jitter, app, 0, CMP_LT, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, ">")) { - scheme_generate_nary_arith(jitter, app, 0, CMP_GT, for_branch, branch_short); + scheme_generate_nary_arith(jitter, app, 0, CMP_GT, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "<=")) { - scheme_generate_nary_arith(jitter, app, 0, CMP_LEQ, for_branch, branch_short); + scheme_generate_nary_arith(jitter, app, 0, CMP_LEQ, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, ">=")) { - scheme_generate_nary_arith(jitter, app, 0, CMP_GEQ, for_branch, branch_short); + scheme_generate_nary_arith(jitter, app, 0, CMP_GEQ, for_branch, branch_short, dest); return 1; } else if (IS_NAMED_PRIM(rator, "current-future")) { mz_rs_sync(); JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); mz_prepare(0); (void)mz_finish(scheme_current_future); - jit_retval(JIT_R0); + jit_retval(dest); return 1; } else if (IS_NAMED_PRIM(rator, "box-cas!") || (IS_NAMED_PRIM(rator, "unsafe-box*-cas!"))) { - GC_CAN_IGNORE jit_insn *ref, *reffail, *reffalse, *reftrue; int unsafe = 0; @@ -3331,11 +3366,11 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int scheme_add_branch_false(for_branch, reffalse); __END_SHORT_JUMPS__(branch_short); } else { - (void)jit_movi_p(JIT_R0, scheme_true); + (void)jit_movi_p(dest, scheme_true); reftrue = jit_jmpi(jit_forward()); mz_patch_branch(reffalse); - (void)jit_movi_p(JIT_R0, scheme_false); + (void)jit_movi_p(dest, scheme_false); mz_patch_branch(reftrue); __END_TINY_JUMPS__(1); @@ -3544,13 +3579,13 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int if (can_chaperone) scheme_mz_need_space(jitter, 3); generate_vector_op(jitter, 1, 0, base_offset, 0, unsafe, flonum_arg, result_ignored, can_chaperone, - for_struct, for_fx, check_mutable); + for_struct, for_fx, check_mutable, dest); CHECK_LIMIT(); } else if (which == 3) { /* flvector-set! is relatively simple and worth inlining */ generate_vector_op(jitter, 1, 0, base_offset, 1, unsafe, flonum_arg, result_ignored, can_chaperone, - for_struct, for_fx, 0); + for_struct, for_fx, 0, dest); CHECK_LIMIT(); } else if ((which == 4) || (which == 5)) { /* unsafe-{s,u}16vector-set! */ @@ -3564,7 +3599,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int jit_stxr_s(JIT_R1, JIT_R0, JIT_R2); CHECK_LIMIT(); if (!result_ignored) - (void)jit_movi_p(JIT_R0, scheme_void); + (void)jit_movi_p(dest, scheme_void); } else if (which == 1) { if (unsafe) { jit_rshi_ul(JIT_R1, JIT_R1, 1); @@ -3573,10 +3608,12 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int jit_ldxi_i(JIT_R2, JIT_R2, &((Scheme_Small_Object *)0x0)->u.char_val); jit_stxr_i(JIT_R1, JIT_R0, JIT_R2); if (!result_ignored) - (void)jit_movi_p(JIT_R0, scheme_void); + (void)jit_movi_p(dest, scheme_void); } else { mz_rs_str(JIT_R2); (void)jit_calli(sjc.string_set_check_index_code); + if (!result_ignored) + (void)jit_movr_p(dest, JIT_R0); } } else { if (unsafe) { @@ -3585,10 +3622,12 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int jit_rshi_ul(JIT_R2, JIT_R2, 1); jit_stxr_c(JIT_R1, JIT_R0, JIT_R2); if (!result_ignored) - (void)jit_movi_p(JIT_R0, scheme_void); + (void)jit_movi_p(dest, scheme_void); } else { mz_rs_str(JIT_R2); (void)jit_calli(sjc.bytes_set_check_index_code); + if (!result_ignored) + (void)jit_movr_p(dest, JIT_R0); } } } else { @@ -3609,7 +3648,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int if (can_chaperone) scheme_mz_need_space(jitter, 3); generate_vector_op(jitter, 1, 1, base_offset, 0, unsafe, flonum_arg, result_ignored, can_chaperone, - for_struct, for_fx, check_mutable); + for_struct, for_fx, check_mutable, dest); CHECK_LIMIT(); } else if ((which == 4) || (which == 5)) { /* unsafe-{s,u}16vector-set! */ @@ -3622,12 +3661,12 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int jit_stxi_s(offset, JIT_R0, JIT_R2); CHECK_LIMIT(); if (!result_ignored) - (void)jit_movi_p(JIT_R0, scheme_void); + (void)jit_movi_p(dest, scheme_void); } else if (which == 3) { /* flvector-set! is relatively simple and worth inlining */ generate_vector_op(jitter, 1, 1, base_offset, 1, unsafe, flonum_arg, result_ignored, can_chaperone, - for_struct, for_fx, 0); + for_struct, for_fx, 0, dest); CHECK_LIMIT(); } else if (which == 1) { if (unsafe) { @@ -3635,10 +3674,12 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int jit_ldxi_i(JIT_R2, JIT_R2, &((Scheme_Small_Object *)0x0)->u.char_val); jit_stxr_i(JIT_V1, JIT_R0, JIT_R2); if (!result_ignored) - (void)jit_movi_p(JIT_R0, scheme_void); + (void)jit_movi_p(dest, scheme_void); } else { mz_rs_str(JIT_R2); (void)jit_calli(sjc.string_set_code); + if (!result_ignored) + (void)jit_movr_p(dest, JIT_R0); } } else { if (unsafe) { @@ -3646,10 +3687,12 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int jit_rshi_ul(JIT_R2, JIT_R2, 1); jit_stxr_c(JIT_V1, JIT_R0, JIT_R2); if (!result_ignored) - (void)jit_movi_p(JIT_R0, scheme_void); + (void)jit_movi_p(dest, scheme_void); } else { mz_rs_str(JIT_R2); (void)jit_calli(sjc.bytes_set_code); + if (!result_ignored) + (void)jit_movr_p(dest, JIT_R0); } } } @@ -3719,12 +3762,12 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int CHECK_LIMIT(); if (!result_ignored) - (void)jit_movi_p(JIT_R0, scheme_void); + (void)jit_movi_p(dest, scheme_void); return 1; } else if (IS_NAMED_PRIM(rator, "vector-immutable") || IS_NAMED_PRIM(rator, "vector")) { - return generate_vector_alloc(jitter, rator, app, NULL, NULL); + return generate_vector_alloc(jitter, rator, app, NULL, NULL, dest); } else if (IS_NAMED_PRIM(rator, "list") || IS_NAMED_PRIM(rator, "list*")) { int c = app->num_args; @@ -3743,6 +3786,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int (void)jit_calli(sjc.make_list_star_code); else (void)jit_calli(sjc.make_list_code); + jit_movr_p(dest, JIT_R0); #else JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); jit_movi_l(JIT_R0, c); @@ -3756,7 +3800,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int else (void)mz_finish_lwe(ts_scheme_jit_make_list, refr); } - jit_retval(JIT_R0); + jit_retval(dest); #endif if (c) { @@ -3777,6 +3821,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int jit_movi_l(JIT_V1, c); (void)jit_calli(sjc.values_code); + jit_movr_p(dest, JIT_R0); mz_rs_inc(c); /* no sync */ mz_runstack_popped(jitter, c); @@ -3785,34 +3830,35 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int jit_movi_l(JIT_R0, 0); jit_stxi_l(((int)&((Scheme_Thread *)0x0)->ku.multiple.count), JIT_R2, JIT_R0); jit_stxi_p(((int)&((Scheme_Thread *)0x0)->ku.multiple.array), JIT_R2, JIT_R0); - (void)jit_movi_p(JIT_R0, SCHEME_MULTIPLE_VALUES); + (void)jit_movi_p(dest, SCHEME_MULTIPLE_VALUES); } return 1; } else if (IS_NAMED_PRIM(rator, "+")) { - return scheme_generate_nary_arith(jitter, app, ARITH_ADD, 0, NULL, 1); + return scheme_generate_nary_arith(jitter, app, ARITH_ADD, 0, NULL, 1, dest); } else if (IS_NAMED_PRIM(rator, "-")) { - return scheme_generate_nary_arith(jitter, app, ARITH_SUB, 0, NULL, 1); + return scheme_generate_nary_arith(jitter, app, ARITH_SUB, 0, NULL, 1, dest); } else if (IS_NAMED_PRIM(rator, "*")) { - return scheme_generate_nary_arith(jitter, app, ARITH_MUL, 0, NULL, 1); + return scheme_generate_nary_arith(jitter, app, ARITH_MUL, 0, NULL, 1, dest); } else if (IS_NAMED_PRIM(rator, "/")) { - return scheme_generate_nary_arith(jitter, app, ARITH_DIV, 0, NULL, 1); + return scheme_generate_nary_arith(jitter, app, ARITH_DIV, 0, NULL, 1, dest); } else if (IS_NAMED_PRIM(rator, "bitwise-and")) { - return scheme_generate_nary_arith(jitter, app, ARITH_AND, 0, NULL, 1); + return scheme_generate_nary_arith(jitter, app, ARITH_AND, 0, NULL, 1, dest); } else if (IS_NAMED_PRIM(rator, "bitwise-ior")) { - return scheme_generate_nary_arith(jitter, app, ARITH_IOR, 0, NULL, 1); + return scheme_generate_nary_arith(jitter, app, ARITH_IOR, 0, NULL, 1, dest); } else if (IS_NAMED_PRIM(rator, "bitwise-xor")) { - return scheme_generate_nary_arith(jitter, app, ARITH_XOR, 0, NULL, 1); + return scheme_generate_nary_arith(jitter, app, ARITH_XOR, 0, NULL, 1, dest); } else if (IS_NAMED_PRIM(rator, "min")) { - return scheme_generate_nary_arith(jitter, app, ARITH_MIN, 0, NULL, 1); + return scheme_generate_nary_arith(jitter, app, ARITH_MIN, 0, NULL, 1, dest); } else if (IS_NAMED_PRIM(rator, "max")) { - return scheme_generate_nary_arith(jitter, app, ARITH_MAX, 0, NULL, 1); + return scheme_generate_nary_arith(jitter, app, ARITH_MAX, 0, NULL, 1, dest); } else if (IS_NAMED_PRIM(rator, "checked-procedure-check-and-extract")) { scheme_generate_app(app, NULL, 5, jitter, 0, 0, 0, 2); /* sync'd below */ CHECK_LIMIT(); mz_rs_sync(); (void)jit_calli(sjc.struct_proc_extract_code); + jit_movr_p(dest, JIT_R0); CHECK_LIMIT(); mz_rs_inc(5); @@ -3832,7 +3878,7 @@ int scheme_generate_inlined_nary(mz_jit_state *jitter, Scheme_App_Rec *app, int return 0; } -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) /* Args must be in R0 (car) and R1 (cdr); uses R2 and V1 as temporaries */ { #ifdef CAN_INLINE_ALLOC @@ -3847,7 +3893,7 @@ int scheme_generate_cons_alloc(mz_jit_state *jitter, int rev, int inline_retry) jit_stxi_p((intptr_t)&SCHEME_CAR(0x0) + OBJHEAD_SIZE, JIT_V1, JIT_R0); jit_stxi_p((intptr_t)&SCHEME_CDR(0x0) + OBJHEAD_SIZE, JIT_V1, JIT_R1); } - jit_addi_p(JIT_R0, JIT_V1, OBJHEAD_SIZE); + jit_addi_p(dest, JIT_V1, OBJHEAD_SIZE); #else /* Non-inlined */ JIT_UPDATE_THREAD_RSPTR_IF_NEEDED(); @@ -3863,17 +3909,18 @@ int scheme_generate_cons_alloc(mz_jit_state *jitter, int rev, int inline_retry) GC_CAN_IGNORE jit_insn *refr; (void)mz_finish_lwe(ts_scheme_make_pair, refr); } - jit_retval(JIT_R0); + jit_retval(dest); #endif return 1; } static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator, - Scheme_App_Rec *app, Scheme_App2_Rec *app2, Scheme_App3_Rec *app3) + Scheme_App_Rec *app, Scheme_App2_Rec *app2, Scheme_App3_Rec *app3, + int dest) /* de-sync'd ok */ { - int imm, i, c; + int imm, i, c, tmp; imm = IS_NAMED_PRIM(rator, "vector-immutable"); @@ -3913,7 +3960,7 @@ static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator, } jit_movi_l(JIT_R1, c); jit_stxi_l((intptr_t)&SCHEME_VEC_SIZE(0x0) + OBJHEAD_SIZE, JIT_V1, JIT_R1); - jit_addi_p(JIT_R0, JIT_V1, OBJHEAD_SIZE); + jit_addi_p(dest, JIT_V1, OBJHEAD_SIZE); #else { /* Non-inlined */ @@ -3944,15 +3991,17 @@ static int generate_vector_alloc(mz_jit_state *jitter, Scheme_Object *rator, (void)mz_finish_lwe(ts_scheme_jit_make_vector, refr); } } - jit_retval(JIT_R0); + jit_retval(dest); #endif CHECK_LIMIT(); + tmp = ((dest == JIT_R1) ? JIT_R0 : JIT_R1); + if (app) { for (i = 0; i < c; i++) { - jit_ldxi_p(JIT_R1, JIT_RUNSTACK, WORDS_TO_BYTES(i)); - jit_stxi_p((intptr_t)&SCHEME_VEC_ELS(0x0)[i], JIT_R0, JIT_R1); + jit_ldxi_p(tmp, JIT_RUNSTACK, WORDS_TO_BYTES(i)); + jit_stxi_p((intptr_t)&SCHEME_VEC_ELS(0x0)[i], dest, tmp); CHECK_LIMIT(); } @@ -3972,11 +4021,11 @@ int scheme_generate_inlined_test(mz_jit_state *jitter, Scheme_Object *obj, int b { switch (SCHEME_TYPE(obj)) { case scheme_application_type: - return scheme_generate_inlined_nary(jitter, (Scheme_App_Rec *)obj, 0, 0, for_branch, branch_short, 0); + return scheme_generate_inlined_nary(jitter, (Scheme_App_Rec *)obj, 0, 0, for_branch, branch_short, 0, JIT_R0); case scheme_application2_type: - return scheme_generate_inlined_unary(jitter, (Scheme_App2_Rec *)obj, 0, 0, for_branch, branch_short, need_sync, 0); + return scheme_generate_inlined_unary(jitter, (Scheme_App2_Rec *)obj, 0, 0, for_branch, branch_short, need_sync, 0, JIT_R0); case scheme_application3_type: - return scheme_generate_inlined_binary(jitter, (Scheme_App3_Rec *)obj, 0, 0, for_branch, branch_short, need_sync, 0); + return scheme_generate_inlined_binary(jitter, (Scheme_App3_Rec *)obj, 0, 0, for_branch, branch_short, need_sync, 0, JIT_R0); } return 0; diff --git a/src/racket/src/lightning/ppc/core.h b/src/racket/src/lightning/ppc/core.h index 3b26d9c8b1..1b85586541 100644 --- a/src/racket/src/lightning/ppc/core.h +++ b/src/racket/src/lightning/ppc/core.h @@ -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))