@@ -67,6 +67,7 @@ module Generate (Target : Target_sig.S) = struct
6767 type repr =
6868 | Value
6969 | Float
70+ | Int
7071 | Int32
7172 | Nativeint
7273 | Int64
@@ -75,24 +76,23 @@ module Generate (Target : Target_sig.S) = struct
7576 match r with
7677 | Value -> Type. value
7778 | Float -> F64
78- | Int32 -> I32
79- | Nativeint -> I32
79+ | Int | Int32 | Nativeint -> I32
8080 | Int64 -> I64
8181
8282 let specialized_primitive_type (_ , params , result ) =
8383 { W. params = List. map ~f: repr_type params; result = [ repr_type result ] }
8484
8585 let box_value r e =
8686 match r with
87- | Value -> e
87+ | Value | Int -> e
8888 | Float -> Memory. box_float e
8989 | Int32 -> Memory. box_int32 e
9090 | Nativeint -> Memory. box_nativeint e
9191 | Int64 -> Memory. box_int64 e
9292
9393 let unbox_value r e =
9494 match r with
95- | Value -> e
95+ | Value | Int -> e
9696 | Float -> Memory. unbox_float e
9797 | Int32 -> Memory. unbox_int32 e
9898 | Nativeint -> Memory. unbox_nativeint e
@@ -105,9 +105,9 @@ module Generate (Target : Target_sig.S) = struct
105105 [ " caml_int32_bswap" , (`Pure , [ Int32 ], Int32 )
106106 ; " caml_nativeint_bswap" , (`Pure , [ Nativeint ], Nativeint )
107107 ; " caml_int64_bswap" , (`Pure , [ Int64 ], Int64 )
108- ; " caml_int32_compare" , (`Pure , [ Int32 ; Int32 ], Value )
109- ; " caml_nativeint_compare" , (`Pure , [ Nativeint ; Nativeint ], Value )
110- ; " caml_int64_compare" , (`Pure , [ Int64 ; Int64 ], Value )
108+ ; " caml_int32_compare" , (`Pure , [ Int32 ; Int32 ], Int )
109+ ; " caml_nativeint_compare" , (`Pure , [ Nativeint ; Nativeint ], Int )
110+ ; " caml_int64_compare" , (`Pure , [ Int64 ; Int64 ], Int )
111111 ; " caml_string_get32" , (`Mutator , [ Value ; Value ], Int32 )
112112 ; " caml_string_get64" , (`Mutator , [ Value ; Value ], Int64 )
113113 ; " caml_bytes_get32" , (`Mutator , [ Value ; Value ], Int32 )
@@ -124,7 +124,7 @@ module Generate (Target : Target_sig.S) = struct
124124 ; " caml_ldexp_float" , (`Pure , [ Float ; Value ], Float )
125125 ; " caml_erf_float" , (`Pure , [ Float ], Float )
126126 ; " caml_erfc_float" , (`Pure , [ Float ], Float )
127- ; " caml_float_compare" , (`Pure , [ Float ; Float ], Value )
127+ ; " caml_float_compare" , (`Pure , [ Float ; Float ], Int )
128128 ];
129129 h
130130
@@ -283,6 +283,38 @@ module Generate (Target : Target_sig.S) = struct
283283 (transl_prim_arg ctx ?typ:tz z )
284284 | _ -> invalid_arity name l ~expected: 3 )
285285
286+ let register_comparison name cmp_int cmp_boxed_int cmp_float =
287+ register_prim name `Mutable (fun ctx _ l ->
288+ match l with
289+ | [ x; y ] -> (
290+ let x' = transl_prim_arg ctx x in
291+ let y' = transl_prim_arg ctx y in
292+ match get_type ctx x, get_type ctx y with
293+ | Int _ , Int _ -> cmp_int ctx x y
294+ | Number Int32 , Number Int32 ->
295+ let * x' = Memory. unbox_int32 x' in
296+ let * y' = Memory. unbox_int32 y' in
297+ return (W. BinOp (I32 cmp_boxed_int, x', y'))
298+ | Number Nativeint , Number Nativeint ->
299+ let * x' = Memory. unbox_nativeint x' in
300+ let * y' = Memory. unbox_nativeint y' in
301+ return (W. BinOp (I32 cmp_boxed_int, x', y'))
302+ | Number Int64 , Number Int64 ->
303+ let * x' = Memory. unbox_int64 x' in
304+ let * y' = Memory. unbox_int64 y' in
305+ return (W. BinOp (I64 cmp_boxed_int, x', y'))
306+ | Number Float , Number Float -> float_comparison cmp_float x' y'
307+ | _ ->
308+ let * f =
309+ register_import
310+ ~name
311+ (Fun { W. params = [ Type. value; Type. value ]; result = [ I32 ] })
312+ in
313+ let * x' = x' in
314+ let * y' = y' in
315+ return (W. Call (f, [ x'; y' ])))
316+ | _ -> invalid_arity name l ~expected: 2 )
317+
286318 let () =
287319 register_bin_prim
288320 " caml_array_unsafe_get"
@@ -764,7 +796,93 @@ module Generate (Target : Target_sig.S) = struct
764796 l
765797 ~init: (return [] )
766798 in
767- Memory. allocate ~tag: 0 ~deadcode_sentinal: ctx.deadcode_sentinal ~load l)
799+ Memory. allocate ~tag: 0 ~deadcode_sentinal: ctx.deadcode_sentinal ~load l);
800+ register_comparison
801+ " caml_greaterthan"
802+ (fun ctx x y -> translate_int_comparison ctx (fun y x -> Arith. (x < y)) x y)
803+ (Gt S )
804+ Gt ;
805+ register_comparison
806+ " caml_greaterequal"
807+ (fun ctx x y -> translate_int_comparison ctx (fun y x -> Arith. (x < = y)) x y)
808+ (Ge S )
809+ Ge ;
810+ register_comparison
811+ " caml_lessthan"
812+ (fun ctx x y -> translate_int_comparison ctx Arith. ( < ) x y)
813+ (Lt S )
814+ Lt ;
815+ register_comparison
816+ " caml_lessequal"
817+ (fun ctx x y -> translate_int_comparison ctx Arith. ( < = ) x y)
818+ (Le S )
819+ Le ;
820+ register_comparison
821+ " caml_equal"
822+ (fun ctx x y -> translate_int_equality ctx Arith. ( = ) Value. eq x y)
823+ Eq
824+ Eq ;
825+ register_comparison
826+ " caml_notequal"
827+ (fun ctx x y -> translate_int_equality ctx Arith. ( <> ) Value. neq x y)
828+ Ne
829+ Ne ;
830+ register_prim " caml_compare" `Mutable (fun ctx _ l ->
831+ match l with
832+ | [ x; y ] -> (
833+ let x' = transl_prim_arg ctx x in
834+ let y' = transl_prim_arg ctx y in
835+ match get_type ctx x, get_type ctx y with
836+ | Int _ , Int _ ->
837+ Arith. (
838+ (Value. int_val y' < Value. int_val x')
839+ - (Value. int_val x' < Value. int_val y'))
840+ | Number Int32 , Number Int32 ->
841+ let * f =
842+ register_import
843+ ~name: " caml_int32_compare"
844+ (Fun { W. params = [ Type. value; Type. value ]; result = [ I32 ] })
845+ in
846+ let * x' = Memory. unbox_int32 x' in
847+ let * y' = Memory. unbox_int32 y' in
848+ return (W. Call (f, [ x'; y' ]))
849+ | Number Nativeint , Number Nativeint ->
850+ let * f =
851+ register_import
852+ ~name: " caml_nativeint_compare"
853+ (Fun (Type. primitive_type 2 ))
854+ in
855+ let * x' = Memory. unbox_nativeint x' in
856+ let * y' = Memory. unbox_nativeint y' in
857+ return (W. Call (f, [ x'; y' ]))
858+ | Number Int64 , Number Int64 ->
859+ let * f =
860+ register_import
861+ ~name: " caml_int64_compare"
862+ (Fun { W. params = [ Type. value; Type. value ]; result = [ I32 ] })
863+ in
864+ let * x' = Memory. unbox_int64 x' in
865+ let * y' = Memory. unbox_int64 y' in
866+ return (W. Call (f, [ x'; y' ]))
867+ | Number Float , Number Float ->
868+ let * f =
869+ register_import
870+ ~name: " caml_float_compare"
871+ (Fun { W. params = [ Type. value; Type. value ]; result = [ I32 ] })
872+ in
873+ let * x' = Memory. unbox_int64 x' in
874+ let * y' = Memory. unbox_int64 y' in
875+ return (W. Call (f, [ x'; y' ]))
876+ | _ ->
877+ let * f =
878+ register_import
879+ ~name: " caml_compare"
880+ (Fun { W. params = [ Type. value; Type. value ]; result = [ I32 ] })
881+ in
882+ let * x' = x' in
883+ let * y' = y' in
884+ return (W. Call (f, [ x'; y' ])))
885+ | _ -> invalid_arity " caml_compare" l ~expected: 2 )
768886
769887 let rec translate_expr ctx context x e =
770888 match e with
0 commit comments