JIT-inline `eqv?'
This commit is contained in:
parent
e78a60016f
commit
f54d977de1
|
@ -15,7 +15,7 @@
|
|||
(namespace-require 'racket/flonum)
|
||||
(namespace-require 'racket/fixnum)
|
||||
(let* ([check-error-message (lambda (name proc [fixnum? #f])
|
||||
(unless (memq name '(eq? not null? pair? list?
|
||||
(unless (memq name '(eq? eqv? not null? pair? list?
|
||||
real? number? boolean?
|
||||
procedure? symbol?
|
||||
string? bytes?
|
||||
|
@ -173,6 +173,22 @@
|
|||
(un #t 'bytes? #"apple")
|
||||
|
||||
(bin #f 'eq? 0 10)
|
||||
(bin-exact #t 'eq? 10 10)
|
||||
|
||||
(bin-exact #f 'eqv? 0 10)
|
||||
(bin-exact #f 'eqv? "apple" "banana")
|
||||
(bin-exact #t 'eqv? 10 10)
|
||||
(bin-exact #t 'eqv? #\a #\a)
|
||||
(bin-exact #f 'eqv? #\a #\b)
|
||||
(bin-exact #t 'eqv? #\u3bb #\u3bb)
|
||||
(bin-exact #f 'eqv? #\u3bb #\u3bc)
|
||||
(bin-exact #t 'eqv? 1.0 1.0)
|
||||
(bin-exact #f 'eqv? 1.0 2.0)
|
||||
(bin-exact #t 'eqv? +nan.0 +nan.0)
|
||||
(bin-exact #t 'eqv? 1/2 1/2)
|
||||
(bin-exact #f 'eqv? 1/2 1/3)
|
||||
(bin-exact #t 'eqv? 1+2i 1+2i)
|
||||
(bin-exact #f 'eqv? 1+2i 1+3i)
|
||||
|
||||
(un #t 'zero? 0)
|
||||
(un #f 'zero? 1)
|
||||
|
|
|
@ -95,7 +95,9 @@ void scheme_init_bool (Scheme_Env *env)
|
|||
scheme_eq_prim = p;
|
||||
scheme_add_global_constant("eq?", p, env);
|
||||
|
||||
scheme_eqv_prim = scheme_make_folding_prim(eqv_prim, "eqv?", 2, 2, 1);
|
||||
p = scheme_make_folding_prim(eqv_prim, "eqv?", 2, 2, 1);
|
||||
SCHEME_PRIM_PROC_FLAGS(p) |= SCHEME_PRIM_IS_BINARY_INLINED;
|
||||
scheme_eqv_prim = p;
|
||||
scheme_add_global_constant("eqv?", scheme_eqv_prim, env);
|
||||
|
||||
scheme_equal_prim = scheme_make_prim_w_arity(equal_prim, "equal?", 2, 2);
|
||||
|
|
|
@ -244,6 +244,7 @@ struct scheme_jit_common_record {
|
|||
void *fl1_fail_code, *fl2rr_fail_code[2], *fl2fr_fail_code[2], *fl2rf_fail_code[2];
|
||||
void *wcm_code, *wcm_nontail_code;
|
||||
void *apply_to_list_tail_code, *apply_to_list_code, *apply_to_list_multi_ok_code;
|
||||
void *eqv_code, *eqv_branch_code;
|
||||
|
||||
#ifdef CAN_INLINE_ALLOC
|
||||
void *make_list_code, *make_list_star_code;
|
||||
|
|
|
@ -2023,6 +2023,63 @@ static int common8(mz_jit_state *jitter, void *_data)
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int common9(mz_jit_state *jitter, void *_data)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* eqv[_branch]_code */
|
||||
/* arguments in R0 and R1; for branch, false return address in V1 */
|
||||
for (i = 0; i < 2; i++) {
|
||||
void *code;
|
||||
GC_CAN_IGNORE jit_insn *ref;
|
||||
|
||||
code = jit_get_ip().ptr;
|
||||
if (i == 0)
|
||||
sjc.eqv_code = code;
|
||||
else
|
||||
sjc.eqv_branch_code = code;
|
||||
|
||||
mz_prolog(JIT_R2);
|
||||
CHECK_LIMIT();
|
||||
|
||||
jit_prepare(2);
|
||||
jit_pusharg_p(JIT_R0);
|
||||
jit_pusharg_p(JIT_R1);
|
||||
(void)jit_finish(scheme_eqv); /* NONGCING, so ok from a future thread */
|
||||
jit_retval(JIT_R0);
|
||||
CHECK_LIMIT();
|
||||
|
||||
__START_TINY_JUMPS__(1);
|
||||
ref = jit_beqi_i(jit_forward(), JIT_R0, 0);
|
||||
__END_TINY_JUMPS__(1);
|
||||
|
||||
if (i) {
|
||||
mz_epilog(JIT_R2);
|
||||
} else {
|
||||
(void)jit_movi_p(JIT_R0, scheme_true);
|
||||
mz_epilog(JIT_R2);
|
||||
}
|
||||
|
||||
__START_TINY_JUMPS__(1);
|
||||
mz_patch_branch(ref);
|
||||
__END_TINY_JUMPS__(1);
|
||||
|
||||
if (i) {
|
||||
mz_epilog_without_jmp();
|
||||
jit_jmpr(JIT_V1);
|
||||
} else {
|
||||
(void)jit_movi_p(JIT_R0, scheme_false);
|
||||
mz_epilog(JIT_R2);
|
||||
}
|
||||
|
||||
scheme_jit_register_sub_func(jitter, code, scheme_false);
|
||||
|
||||
CHECK_LIMIT();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int scheme_do_generate_common(mz_jit_state *jitter, void *_data)
|
||||
{
|
||||
if (!common0(jitter, _data)) return 0;
|
||||
|
@ -2035,6 +2092,7 @@ int scheme_do_generate_common(mz_jit_state *jitter, void *_data)
|
|||
if (!common6(jitter, _data)) return 0;
|
||||
if (!common7(jitter, _data)) return 0;
|
||||
if (!common8(jitter, _data)) return 0;
|
||||
if (!common9(jitter, _data)) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1697,6 +1697,77 @@ int scheme_generate_inlined_binary(mz_jit_state *jitter, Scheme_App3_Rec *app, i
|
|||
__END_SHORT_JUMPS__(branch_short);
|
||||
}
|
||||
|
||||
return 1;
|
||||
} else if (IS_NAMED_PRIM(rator, "eqv?")) {
|
||||
GC_CAN_IGNORE jit_insn *ref_f1, *ref_f2, *ref_f3, *ref_f4, *ref_f5;
|
||||
GC_CAN_IGNORE jit_insn *ref_d1, *ref_d2, *ref_t1;
|
||||
|
||||
generate_two_args(app->rand1, app->rand2, jitter, 0, 2);
|
||||
CHECK_LIMIT();
|
||||
|
||||
if (need_sync) mz_rs_sync();
|
||||
|
||||
__START_SHORT_JUMPS__(branch_short);
|
||||
|
||||
if (for_branch) {
|
||||
scheme_prepare_branch_jump(jitter, for_branch);
|
||||
CHECK_LIMIT();
|
||||
}
|
||||
|
||||
/* eq? */
|
||||
ref_t1 = jit_beqr_p(jit_forward(), JIT_R0, JIT_R1);
|
||||
|
||||
/* if either is fixnum, result is false */
|
||||
ref_f1 = jit_bmsi_ul(jit_forward(), JIT_R0, 0x1);
|
||||
ref_f2 = jit_bmsi_ul(jit_forward(), JIT_R1, 0x1);
|
||||
CHECK_LIMIT();
|
||||
|
||||
/* Both have a tag */
|
||||
jit_ldxi_s(JIT_R2, JIT_R0, &((Scheme_Object *)0x0)->type);
|
||||
jit_ldxi_s(JIT_V1, JIT_R1, &((Scheme_Object *)0x0)->type);
|
||||
ref_f3 = jit_bner_i(jit_forward(), JIT_R2, JIT_V1);
|
||||
|
||||
/* check in range of type treated by eqv: */
|
||||
ref_f4 = jit_blti_i(jit_forward(), JIT_R2, scheme_char_type);
|
||||
ref_f5 = jit_bgti_i(jit_forward(), JIT_R2, scheme_complex_type);
|
||||
CHECK_LIMIT();
|
||||
|
||||
/* in range of interesting types, so break out the generic comparison */
|
||||
if (for_branch) {
|
||||
scheme_add_branch_false_movi(for_branch, jit_patchable_movi_p(JIT_V1, jit_forward()));
|
||||
(void)jit_calli(sjc.eqv_branch_code);
|
||||
|
||||
scheme_add_branch_false(for_branch, ref_f1);
|
||||
scheme_add_branch_false(for_branch, ref_f2);
|
||||
scheme_add_branch_false(for_branch, ref_f3);
|
||||
scheme_add_branch_false(for_branch, ref_f4);
|
||||
scheme_add_branch_false(for_branch, ref_f5);
|
||||
|
||||
mz_patch_branch(ref_t1);
|
||||
scheme_branch_for_true(jitter, for_branch);
|
||||
} else {
|
||||
(void)jit_calli(sjc.eqv_code);
|
||||
jit_retval(JIT_R0);
|
||||
ref_d1 = jit_jmpi(jit_forward());
|
||||
|
||||
mz_patch_branch(ref_t1);
|
||||
jit_movi_p(JIT_R0, scheme_true);
|
||||
ref_d2 = jit_jmpi(jit_forward());
|
||||
|
||||
mz_patch_branch(ref_f1);
|
||||
mz_patch_branch(ref_f2);
|
||||
mz_patch_branch(ref_f3);
|
||||
mz_patch_branch(ref_f4);
|
||||
mz_patch_branch(ref_f5);
|
||||
|
||||
jit_movi_p(JIT_R0, scheme_false);
|
||||
|
||||
mz_patch_ucbranch(ref_d1);
|
||||
mz_patch_ucbranch(ref_d2);
|
||||
}
|
||||
|
||||
__END_SHORT_JUMPS__(branch_short);
|
||||
|
||||
return 1;
|
||||
} else if (IS_NAMED_PRIM(rator, "=")) {
|
||||
scheme_generate_arith(jitter, rator, app->rand1, app->rand2, 2, 0, 0, 0, for_branch, branch_short, 0, 0, NULL);
|
||||
|
|
Loading…
Reference in New Issue
Block a user