fix JIT bug in `fl->fx'
For the case that the argument is unboxed. Closes PR 12240
This commit is contained in:
parent
73071ad186
commit
a857e9e041
|
@ -1628,6 +1628,21 @@
|
||||||
(lambda () (apply values (make-list (add1 (random 1)) '(99))))
|
(lambda () (apply values (make-list (add1 (random 1)) '(99))))
|
||||||
(chaperone-procedure car (lambda (v) v)))))
|
(chaperone-procedure car (lambda (v) v)))))
|
||||||
|
|
||||||
|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
;; check `fl->fx' on unboxed argument:
|
||||||
|
|
||||||
|
(test 1 (lambda (x) (fl->fx (fl/ (fl- x 0.0) 1.0))) 1.0)
|
||||||
|
(test 1 (lambda (x) (inexact->exact (fl/ (fl- x 0.0) 1.0))) 1.0)
|
||||||
|
(err/rt-test (let ([f (lambda (x) (fl->fx (fl/ (fl- x 0.0) 1.0)))])
|
||||||
|
(set! f f)
|
||||||
|
(f 1e100))
|
||||||
|
;; make sure that exception reports actual bad argument, and
|
||||||
|
;; not some bad argument due to the fact that the original
|
||||||
|
;; was unboxed:
|
||||||
|
(lambda (exn)
|
||||||
|
(regexp-match #rx"1e[+]?100" (exn-message exn))))
|
||||||
|
(test (inexact->exact 1e100) (lambda (x) (inexact->exact (fl/ (fl- x 0.0) 1.0))) 1e100)
|
||||||
|
|
||||||
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(report-errs)
|
(report-errs)
|
||||||
|
|
|
@ -246,7 +246,7 @@ struct scheme_jit_common_record {
|
||||||
void *list_ref_code, *list_tail_code;
|
void *list_ref_code, *list_tail_code;
|
||||||
void *finish_tail_call_code, *finish_tail_call_fixup_code;
|
void *finish_tail_call_code, *finish_tail_call_fixup_code;
|
||||||
void *module_run_start_code, *module_exprun_start_code, *module_start_start_code;
|
void *module_run_start_code, *module_exprun_start_code, *module_start_start_code;
|
||||||
void *box_flonum_from_stack_code;
|
void *box_flonum_from_stack_code, *box_flonum_from_reg_code;
|
||||||
void *fl1_fail_code, *fl2rr_fail_code[2], *fl2fr_fail_code[2], *fl2rf_fail_code[2];
|
void *fl1_fail_code, *fl2rr_fail_code[2], *fl2fr_fail_code[2], *fl2rf_fail_code[2];
|
||||||
void *wcm_code, *wcm_nontail_code;
|
void *wcm_code, *wcm_nontail_code;
|
||||||
void *apply_to_list_tail_code, *apply_to_list_code, *apply_to_list_multi_ok_code;
|
void *apply_to_list_tail_code, *apply_to_list_code, *apply_to_list_multi_ok_code;
|
||||||
|
|
|
@ -405,13 +405,14 @@ static int generate_double_arith(mz_jit_state *jitter, Scheme_Object *rator,
|
||||||
/* Unless unboxed, first arg is in JIT_R1, second in JIT_R0.
|
/* 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 push/pop mode, first arg is pushed before second.
|
||||||
If unboxed in direct mode, first arg is in JIT_FPR0+depth
|
If unboxed in direct mode, first arg is in JIT_FPR0+depth
|
||||||
and second is in JIT_FPR1+depth (which is backward). */
|
and second is in JIT_FPR1+depth (which is backward).
|
||||||
|
Unboxed implies unsafe unless arith == ARITH_INEX_EX. */
|
||||||
{
|
{
|
||||||
#if defined(INLINE_FP_OPS) || defined(INLINE_FP_COMP)
|
#if defined(INLINE_FP_OPS) || defined(INLINE_FP_COMP)
|
||||||
GC_CAN_IGNORE jit_insn *ref8, *ref9, *ref10, *refd, *refdt, *refs = NULL, *refs2 = NULL;
|
GC_CAN_IGNORE jit_insn *ref8, *ref9, *ref10, *refd, *refdt, *refs = NULL, *refs2 = NULL;
|
||||||
int no_alloc = unboxed_result, need_post_pop = 0;
|
int no_alloc = unboxed_result, need_post_pop = 0;
|
||||||
|
|
||||||
if (!unsafe_fl) {
|
if (!unsafe_fl && !unboxed) {
|
||||||
/* Maybe they're doubles */
|
/* Maybe they're doubles */
|
||||||
__START_TINY_JUMPS__(1);
|
__START_TINY_JUMPS__(1);
|
||||||
if (two_args) {
|
if (two_args) {
|
||||||
|
@ -561,6 +562,8 @@ static int generate_double_arith(mz_jit_state *jitter, Scheme_Object *rator,
|
||||||
/* to check whether it fits in a fixnum, we
|
/* to check whether it fits in a fixnum, we
|
||||||
need to convert back and check whether it
|
need to convert back and check whether it
|
||||||
is the same */
|
is the same */
|
||||||
|
if (unboxed)
|
||||||
|
jit_movr_d_fppush(fpr1+1, fpr1); /* for slow path */
|
||||||
jit_extr_l_d_fppush(fpr0, JIT_R1);
|
jit_extr_l_d_fppush(fpr0, JIT_R1);
|
||||||
__START_TINY_JUMPS__(1);
|
__START_TINY_JUMPS__(1);
|
||||||
refs = jit_bantieqr_d_fppop(jit_forward(), fpr0, fpr1);
|
refs = jit_bantieqr_d_fppop(jit_forward(), fpr0, fpr1);
|
||||||
|
@ -571,6 +574,10 @@ static int generate_double_arith(mz_jit_state *jitter, Scheme_Object *rator,
|
||||||
__START_TINY_JUMPS__(1);
|
__START_TINY_JUMPS__(1);
|
||||||
refs2 = jit_bner_l(jit_forward(), JIT_R1, JIT_R2);
|
refs2 = jit_bner_l(jit_forward(), JIT_R1, JIT_R2);
|
||||||
__END_TINY_JUMPS__(1);
|
__END_TINY_JUMPS__(1);
|
||||||
|
#ifndef DIRECT_FPR_ACCESS
|
||||||
|
if (unboxed)
|
||||||
|
jit_roundr_d_l_fppop(JIT_R1, fpr2); /* slow path won't be needed */
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
jit_lshi_l(JIT_R0, JIT_R1, 1);
|
jit_lshi_l(JIT_R0, JIT_R1, 1);
|
||||||
jit_ori_l(JIT_R0, JIT_R0, 0x1);
|
jit_ori_l(JIT_R0, JIT_R0, 0x1);
|
||||||
|
@ -691,11 +698,13 @@ static int generate_double_arith(mz_jit_state *jitter, Scheme_Object *rator,
|
||||||
/* No, they're not both doubles, or slow path is needed
|
/* No, they're not both doubles, or slow path is needed
|
||||||
for some other reason. */
|
for some other reason. */
|
||||||
__START_TINY_JUMPS__(1);
|
__START_TINY_JUMPS__(1);
|
||||||
|
if (!unboxed) {
|
||||||
if (two_args) {
|
if (two_args) {
|
||||||
mz_patch_branch(ref8);
|
mz_patch_branch(ref8);
|
||||||
mz_patch_branch(ref10);
|
mz_patch_branch(ref10);
|
||||||
}
|
}
|
||||||
mz_patch_branch(ref9);
|
mz_patch_branch(ref9);
|
||||||
|
}
|
||||||
if (refs)
|
if (refs)
|
||||||
mz_patch_branch(refs);
|
mz_patch_branch(refs);
|
||||||
if (refs2)
|
if (refs2)
|
||||||
|
@ -948,7 +957,7 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
||||||
|
|
||||||
generate_double_arith(jitter, rator, arith, cmp, reversed, !!rand2, 0,
|
generate_double_arith(jitter, rator, arith, cmp, reversed, !!rand2, 0,
|
||||||
&refd, &refdt, for_branch, branch_short,
|
&refd, &refdt, for_branch, branch_short,
|
||||||
(arith == 15) ? (unsafe_fl > 0) : 1,
|
(arith == ARITH_INEX_EX) ? (unsafe_fl > 0) : 1,
|
||||||
args_unboxed, jitter->unbox);
|
args_unboxed, jitter->unbox);
|
||||||
CHECK_LIMIT();
|
CHECK_LIMIT();
|
||||||
ref3 = NULL;
|
ref3 = NULL;
|
||||||
|
@ -957,6 +966,9 @@ int scheme_generate_arith(mz_jit_state *jitter, Scheme_Object *rator, Scheme_Obj
|
||||||
|
|
||||||
if ((arith == ARITH_INEX_EX) && (unsafe_fl < 1)) {
|
if ((arith == ARITH_INEX_EX) && (unsafe_fl < 1)) {
|
||||||
/* need a slow path */
|
/* need a slow path */
|
||||||
|
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, orig_args, reversed, arith, 0, 0);
|
||||||
/* assert: !ref4, since not for_branch */
|
/* assert: !ref4, since not for_branch */
|
||||||
jit_patch_movi(ref, (_jit.x.pc));
|
jit_patch_movi(ref, (_jit.x.pc));
|
||||||
|
|
|
@ -1943,6 +1943,25 @@ static int common5(mz_jit_state *jitter, void *_data)
|
||||||
mz_epilog(JIT_R2);
|
mz_epilog(JIT_R2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* *** box_flonum_from_reg_code *** */
|
||||||
|
/* JIT_FPR2 (reg-based) or JIT_FPR0 (stack-based) has value */
|
||||||
|
{
|
||||||
|
sjc.box_flonum_from_reg_code = jit_get_ip().ptr;
|
||||||
|
|
||||||
|
mz_prolog(JIT_R2);
|
||||||
|
|
||||||
|
JIT_UPDATE_THREAD_RSPTR();
|
||||||
|
|
||||||
|
#ifdef DIRECT_FPR_ACCESS
|
||||||
|
jit_movr_d(JIT_FP0, JIT_FP2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
scheme_generate_alloc_double(jitter, 1);
|
||||||
|
CHECK_LIMIT();
|
||||||
|
|
||||||
|
mz_epilog(JIT_R2);
|
||||||
|
}
|
||||||
|
|
||||||
/* *** fl1_code *** */
|
/* *** fl1_code *** */
|
||||||
/* R0 has argument, V1 has primitive proc */
|
/* R0 has argument, V1 has primitive proc */
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue
Block a user