@@ -68,6 +68,7 @@ module Generate (Target : Target_sig.S) = struct
6868 type repr =
6969 | Value
7070 | Float
71+ | Int
7172 | Int32
7273 | Nativeint
7374 | Int64
@@ -76,24 +77,23 @@ module Generate (Target : Target_sig.S) = struct
7677 match r with
7778 | Value -> Type. value
7879 | Float -> F64
79- | Int32 -> I32
80- | Nativeint -> I32
80+ | Int | Int32 | Nativeint -> I32
8181 | Int64 -> I64
8282
8383 let specialized_primitive_type (_ , params , result ) =
8484 { W. params = List. map ~f: repr_type params; result = [ repr_type result ] }
8585
8686 let box_value r e =
8787 match r with
88- | Value -> e
88+ | Value | Int -> e
8989 | Float -> Memory. box_float e
9090 | Int32 -> Memory. box_int32 e
9191 | Nativeint -> Memory. box_nativeint e
9292 | Int64 -> Memory. box_int64 e
9393
9494 let unbox_value r e =
9595 match r with
96- | Value -> e
96+ | Value | Int -> e
9797 | Float -> Memory. unbox_float e
9898 | Int32 -> Memory. unbox_int32 e
9999 | Nativeint -> Memory. unbox_nativeint e
@@ -106,9 +106,9 @@ module Generate (Target : Target_sig.S) = struct
106106 [ " caml_int32_bswap" , (`Pure , [ Int32 ], Int32 )
107107 ; " caml_nativeint_bswap" , (`Pure , [ Nativeint ], Nativeint )
108108 ; " caml_int64_bswap" , (`Pure , [ Int64 ], Int64 )
109- ; " caml_int32_compare" , (`Pure , [ Int32 ; Int32 ], Value )
110- ; " caml_nativeint_compare" , (`Pure , [ Nativeint ; Nativeint ], Value )
111- ; " caml_int64_compare" , (`Pure , [ Int64 ; Int64 ], Value )
109+ ; " caml_int32_compare" , (`Pure , [ Int32 ; Int32 ], Int )
110+ ; " caml_nativeint_compare" , (`Pure , [ Nativeint ; Nativeint ], Int )
111+ ; " caml_int64_compare" , (`Pure , [ Int64 ; Int64 ], Int )
112112 ; " caml_string_get32" , (`Mutator , [ Value ; Value ], Int32 )
113113 ; " caml_string_get64" , (`Mutator , [ Value ; Value ], Int64 )
114114 ; " caml_bytes_get32" , (`Mutator , [ Value ; Value ], Int32 )
@@ -125,7 +125,7 @@ module Generate (Target : Target_sig.S) = struct
125125 ; " caml_ldexp_float" , (`Pure , [ Float ; Value ], Float )
126126 ; " caml_erf_float" , (`Pure , [ Float ], Float )
127127 ; " caml_erfc_float" , (`Pure , [ Float ], Float )
128- ; " caml_float_compare" , (`Pure , [ Float ; Float ], Value )
128+ ; " caml_float_compare" , (`Pure , [ Float ; Float ], Int )
129129 ];
130130 h
131131
@@ -300,6 +300,38 @@ module Generate (Target : Target_sig.S) = struct
300300 (transl_prim_arg ctx ?typ:tz z )
301301 | _ -> invalid_arity name l ~expected: 3 )
302302
303+ let register_comparison name cmp_int cmp_boxed_int cmp_float =
304+ register_prim name `Mutable (fun ctx _ l ->
305+ match l with
306+ | [ x; y ] -> (
307+ let x' = transl_prim_arg ctx x in
308+ let y' = transl_prim_arg ctx y in
309+ match get_type ctx x, get_type ctx y with
310+ | Int _ , Int _ -> cmp_int ctx x y
311+ | Number Int32 , Number Int32 ->
312+ let * x' = Memory. unbox_int32 x' in
313+ let * y' = Memory. unbox_int32 y' in
314+ return (W. BinOp (I32 cmp_boxed_int, x', y'))
315+ | Number Nativeint , Number Nativeint ->
316+ let * x' = Memory. unbox_nativeint x' in
317+ let * y' = Memory. unbox_nativeint y' in
318+ return (W. BinOp (I32 cmp_boxed_int, x', y'))
319+ | Number Int64 , Number Int64 ->
320+ let * x' = Memory. unbox_int64 x' in
321+ let * y' = Memory. unbox_int64 y' in
322+ return (W. BinOp (I64 cmp_boxed_int, x', y'))
323+ | Number Float , Number Float -> float_comparison cmp_float x' y'
324+ | _ ->
325+ let * f =
326+ register_import
327+ ~name
328+ (Fun { W. params = [ Type. value; Type. value ]; result = [ I32 ] })
329+ in
330+ let * x' = x' in
331+ let * y' = y' in
332+ return (W. Call (f, [ x'; y' ])))
333+ | _ -> invalid_arity name l ~expected: 2 )
334+
303335 let () =
304336 register_bin_prim
305337 " caml_array_unsafe_get"
@@ -781,7 +813,93 @@ module Generate (Target : Target_sig.S) = struct
781813 l
782814 ~init: (return [] )
783815 in
784- Memory. allocate ~tag: 0 ~deadcode_sentinal: ctx.deadcode_sentinal ~load l)
816+ Memory. allocate ~tag: 0 ~deadcode_sentinal: ctx.deadcode_sentinal ~load l);
817+ register_comparison
818+ " caml_greaterthan"
819+ (fun ctx x y -> translate_int_comparison ctx (fun y x -> Arith. (x < y)) x y)
820+ (Gt S )
821+ Gt ;
822+ register_comparison
823+ " caml_greaterequal"
824+ (fun ctx x y -> translate_int_comparison ctx (fun y x -> Arith. (x < = y)) x y)
825+ (Ge S )
826+ Ge ;
827+ register_comparison
828+ " caml_lessthan"
829+ (fun ctx x y -> translate_int_comparison ctx Arith. ( < ) x y)
830+ (Lt S )
831+ Lt ;
832+ register_comparison
833+ " caml_lessequal"
834+ (fun ctx x y -> translate_int_comparison ctx Arith. ( < = ) x y)
835+ (Le S )
836+ Le ;
837+ register_comparison
838+ " caml_equal"
839+ (fun ctx x y -> translate_int_equality ctx ~negate: false x y)
840+ Eq
841+ Eq ;
842+ register_comparison
843+ " caml_notequal"
844+ (fun ctx x y -> translate_int_equality ctx ~negate: true x y)
845+ Ne
846+ Ne ;
847+ register_prim " caml_compare" `Mutable (fun ctx _ l ->
848+ match l with
849+ | [ x; y ] -> (
850+ let x' = transl_prim_arg ctx x in
851+ let y' = transl_prim_arg ctx y in
852+ match get_type ctx x, get_type ctx y with
853+ | Int _ , Int _ ->
854+ Arith. (
855+ (Value. int_val y' < Value. int_val x')
856+ - (Value. int_val x' < Value. int_val y'))
857+ | Number Int32 , Number Int32 ->
858+ let * f =
859+ register_import
860+ ~name: " caml_int32_compare"
861+ (Fun { W. params = [ Type. value; Type. value ]; result = [ I32 ] })
862+ in
863+ let * x' = Memory. unbox_int32 x' in
864+ let * y' = Memory. unbox_int32 y' in
865+ return (W. Call (f, [ x'; y' ]))
866+ | Number Nativeint , Number Nativeint ->
867+ let * f =
868+ register_import
869+ ~name: " caml_nativeint_compare"
870+ (Fun (Type. primitive_type 2 ))
871+ in
872+ let * x' = Memory. unbox_nativeint x' in
873+ let * y' = Memory. unbox_nativeint y' in
874+ return (W. Call (f, [ x'; y' ]))
875+ | Number Int64 , Number Int64 ->
876+ let * f =
877+ register_import
878+ ~name: " caml_int64_compare"
879+ (Fun { W. params = [ Type. value; Type. value ]; result = [ I32 ] })
880+ in
881+ let * x' = Memory. unbox_int64 x' in
882+ let * y' = Memory. unbox_int64 y' in
883+ return (W. Call (f, [ x'; y' ]))
884+ | Number Float , Number Float ->
885+ let * f =
886+ register_import
887+ ~name: " caml_float_compare"
888+ (Fun { W. params = [ Type. value; Type. value ]; result = [ I32 ] })
889+ in
890+ let * x' = Memory. unbox_int64 x' in
891+ let * y' = Memory. unbox_int64 y' in
892+ return (W. Call (f, [ x'; y' ]))
893+ | _ ->
894+ let * f =
895+ register_import
896+ ~name: " caml_compare"
897+ (Fun { W. params = [ Type. value; Type. value ]; result = [ I32 ] })
898+ in
899+ let * x' = x' in
900+ let * y' = y' in
901+ return (W. Call (f, [ x'; y' ])))
902+ | _ -> invalid_arity " caml_compare" l ~expected: 2 )
785903
786904 let rec translate_expr ctx context x e =
787905 match e with
0 commit comments