diff --git a/0001-Don-t-ignore-.-configure-it-s-a-real-git-file.patch b/0001-Don-t-ignore-.-configure-it-s-a-real-git-file.patch index 2ce42ee..aa469a9 100644 --- a/0001-Don-t-ignore-.-configure-it-s-a-real-git-file.patch +++ b/0001-Don-t-ignore-.-configure-it-s-a-real-git-file.patch @@ -1,7 +1,7 @@ From 607ae33eed09f9eafccda1276626e9c509dcbed1 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 24 Jun 2014 22:29:38 +0100 -Subject: [PATCH 01/17] Don't ignore ./configure, it's a real git file. +Subject: [PATCH 01/18] Don't ignore ./configure, it's a real git file. --- .gitignore | 1 - @@ -20,5 +20,5 @@ index 6c66ecc..5d4b626 100644 /ocamlc.opt /expunge -- -2.3.1 +2.4.1 diff --git a/0002-Ensure-empty-compilerlibs-directory-is-created-by-gi.patch b/0002-Ensure-empty-compilerlibs-directory-is-created-by-gi.patch index 182b72f..8656d00 100644 --- a/0002-Ensure-empty-compilerlibs-directory-is-created-by-gi.patch +++ b/0002-Ensure-empty-compilerlibs-directory-is-created-by-gi.patch @@ -1,7 +1,7 @@ From 89f29afc4aaa324585aa010289a4a58416d53700 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 7 Jun 2012 15:36:16 +0100 -Subject: [PATCH 02/17] Ensure empty compilerlibs/ directory is created by git. +Subject: [PATCH 02/18] Ensure empty compilerlibs/ directory is created by git. This directory exists in the OCaml tarball, but is empty. As a result, git ignores it unless we put a dummy file in it. @@ -14,5 +14,5 @@ diff --git a/compilerlibs/.exists b/compilerlibs/.exists new file mode 100644 index 0000000..e69de29 -- -2.3.1 +2.4.1 diff --git a/0003-Don-t-add-rpaths-to-libraries.patch b/0003-Don-t-add-rpaths-to-libraries.patch index c16634b..93af56d 100644 --- a/0003-Don-t-add-rpaths-to-libraries.patch +++ b/0003-Don-t-add-rpaths-to-libraries.patch @@ -1,7 +1,7 @@ From 10209519de242952ebdef608ab5f2f51a6c9e2b3 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 24 Jun 2014 10:00:15 +0100 -Subject: [PATCH 03/17] Don't add rpaths to libraries. +Subject: [PATCH 03/18] Don't add rpaths to libraries. --- tools/Makefile.shared | 6 +++--- @@ -25,5 +25,5 @@ index 2517434..75a75b4 100644 sed -n -e 's/^#ml //p' ../config/Makefile) \ > ocamlmklibconfig.ml -- -2.3.1 +2.4.1 diff --git a/0004-ocamlbyteinfo-ocamlplugininfo-Useful-utilities-from-.patch b/0004-ocamlbyteinfo-ocamlplugininfo-Useful-utilities-from-.patch index ee89ef4..db21321 100644 --- a/0004-ocamlbyteinfo-ocamlplugininfo-Useful-utilities-from-.patch +++ b/0004-ocamlbyteinfo-ocamlplugininfo-Useful-utilities-from-.patch @@ -1,7 +1,7 @@ From b360841d9b1eae64201d1ee7a1ff6dc5a5b0fa87 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 29 May 2012 20:40:36 +0100 -Subject: [PATCH 04/17] ocamlbyteinfo, ocamlplugininfo: Useful utilities from +Subject: [PATCH 04/18] ocamlbyteinfo, ocamlplugininfo: Useful utilities from Debian, sent upstream. See: @@ -236,5 +236,5 @@ index 0000000..e28800f + header.units + end -- -2.3.1 +2.4.1 diff --git a/0005-configure-Allow-user-defined-C-compiler-flags.patch b/0005-configure-Allow-user-defined-C-compiler-flags.patch index 9d11fc5..a211a76 100644 --- a/0005-configure-Allow-user-defined-C-compiler-flags.patch +++ b/0005-configure-Allow-user-defined-C-compiler-flags.patch @@ -1,7 +1,7 @@ From 6193266853d3667f18048989ebaaa0cbcb74afb5 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 29 May 2012 20:44:18 +0100 -Subject: [PATCH 05/17] configure: Allow user defined C compiler flags. +Subject: [PATCH 05/18] configure: Allow user defined C compiler flags. --- configure | 4 ++++ @@ -23,5 +23,5 @@ index 3edb9fd..18b95cd 100755 cclibs="$cclibs $mathlib" -- -2.3.1 +2.4.1 diff --git a/0006-Add-support-for-ppc64.patch b/0006-Add-support-for-ppc64.patch index bef5d80..91a6311 100644 --- a/0006-Add-support-for-ppc64.patch +++ b/0006-Add-support-for-ppc64.patch @@ -1,7 +1,7 @@ From 5022b33b094d5a88c5c372b0873d81023f0d7bb4 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 29 May 2012 20:47:07 +0100 -Subject: [PATCH 06/17] Add support for ppc64. +Subject: [PATCH 06/18] Add support for ppc64. Note (1): This patch was rejected upstream because they don't have appropriate hardware for testing. @@ -2126,5 +2126,5 @@ index 18b95cd..57c8699 100755 aspp="$bytecc -c";; sparc,solaris) as="${TOOLPREF}as" -- -2.3.1 +2.4.1 diff --git a/0007-ppc64-Update-for-OCaml-4.02.0.patch b/0007-ppc64-Update-for-OCaml-4.02.0.patch index ee589cf..92f1e07 100644 --- a/0007-ppc64-Update-for-OCaml-4.02.0.patch +++ b/0007-ppc64-Update-for-OCaml-4.02.0.patch @@ -1,7 +1,7 @@ From 834644b81c536fc81022a0a13f860fb33e3d78d2 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 24 Oct 2014 12:59:23 +0200 -Subject: [PATCH 07/17] ppc64: Update for OCaml 4.02.0. +Subject: [PATCH 07/18] ppc64: Update for OCaml 4.02.0. These are based on the power (ppc32) branch and some guesswork. In particular, I'm not convinced that my changes to floating @@ -201,5 +201,5 @@ index b7bba9b..b582b6a 100644 | Iintop(Imod) -> 40 (* assuming full stall *) | Iintop(Icomp _) -> 4 -- -2.3.1 +2.4.1 diff --git a/0008-Add-support-for-ppc64le.patch b/0008-Add-support-for-ppc64le.patch index ceffd8f..e264706 100644 --- a/0008-Add-support-for-ppc64le.patch +++ b/0008-Add-support-for-ppc64le.patch @@ -1,7 +1,7 @@ From c89bde7d3563e2c7bb725272334fabf53044bd9c Mon Sep 17 00:00:00 2001 From: Michel Normand Date: Tue, 18 Mar 2014 09:15:47 -0400 -Subject: [PATCH 08/17] Add support for ppc64le. +Subject: [PATCH 08/18] Add support for ppc64le. Signed-off-by: Michel Normand --- @@ -1913,5 +1913,5 @@ index 57c8699..c04272c 100755 aspp="$bytecc -c";; sparc,solaris) as="${TOOLPREF}as" -- -2.3.1 +2.4.1 diff --git a/0009-ppc64le-Update-for-OCaml-4.02.0.patch b/0009-ppc64le-Update-for-OCaml-4.02.0.patch index 84d3329..09d9c11 100644 --- a/0009-ppc64le-Update-for-OCaml-4.02.0.patch +++ b/0009-ppc64le-Update-for-OCaml-4.02.0.patch @@ -1,7 +1,7 @@ From 8d86aba4983a254f36f2f1758079b3099ba5fc07 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 24 Oct 2014 12:59:23 +0200 -Subject: [PATCH 09/17] ppc64le: Update for OCaml 4.02.0. +Subject: [PATCH 09/18] ppc64le: Update for OCaml 4.02.0. These are based on the power (ppc32) branch and some guesswork. In particular, I'm not convinced that my changes to floating point @@ -200,5 +200,5 @@ index b7bba9b..b582b6a 100644 | Iintop(Imod) -> 40 (* assuming full stall *) | Iintop(Icomp _) -> 4 -- -2.3.1 +2.4.1 diff --git a/0010-arm-arm64-Mark-stack-as-non-executable.patch b/0010-arm-arm64-Mark-stack-as-non-executable.patch index 234d762..1e52d15 100644 --- a/0010-arm-arm64-Mark-stack-as-non-executable.patch +++ b/0010-arm-arm64-Mark-stack-as-non-executable.patch @@ -1,7 +1,7 @@ From 4d08d0e8511e247a96440693b73773c72b04fee2 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Sat, 10 May 2014 03:20:35 -0400 -Subject: [PATCH 10/17] arm, arm64: Mark stack as non-executable. +Subject: [PATCH 10/18] arm, arm64: Mark stack as non-executable. The same fix as this one, which was only fully applied to i686 & x86-64: @@ -35,5 +35,5 @@ index 9b4b9ab..c23168b 100644 + /* Mark stack as non-executable, PR#4564 */ + .section .note.GNU-stack,"",%progbits -- -2.3.1 +2.4.1 diff --git a/0011-arg-Add-no_arg-and-get_arg-helper-functions.patch b/0011-arg-Add-no_arg-and-get_arg-helper-functions.patch index 67482f0..dd31681 100644 --- a/0011-arg-Add-no_arg-and-get_arg-helper-functions.patch +++ b/0011-arg-Add-no_arg-and-get_arg-helper-functions.patch @@ -1,7 +1,7 @@ From 8ee89eee0500d17ffb91aa2febdeb6792ac53f27 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 1 Apr 2014 11:17:07 +0100 -Subject: [PATCH 11/17] arg: Add no_arg and get_arg helper functions. +Subject: [PATCH 11/18] arg: Add no_arg and get_arg helper functions. The no_arg function in this patch is a no-op. It will do something useful in the followups. @@ -114,5 +114,5 @@ index d7b8ac0..a8f3964 100644 treat_action action with Bad m -> stop (Message m); -- -2.3.1 +2.4.1 diff --git a/0012-arg-Allow-flags-such-as-flag-arg-as-well-as-flag-arg.patch b/0012-arg-Allow-flags-such-as-flag-arg-as-well-as-flag-arg.patch index b7bb135..50ef250 100644 --- a/0012-arg-Allow-flags-such-as-flag-arg-as-well-as-flag-arg.patch +++ b/0012-arg-Allow-flags-such-as-flag-arg-as-well-as-flag-arg.patch @@ -1,7 +1,7 @@ From 350eab7918f0adf385e01411ae6fed3e0579145f Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 1 Apr 2014 11:21:40 +0100 -Subject: [PATCH 12/17] arg: Allow flags such as --flag=arg as well as --flag +Subject: [PATCH 12/18] arg: Allow flags such as --flag=arg as well as --flag arg. Allow flags to be followed directly by their argument, separated by an '=' @@ -80,5 +80,5 @@ index 0999edf..71af638 100644 Examples ([cmd] is assumed to be the command name): -- -2.3.1 +2.4.1 diff --git a/0013-PR-6517-use-ISO-C99-types-u-int-32-64-_t-in-preferen.patch b/0013-PR-6517-use-ISO-C99-types-u-int-32-64-_t-in-preferen.patch index 50d2c07..17b269f 100644 --- a/0013-PR-6517-use-ISO-C99-types-u-int-32-64-_t-in-preferen.patch +++ b/0013-PR-6517-use-ISO-C99-types-u-int-32-64-_t-in-preferen.patch @@ -1,7 +1,7 @@ From 4072cbf56bba989f87783f285952d7227ba5898d Mon Sep 17 00:00:00 2001 From: Xavier Leroy Date: Wed, 27 Aug 2014 09:58:33 +0000 -Subject: [PATCH 13/17] PR#6517: use ISO C99 types {,u}int{32,64}_t in +Subject: [PATCH 13/18] PR#6517: use ISO C99 types {,u}int{32,64}_t in preference to our homegrown types {,u}int{32,64}. git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@15131 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02 @@ -1959,5 +1959,5 @@ index cb3d995..93cdfeb 100644 lseek(fd, (long) -TRAILER_SIZE, SEEK_END); -- -2.3.1 +2.4.1 diff --git a/0014-ppc-ppc64-ppc64le-Mark-stack-as-non-executable.patch b/0014-ppc-ppc64-ppc64le-Mark-stack-as-non-executable.patch index d2fde4b..b00c52c 100644 --- a/0014-ppc-ppc64-ppc64le-Mark-stack-as-non-executable.patch +++ b/0014-ppc-ppc64-ppc64le-Mark-stack-as-non-executable.patch @@ -1,7 +1,7 @@ From 8e493f90181b8b592185b2f9322575113b5ff7d5 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 11 Sep 2014 14:49:54 +0100 -Subject: [PATCH 14/17] ppc, ppc64, ppc64le: Mark stack as non-executable. +Subject: [PATCH 14/18] ppc, ppc64, ppc64le: Mark stack as non-executable. The same fix as this one, which was only fully applied to i686 & x86-64: @@ -70,5 +70,5 @@ index 98c42e2..b7bfce4 100644 +/* Mark stack as non-executable, PR#4564 */ + .section .note.GNU-stack,"",%progbits -- -2.3.1 +2.4.1 diff --git a/0015-ppc64-ppc64le-proc-Interim-definitions-for-op_is_pur.patch b/0015-ppc64-ppc64le-proc-Interim-definitions-for-op_is_pur.patch index 947a23d..3039aed 100644 --- a/0015-ppc64-ppc64le-proc-Interim-definitions-for-op_is_pur.patch +++ b/0015-ppc64-ppc64le-proc-Interim-definitions-for-op_is_pur.patch @@ -1,7 +1,7 @@ From df5201a35d02a13ad7ffd6fb38252851910cae43 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 24 Oct 2014 10:10:54 +0100 -Subject: [PATCH 15/17] ppc64/ppc64le: proc: Interim definitions for op_is_pure +Subject: [PATCH 15/18] ppc64/ppc64le: proc: Interim definitions for op_is_pure and regs_are_volatile. See: https://bugzilla.redhat.com/show_bug.cgi?id=1156300 @@ -80,5 +80,5 @@ index 476c984..56473ac 100644 let num_stack_slots = [| 0; 0 |] -- -2.3.1 +2.4.1 diff --git a/0016-Fix-PR-6490-incorrect-backtraces-in-gdb-on-AArch64.-.patch b/0016-Fix-PR-6490-incorrect-backtraces-in-gdb-on-AArch64.-.patch index 6f2918b..3f1d9c3 100644 --- a/0016-Fix-PR-6490-incorrect-backtraces-in-gdb-on-AArch64.-.patch +++ b/0016-Fix-PR-6490-incorrect-backtraces-in-gdb-on-AArch64.-.patch @@ -1,7 +1,7 @@ From d3ca0ccc0eccfecd4aa922decf99ca7d67d40fa7 Mon Sep 17 00:00:00 2001 From: Mark Shinwell Date: Wed, 6 May 2015 17:37:43 +0000 -Subject: [PATCH 16/17] Fix PR#6490: incorrect backtraces in gdb on AArch64. +Subject: [PATCH 16/18] Fix PR#6490: incorrect backtraces in gdb on AArch64. (Also fixes the same problem for 32-bit ARM.) git-svn-id: http://caml.inria.fr/svn/ocaml/version/4.02@16091 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02 @@ -75,5 +75,5 @@ index 486a583..e943da3 100644 val cfi_adjust_cfa_offset : int -> unit +val cfi_offset : reg:int -> offset:int -> unit -- -2.3.1 +2.4.1 diff --git a/0017-ppc64le-Fix-calling-convention-of-external-functions.patch b/0017-ppc64le-Fix-calling-convention-of-external-functions.patch index 9620f0d..038fe47 100644 --- a/0017-ppc64le-Fix-calling-convention-of-external-functions.patch +++ b/0017-ppc64le-Fix-calling-convention-of-external-functions.patch @@ -1,7 +1,7 @@ From 5b7d4c5d1407115c2c685987be2669a9b0aafa78 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 28 May 2015 16:13:40 -0400 -Subject: [PATCH 17/17] ppc64le: Fix calling convention of external functions +Subject: [PATCH 17/18] ppc64le: Fix calling convention of external functions with > 8 parameters (RHBZ#1225995). For external (ie. C) functions with more than 8 parameters, we must @@ -30,5 +30,5 @@ index 56473ac..c705695 100644 let extcall_use_push = false -- -2.3.1 +2.4.1 diff --git a/0018-aarch64-AArch64-backend-generates-invalid-asm-condit.patch b/0018-aarch64-AArch64-backend-generates-invalid-asm-condit.patch new file mode 100644 index 0000000..615f00f --- /dev/null +++ b/0018-aarch64-AArch64-backend-generates-invalid-asm-condit.patch @@ -0,0 +1,1214 @@ +From 1469caf50519c50979aeb27518f53d5976aed4ce Mon Sep 17 00:00:00 2001 +From: Mark Shinwell +Date: Tue, 9 Jun 2015 11:52:59 +0100 +Subject: [PATCH 18/18] aarch64: AArch64 backend generates invalid asm: + conditional branch out of range (RHBZ#1224815). + +Upstream bug: http://caml.inria.fr/mantis/view.php?id=6878 +--- + .depend | 148 ++++++++++--------- + Makefile | 2 + + asmcomp/arm64/arch.ml | 13 ++ + asmcomp/arm64/emit.mlp | 294 +++++++++++++++++++++++++++++++++++--- + asmcomp/branch_relaxation.ml | 135 +++++++++++++++++ + asmcomp/branch_relaxation.mli | 26 ++++ + asmcomp/branch_relaxation_intf.ml | 53 +++++++ + asmcomp/power/emit.mlp | 190 ++++++++++-------------- + 8 files changed, 655 insertions(+), 206 deletions(-) + create mode 100644 asmcomp/branch_relaxation.ml + create mode 100644 asmcomp/branch_relaxation.mli + create mode 100644 asmcomp/branch_relaxation_intf.ml + +diff --git a/.depend b/.depend +index 5d95a9b..d18b769 100644 +--- a/.depend ++++ b/.depend +@@ -94,10 +94,10 @@ typing/ctype.cmi : typing/types.cmi typing/path.cmi parsing/longident.cmi \ + typing/ident.cmi typing/env.cmi parsing/asttypes.cmi + typing/datarepr.cmi : typing/types.cmi typing/path.cmi typing/ident.cmi \ + parsing/asttypes.cmi ++typing/envaux.cmi : typing/subst.cmi typing/path.cmi typing/env.cmi + typing/env.cmi : utils/warnings.cmi typing/types.cmi typing/subst.cmi \ + typing/path.cmi parsing/longident.cmi parsing/location.cmi \ + typing/ident.cmi utils/consistbl.cmi parsing/asttypes.cmi +-typing/envaux.cmi : typing/subst.cmi typing/path.cmi typing/env.cmi + typing/ident.cmi : + typing/includeclass.cmi : typing/types.cmi typing/env.cmi typing/ctype.cmi + typing/includecore.cmi : typing/types.cmi typing/typedtree.cmi \ +@@ -115,10 +115,10 @@ typing/parmatch.cmi : typing/types.cmi typing/typedtree.cmi \ + typing/path.cmi : typing/ident.cmi + typing/predef.cmi : typing/types.cmi typing/path.cmi typing/ident.cmi + typing/primitive.cmi : ++typing/printtyped.cmi : typing/typedtree.cmi + typing/printtyp.cmi : typing/types.cmi typing/path.cmi \ + typing/outcometree.cmi parsing/longident.cmi typing/ident.cmi \ + typing/env.cmi +-typing/printtyped.cmi : typing/typedtree.cmi + typing/stypes.cmi : typing/typedtree.cmi parsing/location.cmi \ + typing/annot.cmi + typing/subst.cmi : typing/types.cmi typing/path.cmi typing/ident.cmi +@@ -131,11 +131,11 @@ typing/typecore.cmi : typing/types.cmi typing/typedtree.cmi typing/path.cmi \ + typing/typedecl.cmi : typing/types.cmi typing/typedtree.cmi typing/path.cmi \ + parsing/parsetree.cmi parsing/longident.cmi parsing/location.cmi \ + typing/includecore.cmi typing/ident.cmi typing/env.cmi +-typing/typedtree.cmi : typing/types.cmi typing/primitive.cmi typing/path.cmi \ +- parsing/parsetree.cmi parsing/longident.cmi parsing/location.cmi \ +- typing/ident.cmi typing/env.cmi parsing/asttypes.cmi + typing/typedtreeIter.cmi : typing/typedtree.cmi parsing/asttypes.cmi + typing/typedtreeMap.cmi : typing/typedtree.cmi ++typing/typedtree.cmi : typing/types.cmi typing/primitive.cmi typing/path.cmi \ ++ parsing/parsetree.cmi parsing/longident.cmi parsing/location.cmi \ ++ typing/ident.cmi typing/env.cmi parsing/asttypes.cmi + typing/typemod.cmi : typing/types.cmi typing/typedtree.cmi typing/path.cmi \ + parsing/parsetree.cmi parsing/longident.cmi parsing/location.cmi \ + typing/includemod.cmi typing/ident.cmi typing/env.cmi \ +@@ -176,6 +176,12 @@ typing/datarepr.cmo : typing/types.cmi typing/path.cmi parsing/location.cmi \ + typing/datarepr.cmx : typing/types.cmx typing/path.cmx parsing/location.cmx \ + typing/ident.cmx typing/btype.cmx parsing/asttypes.cmi \ + typing/datarepr.cmi ++typing/envaux.cmo : typing/types.cmi typing/subst.cmi typing/printtyp.cmi \ ++ typing/path.cmi utils/misc.cmi typing/ident.cmi typing/env.cmi \ ++ parsing/asttypes.cmi typing/envaux.cmi ++typing/envaux.cmx : typing/types.cmx typing/subst.cmx typing/printtyp.cmx \ ++ typing/path.cmx utils/misc.cmx typing/ident.cmx typing/env.cmx \ ++ parsing/asttypes.cmi typing/envaux.cmi + typing/env.cmo : utils/warnings.cmi typing/types.cmi utils/tbl.cmi \ + typing/subst.cmi typing/predef.cmi typing/path.cmi utils/misc.cmi \ + parsing/longident.cmi parsing/location.cmi typing/ident.cmi \ +@@ -188,12 +194,6 @@ typing/env.cmx : utils/warnings.cmx typing/types.cmx utils/tbl.cmx \ + typing/datarepr.cmx utils/consistbl.cmx utils/config.cmx \ + typing/cmi_format.cmx utils/clflags.cmx typing/btype.cmx \ + parsing/asttypes.cmi typing/env.cmi +-typing/envaux.cmo : typing/types.cmi typing/subst.cmi typing/printtyp.cmi \ +- typing/path.cmi utils/misc.cmi typing/ident.cmi typing/env.cmi \ +- parsing/asttypes.cmi typing/envaux.cmi +-typing/envaux.cmx : typing/types.cmx typing/subst.cmx typing/printtyp.cmx \ +- typing/path.cmx utils/misc.cmx typing/ident.cmx typing/env.cmx \ +- parsing/asttypes.cmi typing/envaux.cmi + typing/ident.cmo : typing/ident.cmi + typing/ident.cmx : typing/ident.cmi + typing/includeclass.cmo : typing/types.cmi typing/printtyp.cmi \ +@@ -252,24 +252,24 @@ typing/predef.cmx : typing/types.cmx typing/path.cmx parsing/location.cmx \ + typing/ident.cmx typing/btype.cmx parsing/asttypes.cmi typing/predef.cmi + typing/primitive.cmo : utils/misc.cmi typing/primitive.cmi + typing/primitive.cmx : utils/misc.cmx typing/primitive.cmi +-typing/printtyp.cmo : typing/types.cmi typing/primitive.cmi \ +- typing/predef.cmi typing/path.cmi typing/outcometree.cmi \ +- typing/oprint.cmi utils/misc.cmi parsing/longident.cmi \ +- parsing/location.cmi typing/ident.cmi typing/env.cmi typing/ctype.cmi \ +- utils/clflags.cmi typing/btype.cmi parsing/asttypes.cmi \ +- typing/printtyp.cmi +-typing/printtyp.cmx : typing/types.cmx typing/primitive.cmx \ +- typing/predef.cmx typing/path.cmx typing/outcometree.cmi \ +- typing/oprint.cmx utils/misc.cmx parsing/longident.cmx \ +- parsing/location.cmx typing/ident.cmx typing/env.cmx typing/ctype.cmx \ +- utils/clflags.cmx typing/btype.cmx parsing/asttypes.cmi \ +- typing/printtyp.cmi + typing/printtyped.cmo : typing/typedtree.cmi parsing/printast.cmi \ + typing/path.cmi utils/misc.cmi parsing/longident.cmi parsing/location.cmi \ + typing/ident.cmi parsing/asttypes.cmi typing/printtyped.cmi + typing/printtyped.cmx : typing/typedtree.cmx parsing/printast.cmx \ + typing/path.cmx utils/misc.cmx parsing/longident.cmx parsing/location.cmx \ + typing/ident.cmx parsing/asttypes.cmi typing/printtyped.cmi ++typing/printtyp.cmo : typing/types.cmi typing/primitive.cmi \ ++ typing/predef.cmi typing/path.cmi typing/outcometree.cmi \ ++ typing/oprint.cmi utils/misc.cmi parsing/longident.cmi \ ++ parsing/location.cmi typing/ident.cmi typing/env.cmi typing/ctype.cmi \ ++ utils/clflags.cmi typing/btype.cmi parsing/asttypes.cmi \ ++ typing/printtyp.cmi ++typing/printtyp.cmx : typing/types.cmx typing/primitive.cmx \ ++ typing/predef.cmx typing/path.cmx typing/outcometree.cmi \ ++ typing/oprint.cmx utils/misc.cmx parsing/longident.cmx \ ++ parsing/location.cmx typing/ident.cmx typing/env.cmx typing/ctype.cmx \ ++ utils/clflags.cmx typing/btype.cmx parsing/asttypes.cmi \ ++ typing/printtyp.cmi + typing/stypes.cmo : typing/typedtree.cmi typing/printtyp.cmi \ + parsing/location.cmi utils/clflags.cmi typing/annot.cmi typing/stypes.cmi + typing/stypes.cmx : typing/typedtree.cmx typing/printtyp.cmx \ +@@ -332,14 +332,6 @@ typing/typedecl.cmx : utils/warnings.cmx typing/typetexp.cmx \ + typing/ident.cmx typing/env.cmx typing/ctype.cmx utils/config.cmx \ + utils/clflags.cmx typing/btype.cmx parsing/asttypes.cmi \ + parsing/ast_helper.cmx typing/typedecl.cmi +-typing/typedtree.cmo : typing/types.cmi typing/primitive.cmi typing/path.cmi \ +- parsing/parsetree.cmi utils/misc.cmi parsing/longident.cmi \ +- parsing/location.cmi typing/ident.cmi typing/env.cmi parsing/asttypes.cmi \ +- typing/typedtree.cmi +-typing/typedtree.cmx : typing/types.cmx typing/primitive.cmx typing/path.cmx \ +- parsing/parsetree.cmi utils/misc.cmx parsing/longident.cmx \ +- parsing/location.cmx typing/ident.cmx typing/env.cmx parsing/asttypes.cmi \ +- typing/typedtree.cmi + typing/typedtreeIter.cmo : typing/typedtree.cmi utils/misc.cmi \ + parsing/asttypes.cmi typing/typedtreeIter.cmi + typing/typedtreeIter.cmx : typing/typedtree.cmx utils/misc.cmx \ +@@ -348,6 +340,14 @@ typing/typedtreeMap.cmo : typing/typedtree.cmi utils/misc.cmi \ + typing/typedtreeMap.cmi + typing/typedtreeMap.cmx : typing/typedtree.cmx utils/misc.cmx \ + typing/typedtreeMap.cmi ++typing/typedtree.cmo : typing/types.cmi typing/primitive.cmi typing/path.cmi \ ++ parsing/parsetree.cmi utils/misc.cmi parsing/longident.cmi \ ++ parsing/location.cmi typing/ident.cmi typing/env.cmi parsing/asttypes.cmi \ ++ typing/typedtree.cmi ++typing/typedtree.cmx : typing/types.cmx typing/primitive.cmx typing/path.cmx \ ++ parsing/parsetree.cmi utils/misc.cmx parsing/longident.cmx \ ++ parsing/location.cmx typing/ident.cmx typing/env.cmx parsing/asttypes.cmi \ ++ typing/typedtree.cmi + typing/typemod.cmo : utils/warnings.cmi typing/typetexp.cmi typing/types.cmi \ + typing/typedtree.cmi typing/typedecl.cmi typing/typecore.cmi \ + typing/typeclass.cmi typing/subst.cmi typing/stypes.cmi \ +@@ -578,27 +578,29 @@ bytecomp/typeopt.cmo : typing/types.cmi typing/typedtree.cmi \ + bytecomp/typeopt.cmx : typing/types.cmx typing/typedtree.cmx \ + typing/predef.cmx typing/path.cmx bytecomp/lambda.cmx typing/ident.cmx \ + typing/env.cmx typing/ctype.cmx bytecomp/typeopt.cmi +-asmcomp/CSEgen.cmi : asmcomp/mach.cmi + asmcomp/asmgen.cmi : bytecomp/lambda.cmi asmcomp/cmm.cmi + asmcomp/asmlibrarian.cmi : + asmcomp/asmlink.cmi : asmcomp/cmx_format.cmi + asmcomp/asmpackager.cmi : typing/env.cmi ++asmcomp/branch_relaxation.cmi : asmcomp/linearize.cmi \ ++ asmcomp/branch_relaxation_intf.cmo + asmcomp/clambda.cmi : bytecomp/lambda.cmi typing/ident.cmi \ + asmcomp/debuginfo.cmi parsing/asttypes.cmi + asmcomp/closure.cmi : bytecomp/lambda.cmi asmcomp/clambda.cmi +-asmcomp/cmm.cmi : bytecomp/lambda.cmi typing/ident.cmi asmcomp/debuginfo.cmi + asmcomp/cmmgen.cmi : asmcomp/cmx_format.cmi asmcomp/cmm.cmi \ + asmcomp/clambda.cmi ++asmcomp/cmm.cmi : bytecomp/lambda.cmi typing/ident.cmi asmcomp/debuginfo.cmi + asmcomp/cmx_format.cmi : asmcomp/clambda.cmi + asmcomp/codegen.cmi : asmcomp/cmm.cmi + asmcomp/coloring.cmi : + asmcomp/comballoc.cmi : asmcomp/mach.cmi + asmcomp/compilenv.cmi : typing/ident.cmi asmcomp/cmx_format.cmi \ + asmcomp/clambda.cmi ++asmcomp/CSEgen.cmi : asmcomp/mach.cmi + asmcomp/deadcode.cmi : asmcomp/mach.cmi + asmcomp/debuginfo.cmi : parsing/location.cmi bytecomp/lambda.cmi +-asmcomp/emit.cmi : asmcomp/linearize.cmi asmcomp/cmm.cmi + asmcomp/emitaux.cmi : asmcomp/debuginfo.cmi ++asmcomp/emit.cmi : asmcomp/linearize.cmi asmcomp/cmm.cmi + asmcomp/interf.cmi : asmcomp/mach.cmi + asmcomp/linearize.cmi : asmcomp/reg.cmi asmcomp/mach.cmi bytecomp/lambda.cmi \ + asmcomp/debuginfo.cmi +@@ -611,8 +613,8 @@ asmcomp/printlinear.cmi : asmcomp/linearize.cmi + asmcomp/printmach.cmi : asmcomp/reg.cmi asmcomp/mach.cmi + asmcomp/proc.cmi : asmcomp/reg.cmi asmcomp/mach.cmi + asmcomp/reg.cmi : typing/ident.cmi asmcomp/cmm.cmi +-asmcomp/reload.cmi : asmcomp/mach.cmi + asmcomp/reloadgen.cmi : asmcomp/reg.cmi asmcomp/mach.cmi ++asmcomp/reload.cmi : asmcomp/mach.cmi + asmcomp/schedgen.cmi : asmcomp/mach.cmi asmcomp/linearize.cmi + asmcomp/scheduling.cmi : asmcomp/linearize.cmi + asmcomp/selectgen.cmi : utils/tbl.cmi asmcomp/reg.cmi asmcomp/mach.cmi \ +@@ -621,12 +623,6 @@ asmcomp/selection.cmi : asmcomp/mach.cmi asmcomp/cmm.cmi + asmcomp/spill.cmi : asmcomp/mach.cmi + asmcomp/split.cmi : asmcomp/mach.cmi + asmcomp/strmatch.cmi : asmcomp/cmm.cmi +-asmcomp/CSE.cmo : asmcomp/mach.cmi asmcomp/CSEgen.cmi asmcomp/arch.cmo +-asmcomp/CSE.cmx : asmcomp/mach.cmx asmcomp/CSEgen.cmx asmcomp/arch.cmx +-asmcomp/CSEgen.cmo : asmcomp/reg.cmi asmcomp/proc.cmi asmcomp/mach.cmi \ +- asmcomp/CSEgen.cmi +-asmcomp/CSEgen.cmx : asmcomp/reg.cmx asmcomp/proc.cmx asmcomp/mach.cmx \ +- asmcomp/CSEgen.cmi + asmcomp/arch.cmo : + asmcomp/arch.cmx : + asmcomp/asmgen.cmo : bytecomp/translmod.cmi asmcomp/split.cmi \ +@@ -677,6 +673,14 @@ asmcomp/asmpackager.cmx : typing/typemod.cmx bytecomp/translmod.cmx \ + utils/config.cmx asmcomp/compilenv.cmx asmcomp/cmx_format.cmi \ + utils/clflags.cmx utils/ccomp.cmx asmcomp/asmlink.cmx asmcomp/asmgen.cmx \ + asmcomp/asmpackager.cmi ++asmcomp/branch_relaxation_intf.cmo : asmcomp/linearize.cmi asmcomp/arch.cmo ++asmcomp/branch_relaxation_intf.cmx : asmcomp/linearize.cmx asmcomp/arch.cmx ++asmcomp/branch_relaxation.cmo : utils/misc.cmi asmcomp/mach.cmi \ ++ asmcomp/linearize.cmi asmcomp/cmm.cmi asmcomp/branch_relaxation_intf.cmo \ ++ asmcomp/branch_relaxation.cmi ++asmcomp/branch_relaxation.cmx : utils/misc.cmx asmcomp/mach.cmx \ ++ asmcomp/linearize.cmx asmcomp/cmm.cmx asmcomp/branch_relaxation_intf.cmx \ ++ asmcomp/branch_relaxation.cmi + asmcomp/clambda.cmo : bytecomp/lambda.cmi typing/ident.cmi \ + asmcomp/debuginfo.cmi parsing/asttypes.cmi asmcomp/clambda.cmi + asmcomp/clambda.cmx : bytecomp/lambda.cmx typing/ident.cmx \ +@@ -691,10 +695,6 @@ asmcomp/closure.cmx : utils/tbl.cmx bytecomp/switch.cmx typing/primitive.cmx \ + asmcomp/debuginfo.cmx asmcomp/compilenv.cmx utils/clflags.cmx \ + asmcomp/clambda.cmx parsing/asttypes.cmi asmcomp/arch.cmx \ + asmcomp/closure.cmi +-asmcomp/cmm.cmo : bytecomp/lambda.cmi typing/ident.cmi asmcomp/debuginfo.cmi \ +- asmcomp/arch.cmo asmcomp/cmm.cmi +-asmcomp/cmm.cmx : bytecomp/lambda.cmx typing/ident.cmx asmcomp/debuginfo.cmx \ +- asmcomp/arch.cmx asmcomp/cmm.cmi + asmcomp/cmmgen.cmo : typing/types.cmi bytecomp/switch.cmi \ + asmcomp/strmatch.cmi asmcomp/proc.cmi typing/primitive.cmi utils/misc.cmi \ + bytecomp/lambda.cmi typing/ident.cmi asmcomp/debuginfo.cmi \ +@@ -707,6 +707,10 @@ asmcomp/cmmgen.cmx : typing/types.cmx bytecomp/switch.cmx \ + utils/config.cmx asmcomp/compilenv.cmx asmcomp/cmx_format.cmi \ + asmcomp/cmm.cmx utils/clflags.cmx asmcomp/clambda.cmx \ + parsing/asttypes.cmi asmcomp/arch.cmx asmcomp/cmmgen.cmi ++asmcomp/cmm.cmo : bytecomp/lambda.cmi typing/ident.cmi asmcomp/debuginfo.cmi \ ++ asmcomp/arch.cmo asmcomp/cmm.cmi ++asmcomp/cmm.cmx : bytecomp/lambda.cmx typing/ident.cmx asmcomp/debuginfo.cmx \ ++ asmcomp/arch.cmx asmcomp/cmm.cmi + asmcomp/codegen.cmo : asmcomp/split.cmi asmcomp/spill.cmi asmcomp/reload.cmi \ + asmcomp/reg.cmi asmcomp/printmach.cmi asmcomp/printlinear.cmi \ + asmcomp/printcmm.cmi asmcomp/liveness.cmi asmcomp/linearize.cmi \ +@@ -729,6 +733,12 @@ asmcomp/compilenv.cmo : utils/misc.cmi parsing/location.cmi typing/ident.cmi \ + asmcomp/compilenv.cmx : utils/misc.cmx parsing/location.cmx typing/ident.cmx \ + typing/env.cmx utils/config.cmx asmcomp/cmx_format.cmi \ + asmcomp/clambda.cmx asmcomp/compilenv.cmi ++asmcomp/CSEgen.cmo : asmcomp/reg.cmi asmcomp/proc.cmi asmcomp/mach.cmi \ ++ asmcomp/CSEgen.cmi ++asmcomp/CSEgen.cmx : asmcomp/reg.cmx asmcomp/proc.cmx asmcomp/mach.cmx \ ++ asmcomp/CSEgen.cmi ++asmcomp/CSE.cmo : asmcomp/mach.cmi asmcomp/CSEgen.cmi asmcomp/arch.cmo ++asmcomp/CSE.cmx : asmcomp/mach.cmx asmcomp/CSEgen.cmx asmcomp/arch.cmx + asmcomp/deadcode.cmo : asmcomp/reg.cmi asmcomp/proc.cmi asmcomp/mach.cmi \ + asmcomp/deadcode.cmi + asmcomp/deadcode.cmx : asmcomp/reg.cmx asmcomp/proc.cmx asmcomp/mach.cmx \ +@@ -737,20 +747,20 @@ asmcomp/debuginfo.cmo : parsing/location.cmi bytecomp/lambda.cmi \ + asmcomp/debuginfo.cmi + asmcomp/debuginfo.cmx : parsing/location.cmx bytecomp/lambda.cmx \ + asmcomp/debuginfo.cmi +-asmcomp/emit.cmo : asmcomp/reg.cmi asmcomp/proc.cmi utils/misc.cmi \ +- asmcomp/mach.cmi asmcomp/linearize.cmi bytecomp/lambda.cmi \ +- asmcomp/emitaux.cmi asmcomp/debuginfo.cmi utils/config.cmi \ +- asmcomp/compilenv.cmi asmcomp/cmm.cmi utils/clflags.cmi asmcomp/arch.cmo \ +- asmcomp/emit.cmi +-asmcomp/emit.cmx : asmcomp/reg.cmx asmcomp/proc.cmx utils/misc.cmx \ +- asmcomp/mach.cmx asmcomp/linearize.cmx bytecomp/lambda.cmx \ +- asmcomp/emitaux.cmx asmcomp/debuginfo.cmx utils/config.cmx \ +- asmcomp/compilenv.cmx asmcomp/cmm.cmx utils/clflags.cmx asmcomp/arch.cmx \ +- asmcomp/emit.cmi + asmcomp/emitaux.cmo : asmcomp/linearize.cmi asmcomp/debuginfo.cmi \ + utils/config.cmi utils/clflags.cmi asmcomp/arch.cmo asmcomp/emitaux.cmi + asmcomp/emitaux.cmx : asmcomp/linearize.cmx asmcomp/debuginfo.cmx \ + utils/config.cmx utils/clflags.cmx asmcomp/arch.cmx asmcomp/emitaux.cmi ++asmcomp/emit.cmo : asmcomp/reg.cmi asmcomp/proc.cmi utils/misc.cmi \ ++ asmcomp/mach.cmi asmcomp/linearize.cmi bytecomp/lambda.cmi \ ++ asmcomp/emitaux.cmi utils/config.cmi asmcomp/compilenv.cmi \ ++ asmcomp/cmm.cmi utils/clflags.cmi asmcomp/branch_relaxation.cmi \ ++ asmcomp/arch.cmo asmcomp/emit.cmi ++asmcomp/emit.cmx : asmcomp/reg.cmx asmcomp/proc.cmx utils/misc.cmx \ ++ asmcomp/mach.cmx asmcomp/linearize.cmx bytecomp/lambda.cmx \ ++ asmcomp/emitaux.cmx utils/config.cmx asmcomp/compilenv.cmx \ ++ asmcomp/cmm.cmx utils/clflags.cmx asmcomp/branch_relaxation.cmx \ ++ asmcomp/arch.cmx asmcomp/emit.cmi + asmcomp/interf.cmo : asmcomp/reg.cmi asmcomp/proc.cmi asmcomp/mach.cmi \ + asmcomp/interf.cmi + asmcomp/interf.cmx : asmcomp/reg.cmx asmcomp/proc.cmx asmcomp/mach.cmx \ +@@ -796,21 +806,19 @@ asmcomp/printmach.cmx : asmcomp/reg.cmx asmcomp/proc.cmx \ + asmcomp/debuginfo.cmx asmcomp/cmm.cmx asmcomp/arch.cmx \ + asmcomp/printmach.cmi + asmcomp/proc.cmo : asmcomp/reg.cmi utils/misc.cmi asmcomp/mach.cmi \ +- utils/config.cmi asmcomp/cmm.cmi utils/clflags.cmi utils/ccomp.cmi \ +- asmcomp/arch.cmo asmcomp/proc.cmi ++ utils/config.cmi asmcomp/cmm.cmi utils/ccomp.cmi asmcomp/arch.cmo \ ++ asmcomp/proc.cmi + asmcomp/proc.cmx : asmcomp/reg.cmx utils/misc.cmx asmcomp/mach.cmx \ +- utils/config.cmx asmcomp/cmm.cmx utils/clflags.cmx utils/ccomp.cmx \ +- asmcomp/arch.cmx asmcomp/proc.cmi ++ utils/config.cmx asmcomp/cmm.cmx utils/ccomp.cmx asmcomp/arch.cmx \ ++ asmcomp/proc.cmi + asmcomp/reg.cmo : typing/ident.cmi asmcomp/cmm.cmi asmcomp/reg.cmi + asmcomp/reg.cmx : typing/ident.cmx asmcomp/cmm.cmx asmcomp/reg.cmi +-asmcomp/reload.cmo : asmcomp/reloadgen.cmi asmcomp/reg.cmi asmcomp/mach.cmi \ +- asmcomp/cmm.cmi utils/clflags.cmi asmcomp/arch.cmo asmcomp/reload.cmi +-asmcomp/reload.cmx : asmcomp/reloadgen.cmx asmcomp/reg.cmx asmcomp/mach.cmx \ +- asmcomp/cmm.cmx utils/clflags.cmx asmcomp/arch.cmx asmcomp/reload.cmi + asmcomp/reloadgen.cmo : asmcomp/reg.cmi utils/misc.cmi asmcomp/mach.cmi \ + asmcomp/reloadgen.cmi + asmcomp/reloadgen.cmx : asmcomp/reg.cmx utils/misc.cmx asmcomp/mach.cmx \ + asmcomp/reloadgen.cmi ++asmcomp/reload.cmo : asmcomp/reloadgen.cmi asmcomp/reload.cmi ++asmcomp/reload.cmx : asmcomp/reloadgen.cmx asmcomp/reload.cmi + asmcomp/schedgen.cmo : asmcomp/reg.cmi asmcomp/proc.cmi asmcomp/mach.cmi \ + asmcomp/linearize.cmi asmcomp/cmm.cmi asmcomp/arch.cmo \ + asmcomp/schedgen.cmi +@@ -827,11 +835,11 @@ asmcomp/selectgen.cmx : utils/tbl.cmx bytecomp/simplif.cmx asmcomp/reg.cmx \ + asmcomp/proc.cmx utils/misc.cmx asmcomp/mach.cmx bytecomp/lambda.cmx \ + typing/ident.cmx asmcomp/debuginfo.cmx asmcomp/cmm.cmx utils/clflags.cmx \ + asmcomp/arch.cmx asmcomp/selectgen.cmi +-asmcomp/selection.cmo : asmcomp/selectgen.cmi asmcomp/proc.cmi \ +- asmcomp/mach.cmi asmcomp/cmm.cmi utils/clflags.cmi asmcomp/arch.cmo \ ++asmcomp/selection.cmo : asmcomp/selectgen.cmi asmcomp/mach.cmi \ ++ asmcomp/compilenv.cmi asmcomp/cmm.cmi utils/clflags.cmi asmcomp/arch.cmo \ + asmcomp/selection.cmi +-asmcomp/selection.cmx : asmcomp/selectgen.cmx asmcomp/proc.cmx \ +- asmcomp/mach.cmx asmcomp/cmm.cmx utils/clflags.cmx asmcomp/arch.cmx \ ++asmcomp/selection.cmx : asmcomp/selectgen.cmx asmcomp/mach.cmx \ ++ asmcomp/compilenv.cmx asmcomp/cmm.cmx utils/clflags.cmx asmcomp/arch.cmx \ + asmcomp/selection.cmi + asmcomp/spill.cmo : asmcomp/reg.cmi asmcomp/proc.cmi utils/misc.cmi \ + asmcomp/mach.cmi asmcomp/spill.cmi +@@ -849,8 +857,8 @@ driver/compenv.cmi : + driver/compile.cmi : + driver/compmisc.cmi : typing/env.cmi + driver/errors.cmi : +-driver/main.cmi : + driver/main_args.cmi : ++driver/main.cmi : + driver/optcompile.cmi : + driver/opterrors.cmi : + driver/optmain.cmi : +@@ -885,6 +893,8 @@ driver/compmisc.cmx : typing/typemod.cmx utils/misc.cmx \ + parsing/asttypes.cmi driver/compmisc.cmi + driver/errors.cmo : parsing/location.cmi driver/errors.cmi + driver/errors.cmx : parsing/location.cmx driver/errors.cmi ++driver/main_args.cmo : utils/warnings.cmi driver/main_args.cmi ++driver/main_args.cmx : utils/warnings.cmx driver/main_args.cmi + driver/main.cmo : utils/warnings.cmi utils/misc.cmi driver/main_args.cmi \ + parsing/location.cmi utils/config.cmi driver/compmisc.cmi \ + driver/compile.cmi driver/compenv.cmi utils/clflags.cmi \ +@@ -895,8 +905,6 @@ driver/main.cmx : utils/warnings.cmx utils/misc.cmx driver/main_args.cmx \ + driver/compile.cmx driver/compenv.cmx utils/clflags.cmx \ + bytecomp/bytepackager.cmx bytecomp/bytelink.cmx \ + bytecomp/bytelibrarian.cmx driver/main.cmi +-driver/main_args.cmo : utils/warnings.cmi driver/main_args.cmi +-driver/main_args.cmx : utils/warnings.cmx driver/main_args.cmi + driver/optcompile.cmo : utils/warnings.cmi typing/typemod.cmi \ + typing/typedtree.cmi typing/typecore.cmi bytecomp/translmod.cmi \ + typing/stypes.cmi bytecomp/simplif.cmi typing/printtyped.cmi \ +diff --git a/Makefile b/Makefile +index 6c0e7e6..7a20e2c 100644 +--- a/Makefile ++++ b/Makefile +@@ -94,6 +94,8 @@ ASMCOMP=asmcomp/arch.cmo asmcomp/debuginfo.cmo \ + asmcomp/deadcode.cmo \ + asmcomp/printlinear.cmo asmcomp/linearize.cmo \ + asmcomp/schedgen.cmo asmcomp/scheduling.cmo \ ++ asmcomp/branch_relaxation_intf.cmo \ ++ asmcomp/branch_relaxation.cmo \ + asmcomp/emitaux.cmo asmcomp/emit.cmo asmcomp/asmgen.cmo \ + asmcomp/asmlink.cmo asmcomp/asmlibrarian.cmo asmcomp/asmpackager.cmo \ + driver/opterrors.cmo driver/optcompile.cmo +diff --git a/asmcomp/arm64/arch.ml b/asmcomp/arm64/arch.ml +index bfbe183..3e62da8 100644 +--- a/asmcomp/arm64/arch.ml ++++ b/asmcomp/arm64/arch.ml +@@ -34,8 +34,12 @@ type addressing_mode = + (* Specific operations *) + + type specific_operation = ++ | Ifar_alloc of int ++ | Ifar_intop_checkbound ++ | Ifar_intop_imm_checkbound of int + | Ishiftarith of arith_operation * int + | Ishiftcheckbound of int ++ | Ifar_shiftcheckbound of int + | Imuladd (* multiply and add *) + | Imulsub (* multiply and subtract *) + | Inegmulf (* floating-point negate and multiply *) +@@ -91,6 +95,12 @@ let print_addressing printreg addr ppf arg = + + let print_specific_operation printreg op ppf arg = + match op with ++ | Ifar_alloc n -> ++ fprintf ppf "(far) alloc %i" n ++ | Ifar_intop_checkbound -> ++ fprintf ppf "%a (far) check > %a" printreg arg.(0) printreg arg.(1) ++ | Ifar_intop_imm_checkbound n -> ++ fprintf ppf "%a (far) check > %i" printreg arg.(0) n + | Ishiftarith(op, shift) -> + let op_name = function + | Ishiftadd -> "+" +@@ -103,6 +113,9 @@ let print_specific_operation printreg op ppf arg = + printreg arg.(0) (op_name op) printreg arg.(1) shift_mark + | Ishiftcheckbound n -> + fprintf ppf "check %a >> %i > %a" printreg arg.(0) n printreg arg.(1) ++ | Ifar_shiftcheckbound n -> ++ fprintf ppf ++ "(far) check %a >> %i > %a" printreg arg.(0) n printreg arg.(1) + | Imuladd -> + fprintf ppf "(%a * %a) + %a" + printreg arg.(0) +diff --git a/asmcomp/arm64/emit.mlp b/asmcomp/arm64/emit.mlp +index c5c30d4..3d7a297 100644 +--- a/asmcomp/arm64/emit.mlp ++++ b/asmcomp/arm64/emit.mlp +@@ -231,6 +231,32 @@ let emit_intconst dst n = + in + if n < 0n then emit_neg true 48 else emit_pos true 48 + ++let num_instructions_for_intconst n = ++ let num_instructions = ref 0 in ++ let rec count_pos first shift = ++ if shift < 0 then begin ++ if first then incr num_instructions ++ end else begin ++ let s = Nativeint.(logand (shift_right_logical n shift) 0xFFFFn) in ++ if s = 0n then count_pos first (shift - 16) else begin ++ incr num_instructions; ++ count_pos false (shift - 16) ++ end ++ end ++ and count_neg first shift = ++ if shift < 0 then begin ++ if first then incr num_instructions ++ end else begin ++ let s = Nativeint.(logand (shift_right_logical n shift) 0xFFFFn) in ++ if s = 0xFFFFn then count_neg first (shift - 16) else begin ++ incr num_instructions; ++ count_neg false (shift - 16) ++ end ++ end ++ in ++ if n < 0n then count_neg true 48 else count_pos true 48; ++ !num_instructions ++ + (* Recognize float constants appropriate for FMOV dst, #fpimm instruction: + "a normalized binary floating point encoding with 1 sign bit, 4 + bits of fraction and a 3-bit exponent" *) +@@ -302,6 +328,217 @@ let emit_load_symbol_addr dst s = + ` ldr {emit_reg dst}, [{emit_reg dst}, #:got_lo12:{emit_symbol s}]\n` + end + ++(* The following functions are used for calculating the sizes of the ++ call GC and bounds check points emitted out-of-line from the function ++ body. See branch_relaxation.mli. *) ++ ++let num_call_gc_and_check_bound_points instr = ++ let rec loop instr ((call_gc, check_bound) as totals) = ++ match instr.desc with ++ | Lend -> totals ++ | Lop (Ialloc _) when !fastcode_flag -> ++ loop instr.next (call_gc + 1, check_bound) ++ | Lop (Iintop Icheckbound) ++ | Lop (Iintop_imm (Icheckbound, _)) ++ | Lop (Ispecific (Ishiftcheckbound _)) -> ++ let check_bound = ++ (* When not in debug mode, there is at most one check-bound point. *) ++ if not !Clflags.debug then min (check_bound + 1) 1 ++ else check_bound + 1 ++ in ++ loop instr.next (call_gc, check_bound) ++ (* The following four should never be seen, since this function is run ++ before branch relaxation. *) ++ | Lop (Ispecific (Ifar_alloc _)) ++ | Lop (Ispecific Ifar_intop_checkbound) ++ | Lop (Ispecific (Ifar_intop_imm_checkbound _)) ++ | Lop (Ispecific (Ifar_shiftcheckbound _)) -> assert false ++ | _ -> loop instr.next totals ++ in ++ loop instr (0, 0) ++ ++let max_out_of_line_code_offset instr ~num_call_gc ~num_check_bound = ++ if num_call_gc < 1 && num_check_bound < 1 then 0 ++ else begin ++ let size_of_call_gc = 2 in ++ let size_of_check_bound = 1 in ++ let size_of_last_thing = ++ (* Call-GC points come before check-bound points. *) ++ if num_check_bound >= 1 then size_of_check_bound else size_of_call_gc ++ in ++ let total_size = ++ size_of_call_gc*num_call_gc + size_of_check_bound*num_check_bound ++ in ++ let max_offset = total_size - size_of_last_thing in ++ assert (max_offset >= 0); ++ max_offset ++ end ++ ++module BR = Branch_relaxation.Make (struct ++ (* CR-someday mshinwell: B and BL have +/- 128Mb ranges; for the moment we ++ assume we will never exceed this. It would seem to be most likely to ++ occur for branches between functions; in this case, the linker should be ++ able to insert veneers anyway. (See section 4.6.7 of the document ++ "ELF for the ARM 64-bit architecture (AArch64)".) *) ++ ++ type distance = int ++ ++ module Cond_branch = struct ++ type t = TB | CB | Bcc ++ ++ let all = [TB; CB; Bcc] ++ ++ (* AArch64 instructions are 32 bits wide, so [distance] in this module ++ means units of 32-bit words. *) ++ let max_displacement = function ++ | TB -> 32 * 1024 / 4 (* +/- 32Kb *) ++ | CB | Bcc -> 1 * 1024 * 1024 / 4 (* +/- 1Mb *) ++ ++ let classify_instr = function ++ | Lop (Ialloc _) ++ | Lop (Iintop Icheckbound) ++ | Lop (Iintop_imm (Icheckbound, _)) ++ | Lop (Ispecific (Ishiftcheckbound _)) -> Some Bcc ++ (* The various "far" variants in [specific_operation] don't need to ++ return [Some] here, since their code sequences never contain any ++ conditional branches that might need relaxing. *) ++ | Lcondbranch (Itruetest, _) ++ | Lcondbranch (Ifalsetest, _) -> Some CB ++ | Lcondbranch (Iinttest _, _) ++ | Lcondbranch (Iinttest_imm _, _) ++ | Lcondbranch (Ifloattest _, _) -> Some Bcc ++ | Lcondbranch (Ioddtest, _) ++ | Lcondbranch (Ieventest, _) -> Some TB ++ | Lcondbranch3 _ -> Some Bcc ++ | _ -> None ++ end ++ ++ let offset_pc_at_branch = 0 ++ ++ let epilogue_size () = ++ if !contains_calls then 3 else 2 ++ ++ let instr_size = function ++ | Lend -> 0 ++ | Lop (Imove | Ispill | Ireload) -> 1 ++ | Lop (Iconst_int n | Iconst_blockheader n) -> ++ num_instructions_for_intconst n ++ | Lop (Iconst_float _) -> 2 ++ | Lop (Iconst_symbol _) -> 2 ++ | Lop (Icall_ind) -> 1 ++ | Lop (Icall_imm _) -> 1 ++ | Lop (Itailcall_ind) -> epilogue_size () ++ | Lop (Itailcall_imm s) -> ++ if s = !function_name then 1 else epilogue_size () ++ | Lop (Iextcall (_, false)) -> 1 ++ | Lop (Iextcall (_, true)) -> 3 ++ | Lop (Istackoffset _) -> 2 ++ | Lop (Iload (size, addr)) | Lop (Istore (size, addr, _)) -> ++ let based = match addr with Iindexed _ -> 0 | Ibased _ -> 1 in ++ based + begin match size with Single -> 2 | _ -> 1 end ++ | Lop (Ialloc _) when !fastcode_flag -> 4 ++ | Lop (Ispecific (Ifar_alloc _)) when !fastcode_flag -> 5 ++ | Lop (Ialloc num_words) | Lop (Ispecific (Ifar_alloc num_words)) -> ++ begin match num_words with ++ | 16 | 24 | 32 -> 1 ++ | _ -> 1 + num_instructions_for_intconst (Nativeint.of_int num_words) ++ end ++ | Lop (Iintop (Icomp _)) -> 2 ++ | Lop (Iintop_imm (Icomp _, _)) -> 2 ++ | Lop (Iintop Icheckbound) -> 2 ++ | Lop (Ispecific Ifar_intop_checkbound) -> 3 ++ | Lop (Iintop_imm (Icheckbound, _)) -> 2 ++ | Lop (Ispecific (Ifar_intop_imm_checkbound _)) -> 3 ++ | Lop (Ispecific (Ishiftcheckbound _)) -> 2 ++ | Lop (Ispecific (Ifar_shiftcheckbound _)) -> 3 ++ | Lop (Iintop Imod) -> 2 ++ | Lop (Iintop Imulh) -> 1 ++ | Lop (Iintop _) -> 1 ++ | Lop (Iintop_imm _) -> 1 ++ | Lop (Ifloatofint | Iintoffloat | Iabsf | Inegf | Ispecific Isqrtf) -> 1 ++ | Lop (Iaddf | Isubf | Imulf | Idivf | Ispecific Inegmulf) -> 1 ++ | Lop (Ispecific (Imuladdf | Inegmuladdf | Imulsubf | Inegmulsubf)) -> 1 ++ | Lop (Ispecific (Ishiftarith _)) -> 1 ++ | Lop (Ispecific (Imuladd | Imulsub)) -> 1 ++ | Lop (Ispecific (Ibswap 16)) -> 2 ++ | Lop (Ispecific (Ibswap _)) -> 1 ++ | Lreloadretaddr -> 0 ++ | Lreturn -> epilogue_size () ++ | Llabel _ -> 0 ++ | Lbranch _ -> 1 ++ | Lcondbranch (tst, _) -> ++ begin match tst with ++ | Itruetest -> 1 ++ | Ifalsetest -> 1 ++ | Iinttest _ -> 2 ++ | Iinttest_imm _ -> 2 ++ | Ifloattest _ -> 2 ++ | Ioddtest -> 1 ++ | Ieventest -> 1 ++ end ++ | Lcondbranch3 (lbl0, lbl1, lbl2) -> ++ 1 + begin match lbl0 with None -> 0 | Some _ -> 1 end ++ + begin match lbl1 with None -> 0 | Some _ -> 1 end ++ + begin match lbl2 with None -> 0 | Some _ -> 1 end ++ | Lswitch jumptbl -> 3 + Array.length jumptbl ++ | Lsetuptrap _ -> 2 ++ | Lpushtrap -> 3 ++ | Lpoptrap -> 1 ++ | Lraise k -> ++ begin match !Clflags.debug, k with ++ | true, (Lambda.Raise_regular | Lambda.Raise_reraise) -> 1 ++ | false, _ ++ | true, Lambda.Raise_notrace -> 4 ++ end ++ ++ let relax_allocation ~num_words = ++ Lop (Ispecific (Ifar_alloc num_words)) ++ ++ let relax_intop_checkbound () = ++ Lop (Ispecific Ifar_intop_checkbound) ++ ++ let relax_intop_imm_checkbound ~bound = ++ Lop (Ispecific (Ifar_intop_imm_checkbound bound)) ++ ++ let relax_specific_op = function ++ | Ishiftcheckbound shift -> Lop (Ispecific (Ifar_shiftcheckbound shift)) ++ | _ -> assert false ++end) ++ ++(* Output the assembly code for allocation. *) ++ ++let assembly_code_for_allocation i ~n ~far = ++ let lbl_frame = record_frame_label i.live i.dbg in ++ if !fastcode_flag then begin ++ let lbl_redo = new_label() in ++ let lbl_call_gc = new_label() in ++ `{emit_label lbl_redo}:`; ++ ` sub {emit_reg reg_alloc_ptr}, {emit_reg reg_alloc_ptr}, #{emit_int n}\n`; ++ ` cmp {emit_reg reg_alloc_ptr}, {emit_reg reg_alloc_limit}\n`; ++ ` add {emit_reg i.res.(0)}, {emit_reg reg_alloc_ptr}, #8\n`; ++ if not far then begin ++ ` b.lo {emit_label lbl_call_gc}\n` ++ end else begin ++ let lbl = new_label () in ++ ` b.cs {emit_label lbl}\n`; ++ ` b {emit_label lbl_call_gc}\n`; ++ `{emit_label lbl}:\n` ++ end; ++ call_gc_sites := ++ { gc_lbl = lbl_call_gc; ++ gc_return_lbl = lbl_redo; ++ gc_frame_lbl = lbl_frame } :: !call_gc_sites ++ end else begin ++ begin match n with ++ | 16 -> ` bl {emit_symbol "caml_alloc1"}\n` ++ | 24 -> ` bl {emit_symbol "caml_alloc2"}\n` ++ | 32 -> ` bl {emit_symbol "caml_alloc3"}\n` ++ | _ -> emit_intconst reg_x15 (Nativeint.of_int n); ++ ` bl {emit_symbol "caml_allocN"}\n` ++ end; ++ `{emit_label lbl_frame}: add {emit_reg i.res.(0)}, {emit_reg reg_alloc_ptr}, #8\n` ++ end ++ + (* Output the assembly code for an instruction *) + + let emit_instr i = +@@ -410,29 +647,9 @@ let emit_instr i = + ` str {emit_reg src}, {emit_addressing addr base}\n` + end + | Lop(Ialloc n) -> +- let lbl_frame = record_frame_label i.live i.dbg in +- if !fastcode_flag then begin +- let lbl_redo = new_label() in +- let lbl_call_gc = new_label() in +- `{emit_label lbl_redo}:`; +- ` sub {emit_reg reg_alloc_ptr}, {emit_reg reg_alloc_ptr}, #{emit_int n}\n`; +- ` cmp {emit_reg reg_alloc_ptr}, {emit_reg reg_alloc_limit}\n`; +- ` add {emit_reg i.res.(0)}, {emit_reg reg_alloc_ptr}, #8\n`; +- ` b.lo {emit_label lbl_call_gc}\n`; +- call_gc_sites := +- { gc_lbl = lbl_call_gc; +- gc_return_lbl = lbl_redo; +- gc_frame_lbl = lbl_frame } :: !call_gc_sites +- end else begin +- begin match n with +- | 16 -> ` bl {emit_symbol "caml_alloc1"}\n` +- | 24 -> ` bl {emit_symbol "caml_alloc2"}\n` +- | 32 -> ` bl {emit_symbol "caml_alloc3"}\n` +- | _ -> emit_intconst reg_x15 (Nativeint.of_int n); +- ` bl {emit_symbol "caml_allocN"}\n` +- end; +- `{emit_label lbl_frame}: add {emit_reg i.res.(0)}, {emit_reg reg_alloc_ptr}, #8\n` +- end ++ assembly_code_for_allocation i ~n ~far:false ++ | Lop(Ispecific (Ifar_alloc n)) -> ++ assembly_code_for_allocation i ~n ~far:true + | Lop(Iintop(Icomp cmp)) -> + ` cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; + ` cset {emit_reg i.res.(0)}, {emit_string (name_for_comparison cmp)}\n` +@@ -443,14 +660,35 @@ let emit_instr i = + let lbl = bound_error_label i.dbg in + ` cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; + ` b.ls {emit_label lbl}\n` ++ | Lop(Ispecific Ifar_intop_checkbound) -> ++ let lbl = bound_error_label i.dbg in ++ let lbl2 = new_label () in ++ ` cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; ++ ` b.ge {emit_label lbl2}\n`; ++ ` b {emit_label lbl}\n`; ++ `{emit_label lbl2}:\n`; + | Lop(Iintop_imm(Icheckbound, n)) -> + let lbl = bound_error_label i.dbg in + ` cmp {emit_reg i.arg.(0)}, #{emit_int n}\n`; + ` b.ls {emit_label lbl}\n` ++ | Lop(Ispecific(Ifar_intop_imm_checkbound bound)) -> ++ let lbl = bound_error_label i.dbg in ++ let lbl2 = new_label () in ++ ` cmp {emit_reg i.arg.(0)}, #{emit_int bound}\n`; ++ ` b.ge {emit_label lbl2}\n`; ++ ` b {emit_label lbl}\n`; ++ `{emit_label lbl2}:\n`; + | Lop(Ispecific(Ishiftcheckbound shift)) -> + let lbl = bound_error_label i.dbg in + ` cmp {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}, lsr #{emit_int shift}\n`; + ` b.cs {emit_label lbl}\n` ++ | Lop(Ispecific(Ifar_shiftcheckbound shift)) -> ++ let lbl = bound_error_label i.dbg in ++ let lbl2 = new_label () in ++ ` cmp {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}, lsr #{emit_int shift}\n`; ++ ` b.ge {emit_label lbl2}\n`; ++ ` b {emit_label lbl}\n`; ++ `{emit_label lbl2}:\n`; + | Lop(Iintop Imod) -> + ` sdiv {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; + ` msub {emit_reg i.res.(0)}, {emit_reg reg_tmp1}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n` +@@ -659,9 +897,19 @@ let fundecl fundecl = + ` str x30, [sp, #{emit_int (n-8)}]\n` + end; + `{emit_label !tailrec_entry_point}:\n`; ++ let num_call_gc, num_check_bound = ++ num_call_gc_and_check_bound_points fundecl.fun_body ++ in ++ let max_out_of_line_code_offset = ++ max_out_of_line_code_offset fundecl.fun_body ~num_call_gc ++ ~num_check_bound ++ in ++ BR.relax fundecl.fun_body ~max_out_of_line_code_offset; + emit_all fundecl.fun_body; + List.iter emit_call_gc !call_gc_sites; + List.iter emit_call_bound_error !bound_error_sites; ++ assert (List.length !call_gc_sites = num_call_gc); ++ assert (List.length !bound_error_sites = num_check_bound); + cfi_endproc(); + ` .type {emit_symbol fundecl.fun_name}, %function\n`; + ` .size {emit_symbol fundecl.fun_name}, .-{emit_symbol fundecl.fun_name}\n`; +diff --git a/asmcomp/branch_relaxation.ml b/asmcomp/branch_relaxation.ml +new file mode 100644 +index 0000000..8fd3891 +--- /dev/null ++++ b/asmcomp/branch_relaxation.ml +@@ -0,0 +1,135 @@ ++(***********************************************************************) ++(* *) ++(* OCaml *) ++(* *) ++(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) ++(* Mark Shinwell, Jane Street Europe *) ++(* *) ++(* Copyright 1996 Institut National de Recherche en Informatique et *) ++(* en Automatique. All rights reserved. This file is distributed *) ++(* under the terms of the Q Public License version 1.0. *) ++(* *) ++(***********************************************************************) ++ ++open Mach ++open Linearize ++ ++module Make (T : Branch_relaxation_intf.S) = struct ++ let label_map code = ++ let map = Hashtbl.create 37 in ++ let rec fill_map pc instr = ++ match instr.desc with ++ | Lend -> (pc, map) ++ | Llabel lbl -> Hashtbl.add map lbl pc; fill_map pc instr.next ++ | op -> fill_map (pc + T.instr_size op) instr.next ++ in ++ fill_map 0 code ++ ++ let branch_overflows map pc_branch lbl_dest max_branch_offset = ++ let pc_dest = Hashtbl.find map lbl_dest in ++ let delta = pc_dest - (pc_branch + T.offset_pc_at_branch) in ++ delta <= -max_branch_offset || delta >= max_branch_offset ++ ++ let opt_branch_overflows map pc_branch opt_lbl_dest max_branch_offset = ++ match opt_lbl_dest with ++ | None -> false ++ | Some lbl_dest -> ++ branch_overflows map pc_branch lbl_dest max_branch_offset ++ ++ let instr_overflows ~code_size ~max_out_of_line_code_offset instr map pc = ++ match T.Cond_branch.classify_instr instr.desc with ++ | None -> false ++ | Some branch -> ++ let max_branch_offset = ++ (* Remember to cut some slack for multi-word instructions (in the ++ [Linearize] sense of the word) where the branch can be anywhere in ++ the middle. 12 words of slack is plenty. *) ++ T.Cond_branch.max_displacement branch - 12 ++ in ++ match instr.desc with ++ | Lop (Ialloc _) ++ | Lop (Iintop Icheckbound) ++ | Lop (Iintop_imm (Icheckbound, _)) ++ | Lop (Ispecific _) -> ++ (* We assume that any branches eligible for relaxation generated ++ by these instructions only branch forward. We further assume ++ that any of these may branch to an out-of-line code block. *) ++ code_size + max_out_of_line_code_offset - pc >= max_branch_offset ++ | Lcondbranch (_, lbl) -> ++ branch_overflows map pc lbl max_branch_offset ++ | Lcondbranch3 (lbl0, lbl1, lbl2) -> ++ opt_branch_overflows map pc lbl0 max_branch_offset ++ || opt_branch_overflows map pc lbl1 max_branch_offset ++ || opt_branch_overflows map pc lbl2 max_branch_offset ++ | _ -> ++ Misc.fatal_error "Unsupported instruction for branch relaxation" ++ ++ let fixup_branches ~code_size ~max_out_of_line_code_offset map code = ++ let expand_optbranch lbl n arg next = ++ match lbl with ++ | None -> next ++ | Some l -> ++ instr_cons (Lcondbranch (Iinttest_imm (Isigned Cmm.Ceq, n), l)) ++ arg [||] next ++ in ++ let rec fixup did_fix pc instr = ++ match instr.desc with ++ | Lend -> did_fix ++ | _ -> ++ let overflows = ++ instr_overflows ~code_size ~max_out_of_line_code_offset instr map pc ++ in ++ if not overflows then ++ fixup did_fix (pc + T.instr_size instr.desc) instr.next ++ else ++ match instr.desc with ++ | Lop (Ialloc num_words) -> ++ instr.desc <- T.relax_allocation ~num_words; ++ fixup true (pc + T.instr_size instr.desc) instr.next ++ | Lop (Iintop Icheckbound) -> ++ instr.desc <- T.relax_intop_checkbound (); ++ fixup true (pc + T.instr_size instr.desc) instr.next ++ | Lop (Iintop_imm (Icheckbound, bound)) -> ++ instr.desc <- T.relax_intop_imm_checkbound ~bound; ++ fixup true (pc + T.instr_size instr.desc) instr.next ++ | Lop (Ispecific specific) -> ++ instr.desc <- T.relax_specific_op specific; ++ fixup true (pc + T.instr_size instr.desc) instr.next ++ | Lcondbranch (test, lbl) -> ++ let lbl2 = new_label() in ++ let cont = ++ instr_cons (Lbranch lbl) [||] [||] ++ (instr_cons (Llabel lbl2) [||] [||] instr.next) ++ in ++ instr.desc <- Lcondbranch (invert_test test, lbl2); ++ instr.next <- cont; ++ fixup true (pc + T.instr_size instr.desc) instr.next ++ | Lcondbranch3 (lbl0, lbl1, lbl2) -> ++ let cont = ++ expand_optbranch lbl0 0 instr.arg ++ (expand_optbranch lbl1 1 instr.arg ++ (expand_optbranch lbl2 2 instr.arg instr.next)) ++ in ++ instr.desc <- cont.desc; ++ instr.next <- cont.next; ++ fixup true pc instr ++ | _ -> ++ Misc.fatal_error "Unsupported instruction for branch relaxation" ++ in ++ fixup false 0 code ++ ++ (* Iterate branch expansion till all conditional branches are OK *) ++ ++ let rec relax code ~max_out_of_line_code_offset = ++ let min_of_max_branch_offsets = ++ List.fold_left (fun min_of_max_branch_offsets branch -> ++ min min_of_max_branch_offsets ++ (T.Cond_branch.max_displacement branch)) ++ max_int T.Cond_branch.all ++ in ++ let (code_size, map) = label_map code in ++ if code_size >= min_of_max_branch_offsets ++ && fixup_branches ~code_size ~max_out_of_line_code_offset map code ++ then relax code ~max_out_of_line_code_offset ++ else () ++end +diff --git a/asmcomp/branch_relaxation.mli b/asmcomp/branch_relaxation.mli +new file mode 100644 +index 0000000..9d517b1 +--- /dev/null ++++ b/asmcomp/branch_relaxation.mli +@@ -0,0 +1,26 @@ ++(***********************************************************************) ++(* *) ++(* OCaml *) ++(* *) ++(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) ++(* Mark Shinwell, Jane Street Europe *) ++(* *) ++(* Copyright 1996 Institut National de Recherche en Informatique et *) ++(* en Automatique. All rights reserved. This file is distributed *) ++(* under the terms of the Q Public License version 1.0. *) ++(* *) ++(***********************************************************************) ++ ++(* Fix up conditional branches that exceed hardware-allowed ranges. *) ++ ++module Make (T : Branch_relaxation_intf.S) : sig ++ val relax ++ : Linearize.instruction ++ (* [max_offset_of_out_of_line_code] specifies the furthest distance, ++ measured from the first address immediately after the last instruction ++ of the function, that may be branched to from within the function in ++ order to execute "out of line" code blocks such as call GC and ++ bounds check points. *) ++ -> max_out_of_line_code_offset:T.distance ++ -> unit ++end +diff --git a/asmcomp/branch_relaxation_intf.ml b/asmcomp/branch_relaxation_intf.ml +new file mode 100644 +index 0000000..fb721b2 +--- /dev/null ++++ b/asmcomp/branch_relaxation_intf.ml +@@ -0,0 +1,53 @@ ++(***********************************************************************) ++(* *) ++(* OCaml *) ++(* *) ++(* Mark Shinwell, Jane Street Europe *) ++(* *) ++(* Copyright 1996 Institut National de Recherche en Informatique et *) ++(* en Automatique. All rights reserved. This file is distributed *) ++(* under the terms of the Q Public License version 1.0. *) ++(* *) ++(***********************************************************************) ++ ++module type S = sig ++ (* The distance between two instructions, in arbitrary units (typically ++ the natural word size of instructions). *) ++ type distance = int ++ ++ module Cond_branch : sig ++ (* The various types of conditional branches for a given target that ++ may require relaxation. *) ++ type t ++ ++ (* All values of type [t] that the emitter may produce. *) ++ val all : t list ++ ++ (* If [max_displacement branch] is [n] then [branch] is assumed to ++ reach any address in the range [pc - n, pc + n] (inclusive), after ++ the [pc] of the branch has been adjusted by [offset_pc_at_branch] ++ (see below). *) ++ val max_displacement : t -> distance ++ ++ (* Which variety of conditional branch may be produced by the emitter for a ++ given instruction description. For the moment we assume that only one ++ such variety per instruction description is needed. *) ++ val classify_instr : Linearize.instruction_desc -> t option ++ end ++ ++ (* The value to be added to the program counter (in [distance] units) ++ when it is at a branch instruction, prior to calculating the distance ++ to a branch target. *) ++ val offset_pc_at_branch : distance ++ ++ (* The maximum size of a given instruction. *) ++ val instr_size : Linearize.instruction_desc -> distance ++ ++ (* Insertion of target-specific code to relax operations that cannot be ++ relaxed generically. It is assumed that these rewrites do not change ++ the size of out-of-line code (cf. branch_relaxation.mli). *) ++ val relax_allocation : num_words:int -> Linearize.instruction_desc ++ val relax_intop_checkbound : unit -> Linearize.instruction_desc ++ val relax_intop_imm_checkbound : bound:int -> Linearize.instruction_desc ++ val relax_specific_op : Arch.specific_operation -> Linearize.instruction_desc ++end +diff --git a/asmcomp/power/emit.mlp b/asmcomp/power/emit.mlp +index 8e31b58..717ab12 100644 +--- a/asmcomp/power/emit.mlp ++++ b/asmcomp/power/emit.mlp +@@ -308,126 +308,87 @@ let defined_functions = ref StringSet.empty + (* Label of glue code for calling the GC *) + let call_gc_label = ref 0 + +-(* Fixup conditional branches that exceed hardware allowed range *) ++module BR = Branch_relaxation.Make (struct ++ type distance = int + +-let load_store_size = function +- Ibased(s, d) -> 2 +- | Iindexed ofs -> if is_immediate ofs then 1 else 3 +- | Iindexed2 -> 1 ++ module Cond_branch = struct ++ type t = Branch + +-let instr_size = function +- Lend -> 0 +- | Lop(Imove | Ispill | Ireload) -> 1 +- | Lop(Iconst_int n | Iconst_blockheader n) -> +- if is_native_immediate n then 1 else 2 +- | Lop(Iconst_float s) -> 2 +- | Lop(Iconst_symbol s) -> 2 +- | Lop(Icall_ind) -> 2 +- | Lop(Icall_imm s) -> 1 +- | Lop(Itailcall_ind) -> 5 +- | Lop(Itailcall_imm s) -> if s = !function_name then 1 else 4 +- | Lop(Iextcall(s, true)) -> 3 +- | Lop(Iextcall(s, false)) -> if pic_externals then 4 else 1 +- | Lop(Istackoffset n) -> 1 +- | Lop(Iload(chunk, addr)) -> ++ let all = [Branch] ++ ++ let max_displacement = function ++ (* 14-bit signed offset in words. *) ++ | Branch -> 8192 ++ ++ let classify_instr = function ++ | Lop (Ialloc _) ++ (* [Ialloc_far] does not need to be here, since its code sequence ++ never involves any conditional branches that might need relaxing. *) ++ | Lcondbranch _ ++ | Lcondbranch3 _ -> Some Branch ++ | _ -> None ++ end ++ ++ let offset_pc_at_branch = 1 ++ ++ let load_store_size = function ++ | Ibased(s, d) -> 2 ++ | Iindexed ofs -> if is_immediate ofs then 1 else 3 ++ | Iindexed2 -> 1 ++ ++ let instr_size = function ++ | Lend -> 0 ++ | Lop(Imove | Ispill | Ireload) -> 1 ++ | Lop(Iconst_int n | Iconst_blockheader n) -> ++ if is_native_immediate n then 1 else 2 ++ | Lop(Iconst_float s) -> 2 ++ | Lop(Iconst_symbol s) -> 2 ++ | Lop(Icall_ind) -> 2 ++ | Lop(Icall_imm s) -> 1 ++ | Lop(Itailcall_ind) -> 5 ++ | Lop(Itailcall_imm s) -> if s = !function_name then 1 else 4 ++ | Lop(Iextcall(s, true)) -> 3 ++ | Lop(Iextcall(s, false)) -> if pic_externals then 4 else 1 ++ | Lop(Istackoffset n) -> 1 ++ | Lop(Iload(chunk, addr)) -> + if chunk = Byte_signed + then load_store_size addr + 1 + else load_store_size addr +- | Lop(Istore(chunk, addr, _)) -> load_store_size addr +- | Lop(Ialloc n) -> 4 +- | Lop(Ispecific(Ialloc_far n)) -> 5 +- | Lop(Iintop Imod) -> 3 +- | Lop(Iintop(Icomp cmp)) -> 4 +- | Lop(Iintop op) -> 1 +- | Lop(Iintop_imm(Icomp cmp, n)) -> 4 +- | Lop(Iintop_imm(op, n)) -> 1 +- | Lop(Inegf | Iabsf | Iaddf | Isubf | Imulf | Idivf) -> 1 +- | Lop(Ifloatofint) -> 9 +- | Lop(Iintoffloat) -> 4 +- | Lop(Ispecific sop) -> 1 +- | Lreloadretaddr -> 2 +- | Lreturn -> 2 +- | Llabel lbl -> 0 +- | Lbranch lbl -> 1 +- | Lcondbranch(tst, lbl) -> 2 +- | Lcondbranch3(lbl0, lbl1, lbl2) -> ++ | Lop(Istore(chunk, addr, _)) -> load_store_size addr ++ | Lop(Ialloc n) -> 4 ++ | Lop(Ispecific(Ialloc_far n)) -> 5 ++ | Lop(Iintop Imod) -> 3 ++ | Lop(Iintop(Icomp cmp)) -> 4 ++ | Lop(Iintop op) -> 1 ++ | Lop(Iintop_imm(Icomp cmp, n)) -> 4 ++ | Lop(Iintop_imm(op, n)) -> 1 ++ | Lop(Inegf | Iabsf | Iaddf | Isubf | Imulf | Idivf) -> 1 ++ | Lop(Ifloatofint) -> 9 ++ | Lop(Iintoffloat) -> 4 ++ | Lop(Ispecific sop) -> 1 ++ | Lreloadretaddr -> 2 ++ | Lreturn -> 2 ++ | Llabel lbl -> 0 ++ | Lbranch lbl -> 1 ++ | Lcondbranch(tst, lbl) -> 2 ++ | Lcondbranch3(lbl0, lbl1, lbl2) -> + 1 + (if lbl0 = None then 0 else 1) + + (if lbl1 = None then 0 else 1) + + (if lbl2 = None then 0 else 1) +- | Lswitch jumptbl -> 8 +- | Lsetuptrap lbl -> 1 +- | Lpushtrap -> 4 +- | Lpoptrap -> 2 +- | Lraise _ -> 6 +- +-let label_map code = +- let map = Hashtbl.create 37 in +- let rec fill_map pc instr = +- match instr.desc with +- Lend -> (pc, map) +- | Llabel lbl -> Hashtbl.add map lbl pc; fill_map pc instr.next +- | op -> fill_map (pc + instr_size op) instr.next +- in fill_map 0 code +- +-let max_branch_offset = 8180 +-(* 14-bit signed offset in words. Remember to cut some slack +- for multi-word instructions where the branch can be anywhere in +- the middle. 12 words of slack is plenty. *) +- +-let branch_overflows map pc_branch lbl_dest = +- let pc_dest = Hashtbl.find map lbl_dest in +- let delta = pc_dest - (pc_branch + 1) in +- delta <= -max_branch_offset || delta >= max_branch_offset +- +-let opt_branch_overflows map pc_branch opt_lbl_dest = +- match opt_lbl_dest with +- None -> false +- | Some lbl_dest -> branch_overflows map pc_branch lbl_dest +- +-let fixup_branches codesize map code = +- let expand_optbranch lbl n arg next = +- match lbl with +- None -> next +- | Some l -> +- instr_cons (Lcondbranch(Iinttest_imm(Isigned Ceq, n), l)) +- arg [||] next in +- let rec fixup did_fix pc instr = +- match instr.desc with +- Lend -> did_fix +- | Lcondbranch(test, lbl) when branch_overflows map pc lbl -> +- let lbl2 = new_label() in +- let cont = +- instr_cons (Lbranch lbl) [||] [||] +- (instr_cons (Llabel lbl2) [||] [||] instr.next) in +- instr.desc <- Lcondbranch(invert_test test, lbl2); +- instr.next <- cont; +- fixup true (pc + 2) instr.next +- | Lcondbranch3(lbl0, lbl1, lbl2) +- when opt_branch_overflows map pc lbl0 +- || opt_branch_overflows map pc lbl1 +- || opt_branch_overflows map pc lbl2 -> +- let cont = +- expand_optbranch lbl0 0 instr.arg +- (expand_optbranch lbl1 1 instr.arg +- (expand_optbranch lbl2 2 instr.arg instr.next)) in +- instr.desc <- cont.desc; +- instr.next <- cont.next; +- fixup true pc instr +- | Lop(Ialloc n) when codesize - pc >= max_branch_offset -> +- instr.desc <- Lop(Ispecific(Ialloc_far n)); +- fixup true (pc + 4) instr.next +- | op -> +- fixup did_fix (pc + instr_size op) instr.next +- in fixup false 0 code +- +-(* Iterate branch expansion till all conditional branches are OK *) +- +-let rec branch_normalization code = +- let (codesize, map) = label_map code in +- if codesize >= max_branch_offset && fixup_branches codesize map code +- then branch_normalization code +- else () +- ++ | Lswitch jumptbl -> 8 ++ | Lsetuptrap lbl -> 1 ++ | Lpushtrap -> 4 ++ | Lpoptrap -> 2 ++ | Lraise _ -> 6 ++ ++ let relax_allocation ~num_words = Lop (Ispecific (Ialloc_far num_words)) ++ ++ (* [classify_addr], above, never identifies these instructions as needing ++ relaxing. As such, these functions should never be called. *) ++ let relax_specific_op _ = assert false ++ let relax_intop_checkbound () = assert false ++ let relax_intop_imm_checkbound ~bound:_ = assert false ++end) + + (* Output the assembly code for an instruction *) + +@@ -848,7 +809,10 @@ let fundecl fundecl = + ` addi {emit_gpr 1}, {emit_gpr 1}, {emit_int(-n)}\n` + end; + `{emit_label !tailrec_entry_point}:\n`; +- branch_normalization fundecl.fun_body; ++ (* On this target, there is at most one "out of line" code block per ++ function: a single "call GC" point. It comes immediately after the ++ function's body. *) ++ BR.relax fundecl.fun_body ~max_out_of_line_code_offset:0; + emit_all fundecl.fun_body; + (* Emit the glue code to call the GC *) + if !call_gc_label > 0 then begin +-- +2.4.1 + diff --git a/ocaml.spec b/ocaml.spec index 598e1b1..c94ddcc 100644 --- a/ocaml.spec +++ b/ocaml.spec @@ -17,7 +17,7 @@ Name: ocaml Version: 4.02.1 -Release: 5%{?dist} +Release: 6%{?dist} Summary: OCaml compiler and programming environment @@ -62,6 +62,7 @@ Patch0014: 0014-ppc-ppc64-ppc64le-Mark-stack-as-non-executable.patch Patch0015: 0015-ppc64-ppc64le-proc-Interim-definitions-for-op_is_pur.patch Patch0016: 0016-Fix-PR-6490-incorrect-backtraces-in-gdb-on-AArch64.-.patch Patch0017: 0017-ppc64le-Fix-calling-convention-of-external-functions.patch +Patch0018: 0018-aarch64-AArch64-backend-generates-invalid-asm-condit.patch # Add BFD support so that ocamlobjinfo supports *.cmxs format (RHBZ#1113735). BuildRequires: binutils-devel @@ -423,6 +424,10 @@ fi %changelog +* Tue Jun 09 2015 Richard W.M. Jones - 4.02.1-6 +- aarch64: AArch64 backend generates invalid asm: conditional branch + out of range (RHBZ#1224815). + * Thu May 28 2015 Richard W.M. Jones - 4.02.1-5 - ppc64le: Fix calling convention of external functions with > 8 parameters (RHBZ#1225995).