summaryrefslogtreecommitdiff
path: root/asmcomp/cmmgen.ml
diff options
context:
space:
mode:
authorGreta Yorsh <45005955+gretay-js@users.noreply.github.com>2020-03-26 09:58:10 +0000
committerGitHub <noreply@github.com>2020-03-26 10:58:10 +0100
commit824ce3549211f9d72ca3c58362f088a4369ebc2e (patch)
tree3f8ff9b108e586a52e35422fcad82f06fb11d8a5 /asmcomp/cmmgen.ml
parentbc3246c5289dc32841509f349f90a304170fc2cc (diff)
downloadocaml-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.ml29
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 _