···9191 (Pierre Chambart, review by Gabriel Scherer and Xavier Leroy,
9292 report by Patrick Nicodemus)
93939494+- #13667: (originally #11162) Fix instr_size computation on arm64.
9595+ (Stephen Dolan and Tim McGilchrist, review by Xavier Leroy
9696+ and David Allsopp)
9797+9498### Standard library:
959996100- #13729: Add Either.retract
···407407 max_offset
408408 end
409409410410-module BR = Branch_relaxation.Make (struct
410410+module Size = struct
411411 (* CR-someday mshinwell: B and BL have +/- 128Mb ranges; for the moment we
412412 assume we will never exceed this. It would seem to be most likely to
413413 occur for branches between functions; in this case, the linker should be
···449449450450 let offset_pc_at_branch = 0
451451452452+ let addsub_size n =
453453+ let m = abs n in
454454+ assert (m < 0x1_000_000);
455455+ let ml = m land 0xFFF and mh = m land 0xFFF_000 in
456456+ max 1 ((if mh <> 0 then 1 else 0) +
457457+ (if ml <> 0 then 1 else 0))
458458+459459+ let stack_adj_size n =
460460+ (* see emit_stack_adjustment *)
461461+ addsub_size n
462462+452463 let prologue_size f =
453453- (if initial_stack_offset f > 0 then 2 else 0)
454454- + (if f.fun_frame_required then (if fp then 2 else 1) else 0)
464464+ let stk = initial_stack_offset f in
465465+ (if stk > 0 then stack_adj_size (-stk) else 0)
466466+ + (if f.fun_frame_required then (if fp then 2 else 1) else 0)
455467456468 let epilogue_size f =
457457- if f.fun_frame_required then 3 else 2
469469+ let stk = initial_stack_offset f in
470470+ (if stk > 0 then stack_adj_size stk else 0) +
471471+ (if f.fun_frame_required then 1 else 0) +
472472+ 1
458473459474 let instr_size f = function
460475 | Lend -> 0
···462477 | Lop (Imove | Ispill | Ireload) -> 1
463478 | Lop (Iconst_int n) ->
464479 num_instructions_for_intconst n
465465- | Lop (Iconst_float _) -> 2
480480+ | Lop (Iconst_float f) ->
481481+ if f = 0L || is_immediate_float f then 1 else 2
466482 | Lop (Iconst_symbol _) -> 2
467483 | Lop (Icall_ind) -> 1
468484 | Lop (Icall_imm _) -> 1
···472488 | Lop (Iextcall {alloc; stack_ofs} ) ->
473489 if stack_ofs > 0 then 5
474490 else if alloc then 3
475475- else 7
476476- | Lop (Istackoffset _) -> 2
491491+ else 5
492492+ | Lop (Istackoffset n) -> stack_adj_size (-n)
477493 | Lop (Iload { memory_chunk; addressing_mode; is_atomic }) ->
478494 let based = match addressing_mode with Iindexed _ -> 0 | Ibased _ -> 1
479495 and barrier = if is_atomic then 1 else 0
···489505 based + barrier + single
490506 | Lop (Ialloc _) when f.fun_fast -> 5
491507 | Lop (Ispecific (Ialloc_far _)) when f.fun_fast -> 6
492492- | Lop (Ipoll _) -> 3
493493- | Lop (Ispecific (Ipoll_far _)) -> 4
508508+ | Lop (Ipoll {return_label=None}) -> 3
509509+ | Lop (Ipoll {return_label=Some _}) -> 4
510510+ | Lop (Ispecific (Ipoll_far {return_label=None})) -> 4
511511+ | Lop (Ispecific (Ipoll_far {return_label=Some _})) -> 5
494512 | Lop (Ialloc { bytes = num_bytes; _ })
495513 | Lop (Ispecific (Ialloc_far { bytes = num_bytes; _ })) ->
496514 begin match num_bytes with
497497- | 16 | 24 | 32 -> 1
498498- | _ -> 1 + num_instructions_for_intconst (Nativeint.of_int num_bytes)
515515+ | 16 | 24 | 32 -> 2
516516+ | _ -> 2 + num_instructions_for_intconst (Nativeint.of_int num_bytes)
499517 end
500518 | Lop (Iintop (Icomp _)) -> 2
501519 | Lop (Icompf _) -> 2
···508526 | Lop (Ispecific (Ishiftcheckbound_far _)) -> 3
509527 | Lop (Iintop Imod) -> 2
510528 | Lop (Iintop Imulh) -> 1
529529+ | Lop (Iintop_imm ((Iadd|Isub), n)) -> addsub_size n
511530 | Lop (Iintop _) -> 1
512531 | Lop (Iintop_imm _) -> 1
513532 | Lop (Ifloatofint | Iintoffloat | Iabsf | Inegf | Ispecific Isqrtf) -> 1
···568587 | Ishiftcheckbound { shift; } ->
569588 Lop (Ispecific (Ishiftcheckbound_far { shift; }))
570589 | _ -> assert false
571571-end)
590590+end
591591+module BR = Branch_relaxation.Make (Size)
572592573593(* Output the assembly code for allocation. *)
574594···1073109310741094(* Emission of an instruction sequence *)
1075109510761076-let rec emit_all env i =
10771077- if i.desc = Lend then () else (emit_instr env i; emit_all env i.next)
10961096+(* for debugging instr_size errors *)
10971097+let emit_instr_debug env i =
10981098+ let lbl = new_label () in
10991099+ `{emit_label lbl}:\n`;
11001100+ emit_instr env i;
11011101+ let sz = Size.instr_size env.f i.desc * 4 in
11021102+ ` .ifne (. - {emit_label lbl}) - {emit_int sz}\n`;
11031103+ ` .error \"Emit.instr_size: instruction length mismatch\"\n`;
11041104+ ` .endif\n`
11051105+11061106+let rec emit_all env lbl_start acc i =
11071107+ let debug = Config.with_codegen_invariants in
11081108+ match i.desc with
11091109+ | Lend ->
11101110+ if debug then begin
11111111+ (* acc measures in units of 32-bit instructions *)
11121112+ let sz = acc * 4 in
11131113+ ` .ifne (. - {emit_label lbl_start}) - {emit_int sz}\n`;
11141114+ ` .error \"Emit.instr_size: instruction length mismatch\"\n`;
11151115+ ` .endif\n`;
11161116+ end
11171117+ else
11181118+ ()
11191119+ | _ ->
11201120+ if debug then emit_instr_debug env i else emit_instr env i;
11211121+ emit_all env lbl_start (acc + Size.instr_size env.f i.desc) i.next
11221122+11231123+let emit_all env i =
11241124+ let lbl = new_label () in
11251125+ `{emit_label lbl}:\n`;
11261126+ emit_all env lbl 0 i
1078112710791128(* Emission of a function declaration *)
10801129
+20
configure
···862862otherlibraries
863863instrumented_runtime_libs
864864instrumented_runtime
865865+codegen_invariants
865866debug_runtime
866867cmxs
867868natdynlink_archive
···998999ac_user_opts='
9991000enable_option_checking
10001001enable_debug_runtime
10021002+enable_codegen_invariants
10011003enable_ocamldebug
10021004enable_debugger
10031005enable_dependency_generation
···16971699 --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
16981700 --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
16991701 --disable-debug-runtime do not build runtime with debugging support
17021702+ --enable-codegen-invariants
17031703+ enable invariants checks in native codegen
17001704 --enable-ocamldebug build ocamldebug [default=auto]
17011705 --enable-debugger alias for --enable-ocamldebug
17021706 --disable-dependency-generation
···35003504350135053502350635073507+35033508 # TODO: rename this variable
3504350935053510···38663871if test ${enable_debug_runtime+y}
38673872then :
38683873 enableval=$enable_debug_runtime;
38743874+fi
38753875+38763876+38773877+# Check whether --enable-codegen-invariants was given.
38783878+if test ${enable_codegen_invariants+y}
38793879+then :
38803880+ enableval=$enable_codegen_invariants;
38693881fi
3870388238713883···2166221674 debug_runtime=false ;; #(
2166321675 *) :
2166421676 debug_runtime=true ;;
2167721677+esac
2167821678+2167921679+## Should the codegen with debugging support be built
2168021680+case $enable_codegen_invariants in #(
2168121681+ no) :
2168221682+ codegen_invariants=false ;; #(
2168321683+ *) :
2168421684+ codegen_invariants=true ;;
2166521685esac
21666216862166721687## Determine how to link with the POSIX threads library
+10
configure.ac
···196196AC_SUBST([natdynlink_archive])
197197AC_SUBST([cmxs])
198198AC_SUBST([debug_runtime])
199199+AC_SUBST([codegen_invariants])
199200AC_SUBST([instrumented_runtime])
200201AC_SUBST([instrumented_runtime_libs])
201202AC_SUBST([otherlibraries])
···377378AC_ARG_ENABLE([debug-runtime],
378379 [AS_HELP_STRING([--disable-debug-runtime],
379380 [do not build runtime with debugging support])])
381381+382382+AC_ARG_ENABLE([codegen-invariants],
383383+ [AS_HELP_STRING([--enable-codegen-invariants],
384384+ [enable invariants checks in native codegen])])
380385381386AC_ARG_ENABLE([ocamldebug],
382387 [AS_HELP_STRING([--enable-ocamldebug],
···24382443AS_CASE([$enable_debug_runtime],
24392444 [no], [debug_runtime=false],
24402445 [debug_runtime=true])
24462446+24472447+## Should the codegen with debugging support be built
24482448+AS_CASE([$enable_codegen_invariants],
24492449+ [no], [codegen_invariants=false],
24502450+ [codegen_invariants=true])
2441245124422452## Determine how to link with the POSIX threads library
24432453
···227227val with_cmm_invariants : bool
228228(** Whether the invariants checks for Cmm are enabled *)
229229230230+val with_codegen_invariants : bool
231231+(** Whether the invariant checks for native code generation are enabled. *)
232232+230233val reserved_header_bits : int
231234(** How many bits of a block's header are reserved *)
232235