diff options
author | Greta Yorsh <45005955+gretay-js@users.noreply.github.com> | 2020-03-26 09:58:10 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-26 10:58:10 +0100 |
commit | 824ce3549211f9d72ca3c58362f088a4369ebc2e (patch) | |
tree | 3f8ff9b108e586a52e35422fcad82f06fb11d8a5 /asmcomp/cmmgen.ml | |
parent | bc3246c5289dc32841509f349f90a304170fc2cc (diff) | |
download | ocaml-824ce3549211f9d72ca3c58362f088a4369ebc2e.tar.gz |
Replace caml_int_compare and caml_float_compare with primitives (#2324)
Diffstat (limited to 'asmcomp/cmmgen.ml')
-rw-r--r-- | asmcomp/cmmgen.ml | 29 |
1 files changed, 28 insertions, 1 deletions
diff --git a/asmcomp/cmmgen.ml b/asmcomp/cmmgen.ml index 87339aadb3..6e1c924dc4 100644 --- a/asmcomp/cmmgen.ml +++ b/asmcomp/cmmgen.ml @@ -277,7 +277,6 @@ let unbox_number dbg bn arg = | Boxed_integer (bi, _) -> unbox_int dbg bi arg - (* Auxiliary functions for optimizing "let" of boxed numbers (floats and boxed integers *) @@ -543,6 +542,7 @@ let rec transl env e = | Psetfield (_, _, _) | Psetfield_computed (_, _) | Pfloatfield _ | Psetfloatfield (_, _) | Pduprecord (_, _) | Praise _ | Pdivint _ | Pmodint _ | Pintcomp _ | Poffsetint _ + | Pcompare_ints | Pcompare_floats | Pcompare_bints _ | Poffsetref _ | Pfloatcomp _ | Parraylength _ | Parrayrefu _ | Parraysetu _ | Parrayrefs _ | Parraysets _ | Pbintofint _ | Pintofbint _ | Pcvtbint (_, _) | Pnegbint _ @@ -841,6 +841,7 @@ and transl_prim_1 env p arg dbg = | Pmakeblock (_, _, _) | Psetfield (_, _, _) | Psetfield_computed (_, _) | Psetfloatfield (_, _) | Pduprecord (_, _) | Pccall _ | Pdivint _ | Pmodint _ | Pintcomp _ | Pfloatcomp _ | Pmakearray (_, _) + | Pcompare_ints | Pcompare_floats | Pcompare_bints _ | Pduparray (_, _) | Parrayrefu _ | Parraysetu _ | Parrayrefs _ | Parraysets _ | Paddbint _ | Psubbint _ | Pmulbint _ | Pdivbint _ | Pmodbint _ | Pandbint _ | Porbint _ | Pxorbint _ @@ -907,6 +908,31 @@ and transl_prim_2 env p arg1 arg2 dbg = asr_int_caml (transl env arg1) (transl env arg2) dbg | Pintcomp cmp -> int_comp_caml cmp (transl env arg1) (transl env arg2) dbg + | Pcompare_ints -> + (* Compare directly on tagged ints *) + mk_compare_ints dbg (transl env arg1) (transl env arg2) + | Pcompare_bints bi -> + let a1 = transl_unbox_int dbg env bi arg1 in + let a2 = transl_unbox_int dbg env bi arg2 in + mk_compare_ints dbg a1 a2 + | Pcompare_floats -> + let a1 = transl_unbox_float dbg env arg1 in + let a2 = transl_unbox_float dbg env arg2 in + let op1 = Cop(Ccmpf(CFgt), [a1; a2], dbg) in + let op2 = Cop(Ccmpf(CFlt), [a1; a2], dbg) in + let op3 = Cop(Ccmpf(CFeq), [a1; a1], dbg) in + let op4 = Cop(Ccmpf(CFeq), [a2; a2], dbg) in + (* If both operands a1 and a2 are not NaN, then op3 = op4 = 1, + and the result is op1 - op2. + If at least one of the operands is NaN, + then op1 = op2 = 0, and the result is op3 - op4, + which orders NaN before other values. + To detect if the operand is NaN, we use the property: + for all x, NaN is not equal to x, even if x is NaN. + Therefore, op3 is 0 if and only if a1 is NaN, + and op4 is 0 if and only if a2 is NaN. + See also caml_float_compare_unboxed in runtime/floats.c *) + tag_int (add_int (sub_int op1 op2 dbg) (sub_int op3 op4 dbg) dbg) dbg | Pisout -> transl_isout (transl env arg1) (transl env arg2) dbg (* Float operations *) @@ -1063,6 +1089,7 @@ and transl_prim_3 env p arg1 arg2 arg3 dbg = | Pbswap16 | Pint_as_pointer | Popaque | Pread_symbol _ | Pmakeblock (_, _, _) | Pfield _ | Psetfield (_, _, _) | Pfloatfield _ | Psetfloatfield (_, _) | Pduprecord (_, _) | Pccall _ | Praise _ | Pdivint _ | Pmodint _ | Pintcomp _ + | Pcompare_ints | Pcompare_floats | Pcompare_bints _ | Poffsetint _ | Poffsetref _ | Pfloatcomp _ | Pmakearray (_, _) | Pduparray (_, _) | Parraylength _ | Parrayrefu _ | Parrayrefs _ | Pbintofint _ | Pintofbint _ | Pcvtbint (_, _) | Pnegbint _ | Paddbint _ |