@@ -36,6 +36,7 @@ module Generate (Target : Target_sig.S) = struct
36
36
{ live : int array
37
37
; in_cps : Effects .in_cps
38
38
; deadcode_sentinal : Var .t
39
+ ; types : Typing .typ Var.Tbl .t
39
40
; blocks : block Addr.Map .t
40
41
; closures : Closure_conversion .closure Var.Map .t
41
42
; global_context : Code_generation .context
@@ -233,6 +234,39 @@ module Generate (Target : Target_sig.S) = struct
233
234
f context (transl_prim_arg x) (transl_prim_arg y) (transl_prim_arg z)
234
235
| _ -> invalid_arity name l ~expected: 3 )
235
236
237
+ let get_type ctx p =
238
+ match p with
239
+ | Pv x -> Var.Tbl. get ctx.types x
240
+ | Pc c -> Typing. constant_type c
241
+
242
+ let register_comparison name cmp_int cmp_boxed_int cmp_float =
243
+ register_prim name `Mutable (fun ctx _ transl_prim_arg l ->
244
+ match l with
245
+ | [ x; y ] -> (
246
+ let x' = transl_prim_arg x in
247
+ let y' = transl_prim_arg y in
248
+ match get_type ctx x, get_type ctx y with
249
+ | Number Int , Number Int -> cmp_int x' y'
250
+ | Number Int32 , Number Int32 ->
251
+ let * x' = Memory. unbox_int32 x' in
252
+ let * y' = Memory. unbox_int32 y' in
253
+ Value. val_int (return (W. BinOp (I32 cmp_boxed_int, x', y')))
254
+ | Number Nativeint , Number Nativeint ->
255
+ let * x' = Memory. unbox_nativeint x' in
256
+ let * y' = Memory. unbox_nativeint y' in
257
+ Value. val_int (return (W. BinOp (I32 cmp_boxed_int, x', y')))
258
+ | Number Int64 , Number Int64 ->
259
+ let * x' = Memory. unbox_int64 x' in
260
+ let * y' = Memory. unbox_int64 y' in
261
+ Value. val_int (return (W. BinOp (I64 cmp_boxed_int, x', y')))
262
+ | Number Float , Number Float -> float_comparison cmp_float x' y'
263
+ | _ ->
264
+ let * f = register_import ~name (Fun (func_type 2 )) in
265
+ let * x' = x' in
266
+ let * y' = y' in
267
+ return (W. Call (f, [ x'; y' ])))
268
+ | _ -> invalid_arity name l ~expected: 2 )
269
+
236
270
let () =
237
271
register_bin_prim " caml_array_unsafe_get" `Mutable Memory. gen_array_get;
238
272
register_bin_prim " caml_floatarray_unsafe_get" `Mutable Memory. float_array_get;
@@ -605,7 +639,66 @@ module Generate (Target : Target_sig.S) = struct
605
639
l
606
640
~init: (return [] )
607
641
in
608
- Memory. allocate ~tag: 0 ~deadcode_sentinal: ctx.deadcode_sentinal l)
642
+ Memory. allocate ~tag: 0 ~deadcode_sentinal: ctx.deadcode_sentinal l);
643
+ register_comparison " caml_greaterthan" (fun y x -> Value. lt x y) (Gt S ) Gt ;
644
+ register_comparison " caml_greaterequal" (fun y x -> Value. le x y) (Ge S ) Ge ;
645
+ register_comparison " caml_lessthan" Value. lt (Lt S ) Lt ;
646
+ register_comparison " caml_lessequal" Value. le (Le S ) Le ;
647
+ register_comparison
648
+ " caml_equal"
649
+ (fun x y ->
650
+ let * x = x in
651
+ let * y = y in
652
+ return (W. RefEq (x, y)))
653
+ Eq
654
+ Eq ;
655
+ register_comparison
656
+ " caml_notequal"
657
+ (fun x y ->
658
+ let * x = x in
659
+ let * y = y in
660
+ return (W. UnOp (I32 Eqz , RefEq (x, y))))
661
+ Ne
662
+ Ne ;
663
+ register_prim " caml_compare" `Mutable (fun ctx _ transl_prim_arg l ->
664
+ match l with
665
+ | [ x; y ] -> (
666
+ let x' = transl_prim_arg x in
667
+ let y' = transl_prim_arg y in
668
+ match get_type ctx x, get_type ctx y with
669
+ | Number Int , Number Int ->
670
+ Value. val_int
671
+ Arith. (
672
+ (Value. int_val y' < Value. int_val x')
673
+ - (Value. int_val x' < Value. int_val y'))
674
+ | Number Int32 , Number Int32 ->
675
+ let * f = register_import ~name: " caml_int32_compare" (Fun (func_type 2 )) in
676
+ let * x' = Memory. unbox_int32 x' in
677
+ let * y' = Memory. unbox_int32 y' in
678
+ return (W. Call (f, [ x'; y' ]))
679
+ | Number Nativeint , Number Nativeint ->
680
+ let * f =
681
+ register_import ~name: " caml_nativeint_compare" (Fun (func_type 2 ))
682
+ in
683
+ let * x' = Memory. unbox_nativeint x' in
684
+ let * y' = Memory. unbox_nativeint y' in
685
+ return (W. Call (f, [ x'; y' ]))
686
+ | Number Int64 , Number Int64 ->
687
+ let * f = register_import ~name: " caml_int64_compare" (Fun (func_type 2 )) in
688
+ let * x' = Memory. unbox_int64 x' in
689
+ let * y' = Memory. unbox_int64 y' in
690
+ return (W. Call (f, [ x'; y' ]))
691
+ | Number Float , Number Float ->
692
+ let * f = register_import ~name: " caml_float_compare" (Fun (func_type 2 )) in
693
+ let * x' = Memory. unbox_int64 x' in
694
+ let * y' = Memory. unbox_int64 y' in
695
+ return (W. Call (f, [ x'; y' ]))
696
+ | _ ->
697
+ let * f = register_import ~name: " caml_compare" (Fun (func_type 2 )) in
698
+ let * x' = x' in
699
+ let * y' = y' in
700
+ return (W. Call (f, [ x'; y' ])))
701
+ | _ -> invalid_arity " caml_compare" l ~expected: 2 )
609
702
610
703
let rec translate_expr ctx context x e =
611
704
match e with
@@ -1175,7 +1268,8 @@ module Generate (Target : Target_sig.S) = struct
1175
1268
~should_export
1176
1269
~warn_on_unhandled_effect
1177
1270
*)
1178
- ~deadcode_sentinal =
1271
+ ~deadcode_sentinal
1272
+ ~types =
1179
1273
global_context.unit_name < - unit_name;
1180
1274
let p, closures = Closure_conversion. f p in
1181
1275
(*
@@ -1185,6 +1279,7 @@ module Generate (Target : Target_sig.S) = struct
1185
1279
{ live = live_vars
1186
1280
; in_cps
1187
1281
; deadcode_sentinal
1282
+ ; types
1188
1283
; blocks = p.blocks
1189
1284
; closures
1190
1285
; global_context
@@ -1292,8 +1387,10 @@ let start () = make_context ~value_type:Gc_target.Value.value
1292
1387
1293
1388
let f ~context ~unit_name p ~live_vars ~in_cps ~deadcode_sentinal =
1294
1389
let t = Timer. make () in
1390
+ let state, info = Global_flow. f' ~fast: false p in
1391
+ let types = Typing. f ~state ~info p in
1295
1392
let p = fix_switch_branches p in
1296
- let res = G. f ~context ~unit_name ~live_vars ~in_cps ~deadcode_sentinal p in
1393
+ let res = G. f ~context ~unit_name ~live_vars ~in_cps ~deadcode_sentinal ~types p in
1297
1394
if times () then Format. eprintf " code gen.: %a@." Timer. print t;
1298
1395
res
1299
1396
0 commit comments