From 447a542d5adaa78047c8c802b36e249ed57002a8 Mon Sep 17 00:00:00 2001 From: Simon Spies Date: Fri, 9 May 2025 14:30:03 +0100 Subject: [PATCH 1/4] allow larger integer ranges in asm directives --- backend/amd64/emit.ml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/amd64/emit.ml b/backend/amd64/emit.ml index d2b554b9717..4905038e3eb 100644 --- a/backend/amd64/emit.ml +++ b/backend/amd64/emit.ml @@ -2688,7 +2688,10 @@ let end_assembly () = let l = label_to_asm_label ~section:Data l in ND.label l); efa_8 = (fun n -> ND.uint8 (Numbers.Uint8.of_nonnegative_int_exn n)); - efa_16 = (fun n -> ND.int16 (Numbers.Int16.of_int_exn n)); + efa_16 = (fun n -> + if n > 0x7fff (* 2^15 - 1 = 32767, the max signed 16-bit int *) + then ND.uint16 (Numbers.Uint16.of_nonnegative_int_exn n) + else ND.int16 (Numbers.Int16.of_int_exn n)); efa_32 = (fun n -> ND.int32 n); efa_word = (fun n -> ND.targetint (Targetint.of_int_exn n)); efa_align = (fun n -> ND.align ~fill_x86_bin_emitter:Zero ~bytes:n); From c83ef958528c9b63a0143ca0d5402913155ac5c9 Mon Sep 17 00:00:00 2001 From: Simon Spies Date: Fri, 9 May 2025 14:33:57 +0100 Subject: [PATCH 2/4] ocamlformat --- backend/amd64/emit.ml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/backend/amd64/emit.ml b/backend/amd64/emit.ml index 4905038e3eb..e9989563ced 100644 --- a/backend/amd64/emit.ml +++ b/backend/amd64/emit.ml @@ -2688,10 +2688,11 @@ let end_assembly () = let l = label_to_asm_label ~section:Data l in ND.label l); efa_8 = (fun n -> ND.uint8 (Numbers.Uint8.of_nonnegative_int_exn n)); - efa_16 = (fun n -> - if n > 0x7fff (* 2^15 - 1 = 32767, the max signed 16-bit int *) - then ND.uint16 (Numbers.Uint16.of_nonnegative_int_exn n) - else ND.int16 (Numbers.Int16.of_int_exn n)); + efa_16 = + (fun n -> + if n > 0x7fff (* 2^15 - 1 = 32767, the max signed 16-bit int *) + then ND.uint16 (Numbers.Uint16.of_nonnegative_int_exn n) + else ND.int16 (Numbers.Int16.of_int_exn n)); efa_32 = (fun n -> ND.int32 n); efa_word = (fun n -> ND.targetint (Targetint.of_int_exn n)); efa_align = (fun n -> ND.align ~fill_x86_bin_emitter:Zero ~bytes:n); From 10cf93d0d8bf1a1d52647580fab25ff3cabc019e Mon Sep 17 00:00:00 2001 From: Simon Spies Date: Fri, 9 May 2025 14:52:12 +0100 Subject: [PATCH 3/4] allow only non-negative numbers --- backend/amd64/emit.ml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/backend/amd64/emit.ml b/backend/amd64/emit.ml index e9989563ced..25a88b587d5 100644 --- a/backend/amd64/emit.ml +++ b/backend/amd64/emit.ml @@ -2688,11 +2688,7 @@ let end_assembly () = let l = label_to_asm_label ~section:Data l in ND.label l); efa_8 = (fun n -> ND.uint8 (Numbers.Uint8.of_nonnegative_int_exn n)); - efa_16 = - (fun n -> - if n > 0x7fff (* 2^15 - 1 = 32767, the max signed 16-bit int *) - then ND.uint16 (Numbers.Uint16.of_nonnegative_int_exn n) - else ND.int16 (Numbers.Int16.of_int_exn n)); + efa_16 = (fun n -> ND.uint16 (Numbers.Uint16.of_nonnegative_int_exn n)); efa_32 = (fun n -> ND.int32 n); efa_word = (fun n -> ND.targetint (Targetint.of_int_exn n)); efa_align = (fun n -> ND.align ~fill_x86_bin_emitter:Zero ~bytes:n); From e7ed3706fa22f9e18abb0d3bc8594e689f061754 Mon Sep 17 00:00:00 2001 From: Simon Spies Date: Fri, 9 May 2025 15:46:45 +0100 Subject: [PATCH 4/4] split 16-bit integer emission into signed and unsigned --- backend/amd64/emit.ml | 3 ++- backend/arm64/emit.ml | 3 ++- backend/emitaux.ml | 18 ++++++++++-------- backend/emitaux.mli | 3 ++- runtime/caml/frame_descriptors.h | 2 ++ 5 files changed, 18 insertions(+), 11 deletions(-) diff --git a/backend/amd64/emit.ml b/backend/amd64/emit.ml index 25a88b587d5..1e1b0faa08e 100644 --- a/backend/amd64/emit.ml +++ b/backend/amd64/emit.ml @@ -2688,7 +2688,8 @@ let end_assembly () = let l = label_to_asm_label ~section:Data l in ND.label l); efa_8 = (fun n -> ND.uint8 (Numbers.Uint8.of_nonnegative_int_exn n)); - efa_16 = (fun n -> ND.uint16 (Numbers.Uint16.of_nonnegative_int_exn n)); + efa_i16 = (fun n -> ND.int16 (Numbers.Int16.of_int_exn n)); + efa_u16 = (fun n -> ND.uint16 (Numbers.Uint16.of_nonnegative_int_exn n)); efa_32 = (fun n -> ND.int32 n); efa_word = (fun n -> ND.targetint (Targetint.of_int_exn n)); efa_align = (fun n -> ND.align ~fill_x86_bin_emitter:Zero ~bytes:n); diff --git a/backend/arm64/emit.ml b/backend/arm64/emit.ml index 8fe697309cd..b0cab1ffefd 100644 --- a/backend/arm64/emit.ml +++ b/backend/arm64/emit.ml @@ -2220,7 +2220,8 @@ let end_assembly () = D.type_label ~ty:Object lbl; D.label lbl); efa_8 = (fun n -> D.uint8 (Numbers.Uint8.of_nonnegative_int_exn n)); - efa_16 = (fun n -> D.uint16 (Numbers.Uint16.of_nonnegative_int_exn n)); + efa_i16 = (fun n -> D.int16 (Numbers.Int16.of_int_exn n)); + efa_u16 = (fun n -> D.uint16 (Numbers.Uint16.of_nonnegative_int_exn n)); (* CR sspies: for some reason, we can get negative numbers here *) efa_32 = (fun n -> D.int32 n); efa_word = (fun n -> D.targetint (Targetint.of_int_exn n)); diff --git a/backend/emitaux.ml b/backend/emitaux.ml index 37fef20bd23..6a22f3eb3a9 100644 --- a/backend/emitaux.ml +++ b/backend/emitaux.ml @@ -199,7 +199,8 @@ type emit_frame_actions = { efa_code_label : Label.t -> unit; efa_data_label : Label.t -> unit; efa_8 : int -> unit; - efa_16 : int -> unit; + efa_i16 : int -> unit; + efa_u16 : int -> unit; efa_32 : int32 -> unit; efa_word : int -> unit; efa_align : int -> unit; @@ -252,12 +253,13 @@ let emit_frames a = below. *) if fd.fd_long then ( - a.efa_16 Flambda_backend_flags.max_long_frames_threshold; + a.efa_u16 Flambda_backend_flags.max_long_frames_threshold; a.efa_align 4); - let emit_16_or_32 = if fd.fd_long then emit_32 else a.efa_16 in - emit_16_or_32 (fd.fd_frame_size + flags); - emit_16_or_32 (List.length fd.fd_live_offset); - List.iter emit_16_or_32 fd.fd_live_offset; + let emit_signed_16_or_32 = if fd.fd_long then emit_32 else a.efa_i16 in + (* CR sspies: We should also split the case for 32-bit integers now. *) + emit_signed_16_or_32 (fd.fd_frame_size + flags); + emit_signed_16_or_32 (List.length fd.fd_live_offset); + List.iter emit_signed_16_or_32 fd.fd_live_offset; (match fd.fd_debuginfo with | _ when flags = 0 -> () | Dbg_other dbg -> @@ -295,8 +297,8 @@ let emit_frames a = in let emit_defname (_filename, defname, loc) (file_lbl, lbl) = let emit_loc (start_chr, end_chr, end_offset) = - a.efa_16 start_chr; - a.efa_16 end_chr; + a.efa_u16 start_chr; + a.efa_u16 end_chr; a.efa_32 (Int32.of_int end_offset) in (* These must be 32-bit aligned, both because they contain a 32-bit value, diff --git a/backend/emitaux.mli b/backend/emitaux.mli index 3aa0ae31eca..3a0c351c0d4 100644 --- a/backend/emitaux.mli +++ b/backend/emitaux.mli @@ -101,7 +101,8 @@ type emit_frame_actions = { efa_code_label : Label.t -> unit; efa_data_label : Label.t -> unit; efa_8 : int -> unit; - efa_16 : int -> unit; + efa_i16 : int -> unit; (** signed 16-bit integers *) + efa_u16 : int -> unit; (** unsigned 16-bit integers *) efa_32 : int32 -> unit; efa_word : int -> unit; efa_align : int -> unit; diff --git a/runtime/caml/frame_descriptors.h b/runtime/caml/frame_descriptors.h index cfc9f7e262d..8fb50c1b188 100644 --- a/runtime/caml/frame_descriptors.h +++ b/runtime/caml/frame_descriptors.h @@ -65,6 +65,8 @@ typedef struct { uint16_t frame_data; /* frame size and various flags */ uint16_t num_live; uint16_t live_ofs[1 /* num_live */]; + /* CR sspies: This is no longer correct. Due to recent changes in the compiler, the + offsets can now also be negative. */ /* If frame_has_allocs(), alloc lengths follow: uint8_t num_allocs;