@@ -606,10 +606,10 @@ module Make (Target : Cfg_selectgen_target_intf.S) = struct
606
606
Ok (Array. concat (Array. to_list locs), stack_ofs)
607
607
608
608
and emit_stores env sub_cfg dbg (args : Cmm.expression list ) regs_addr =
609
+ let byte_offset = ref (- Arch. size_int) in
609
610
let addressing_mode =
610
- ref (Arch. offset_addressing Arch. identity_addressing ( - Arch. size_int) )
611
+ ref (Arch. offset_addressing Arch. identity_addressing ! byte_offset )
611
612
in
612
- let byte_offset = ref 0 in
613
613
let base =
614
614
assert (Array. length regs_addr = 1 );
615
615
ref regs_addr
@@ -654,32 +654,35 @@ module Make (Target : Cfg_selectgen_target_intf.S) = struct
654
654
| Maybe_out_of_range ->
655
655
Target. is_store_out_of_range chunk ~byte_offset: ! byte_offset
656
656
in
657
- let new_addressing_mode =
658
- match is_out_of_range with
659
- | Within_range -> ! addressing_mode
660
- | Out_of_range ->
661
- (* Use a temporary to store the address [!base + offset]. *)
662
- let tmp = Reg. createv Cmm. typ_int in
663
- (* CR-someday xclerc: Now that this code in the "generic" part,
664
- it is maybe a bit unexpected to assume there is no better
665
- sequence to emit x += k. That being said, it is a corner
666
- case . *)
667
- insert_debug env sub_cfg
668
- ( Op ( SU. make_const_int ( Nativeint. of_int ! byte_offset)))
669
- dbg [||] tmp;
670
- insert_debug env sub_cfg ( Op ( Operation. Intop Iadd )) dbg
671
- ( Array. append ! base tmp) tmp;
672
- (* Use the temporary as the new base address. *)
673
- base := tmp ;
674
- Arch. identity_addressing
657
+ let reset_addressing () =
658
+ (* Use a temporary to store the address [!base + !byte_offset]. *)
659
+ let tmp = Reg. createv Cmm. typ_int in
660
+ (* CR-someday xclerc: Now that this code in the "generic" part, it
661
+ is maybe a bit unexpected to assume there is no better sequence
662
+ to emit x += k. That being said, it is a corner case. *)
663
+ insert_debug env sub_cfg
664
+ ( Op ( SU. make_const_int ( Nativeint. of_int ! byte_offset)))
665
+ dbg [||] tmp;
666
+ (* The new base is a pointer into the middle of an ocaml value . *)
667
+ assert ( ! byte_offset > 0 );
668
+ let new_base = Reg. createv Cmm. typ_addr in
669
+ insert_debug env sub_cfg ( Op ( Operation. Intop Iadd )) dbg
670
+ ( Array. append ! base tmp) new_base;
671
+ (* Use the temporary as the new base address. *)
672
+ base := new_base;
673
+ byte_offset := 0 ;
674
+ addressing_mode := Arch. identity_addressing
675
675
in
676
+ (match is_out_of_range with
677
+ | Within_range -> ()
678
+ | Out_of_range -> reset_addressing () );
676
679
insert_debug env sub_cfg
677
- (Op (Store (chunk, new_addressing_mode , false )))
680
+ (Op (Store (chunk, ! addressing_mode , false )))
678
681
dbg
679
- (Array. append [| r |] regs_addr )
682
+ (Array. append [| r |] ! base )
680
683
[||];
681
684
let size = SU. size_component r.Reg. typ in
682
- addressing_mode := Arch. offset_addressing new_addressing_mode size;
685
+ addressing_mode := Arch. offset_addressing ! addressing_mode size;
683
686
byte_offset := ! byte_offset + size
684
687
done
685
688
| Some op ->
0 commit comments