diff --git a/0001-Add-.gitignore-file-to-ignore-generated-files.patch b/0001-Add-.gitignore-file-to-ignore-generated-files.patch deleted file mode 100644 index 527beae..0000000 --- a/0001-Add-.gitignore-file-to-ignore-generated-files.patch +++ /dev/null @@ -1,366 +0,0 @@ -From 07839dfc746ccee318601b9668aa094d4465bc6e Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Thu, 7 Jun 2012 16:00:28 +0100 -Subject: [PATCH 01/14] Add .gitignore file to ignore generated files. - ---- - .gitignore | 347 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 347 insertions(+) - create mode 100644 .gitignore - -diff --git a/.gitignore b/.gitignore -new file mode 100644 -index 0000000..7191b83 ---- /dev/null -+++ b/.gitignore -@@ -0,0 +1,347 @@ -+*~ -+*.a -+*.bak -+*.cma -+*.cmi -+*.cmo -+*.cmx -+*.o -+*.so -+/_boot_log1 -+/_boot_log2 -+/_build/ -+/_log -+/asmcomp/arch.ml -+/asmcomp/emit.ml -+/asmcomp/proc.ml -+/asmcomp/reload.ml -+/asmcomp/scheduling.ml -+/asmcomp/selection.ml -+/asmrun/alloc.c -+/asmrun/array.c -+/asmrun/callback.c -+/asmrun/compact.c -+/asmrun/compare.c -+/asmrun/custom.c -+/asmrun/debugger.c -+/asmrun/dynlink.c -+/asmrun/extern.c -+/asmrun/finalise.c -+/asmrun/floats.c -+/asmrun/freelist.c -+/asmrun/gc_ctrl.c -+/asmrun/globroots.c -+/asmrun/hash.c -+/asmrun/intern.c -+/asmrun/ints.c -+/asmrun/io.c -+/asmrun/lexing.c -+/asmrun/main.c -+/asmrun/major_gc.c -+/asmrun/md5.c -+/asmrun/memory.c -+/asmrun/meta.c -+/asmrun/minor_gc.c -+/asmrun/misc.c -+/asmrun/obj.c -+/asmrun/parsing.c -+/asmrun/printexc.c -+/asmrun/signals.c -+/asmrun/str.c -+/asmrun/sys.c -+/asmrun/terminfo.c -+/asmrun/unix.c -+/asmrun/weak.c -+/boot/camlheader -+/boot/myocamlbuild -+/boot/ocamlrun -+/boot/ocamlyacc -+/build/ocamlbuild_mixed_mode -+/bytecomp/opcodes.ml -+/bytecomp/runtimedef.ml -+/byterun/jumptbl.h -+/byterun/ld.conf -+/byterun/ocamlrun -+/byterun/primitives -+/byterun/prims.c -+/byterun/version.h -+/compilerlibs/ocamlbytecomp.cmxa -+/compilerlibs/ocamlcommon.cmxa -+/compilerlibs/ocamloptcomp.cmxa -+/configure -+/config/Makefile -+/config/config.sh -+/config/m.h -+/config/s.h -+/debugger/dynlink.ml -+/debugger/dynlink.mli -+/debugger/lexer.ml -+/debugger/ocamldebug -+/debugger/parser.ml -+/debugger/parser.mli -+/expunge -+/lex/lexer.ml -+/lex/ocamllex -+/lex/ocamllex.opt -+/lex/parser.ml -+/lex/parser.mli -+/lex/parser.output -+/myocamlbuild_config.ml -+/ocamlbuild-mixed-boot -+/ocaml -+/ocamlc -+/ocamlc.opt -+/ocamlcomp.sh -+/ocamlcompopt.sh -+/ocamldoc/generators/odoc_literate.cmxs -+/ocamldoc/generators/odoc_todo.cmxs -+/ocamldoc/ocamldoc -+/ocamldoc/ocamldoc.opt -+/ocamldoc/odoc_info.cmxa -+/ocamldoc/odoc_lexer.ml -+/ocamldoc/odoc_ocamlhtml.ml -+/ocamldoc/odoc_parser.ml -+/ocamldoc/odoc_parser.mli -+/ocamldoc/odoc_parser.output -+/ocamldoc/odoc_see_lexer.ml -+/ocamldoc/odoc_text_lexer.ml -+/ocamldoc/odoc_text_parser.ml -+/ocamldoc/odoc_text_parser.mli -+/ocamldoc/odoc_text_parser.output -+/ocamldoc/stdlib_man/ -+/ocamlnat -+/ocamlopt -+/ocamlopt.opt -+/otherlibs/bigarray/bigarray.cmxa -+/otherlibs/bigarray/bigarray.cmxs -+/otherlibs/dynlink/dynlink.cmxa -+/otherlibs/dbm/ -+/otherlibs/dynlink/extract_crc -+/otherlibs/graph/graphics.cmxa -+/otherlibs/graph/graphics.cmxs -+/otherlibs/labltk/frx/frxlib.cmxa -+/otherlibs/labltk/jpf/jpflib.cmxa -+/otherlibs/labltk/lib/labltk.cmxa -+/otherlibs/labltk/browser/dummy.mli -+/otherlibs/labltk/browser/help.ml -+/otherlibs/labltk/browser/ocamlbrowser -+/otherlibs/labltk/camltk/.depend -+/otherlibs/labltk/camltk/_tkfgen.ml -+/otherlibs/labltk/camltk/_tkgen.ml -+/otherlibs/labltk/camltk/_tkgen.mli -+/otherlibs/labltk/camltk/_tkigen.ml -+/otherlibs/labltk/camltk/cBell.ml -+/otherlibs/labltk/camltk/cBell.mli -+/otherlibs/labltk/camltk/cButton.ml -+/otherlibs/labltk/camltk/cButton.mli -+/otherlibs/labltk/camltk/cCanvas.ml -+/otherlibs/labltk/camltk/cCanvas.mli -+/otherlibs/labltk/camltk/cCheckbutton.ml -+/otherlibs/labltk/camltk/cCheckbutton.mli -+/otherlibs/labltk/camltk/cClipboard.ml -+/otherlibs/labltk/camltk/cClipboard.mli -+/otherlibs/labltk/camltk/cDialog.ml -+/otherlibs/labltk/camltk/cDialog.mli -+/otherlibs/labltk/camltk/cEncoding.ml -+/otherlibs/labltk/camltk/cEncoding.mli -+/otherlibs/labltk/camltk/cEntry.ml -+/otherlibs/labltk/camltk/cEntry.mli -+/otherlibs/labltk/camltk/cFocus.ml -+/otherlibs/labltk/camltk/cFocus.mli -+/otherlibs/labltk/camltk/cFont.ml -+/otherlibs/labltk/camltk/cFont.mli -+/otherlibs/labltk/camltk/cFrame.ml -+/otherlibs/labltk/camltk/cFrame.mli -+/otherlibs/labltk/camltk/cGrab.ml -+/otherlibs/labltk/camltk/cGrab.mli -+/otherlibs/labltk/camltk/cGrid.ml -+/otherlibs/labltk/camltk/cGrid.mli -+/otherlibs/labltk/camltk/cImage.ml -+/otherlibs/labltk/camltk/cImage.mli -+/otherlibs/labltk/camltk/cImagebitmap.ml -+/otherlibs/labltk/camltk/cImagebitmap.mli -+/otherlibs/labltk/camltk/cImagephoto.ml -+/otherlibs/labltk/camltk/cImagephoto.mli -+/otherlibs/labltk/camltk/cLabel.ml -+/otherlibs/labltk/camltk/cLabel.mli -+/otherlibs/labltk/camltk/cListbox.ml -+/otherlibs/labltk/camltk/cListbox.mli -+/otherlibs/labltk/camltk/cMenu.ml -+/otherlibs/labltk/camltk/cMenu.mli -+/otherlibs/labltk/camltk/cMenubutton.ml -+/otherlibs/labltk/camltk/cMenubutton.mli -+/otherlibs/labltk/camltk/cMessage.ml -+/otherlibs/labltk/camltk/cMessage.mli -+/otherlibs/labltk/camltk/cOption.ml -+/otherlibs/labltk/camltk/cOption.mli -+/otherlibs/labltk/camltk/cOptionmenu.ml -+/otherlibs/labltk/camltk/cOptionmenu.mli -+/otherlibs/labltk/camltk/cPack.ml -+/otherlibs/labltk/camltk/cPack.mli -+/otherlibs/labltk/camltk/cPalette.ml -+/otherlibs/labltk/camltk/cPalette.mli -+/otherlibs/labltk/camltk/cPixmap.ml -+/otherlibs/labltk/camltk/cPixmap.mli -+/otherlibs/labltk/camltk/cPlace.ml -+/otherlibs/labltk/camltk/cPlace.mli -+/otherlibs/labltk/camltk/cRadiobutton.ml -+/otherlibs/labltk/camltk/cRadiobutton.mli -+/otherlibs/labltk/camltk/cResource.ml -+/otherlibs/labltk/camltk/cResource.mli -+/otherlibs/labltk/camltk/cScale.ml -+/otherlibs/labltk/camltk/cScale.mli -+/otherlibs/labltk/camltk/cScrollbar.ml -+/otherlibs/labltk/camltk/cScrollbar.mli -+/otherlibs/labltk/camltk/cSelection.ml -+/otherlibs/labltk/camltk/cSelection.mli -+/otherlibs/labltk/camltk/cText.ml -+/otherlibs/labltk/camltk/cText.mli -+/otherlibs/labltk/camltk/cTk.ml -+/otherlibs/labltk/camltk/cTkvars.ml -+/otherlibs/labltk/camltk/cTkvars.mli -+/otherlibs/labltk/camltk/cTkwait.ml -+/otherlibs/labltk/camltk/cTkwait.mli -+/otherlibs/labltk/camltk/cToplevel.ml -+/otherlibs/labltk/camltk/cToplevel.mli -+/otherlibs/labltk/camltk/cWinfo.ml -+/otherlibs/labltk/camltk/cWinfo.mli -+/otherlibs/labltk/camltk/cWm.ml -+/otherlibs/labltk/camltk/cWm.mli -+/otherlibs/labltk/camltk/camltk.ml -+/otherlibs/labltk/compiler/copyright.ml -+/otherlibs/labltk/compiler/lexer.ml -+/otherlibs/labltk/compiler/parser.ml -+/otherlibs/labltk/compiler/parser.mli -+/otherlibs/labltk/compiler/parser.output -+/otherlibs/labltk/compiler/pp -+/otherlibs/labltk/compiler/pplex.ml -+/otherlibs/labltk/compiler/ppyac.ml -+/otherlibs/labltk/compiler/ppyac.mli -+/otherlibs/labltk/compiler/ppyac.output -+/otherlibs/labltk/compiler/tkcompiler -+/otherlibs/labltk/labltk/.depend -+/otherlibs/labltk/labltk/_tkfgen.ml -+/otherlibs/labltk/labltk/_tkgen.ml -+/otherlibs/labltk/labltk/_tkgen.mli -+/otherlibs/labltk/labltk/_tkigen.ml -+/otherlibs/labltk/labltk/bell.ml -+/otherlibs/labltk/labltk/bell.mli -+/otherlibs/labltk/labltk/button.ml -+/otherlibs/labltk/labltk/button.mli -+/otherlibs/labltk/labltk/canvas.ml -+/otherlibs/labltk/labltk/canvas.mli -+/otherlibs/labltk/labltk/checkbutton.ml -+/otherlibs/labltk/labltk/checkbutton.mli -+/otherlibs/labltk/labltk/clipboard.ml -+/otherlibs/labltk/labltk/clipboard.mli -+/otherlibs/labltk/labltk/dialog.ml -+/otherlibs/labltk/labltk/dialog.mli -+/otherlibs/labltk/labltk/encoding.ml -+/otherlibs/labltk/labltk/encoding.mli -+/otherlibs/labltk/labltk/entry.ml -+/otherlibs/labltk/labltk/entry.mli -+/otherlibs/labltk/labltk/focus.ml -+/otherlibs/labltk/labltk/focus.mli -+/otherlibs/labltk/labltk/font.ml -+/otherlibs/labltk/labltk/font.mli -+/otherlibs/labltk/labltk/frame.ml -+/otherlibs/labltk/labltk/frame.mli -+/otherlibs/labltk/labltk/grab.ml -+/otherlibs/labltk/labltk/grab.mli -+/otherlibs/labltk/labltk/grid.ml -+/otherlibs/labltk/labltk/grid.mli -+/otherlibs/labltk/labltk/image.ml -+/otherlibs/labltk/labltk/image.mli -+/otherlibs/labltk/labltk/imagebitmap.ml -+/otherlibs/labltk/labltk/imagebitmap.mli -+/otherlibs/labltk/labltk/imagephoto.ml -+/otherlibs/labltk/labltk/imagephoto.mli -+/otherlibs/labltk/labltk/label.ml -+/otherlibs/labltk/labltk/label.mli -+/otherlibs/labltk/labltk/labltk.ml -+/otherlibs/labltk/labltk/listbox.ml -+/otherlibs/labltk/labltk/listbox.mli -+/otherlibs/labltk/labltk/menu.ml -+/otherlibs/labltk/labltk/menu.mli -+/otherlibs/labltk/labltk/menubutton.ml -+/otherlibs/labltk/labltk/menubutton.mli -+/otherlibs/labltk/labltk/message.ml -+/otherlibs/labltk/labltk/message.mli -+/otherlibs/labltk/labltk/option.ml -+/otherlibs/labltk/labltk/option.mli -+/otherlibs/labltk/labltk/optionmenu.ml -+/otherlibs/labltk/labltk/optionmenu.mli -+/otherlibs/labltk/labltk/pack.ml -+/otherlibs/labltk/labltk/pack.mli -+/otherlibs/labltk/labltk/palette.ml -+/otherlibs/labltk/labltk/palette.mli -+/otherlibs/labltk/labltk/pixmap.ml -+/otherlibs/labltk/labltk/pixmap.mli -+/otherlibs/labltk/labltk/place.ml -+/otherlibs/labltk/labltk/place.mli -+/otherlibs/labltk/labltk/radiobutton.ml -+/otherlibs/labltk/labltk/radiobutton.mli -+/otherlibs/labltk/labltk/scale.ml -+/otherlibs/labltk/labltk/scale.mli -+/otherlibs/labltk/labltk/scrollbar.ml -+/otherlibs/labltk/labltk/scrollbar.mli -+/otherlibs/labltk/labltk/selection.ml -+/otherlibs/labltk/labltk/selection.mli -+/otherlibs/labltk/labltk/text.ml -+/otherlibs/labltk/labltk/text.mli -+/otherlibs/labltk/labltk/tk.ml -+/otherlibs/labltk/labltk/tkvars.ml -+/otherlibs/labltk/labltk/tkvars.mli -+/otherlibs/labltk/labltk/tkwait.ml -+/otherlibs/labltk/labltk/tkwait.mli -+/otherlibs/labltk/labltk/toplevel.ml -+/otherlibs/labltk/labltk/toplevel.mli -+/otherlibs/labltk/labltk/winfo.ml -+/otherlibs/labltk/labltk/winfo.mli -+/otherlibs/labltk/labltk/wm.ml -+/otherlibs/labltk/labltk/wm.mli -+/otherlibs/labltk/lib/labltk -+/otherlibs/labltk/lib/labltktop -+/otherlibs/num/nums.cmxa -+/otherlibs/num/nums.cmxs -+/otherlibs/str/str.cmxa -+/otherlibs/str/str.cmxs -+/otherlibs/systhreads/threads.cmxa -+/otherlibs/threads/marshal.mli -+/otherlibs/threads/pervasives.mli -+/otherlibs/threads/unix.mli -+/otherlibs/unix/unix.cmxa -+/otherlibs/unix/unix.cmxs -+/package-macosx -+/parsing/lexer.ml -+/parsing/linenum.ml -+/parsing/parser.ml -+/parsing/parser.mli -+/parsing/parser.output -+/stdlib/caml -+/stdlib/camlheader -+/stdlib/camlheader_ur -+/stdlib/camlheaderd -+/stdlib/stdlib.cmxa -+/stdlib/stdlib.p.cmxa -+/stdlib/sys.ml -+/tools/cvt_emit -+/tools/cvt_emit.ml -+/tools/dumpobj -+/tools/myocamlbuild_config.ml -+/tools/objinfo -+/tools/objinfo_helper -+/tools/ocamlcp -+/tools/ocamldep -+/tools/ocamldep.opt -+/tools/ocamlmklib -+/tools/ocamlmklib.ml -+/tools/ocamlmktop -+/tools/ocamloptp -+/tools/ocamlprof -+/tools/opnames.ml -+/tools/read_cmt -+/tools/read_cmt.opt -+/utils/config.ml -+/yacc/ocamlyacc -+/yacc/version.h --- -1.9.0 - 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 new file mode 100644 index 0000000..8bf7f61 --- /dev/null +++ b/0001-Don-t-ignore-.-configure-it-s-a-real-git-file.patch @@ -0,0 +1,24 @@ +From 73598ab5b5b9c859e900413a31ca6452c324ff3d Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 24 Jun 2014 22:29:38 +0100 +Subject: [PATCH 01/10] Don't ignore ./configure, it's a real git file. + +--- + .gitignore | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/.gitignore b/.gitignore +index 2817041..6835234 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -22,7 +22,6 @@ + /.depend + /.depend.nt + /.DS_Store +-/configure + /ocamlc + /ocamlc.opt + /expunge +-- +1.9.0 + 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 6208ace..afa4d92 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 7756582741dc56070c03629a3b4640147723beda Mon Sep 17 00:00:00 2001 +From 8566059ac5eb68ac8006ba8d825644411d4c4cd1 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Thu, 7 Jun 2012 15:36:16 +0100 -Subject: [PATCH 02/14] Ensure empty compilerlibs/ directory is created by git. +Subject: [PATCH 02/10] 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. diff --git a/0003-Don-t-add-rpaths-to-libraries.patch b/0003-Don-t-add-rpaths-to-libraries.patch new file mode 100644 index 0000000..c27d19e --- /dev/null +++ b/0003-Don-t-add-rpaths-to-libraries.patch @@ -0,0 +1,29 @@ +From 8d1cb3e2a169a642a0c75e965bc6fc17184124c8 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 24 Jun 2014 10:00:15 +0100 +Subject: [PATCH 03/10] Don't add rpaths to libraries. + +--- + tools/Makefile.shared | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/tools/Makefile.shared b/tools/Makefile.shared +index c4c9030..7a918e5 100644 +--- a/tools/Makefile.shared ++++ b/tools/Makefile.shared +@@ -112,9 +112,9 @@ ocamlmklibconfig.ml: ../config/Makefile + echo 'let ext_dll = "$(EXT_DLL)"'; \ + echo 'let supports_shared_libraries = $(SUPPORTS_SHARED_LIBRARIES)';\ + echo 'let mkdll = "$(MKDLL)"'; \ +- echo 'let byteccrpath = "$(BYTECCRPATH)"'; \ +- echo 'let nativeccrpath = "$(NATIVECCRPATH)"'; \ +- echo 'let mksharedlibrpath = "$(MKSHAREDLIBRPATH)"'; \ ++ echo 'let byteccrpath = ""'; \ ++ echo 'let nativeccrpath = ""'; \ ++ echo 'let mksharedlibrpath = ""'; \ + echo 'let toolpref = "$(TOOLPREF)"'; \ + sed -n -e 's/^#ml //p' ../config/Makefile) \ + > ocamlmklibconfig.ml +-- +1.9.0 + diff --git a/0003-ocamlbyteinfo-ocamlplugininfo-Useful-utilities-from-.patch b/0003-ocamlbyteinfo-ocamlplugininfo-Useful-utilities-from-.patch deleted file mode 100644 index 9bc9b44..0000000 --- a/0003-ocamlbyteinfo-ocamlplugininfo-Useful-utilities-from-.patch +++ /dev/null @@ -1,240 +0,0 @@ -From a6d87cd4bc62d3987835c1ac844f35cc06804294 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 29 May 2012 20:40:36 +0100 -Subject: [PATCH 03/14] ocamlbyteinfo, ocamlplugininfo: Useful utilities from - Debian, sent upstream. - -See: -http://git.debian.org/?p=pkg-ocaml-maint/packages/ocaml.git;a=tree;f=debian/ocamlbyteinfo;hb=HEAD ---- - ocamlbyteinfo.ml | 101 +++++++++++++++++++++++++++++++++++++++++++++++++ - ocamlplugininfo.ml | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 210 insertions(+) - create mode 100644 ocamlbyteinfo.ml - create mode 100644 ocamlplugininfo.ml - -diff --git a/ocamlbyteinfo.ml b/ocamlbyteinfo.ml -new file mode 100644 -index 0000000..eb9a293 ---- /dev/null -+++ b/ocamlbyteinfo.ml -@@ -0,0 +1,101 @@ -+(***********************************************************************) -+(* *) -+(* Objective Caml *) -+(* *) -+(* Xavier Leroy, projet Gallium, INRIA Rocquencourt *) -+(* *) -+(* Copyright 2009 Institut National de Recherche en Informatique et *) -+(* en Automatique. All rights reserved. This file is distributed *) -+(* under the terms of the GNU Library General Public License, with *) -+(* the special exception on linking described in file ../../LICENSE. *) -+(* *) -+(***********************************************************************) -+ -+(* $Id$ *) -+ -+(* Dumps a bytecode binary file *) -+ -+open Sys -+open Dynlinkaux -+ -+let input_stringlist ic len = -+ let get_string_list sect len = -+ let rec fold s e acc = -+ if e != len then -+ if sect.[e] = '\000' then -+ fold (e+1) (e+1) (String.sub sect s (e-s) :: acc) -+ else fold s (e+1) acc -+ else acc -+ in fold 0 0 [] -+ in -+ let sect = String.create len in -+ let _ = really_input ic sect 0 len in -+ get_string_list sect len -+ -+let print = Printf.printf -+let perr s = -+ Printf.eprintf "%s\n" s; -+ exit(1) -+let p_title title = print "%s:\n" title -+ -+let p_section title format pdata = function -+ | [] -> () -+ | l -> -+ p_title title; -+ List.iter -+ (fun (name, data) -> print format (pdata data) name) -+ l -+ -+let p_list title format = function -+ | [] -> () -+ | l -> -+ p_title title; -+ List.iter -+ (fun name -> print format name) -+ l -+ -+let _ = -+ try -+ let input_name = Sys.argv.(1) in -+ let ic = open_in_bin input_name in -+ Bytesections.read_toc ic; -+ List.iter -+ (fun section -> -+ try -+ let len = Bytesections.seek_section ic section in -+ if len > 0 then match section with -+ | "CRCS" -> -+ p_section -+ "Imported Units" -+ "\t%s\t%s\n" -+ Digest.to_hex -+ (input_value ic : (string * Digest.t) list) -+ | "DLLS" -> -+ p_list -+ "Used Dlls" "\t%s\n" -+ (input_stringlist ic len) -+ | "DLPT" -> -+ p_list -+ "Additional Dll paths" -+ "\t%s\n" -+ (input_stringlist ic len) -+ | "PRIM" -> -+ let prims = (input_stringlist ic len) in -+ print "Uses unsafe features: "; -+ begin match prims with -+ [] -> print "no\n" -+ | l -> print "YES\n"; -+ p_list "Primitives declared in this module" -+ "\t%s\n" -+ l -+ end -+ | _ -> () -+ with Not_found | Failure _ | Invalid_argument _ -> () -+ ) -+ ["CRCS"; "DLLS"; "DLPT"; "PRIM"]; -+ close_in ic -+ with -+ | Sys_error msg -> -+ perr msg -+ | Invalid_argument("index out of bounds") -> -+ perr (Printf.sprintf "Usage: %s filename" Sys.argv.(0)) -diff --git a/ocamlplugininfo.ml b/ocamlplugininfo.ml -new file mode 100644 -index 0000000..e28800f ---- /dev/null -+++ b/ocamlplugininfo.ml -@@ -0,0 +1,109 @@ -+(***********************************************************************) -+(* *) -+(* Objective Caml *) -+(* *) -+(* Xavier Leroy, projet Gallium, INRIA Rocquencourt *) -+(* *) -+(* Copyright 2009 Institut National de Recherche en Informatique et *) -+(* en Automatique. All rights reserved. This file is distributed *) -+(* under the terms of the GNU Library General Public License, with *) -+(* the special exception on linking described in file ../../LICENSE. *) -+(* *) -+(***********************************************************************) -+ -+(* $Id$ *) -+ -+(* Dumps a .cmxs file *) -+ -+open Natdynlink -+open Format -+ -+let file = -+ try -+ Sys.argv.(1) -+ with _ -> begin -+ Printf.eprintf "Usage: %s file.cmxs\n" Sys.argv.(0); -+ exit(1) -+ end -+ -+exception Abnormal_exit -+ -+let error s e = -+ let eprint = Printf.eprintf in -+ let print_exc s = function -+ | End_of_file -> -+ eprint "%s: %s\n" s file -+ | Abnormal_exit -> -+ eprint "%s\n" s -+ | e -> eprint "%s\n" (Printexc.to_string e) -+ in -+ print_exc s e; -+ exit(1) -+ -+let read_in command = -+ let cmd = Printf.sprintf command file in -+ let ic = Unix.open_process_in cmd in -+ try -+ let line = input_line ic in -+ begin match (Unix.close_process_in ic) with -+ | Unix.WEXITED 0 -> Str.split (Str.regexp "[ ]+") line -+ | Unix.WEXITED _ | Unix.WSIGNALED _ | Unix.WSTOPPED _ -> -+ error -+ (Printf.sprintf -+ "Command \"%s\" exited abnormally" -+ cmd -+ ) -+ Abnormal_exit -+ end -+ with e -> error "File is empty" e -+ -+let get_offset adr_off adr_sec = -+ try -+ let adr = List.nth adr_off 4 in -+ let off = List.nth adr_off 5 in -+ let sec = List.hd adr_sec in -+ -+ let (!) x = Int64.of_string ("0x" ^ x) in -+ let (+) = Int64.add in -+ let (-) = Int64.sub in -+ -+ Int64.to_int (!off + !sec - !adr) -+ -+ with Failure _ | Invalid_argument _ -> -+ error -+ "Command output doesn't have the expected format" -+ Abnormal_exit -+ -+let print_infos name crc defines cmi cmx = -+ let print_name_crc (name, crc) = -+ printf "@ %s (%s)" name (Digest.to_hex crc) -+ in -+ let pr_imports ppf imps = List.iter print_name_crc imps in -+ printf "Name: %s@." name; -+ printf "CRC of implementation: %s@." (Digest.to_hex crc); -+ printf "@[Globals defined:"; -+ List.iter (fun s -> printf "@ %s" s) defines; -+ printf "@]@."; -+ printf "@[Interfaces imported:%a@]@." pr_imports cmi; -+ printf "@[Implementations imported:%a@]@." pr_imports cmx -+ -+let _ = -+ let adr_off = read_in "objdump -h %s | grep ' .data '" in -+ let adr_sec = read_in "objdump -T %s | grep ' caml_plugin_header$'" in -+ -+ let ic = open_in file in -+ let _ = seek_in ic (get_offset adr_off adr_sec) in -+ let header = (input_value ic : Natdynlink.dynheader) in -+ if header.magic <> Natdynlink.dyn_magic_number then -+ raise(Error(Natdynlink.Not_a_bytecode_file file)) -+ else begin -+ List.iter -+ (fun ui -> -+ print_infos -+ ui.name -+ ui.crc -+ ui.defines -+ ui.imports_cmi -+ ui.imports_cmx) -+ header.units -+ end --- -1.9.0 - diff --git a/0004-Don-t-add-rpaths-to-libraries.patch b/0004-Don-t-add-rpaths-to-libraries.patch deleted file mode 100644 index efe4095..0000000 --- a/0004-Don-t-add-rpaths-to-libraries.patch +++ /dev/null @@ -1,26 +0,0 @@ -From c3a733c10827896a6e3c217b383e874df303d50b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 29 May 2012 20:43:34 +0100 -Subject: [PATCH 04/14] Don't add rpaths to libraries. - ---- - tools/Makefile.shared | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/tools/Makefile.shared b/tools/Makefile.shared -index 117f576..cad227d 100644 ---- a/tools/Makefile.shared -+++ b/tools/Makefile.shared -@@ -116,9 +116,6 @@ ocamlmklib.ml: ocamlmklib.mlp ../config/Makefile - sed -e "s|%%BINDIR%%|$(BINDIR)|" \ - -e "s|%%SUPPORTS_SHARED_LIBRARIES%%|$(SUPPORTS_SHARED_LIBRARIES)|" \ - -e "s|%%MKSHAREDLIB%%|$(MKSHAREDLIB)|" \ -- -e "s|%%BYTECCRPATH%%|$(BYTECCRPATH)|" \ -- -e "s|%%NATIVECCRPATH%%|$(NATIVECCRPATH)|" \ -- -e "s|%%MKSHAREDLIBRPATH%%|$(MKSHAREDLIBRPATH)|" \ - -e "s|%%RANLIB%%|$(RANLIB)|" \ - ocamlmklib.mlp >> ocamlmklib.ml - --- -1.9.0 - diff --git a/0004-ocamlbyteinfo-ocamlplugininfo-Useful-utilities-from-.patch b/0004-ocamlbyteinfo-ocamlplugininfo-Useful-utilities-from-.patch new file mode 100644 index 0000000..a239f5c --- /dev/null +++ b/0004-ocamlbyteinfo-ocamlplugininfo-Useful-utilities-from-.patch @@ -0,0 +1,240 @@ +From 0112a99407da09f066c9cbaa41fe770370ba6706 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 29 May 2012 20:40:36 +0100 +Subject: [PATCH 04/10] ocamlbyteinfo, ocamlplugininfo: Useful utilities from + Debian, sent upstream. + +See: +http://git.debian.org/?p=pkg-ocaml-maint/packages/ocaml.git;a=tree;f=debian/ocamlbyteinfo;hb=HEAD +--- + ocamlbyteinfo.ml | 101 +++++++++++++++++++++++++++++++++++++++++++++++++ + ocamlplugininfo.ml | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 210 insertions(+) + create mode 100644 ocamlbyteinfo.ml + create mode 100644 ocamlplugininfo.ml + +diff --git a/ocamlbyteinfo.ml b/ocamlbyteinfo.ml +new file mode 100644 +index 0000000..eb9a293 +--- /dev/null ++++ b/ocamlbyteinfo.ml +@@ -0,0 +1,101 @@ ++(***********************************************************************) ++(* *) ++(* Objective Caml *) ++(* *) ++(* Xavier Leroy, projet Gallium, INRIA Rocquencourt *) ++(* *) ++(* Copyright 2009 Institut National de Recherche en Informatique et *) ++(* en Automatique. All rights reserved. This file is distributed *) ++(* under the terms of the GNU Library General Public License, with *) ++(* the special exception on linking described in file ../../LICENSE. *) ++(* *) ++(***********************************************************************) ++ ++(* $Id$ *) ++ ++(* Dumps a bytecode binary file *) ++ ++open Sys ++open Dynlinkaux ++ ++let input_stringlist ic len = ++ let get_string_list sect len = ++ let rec fold s e acc = ++ if e != len then ++ if sect.[e] = '\000' then ++ fold (e+1) (e+1) (String.sub sect s (e-s) :: acc) ++ else fold s (e+1) acc ++ else acc ++ in fold 0 0 [] ++ in ++ let sect = String.create len in ++ let _ = really_input ic sect 0 len in ++ get_string_list sect len ++ ++let print = Printf.printf ++let perr s = ++ Printf.eprintf "%s\n" s; ++ exit(1) ++let p_title title = print "%s:\n" title ++ ++let p_section title format pdata = function ++ | [] -> () ++ | l -> ++ p_title title; ++ List.iter ++ (fun (name, data) -> print format (pdata data) name) ++ l ++ ++let p_list title format = function ++ | [] -> () ++ | l -> ++ p_title title; ++ List.iter ++ (fun name -> print format name) ++ l ++ ++let _ = ++ try ++ let input_name = Sys.argv.(1) in ++ let ic = open_in_bin input_name in ++ Bytesections.read_toc ic; ++ List.iter ++ (fun section -> ++ try ++ let len = Bytesections.seek_section ic section in ++ if len > 0 then match section with ++ | "CRCS" -> ++ p_section ++ "Imported Units" ++ "\t%s\t%s\n" ++ Digest.to_hex ++ (input_value ic : (string * Digest.t) list) ++ | "DLLS" -> ++ p_list ++ "Used Dlls" "\t%s\n" ++ (input_stringlist ic len) ++ | "DLPT" -> ++ p_list ++ "Additional Dll paths" ++ "\t%s\n" ++ (input_stringlist ic len) ++ | "PRIM" -> ++ let prims = (input_stringlist ic len) in ++ print "Uses unsafe features: "; ++ begin match prims with ++ [] -> print "no\n" ++ | l -> print "YES\n"; ++ p_list "Primitives declared in this module" ++ "\t%s\n" ++ l ++ end ++ | _ -> () ++ with Not_found | Failure _ | Invalid_argument _ -> () ++ ) ++ ["CRCS"; "DLLS"; "DLPT"; "PRIM"]; ++ close_in ic ++ with ++ | Sys_error msg -> ++ perr msg ++ | Invalid_argument("index out of bounds") -> ++ perr (Printf.sprintf "Usage: %s filename" Sys.argv.(0)) +diff --git a/ocamlplugininfo.ml b/ocamlplugininfo.ml +new file mode 100644 +index 0000000..e28800f +--- /dev/null ++++ b/ocamlplugininfo.ml +@@ -0,0 +1,109 @@ ++(***********************************************************************) ++(* *) ++(* Objective Caml *) ++(* *) ++(* Xavier Leroy, projet Gallium, INRIA Rocquencourt *) ++(* *) ++(* Copyright 2009 Institut National de Recherche en Informatique et *) ++(* en Automatique. All rights reserved. This file is distributed *) ++(* under the terms of the GNU Library General Public License, with *) ++(* the special exception on linking described in file ../../LICENSE. *) ++(* *) ++(***********************************************************************) ++ ++(* $Id$ *) ++ ++(* Dumps a .cmxs file *) ++ ++open Natdynlink ++open Format ++ ++let file = ++ try ++ Sys.argv.(1) ++ with _ -> begin ++ Printf.eprintf "Usage: %s file.cmxs\n" Sys.argv.(0); ++ exit(1) ++ end ++ ++exception Abnormal_exit ++ ++let error s e = ++ let eprint = Printf.eprintf in ++ let print_exc s = function ++ | End_of_file -> ++ eprint "%s: %s\n" s file ++ | Abnormal_exit -> ++ eprint "%s\n" s ++ | e -> eprint "%s\n" (Printexc.to_string e) ++ in ++ print_exc s e; ++ exit(1) ++ ++let read_in command = ++ let cmd = Printf.sprintf command file in ++ let ic = Unix.open_process_in cmd in ++ try ++ let line = input_line ic in ++ begin match (Unix.close_process_in ic) with ++ | Unix.WEXITED 0 -> Str.split (Str.regexp "[ ]+") line ++ | Unix.WEXITED _ | Unix.WSIGNALED _ | Unix.WSTOPPED _ -> ++ error ++ (Printf.sprintf ++ "Command \"%s\" exited abnormally" ++ cmd ++ ) ++ Abnormal_exit ++ end ++ with e -> error "File is empty" e ++ ++let get_offset adr_off adr_sec = ++ try ++ let adr = List.nth adr_off 4 in ++ let off = List.nth adr_off 5 in ++ let sec = List.hd adr_sec in ++ ++ let (!) x = Int64.of_string ("0x" ^ x) in ++ let (+) = Int64.add in ++ let (-) = Int64.sub in ++ ++ Int64.to_int (!off + !sec - !adr) ++ ++ with Failure _ | Invalid_argument _ -> ++ error ++ "Command output doesn't have the expected format" ++ Abnormal_exit ++ ++let print_infos name crc defines cmi cmx = ++ let print_name_crc (name, crc) = ++ printf "@ %s (%s)" name (Digest.to_hex crc) ++ in ++ let pr_imports ppf imps = List.iter print_name_crc imps in ++ printf "Name: %s@." name; ++ printf "CRC of implementation: %s@." (Digest.to_hex crc); ++ printf "@[Globals defined:"; ++ List.iter (fun s -> printf "@ %s" s) defines; ++ printf "@]@."; ++ printf "@[Interfaces imported:%a@]@." pr_imports cmi; ++ printf "@[Implementations imported:%a@]@." pr_imports cmx ++ ++let _ = ++ let adr_off = read_in "objdump -h %s | grep ' .data '" in ++ let adr_sec = read_in "objdump -T %s | grep ' caml_plugin_header$'" in ++ ++ let ic = open_in file in ++ let _ = seek_in ic (get_offset adr_off adr_sec) in ++ let header = (input_value ic : Natdynlink.dynheader) in ++ if header.magic <> Natdynlink.dyn_magic_number then ++ raise(Error(Natdynlink.Not_a_bytecode_file file)) ++ else begin ++ List.iter ++ (fun ui -> ++ print_infos ++ ui.name ++ ui.crc ++ ui.defines ++ ui.imports_cmi ++ ui.imports_cmx) ++ header.units ++ end +-- +1.9.0 + diff --git a/0005-configure-Allow-user-defined-C-compiler-flags.patch b/0005-configure-Allow-user-defined-C-compiler-flags.patch index 5864c92..89688bc 100644 --- a/0005-configure-Allow-user-defined-C-compiler-flags.patch +++ b/0005-configure-Allow-user-defined-C-compiler-flags.patch @@ -1,17 +1,17 @@ -From 459e9550f174e11176a2ece013fc4dd2b08a06bb Mon Sep 17 00:00:00 2001 +From 96ec5173787ce5e03dca7da6527c4cc732772051 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 29 May 2012 20:44:18 +0100 -Subject: [PATCH 05/14] configure: Allow user defined C compiler flags. +Subject: [PATCH 05/10] configure: Allow user defined C compiler flags. --- configure | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/configure b/configure -index 07b1c35..39b38dc 100755 +index 74d489f..251ee2c 100755 --- a/configure +++ b/configure -@@ -1612,6 +1612,10 @@ case "$buggycc" in +@@ -1629,6 +1629,10 @@ case "$buggycc" in nativecccompopts="$nativecccompopts -fomit-frame-pointer";; esac diff --git a/0006-Add-support-for-ppc64.patch b/0006-Add-support-for-ppc64.patch index 35e3b74..166e7b6 100644 --- a/0006-Add-support-for-ppc64.patch +++ b/0006-Add-support-for-ppc64.patch @@ -1,7 +1,7 @@ -From a85437a0d2ffdf7a340d379789500eb583ae4708 Mon Sep 17 00:00:00 2001 +From 443863864a99a0408c6068ba0b5ba6beddec337a Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Tue, 29 May 2012 20:47:07 +0100 -Subject: [PATCH 06/14] Add support for ppc64. +Subject: [PATCH 06/10] Add support for ppc64. Note (1): This patch was rejected upstream because they don't have appropriate hardware for testing. @@ -1576,10 +1576,10 @@ index 0000000..53b7828 + +let fundecl f = (new selector)#emit_fundecl f diff --git a/asmrun/Makefile b/asmrun/Makefile -index 5ebf7aa..6a8ed98 100644 +index 63ff80c..5da022c 100644 --- a/asmrun/Makefile +++ b/asmrun/Makefile -@@ -90,6 +90,12 @@ power.o: power-$(SYSTEM).o +@@ -93,6 +93,12 @@ power.o: power-$(SYSTEM).o power.p.o: power-$(SYSTEM).o cp power-$(SYSTEM).o power.p.o @@ -2085,7 +2085,7 @@ index 0000000..b2c24d6 + .align 3 + diff --git a/asmrun/stack.h b/asmrun/stack.h -index 57c87fa..756db95 100644 +index 92b3c28..5202c3a 100644 --- a/asmrun/stack.h +++ b/asmrun/stack.h @@ -46,6 +46,15 @@ @@ -2105,26 +2105,26 @@ index 57c87fa..756db95 100644 #define Saved_return_address(sp) *((intnat *)((sp) - 4)) #define Callback_link(sp) ((struct caml_context *)((sp) + 8)) diff --git a/configure b/configure -index 39b38dc..9b02664 100755 +index 251ee2c..5f92bac 100755 --- a/configure +++ b/configure -@@ -694,6 +694,7 @@ case "$host" in - arch=i386; system=macosx +@@ -807,6 +807,7 @@ case "$target" in fi;; i[3456]86-*-gnu*) arch=i386; system=gnu;; + i[3456]86-*-mingw*) arch=i386; system=mingw;; + powerpc64-*-linux*) arch=power64; model=ppc64; system=elf;; powerpc*-*-linux*) arch=power; model=ppc; system=elf;; powerpc-*-netbsd*) arch=power; model=ppc; system=elf;; powerpc-*-openbsd*) arch=power; model=ppc; system=bsd_elf;; -@@ -776,6 +777,8 @@ case "$arch,$model,$system" in - aspp='gcc -c';; - power,*,bsd*) as='as' - aspp='gcc -c';; -+ power64,*,elf) as='as -u -m ppc64' -+ aspp='gcc -c';; - power,*,rhapsody) as="as -arch $model" - aspp="$bytecc -c";; - sparc,*,solaris) as='as' +@@ -886,6 +887,8 @@ case "$arch,$system" in + aspp="/usr/ccs/bin/${TOOLPREF}as -P";; + power,elf) as="${TOOLPREF}as -u -m ppc" + aspp="${TOOLPREF}gcc -c";; ++ power64,*,elf) as='${TOOLPREF}as -u -m ppc64' ++ aspp='${TOOLPREF}gcc -c';; + power,rhapsody) as="${TOOLPREF}as -arch $model" + aspp="$bytecc -c";; + sparc,solaris) as="${TOOLPREF}as" -- 1.9.0 diff --git a/0007-Add-support-for-ppc64le.patch b/0007-Add-support-for-ppc64le.patch new file mode 100644 index 0000000..ff5f928 --- /dev/null +++ b/0007-Add-support-for-ppc64le.patch @@ -0,0 +1,1917 @@ +From 69837e1be517082e841d583f59f017edfd7ffa39 Mon Sep 17 00:00:00 2001 +From: Michel Normand +Date: Tue, 18 Mar 2014 09:15:47 -0400 +Subject: [PATCH 07/10] Add support for ppc64le. + +Signed-off-by: Michel Normand +--- + asmcomp/power64le/arch.ml | 88 ++++ + asmcomp/power64le/emit.mlp | 981 ++++++++++++++++++++++++++++++++++++++++ + asmcomp/power64le/proc.ml | 240 ++++++++++ + asmcomp/power64le/reload.ml | 18 + + asmcomp/power64le/scheduling.ml | 65 +++ + asmcomp/power64le/selection.ml | 101 +++++ + asmrun/Makefile | 6 + + asmrun/power64-elf.S | 95 +++- + asmrun/power64le-elf.S | 1 + + asmrun/stack.h | 9 + + config/gnu/config.guess | 3 + + configure | 3 + + 12 files changed, 1609 insertions(+), 1 deletion(-) + create mode 100644 asmcomp/power64le/arch.ml + create mode 100644 asmcomp/power64le/emit.mlp + create mode 100644 asmcomp/power64le/proc.ml + create mode 100644 asmcomp/power64le/reload.ml + create mode 100644 asmcomp/power64le/scheduling.ml + create mode 100644 asmcomp/power64le/selection.ml + create mode 120000 asmrun/power64le-elf.S + +diff --git a/asmcomp/power64le/arch.ml b/asmcomp/power64le/arch.ml +new file mode 100644 +index 0000000..586534b +--- /dev/null ++++ b/asmcomp/power64le/arch.ml +@@ -0,0 +1,88 @@ ++(***********************************************************************) ++(* *) ++(* Objective Caml *) ++(* *) ++(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) ++(* *) ++(* 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. *) ++(* *) ++(***********************************************************************) ++ ++(* $Id: arch.ml 9547 2010-01-22 12:48:24Z doligez $ *) ++ ++(* Specific operations for the PowerPC processor *) ++ ++open Format ++ ++(* Machine-specific command-line options *) ++ ++let command_line_options = [] ++ ++(* Specific operations *) ++ ++type specific_operation = ++ Imultaddf (* multiply and add *) ++ | Imultsubf (* multiply and subtract *) ++ | Ialloc_far of int (* allocation in large functions *) ++ ++(* Addressing modes *) ++ ++type addressing_mode = ++ Ibased of string * int (* symbol + displ *) ++ | Iindexed of int (* reg + displ *) ++ | Iindexed2 (* reg + reg *) ++ ++(* Sizes, endianness *) ++ ++let big_endian = false ++ ++let size_addr = 8 ++let size_int = size_addr ++let size_float = 8 ++ ++let allow_unaligned_access = false ++ ++(* Behavior of division *) ++ ++let division_crashes_on_overflow = false ++ ++(* Operations on addressing modes *) ++ ++let identity_addressing = Iindexed 0 ++ ++let offset_addressing addr delta = ++ match addr with ++ Ibased(s, n) -> Ibased(s, n + delta) ++ | Iindexed n -> Iindexed(n + delta) ++ | Iindexed2 -> assert false ++ ++let num_args_addressing = function ++ Ibased(s, n) -> 0 ++ | Iindexed n -> 1 ++ | Iindexed2 -> 2 ++ ++(* Printing operations and addressing modes *) ++ ++let print_addressing printreg addr ppf arg = ++ match addr with ++ | Ibased(s, n) -> ++ let idx = if n <> 0 then Printf.sprintf " + %i" n else "" in ++ fprintf ppf "\"%s\"%s" s idx ++ | Iindexed n -> ++ let idx = if n <> 0 then Printf.sprintf " + %i" n else "" in ++ fprintf ppf "%a%s" printreg arg.(0) idx ++ | Iindexed2 -> ++ fprintf ppf "%a + %a" printreg arg.(0) printreg arg.(1) ++ ++let print_specific_operation printreg op ppf arg = ++ match op with ++ | Imultaddf -> ++ fprintf ppf "%a *f %a +f %a" ++ printreg arg.(0) printreg arg.(1) printreg arg.(2) ++ | Imultsubf -> ++ fprintf ppf "%a *f %a -f %a" ++ printreg arg.(0) printreg arg.(1) printreg arg.(2) ++ | Ialloc_far n -> ++ fprintf ppf "alloc_far %d" n +diff --git a/asmcomp/power64le/emit.mlp b/asmcomp/power64le/emit.mlp +new file mode 100644 +index 0000000..5736a18 +--- /dev/null ++++ b/asmcomp/power64le/emit.mlp +@@ -0,0 +1,981 @@ ++(***********************************************************************) ++(* *) ++(* Objective Caml *) ++(* *) ++(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) ++(* *) ++(* 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. *) ++(* *) ++(***********************************************************************) ++ ++(* $Id: emit.mlp 9547 2010-01-22 12:48:24Z doligez $ *) ++ ++(* Emission of PowerPC assembly code *) ++ ++module StringSet = Set.Make(struct type t = string let compare = compare end) ++ ++open Misc ++open Cmm ++open Arch ++open Proc ++open Reg ++open Mach ++open Linearize ++open Emitaux ++ ++(* Layout of the stack. The stack is kept 16-aligned. *) ++ ++let stack_size_lbl = ref 0 ++let stack_slot_lbl = ref 0 ++let stack_args_size = ref 0 ++let stack_traps_size = ref 0 ++ ++(* We have a stack frame of our own if we call other functions (including ++ use of exceptions, or if we need more than the red zone *) ++let has_stack_frame () = ++ if !contains_calls || (num_stack_slots.(0) + num_stack_slots.(1)) > (288-16)/8 then ++ true ++ else ++ false ++ ++let frame_size_sans_args () = ++ let size = 8 * num_stack_slots.(0) + 8 * num_stack_slots.(1) + 48 in ++ Misc.align size 16 ++ ++let slot_offset loc cls = ++ match loc with ++ Local n -> ++ if cls = 0 ++ then (!stack_slot_lbl, num_stack_slots.(1) * 8 + n * 8) ++ else (!stack_slot_lbl, n * 8) ++ | Incoming n -> ((if has_stack_frame() then !stack_size_lbl else 0), 48 + n) ++ | Outgoing n -> (0, n) ++ ++(* Output a symbol *) ++ ++let emit_symbol = ++ match Config.system with ++ | "elf" | "bsd" -> (fun s -> Emitaux.emit_symbol '.' s) ++ | "rhapsody" -> (fun s -> emit_char '_'; Emitaux.emit_symbol '$' s) ++ | _ -> assert false ++ ++(* Output a label *) ++ ++let label_prefix = ++ match Config.system with ++ | "elf" | "bsd" -> ".L" ++ | "rhapsody" -> "L" ++ | _ -> assert false ++ ++let emit_label lbl = ++ emit_string label_prefix; emit_int lbl ++ ++(* Section switching *) ++ ++let toc_space = ++ match Config.system with ++ | "elf" | "bsd" -> " .section \".toc\",\"aw\"\n" ++ | "rhapsody" -> " .toc\n" ++ | _ -> assert false ++ ++let data_space = ++ match Config.system with ++ | "elf" | "bsd" -> " .section \".data\"\n" ++ | "rhapsody" -> " .data\n" ++ | _ -> assert false ++ ++let abiversion = ++ match Config.system with ++ | "elf" | "bsd" -> " .abiversion 2\n" ++ | _ -> assert false ++ ++let code_space = ++ match Config.system with ++ | "elf" | "bsd" -> " .section \".text\"\n" ++ | "rhapsody" -> " .text\n" ++ | _ -> assert false ++ ++let rodata_space = ++ match Config.system with ++ | "elf" | "bsd" -> " .section \".rodata\"\n" ++ | "rhapsody" -> " .const\n" ++ | _ -> assert false ++ ++(* Output a pseudo-register *) ++ ++let emit_reg r = ++ match r.loc with ++ Reg r -> emit_string (register_name r) ++ | _ -> fatal_error "Emit.emit_reg" ++ ++let use_full_regnames = ++ Config.system = "rhapsody" ++ ++let emit_gpr r = ++ if use_full_regnames then emit_char 'r'; ++ emit_int r ++ ++let emit_fpr r = ++ if use_full_regnames then emit_char 'f'; ++ emit_int r ++ ++let emit_ccr r = ++ if use_full_regnames then emit_string "cr"; ++ emit_int r ++ ++(* Output a stack reference *) ++ ++let emit_stack r = ++ match r.loc with ++ Stack s -> ++ let lbl, ofs = slot_offset s (register_class r) in ++ if lbl > 0 then ++ `{emit_label lbl}+`; ++ `{emit_int ofs}({emit_gpr 1})` ++ | _ -> fatal_error "Emit.emit_stack" ++ ++(* Split a 32-bit integer constants in two 16-bit halves *) ++ ++let low n = n land 0xFFFF ++let high n = n asr 16 ++ ++let nativelow n = Nativeint.to_int n land 0xFFFF ++let nativehigh n = Nativeint.to_int (Nativeint.shift_right n 16) ++ ++let is_immediate n = ++ n <= 32767 && n >= -32768 ++ ++let is_native_immediate n = ++ n <= 32767n && n >= -32768n ++ ++ ++type tocentry = ++ TocSymOfs of (string * int) ++ | TocLabel of int ++ | TocInt of nativeint ++ | TocFloat of string ++ ++(* List of all labels in tocref (reverse order) *) ++let tocref_entries = ref [] ++ ++(* Output a TOC reference *) ++ ++let emit_symbol_offset (s, d) = ++ emit_symbol s; ++ if d > 0 then `+`; ++ if d <> 0 then emit_int d ++ ++let emit_tocentry entry = ++ match entry with ++ TocSymOfs(s,d) -> emit_symbol_offset(s,d) ++ | TocInt i -> emit_nativeint i ++ | TocFloat f -> emit_string f ++ | TocLabel lbl -> emit_label lbl ++ ++ let rec tocref_label = function ++ ( [] , content ) -> ++ let lbl = new_label() in ++ tocref_entries := (lbl, content) :: !tocref_entries; ++ lbl ++ | ( (lbl, o_content) :: lst, content) -> ++ if content = o_content then ++ lbl ++ else ++ tocref_label (lst, content) ++ ++let emit_tocref entry = ++ let lbl = tocref_label (!tocref_entries,entry) in ++ emit_label lbl; emit_string "@toc(2) #"; emit_tocentry entry ++ ++ ++(* Output a load or store operation *) ++ ++let valid_offset instr ofs = ++ ofs land 3 = 0 || (instr <> "ld" && instr <> "std") ++ ++let emit_load_store instr addressing_mode addr n arg = ++ match addressing_mode with ++ Ibased(s, d) -> ++ let dd = (d + 0x8000) in (* We can only offset by -0x8000 .. +0x7fff *) ++ let a = (dd land -0x10000) in ++ let b = (dd land 0xffff) - 0x8000 in ++ ` ld {emit_gpr 11}, {emit_tocref (TocSymOfs (s,a))}\n`; ++ ` {emit_string instr} {emit_reg arg}, {emit_int b}({emit_gpr 11})\n` ++ | Iindexed ofs -> ++ if is_immediate ofs && valid_offset instr ofs then ++ ` {emit_string instr} {emit_reg arg}, {emit_int ofs}({emit_reg addr.(n)})\n` ++ else begin ++ ` lis {emit_gpr 0}, {emit_int(high ofs)}\n`; ++ if low ofs <> 0 then ++ ` ori {emit_gpr 0}, {emit_gpr 0}, {emit_int(low ofs)}\n`; ++ ` {emit_string instr}x {emit_reg arg}, {emit_reg addr.(n)}, {emit_gpr 0}\n` ++ end ++ | Iindexed2 -> ++ ` {emit_string instr}x {emit_reg arg}, {emit_reg addr.(n)}, {emit_reg addr.(n+1)}\n` ++ ++(* After a comparison, extract the result as 0 or 1 *) ++ ++let emit_set_comp cmp res = ++ ` mfcr {emit_gpr 0}\n`; ++ let bitnum = ++ match cmp with ++ Ceq | Cne -> 2 ++ | Cgt | Cle -> 1 ++ | Clt | Cge -> 0 in ++` rlwinm {emit_reg res}, {emit_gpr 0}, {emit_int(bitnum+1)}, 31, 31\n`; ++ begin match cmp with ++ Cne | Cle | Cge -> ` xori {emit_reg res}, {emit_reg res}, 1\n` ++ | _ -> () ++ end ++ ++(* Record live pointers at call points *) ++ ++type frame_descr = ++ { fd_lbl: int; (* Return address *) ++ fd_frame_size_lbl: int; (* Size of stack frame *) ++ fd_live_offset: (int * int) list } (* Offsets/regs of live addresses *) ++ ++let frame_descriptors = ref([] : frame_descr list) ++ ++let record_frame live = ++ let lbl = new_label() in ++ let live_offset = ref [] in ++ Reg.Set.iter ++ (function ++ {typ = Addr; loc = Reg r} -> ++ live_offset := (0, (r lsl 1) + 1) :: !live_offset ++ | {typ = Addr; loc = Stack s} as reg -> ++ live_offset := slot_offset s (register_class reg) :: !live_offset ++ | _ -> ()) ++ live; ++ frame_descriptors := ++ { fd_lbl = lbl; ++ fd_frame_size_lbl = !stack_size_lbl; (* frame_size *) ++ fd_live_offset = !live_offset } :: !frame_descriptors; ++ `{emit_label lbl}:\n` ++ ++let emit_frame fd = ++ ` .quad {emit_label fd.fd_lbl} + 4\n`; ++ ` .short {emit_label fd.fd_frame_size_lbl}\n`; ++ ` .short {emit_int (List.length fd.fd_live_offset)}\n`; ++ List.iter ++ (fun (lbl,n) -> ++ ` .short `; ++ if lbl > 0 then `{emit_label lbl}+`; ++ `{emit_int n}\n`) ++ fd.fd_live_offset; ++ ` .align 3\n` ++ ++(* Record external C functions to be called in a position-independent way ++ (for MacOSX) *) ++ ++let pic_externals = (Config.system = "rhapsody") ++ ++let external_functions = ref StringSet.empty ++ ++let emit_external s = ++ ` .non_lazy_symbol_pointer\n`; ++ `L{emit_symbol s}$non_lazy_ptr:\n`; ++ ` .indirect_symbol {emit_symbol s}\n`; ++ ` .quad 0\n` ++ ++(* Names for conditional branches after comparisons *) ++ ++let branch_for_comparison = function ++ Ceq -> "beq" | Cne -> "bne" ++ | Cle -> "ble" | Cgt -> "bgt" ++ | Cge -> "bge" | Clt -> "blt" ++ ++let name_for_int_comparison = function ++ Isigned cmp -> ("cmpd", branch_for_comparison cmp) ++ | Iunsigned cmp -> ("cmpld", branch_for_comparison cmp) ++ ++(* Names for various instructions *) ++ ++let name_for_intop = function ++ Iadd -> "add" ++ | Imul -> "mulld" ++ | Idiv -> "divd" ++ | Iand -> "and" ++ | Ior -> "or" ++ | Ixor -> "xor" ++ | Ilsl -> "sld" ++ | Ilsr -> "srd" ++ | Iasr -> "srad" ++ | _ -> Misc.fatal_error "Emit.Intop" ++ ++let name_for_intop_imm = function ++ Iadd -> "addi" ++ | Imul -> "mulli" ++ | Iand -> "andi." ++ | Ior -> "ori" ++ | Ixor -> "xori" ++ | Ilsl -> "sldi" ++ | Ilsr -> "srdi" ++ | Iasr -> "sradi" ++ | _ -> Misc.fatal_error "Emit.Intop_imm" ++ ++let name_for_floatop1 = function ++ Inegf -> "fneg" ++ | Iabsf -> "fabs" ++ | _ -> Misc.fatal_error "Emit.Iopf1" ++ ++let name_for_floatop2 = function ++ Iaddf -> "fadd" ++ | Isubf -> "fsub" ++ | Imulf -> "fmul" ++ | Idivf -> "fdiv" ++ | _ -> Misc.fatal_error "Emit.Iopf2" ++ ++let name_for_specific = function ++ Imultaddf -> "fmadd" ++ | Imultsubf -> "fmsub" ++ | _ -> Misc.fatal_error "Emit.Ispecific" ++ ++(* Name of current function *) ++let function_name = ref "" ++(* Entry point for tail recursive calls *) ++let tailrec_entry_point = ref 0 ++(* Names of functions defined in the current file *) ++let defined_functions = ref StringSet.empty ++(* Label of glue code for calling the GC *) ++let call_gc_label = ref 0 ++(* Label of jump table *) ++let lbl_jumptbl = ref 0 ++(* List of all labels in jumptable (reverse order) *) ++let jumptbl_entries = ref [] ++(* Number of jumptable entries *) ++let num_jumptbl_entries = ref 0 ++ ++(* Fixup conditional branches that exceed hardware allowed range *) ++ ++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) -> if is_native_immediate n then 1 else 2 ++ | Lop(Iconst_float s) -> 2 ++ | Lop(Iconst_symbol s) -> 2 ++ | Lop(Icall_ind) -> 4 ++ | Lop(Icall_imm s) -> 5 ++ | Lop(Itailcall_ind) -> if !contains_calls then 5 else if has_stack_frame() then 3 else 2 ++ | Lop(Itailcall_imm s) -> if s = !function_name then 1 else ++ if !contains_calls then 6 else ++ if has_stack_frame() then 4 else 3 ++ | Lop(Iextcall(s, true)) -> 6 ++ | Lop(Iextcall(s, false)) -> 5 ++ | Lop(Istackoffset n) -> 0 ++ | 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(Idiv, n)) -> 2 ++ | Lop(Iintop_imm(Imod, n)) -> 4 ++ | Lop(Iintop_imm(Icomp cmp, n)) -> 4 ++ | Lop(Iintop_imm(op, n)) -> 1 ++ | Lop(Inegf | Iabsf | Iaddf | Isubf | Imulf | Idivf) -> 1 ++ | Lop(Ifloatofint) -> 3 ++ | Lop(Iintoffloat) -> 3 ++ | Lop(Ispecific sop) -> 1 ++ | Lreloadretaddr -> 2 ++ | Lreturn -> if has_stack_frame() then 2 else 1 ++ | 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 -> 7 ++ | Lsetuptrap lbl -> 1 ++ | Lpushtrap -> 7 ++ | Lpoptrap -> 1 ++ | 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 () ++ ++ ++(* Output the assembly code for an instruction *) ++ ++let rec emit_instr i dslot = ++ match i.desc with ++ Lend -> () ++ | Lop(Imove | Ispill | Ireload) -> ++ let src = i.arg.(0) and dst = i.res.(0) in ++ if src.loc <> dst.loc then begin ++ match (src, dst) with ++ {loc = Reg rs; typ = (Int | Addr)}, {loc = Reg rd} -> ++ ` mr {emit_reg dst}, {emit_reg src}\n` ++ | {loc = Reg rs; typ = Float}, {loc = Reg rd; typ = Float} -> ++ ` fmr {emit_reg dst}, {emit_reg src}\n` ++ | {loc = Reg rs; typ = (Int | Addr)}, {loc = Stack sd} -> ++ ` std {emit_reg src}, {emit_stack dst}\n` ++ | {loc = Reg rs; typ = Float}, {loc = Stack sd} -> ++ ` stfd {emit_reg src}, {emit_stack dst}\n` ++ | {loc = Stack ss; typ = (Int | Addr)}, {loc = Reg rd} -> ++ ` ld {emit_reg dst}, {emit_stack src}\n` ++ | {loc = Stack ss; typ = Float}, {loc = Reg rd} -> ++ ` lfd {emit_reg dst}, {emit_stack src}\n` ++ | (_, _) -> ++ fatal_error "Emit: Imove" ++ end ++ | Lop(Iconst_int n) -> ++ if is_native_immediate n then ++ ` li {emit_reg i.res.(0)}, {emit_nativeint n}\n` ++ else if n >= -0x8000_0000n && n <= 0x7FFF_FFFFn then begin ++ ` lis {emit_reg i.res.(0)}, {emit_int(nativehigh n)}\n`; ++ if nativelow n <> 0 then ++ ` ori {emit_reg i.res.(0)}, {emit_reg i.res.(0)}, {emit_int(nativelow n)}\n` ++ end else begin ++ ` ld {emit_reg i.res.(0)}, {emit_tocref (TocInt n)}\n` ++ end ++ | Lop(Iconst_float s) -> ++ ` lfd {emit_reg i.res.(0)}, {emit_tocref (TocFloat s)}\n` ++ | Lop(Iconst_symbol s) -> ++ ` ld {emit_reg i.res.(0)}, {emit_tocref (TocSymOfs (s,0))}\n` ++ | Lop(Icall_ind) -> ++ ` std {emit_gpr 2},24({emit_gpr 1})\n`; ++ ` mtctr {emit_reg i.arg.(0)}\n`; ++ record_frame i.live; ++ ` bctrl\n`; ++ ` ld {emit_gpr 2},24({emit_gpr 1})\n` ++ | Lop(Icall_imm s) -> ++ ` ld {emit_gpr 12}, {emit_tocref (TocSymOfs (s,0))}\n`; ++ ` std {emit_gpr 2},24({emit_gpr 1})\n`; ++ ` mtctr {emit_gpr 12}\n`; ++ record_frame i.live; ++ ` bctrl\n`; ++ ` ld {emit_gpr 2},24({emit_gpr 1})\n` ++ | Lop(Itailcall_ind) -> ++ ` mtctr {emit_reg i.arg.(0)}\n`; ++ if has_stack_frame() then ++ ` ld {emit_gpr 1}, 0({emit_gpr 1})\n`; ++ if !contains_calls then begin ++ ` ld {emit_gpr 12}, 16({emit_gpr 1})\n`; ++ ` mtlr {emit_gpr 12}\n` ++ end; ++ ` bctr\n` ++ | Lop(Itailcall_imm s) -> ++ if s = !function_name then ++ ` b {emit_label !tailrec_entry_point}\n` ++ else begin ++ if has_stack_frame() then ++ ` ld {emit_gpr 1}, 0({emit_gpr 1})\n`; ++ if !contains_calls then begin ++ ` ld {emit_gpr 12}, 16({emit_gpr 1})\n`; ++ ` mtlr {emit_gpr 12}\n` ++ end; ++ ` ld {emit_gpr 12}, {emit_tocref (TocSymOfs (s,0))}\n`; ++ ` mtctr {emit_gpr 12}\n`; ++ ` bctr\n` ++ end ++ | Lop(Iextcall(s, alloc)) -> ++ if alloc then begin ++ ` ld {emit_gpr 11}, {emit_tocref (TocSymOfs (s,0))}\n`; ++ ` ld {emit_gpr 12}, {emit_tocref (TocSymOfs ("caml_c_call",0))}\n`; ++ end else ++ ` ld {emit_gpr 12}, {emit_tocref (TocSymOfs (s,0))}\n`; ++ ` std {emit_gpr 2}, 24({emit_gpr 1})\n`; ++ ` mtctr {emit_gpr 12}\n`; ++ if alloc then record_frame i.live; ++ ` bctrl\n`; ++ ` ld {emit_gpr 2}, 24({emit_gpr 1})\n` ++ | Lop(Istackoffset n) -> ++ if n > !stack_args_size then ++ stack_args_size := n ++ | Lop(Iload(chunk, addr)) -> ++ let loadinstr = ++ match chunk with ++ Byte_unsigned -> "lbz" ++ | Byte_signed -> "lbz" ++ | Sixteen_unsigned -> "lhz" ++ | Sixteen_signed -> "lha" ++ | Thirtytwo_unsigned -> "lwz" ++ | Thirtytwo_signed -> "lwa" ++ | Word -> "ld" ++ | Single -> "lfs" ++ | Double | Double_u -> "lfd" in ++ emit_load_store loadinstr addr i.arg 0 i.res.(0); ++ if chunk = Byte_signed then ++ ` extsb {emit_reg i.res.(0)}, {emit_reg i.res.(0)}\n` ++ | Lop(Istore(chunk, addr)) -> ++ let storeinstr = ++ match chunk with ++ Byte_unsigned | Byte_signed -> "stb" ++ | Sixteen_unsigned | Sixteen_signed -> "sth" ++ | Thirtytwo_unsigned | Thirtytwo_signed -> "stw" ++ | Word -> "std" ++ | Single -> "stfs" ++ | Double | Double_u -> "stfd" in ++ emit_load_store storeinstr addr i.arg 1 i.arg.(0) ++ | Lop(Ialloc n) -> ++ if !call_gc_label = 0 then call_gc_label := new_label(); ++ ` addi {emit_gpr 31}, {emit_gpr 31}, {emit_int(-n)}\n`; ++ ` cmpld {emit_gpr 31}, {emit_gpr 30}\n`; ++ ` addi {emit_reg i.res.(0)}, {emit_gpr 31}, 8\n`; ++ record_frame i.live; ++ ` bltl {emit_label !call_gc_label}\n` (* Must be 4 insns to restart *) ++ | Lop(Ispecific(Ialloc_far n)) -> ++ if !call_gc_label = 0 then call_gc_label := new_label(); ++ let lbl = new_label() in ++ ` addi {emit_gpr 31}, {emit_gpr 31}, {emit_int(-n)}\n`; ++ ` cmpld {emit_gpr 31}, {emit_gpr 30}\n`; ++ ` bge {emit_label lbl}\n`; ++ record_frame i.live; ++ ` bl {emit_label !call_gc_label}\n`; (* Must be 4 insns to restart *) ++ `{emit_label lbl}: addi {emit_reg i.res.(0)}, {emit_gpr 31}, {emit_int size_addr}\n` ++ | Lop(Iintop Isub) -> (* subfc has swapped arguments *) ++ ` subfc {emit_reg i.res.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n` ++ | Lop(Iintop Imod) -> ++ ` divd {emit_gpr 0}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; ++ ` mulld {emit_gpr 0}, {emit_gpr 0}, {emit_reg i.arg.(1)}\n`; ++ ` subfc {emit_reg i.res.(0)}, {emit_gpr 0}, {emit_reg i.arg.(0)}\n` ++ | Lop(Iintop(Icomp cmp)) -> ++ begin match cmp with ++ Isigned c -> ++ ` cmpd {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; ++ emit_set_comp c i.res.(0) ++ | Iunsigned c -> ++ ` cmpld {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; ++ emit_set_comp c i.res.(0) ++ end ++ | Lop(Iintop Icheckbound) -> ++ ` tdlle {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n` ++ | Lop(Iintop op) -> ++ let instr = name_for_intop op in ++ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n` ++ | Lop(Iintop_imm(Isub, n)) -> ++ ` addi {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_int(-n)}\n` ++ | Lop(Iintop_imm(Idiv, n)) -> (* n is guaranteed to be a power of 2 *) ++ let l = Misc.log2 n in ++ ` sradi {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_int l}\n`; ++ ` addze {emit_reg i.res.(0)}, {emit_reg i.res.(0)}\n` ++ | Lop(Iintop_imm(Imod, n)) -> (* n is guaranteed to be a power of 2 *) ++ let l = Misc.log2 n in ++ ` sradi {emit_gpr 0}, {emit_reg i.arg.(0)}, {emit_int l}\n`; ++ ` addze {emit_gpr 0}, {emit_gpr 0}\n`; ++ ` sldi {emit_gpr 0}, {emit_gpr 0}, {emit_int l}\n`; ++ ` subfc {emit_reg i.res.(0)}, {emit_gpr 0}, {emit_reg i.arg.(0)}\n` ++ | Lop(Iintop_imm(Icomp cmp, n)) -> ++ begin match cmp with ++ Isigned c -> ++ ` cmpdi {emit_reg i.arg.(0)}, {emit_int n}\n`; ++ emit_set_comp c i.res.(0) ++ | Iunsigned c -> ++ ` cmpldi {emit_reg i.arg.(0)}, {emit_int n}\n`; ++ emit_set_comp c i.res.(0) ++ end ++ | Lop(Iintop_imm(Icheckbound, n)) -> ++ ` tdllei {emit_reg i.arg.(0)}, {emit_int n}\n` ++ | Lop(Iintop_imm(op, n)) -> ++ let instr = name_for_intop_imm op in ++ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_int n}\n` ++ | Lop(Inegf | Iabsf as op) -> ++ let instr = name_for_floatop1 op in ++ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}\n` ++ | Lop(Iaddf | Isubf | Imulf | Idivf as op) -> ++ let instr = name_for_floatop2 op in ++ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n` ++ | Lop(Ifloatofint) -> ++ let ofs = if has_stack_frame() then 16 else 8 * (2 + num_stack_slots.(0) + num_stack_slots.(1)) in ++ ` std {emit_reg i.arg.(0)}, -{emit_int ofs}({emit_gpr 1})\n`; ++ ` lfd {emit_reg i.res.(0)}, -{emit_int ofs}({emit_gpr 1})\n`; ++ ` fcfid {emit_reg i.res.(0)}, {emit_reg i.res.(0)}\n` ++ | Lop(Iintoffloat) -> ++ let ofs = if has_stack_frame() then 16 else 8 * (2 + num_stack_slots.(0) + num_stack_slots.(1)) in ++ ` fctidz {emit_fpr 0}, {emit_reg i.arg.(0)}\n`; ++ ` stfd {emit_fpr 0}, -{emit_int ofs}({emit_gpr 1})\n`; ++ ` ld {emit_reg i.res.(0)}, -{emit_int ofs}({emit_gpr 1})\n` ++ | Lop(Ispecific sop) -> ++ let instr = name_for_specific sop in ++ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(2)}\n` ++ | Lreloadretaddr -> ++ if has_stack_frame() then begin ++ ` ld {emit_gpr 12}, {emit_label !stack_size_lbl}+16({emit_gpr 1})\n`; ++ ` mtlr {emit_gpr 12}\n` ++ end ++ | Lreturn -> ++ if has_stack_frame() then ++ ` ld {emit_gpr 1}, 0({emit_gpr 1})\n`; ++ ` blr\n` ++ | Llabel lbl -> ++ `{emit_label lbl}:\n` ++ | Lbranch lbl -> ++ ` b {emit_label lbl}\n` ++ | Lcondbranch(tst, lbl) -> ++ begin match tst with ++ Itruetest -> ++ ` cmpdi {emit_reg i.arg.(0)}, 0\n`; ++ emit_delay dslot; ++ ` bne {emit_label lbl}\n` ++ | Ifalsetest -> ++ ` cmpdi {emit_reg i.arg.(0)}, 0\n`; ++ emit_delay dslot; ++ ` beq {emit_label lbl}\n` ++ | Iinttest cmp -> ++ let (comp, branch) = name_for_int_comparison cmp in ++ ` {emit_string comp} {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; ++ emit_delay dslot; ++ ` {emit_string branch} {emit_label lbl}\n` ++ | Iinttest_imm(cmp, n) -> ++ let (comp, branch) = name_for_int_comparison cmp in ++ ` {emit_string comp}i {emit_reg i.arg.(0)}, {emit_int n}\n`; ++ emit_delay dslot; ++ ` {emit_string branch} {emit_label lbl}\n` ++ | Ifloattest(cmp, neg) -> ++ ` fcmpu {emit_ccr 0}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; ++ (* bit 0 = lt, bit 1 = gt, bit 2 = eq *) ++ let (bitnum, negtst) = ++ match cmp with ++ Ceq -> (2, neg) ++ | Cne -> (2, not neg) ++ | Cle -> ` cror 3, 0, 2\n`; (* lt or eq *) ++ (3, neg) ++ | Cgt -> (1, neg) ++ | Cge -> ` cror 3, 1, 2\n`; (* gt or eq *) ++ (3, neg) ++ | Clt -> (0, neg) in ++ emit_delay dslot; ++ if negtst ++ then ` bf {emit_int bitnum}, {emit_label lbl}\n` ++ else ` bt {emit_int bitnum}, {emit_label lbl}\n` ++ | Ioddtest -> ++ ` andi. {emit_gpr 0}, {emit_reg i.arg.(0)}, 1\n`; ++ emit_delay dslot; ++ ` bne {emit_label lbl}\n` ++ | Ieventest -> ++ ` andi. {emit_gpr 0}, {emit_reg i.arg.(0)}, 1\n`; ++ emit_delay dslot; ++ ` beq {emit_label lbl}\n` ++ end ++ | Lcondbranch3(lbl0, lbl1, lbl2) -> ++ ` cmpdi {emit_reg i.arg.(0)}, 1\n`; ++ emit_delay dslot; ++ begin match lbl0 with ++ None -> () ++ | Some lbl -> ` blt {emit_label lbl}\n` ++ end; ++ begin match lbl1 with ++ None -> () ++ | Some lbl -> ` beq {emit_label lbl}\n` ++ end; ++ begin match lbl2 with ++ None -> () ++ | Some lbl -> ` bgt {emit_label lbl}\n` ++ end ++ | Lswitch jumptbl -> ++ if !lbl_jumptbl = 0 then lbl_jumptbl := new_label(); ++ ` ld {emit_gpr 11}, {emit_tocref (TocLabel !lbl_jumptbl)}\n`; ++ ` addi {emit_gpr 0}, {emit_reg i.arg.(0)}, {emit_int !num_jumptbl_entries}\n`; ++ ` sldi {emit_gpr 0}, {emit_gpr 0}, 2\n`; ++ ` lwax {emit_gpr 0}, {emit_gpr 11}, {emit_gpr 0}\n`; ++ ` add {emit_gpr 0}, {emit_gpr 11}, {emit_gpr 0}\n`; ++ ` mtctr {emit_gpr 0}\n`; ++ ` bctr\n`; ++ for i = 0 to Array.length jumptbl - 1 do ++ jumptbl_entries := jumptbl.(i) :: !jumptbl_entries; ++ incr num_jumptbl_entries ++ done ++ | Lsetuptrap lbl -> ++ ` bl {emit_label lbl}\n`; ++ | Lpushtrap -> ++ stack_traps_size := !stack_traps_size + 32; ++ ` addi {emit_gpr 11}, {emit_gpr 1}, {emit_label !stack_size_lbl}-{emit_int !stack_traps_size}\n`; ++ ` mflr {emit_gpr 0}\n`; ++ ` std {emit_gpr 29}, 0({emit_gpr 11})\n`; ++ ` std {emit_gpr 0}, 8({emit_gpr 11})\n`; ++ ` std {emit_gpr 1}, 16({emit_gpr 11})\n`; ++ ` std {emit_gpr 2}, 24({emit_gpr 11})\n`; ++ ` mr {emit_gpr 29}, {emit_gpr 11}\n` ++ | Lpoptrap -> ++ ` ld {emit_gpr 29}, 0({emit_gpr 29})\n` ++ | Lraise -> ++ ` ld {emit_gpr 0}, 8({emit_gpr 29})\n`; ++ ` ld {emit_gpr 1}, 16({emit_gpr 29})\n`; ++ ` ld {emit_gpr 2}, 24({emit_gpr 29})\n`; ++ ` mtlr {emit_gpr 0}\n`; ++ ` ld {emit_gpr 29}, 0({emit_gpr 29})\n`; ++ ` blr\n` ++ ++and emit_delay = function ++ None -> () ++ | Some i -> emit_instr i None ++ ++(* Checks if a pseudo-instruction expands to instructions ++ that do not branch and do not affect CR0 nor R12. *) ++ ++let is_simple_instr i = ++ match i.desc with ++ Lop op -> ++ begin match op with ++ Icall_imm _ | Icall_ind | Itailcall_imm _ | Itailcall_ind | ++ Iextcall(_, _) -> false ++ | Ialloc(_) -> false ++ | Iintop(Icomp _) -> false ++ | Iintop_imm(Iand, _) -> false ++ | Iintop_imm(Icomp _, _) -> false ++ | _ -> true ++ end ++ | Lreloadretaddr -> true ++ | _ -> false ++ ++let no_interference res arg = ++ try ++ for i = 0 to Array.length arg - 1 do ++ for j = 0 to Array.length res - 1 do ++ if arg.(i).loc = res.(j).loc then raise Exit ++ done ++ done; ++ true ++ with Exit -> ++ false ++ ++(* Emit a sequence of instructions, trying to fill delay slots for branches *) ++ ++let rec emit_all i = ++ match i with ++ {desc = Lend} -> () ++ | {next = {desc = (Lcondbranch(_, _) | Lcondbranch3(_, _, _))}} ++ when is_simple_instr i && no_interference i.res i.next.arg -> ++ emit_instr i.next (Some i); ++ emit_all i.next.next ++ | _ -> ++ emit_instr i None; ++ emit_all i.next ++ ++(* Emission of a function declaration *) ++ ++let fundecl fundecl = ++ function_name := fundecl.fun_name; ++ defined_functions := StringSet.add fundecl.fun_name !defined_functions; ++ tailrec_entry_point := new_label(); ++ if has_stack_frame() then ++ stack_size_lbl := new_label(); ++ stack_slot_lbl := new_label(); ++ stack_args_size := 0; ++ stack_traps_size := 0; ++ call_gc_label := 0; ++ ` .globl {emit_symbol fundecl.fun_name}\n`; ++ begin match Config.system with ++ | "elf" | "bsd" -> ++ ` .type {emit_symbol fundecl.fun_name}, @function\n`; ++ emit_string code_space; ++ `{emit_symbol fundecl.fun_name}:\n`; ++ | _ -> ++ ` .align 2\n`; ++ emit_string code_space; ++ `{emit_symbol fundecl.fun_name}:\n` ++ end; ++ (* r2 to be setup to current toc *) ++ `0: addis {emit_gpr 2}, {emit_gpr 12},.TOC.-0b@ha\n`; ++ ` addi {emit_gpr 2}, {emit_gpr 2},.TOC.-0b@l\n`; ++ ` .localentry {emit_symbol fundecl.fun_name}, .-{emit_symbol fundecl.fun_name}\n`; ++ if !contains_calls then begin ++ ` mflr {emit_gpr 0}\n`; ++ ` std {emit_gpr 0}, 16({emit_gpr 1})\n` ++ end; ++ if has_stack_frame() then ++ ` stdu {emit_gpr 1}, -{emit_label !stack_size_lbl}({emit_gpr 1})\n`; ++ `{emit_label !tailrec_entry_point}:\n`; ++ branch_normalization fundecl.fun_body; ++ emit_all fundecl.fun_body; ++ ` .size {emit_symbol fundecl.fun_name}, .-{emit_symbol fundecl.fun_name}\n`; ++ if has_stack_frame() then begin ++ ` .set {emit_label !stack_size_lbl},{emit_int (frame_size_sans_args() + !stack_args_size + !stack_traps_size)} # stack size including traps\n`; ++ ` .set {emit_label !stack_slot_lbl},{emit_int (48 + !stack_args_size)} # stack slot offset\n` ++ end else (* leave 8 bytes for float <-> conversions *) ++ ` .set {emit_label !stack_slot_lbl},{emit_int (40-frame_size_sans_args())} # stack slot offset (negative)\n`; ++ ++ (* Emit the glue code to call the GC *) ++ if !call_gc_label > 0 then begin ++ `{emit_label !call_gc_label}:\n`; ++ ` ld {emit_gpr 12}, {emit_tocref (TocSymOfs ("caml_call_gc",0))}\n`; ++ ` mtctr {emit_gpr 12}\n`; ++ ` bctr\n`; ++ end ++ ++(* Emission of data *) ++ ++let declare_global_data s = ++ ` .globl {emit_symbol s}\n`; ++ if Config.system = "elf" || Config.system = "bsd" then ++ ` .type {emit_symbol s}, @object\n` ++ ++let emit_item = function ++ Cglobal_symbol s -> ++ declare_global_data s ++ | Cdefine_symbol s -> ++ `{emit_symbol s}:\n`; ++ | Cdefine_label lbl -> ++ `{emit_label (lbl + 100000)}:\n` ++ | Cint8 n -> ++ ` .byte {emit_int n}\n` ++ | Cint16 n -> ++ ` .short {emit_int n}\n` ++ | Cint32 n -> ++ ` .long {emit_nativeint n}\n` ++ | Cint n -> ++ ` .quad {emit_nativeint n}\n` ++ | Csingle f -> ++ ` .float 0d{emit_string f}\n` ++ | Cdouble f -> ++ ` .double 0d{emit_string f}\n` ++ | Csymbol_address s -> ++ ` .quad {emit_symbol s}\n` ++ | Clabel_address lbl -> ++ ` .quad {emit_label (lbl + 100000)}\n` ++ | Cstring s -> ++ emit_bytes_directive " .byte " s ++ | Cskip n -> ++ if n > 0 then ` .space {emit_int n}\n` ++ | Calign n -> ++ ` .align {emit_int (Misc.log2 n)}\n` ++ ++let data l = ++ emit_string data_space; ++ List.iter emit_item l ++ ++(* Beginning / end of an assembly file *) ++ ++let begin_assembly() = ++ defined_functions := StringSet.empty; ++ external_functions := StringSet.empty; ++ tocref_entries := []; ++ num_jumptbl_entries := 0; ++ jumptbl_entries := []; ++ lbl_jumptbl := 0; ++ (* Emit the beginning of the segments *) ++ let lbl_begin = Compilenv.make_symbol (Some "data_begin") in ++ emit_string data_space; ++ declare_global_data lbl_begin; ++ emit_string abiversion; ++ `{emit_symbol lbl_begin}:\n`; ++ let lbl_begin = Compilenv.make_symbol (Some "code_begin") in ++ emit_string code_space; ++ declare_global_data lbl_begin; ++ `{emit_symbol lbl_begin}:\n` ++ ++let end_assembly() = ++ (* Emit the jump table *) ++ if !num_jumptbl_entries > 0 then begin ++ emit_string code_space; ++ `{emit_label !lbl_jumptbl}:\n`; ++ List.iter ++ (fun lbl -> ` .long {emit_label lbl} - {emit_label !lbl_jumptbl}\n`) ++ (List.rev !jumptbl_entries); ++ jumptbl_entries := [] ++ end; ++ if !tocref_entries <> [] then begin ++ emit_string toc_space; ++ List.iter ++ (fun (lbl, entry) -> ++ `{emit_label lbl}:\n`; ++ match entry with ++ TocFloat f -> ++ ` .double {emit_tocentry entry}\n` ++ | _ -> ++ ` .tc {emit_label lbl}[TC],{emit_tocentry entry}\n` ++ ) ++ !tocref_entries; ++ tocref_entries := [] ++ end; ++ if pic_externals then ++ (* Emit the pointers to external functions *) ++ StringSet.iter emit_external !external_functions; ++ (* Emit the end of the segments *) ++ emit_string code_space; ++ let lbl_end = Compilenv.make_symbol (Some "code_end") in ++ declare_global_data lbl_end; ++ `{emit_symbol lbl_end}:\n`; ++ ` .long 0\n`; ++ emit_string data_space; ++ let lbl_end = Compilenv.make_symbol (Some "data_end") in ++ declare_global_data lbl_end; ++ `{emit_symbol lbl_end}:\n`; ++ ` .quad 0\n`; ++ (* Emit the frame descriptors *) ++ emit_string rodata_space; ++ let lbl = Compilenv.make_symbol (Some "frametable") in ++ declare_global_data lbl; ++ `{emit_symbol lbl}:\n`; ++ ` .quad {emit_int (List.length !frame_descriptors)}\n`; ++ List.iter emit_frame !frame_descriptors; ++ frame_descriptors := [] +diff --git a/asmcomp/power64le/proc.ml b/asmcomp/power64le/proc.ml +new file mode 100644 +index 0000000..9b98577 +--- /dev/null ++++ b/asmcomp/power64le/proc.ml +@@ -0,0 +1,240 @@ ++(***********************************************************************) ++(* *) ++(* Objective Caml *) ++(* *) ++(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) ++(* *) ++(* 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. *) ++(* *) ++(***********************************************************************) ++ ++(* $Id: proc.ml 9547 2010-01-22 12:48:24Z doligez $ *) ++ ++(* Description of the Power PC *) ++ ++open Misc ++open Cmm ++open Reg ++open Arch ++open Mach ++ ++(* Instruction selection *) ++ ++let word_addressed = false ++ ++(* Registers available for register allocation *) ++ ++(* Integer register map: ++ 0 temporary, null register for some operations ++ 1 stack pointer ++ 2 pointer to table of contents ++ 3 - 10 function arguments and results ++ 11 - 12 temporaries ++ 13 pointer to small data area ++ 14 - 28 general purpose, preserved by C ++ 29 trap pointer ++ 30 allocation limit ++ 31 allocation pointer ++ Floating-point register map: ++ 0 temporary ++ 1 - 13 function arguments and results ++ 14 - 31 general purpose, preserved by C ++*) ++ ++let int_reg_name = ++ if Config.system = "rhapsody" then ++ [| "r3"; "r4"; "r5"; "r6"; "r7"; "r8"; "r9"; "r10"; ++ "r14"; "r15"; "r16"; "r17"; "r18"; "r19"; "r20"; "r21"; ++ "r22"; "r23"; "r24"; "r25"; "r26"; "r27"; "r28" |] ++ else ++ [| "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; ++ "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; ++ "22"; "23"; "24"; "25"; "26"; "27"; "28" |] ++ ++let float_reg_name = ++ if Config.system = "rhapsody" then ++ [| "f1"; "f2"; "f3"; "f4"; "f5"; "f6"; "f7"; "f8"; ++ "f9"; "f10"; "f11"; "f12"; "f13"; "f14"; "f15"; "f16"; ++ "f17"; "f18"; "f19"; "f20"; "f21"; "f22"; "f23"; "f24"; ++ "f25"; "f26"; "f27"; "f28"; "f29"; "f30"; "f31" |] ++ else ++ [| "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; ++ "9"; "10"; "11"; "12"; "13"; "14"; "15"; "16"; ++ "17"; "18"; "19"; "20"; "21"; "22"; "23"; "24"; ++ "25"; "26"; "27"; "28"; "29"; "30"; "31" |] ++ ++let num_register_classes = 2 ++ ++let register_class r = ++ match r.typ with ++ Int -> 0 ++ | Addr -> 0 ++ | Float -> 1 ++ ++let num_available_registers = [| 23; 31 |] ++ ++let first_available_register = [| 0; 100 |] ++ ++let register_name r = ++ if r < 100 then int_reg_name.(r) else float_reg_name.(r - 100) ++ ++let rotate_registers = true ++ ++(* Representation of hard registers by pseudo-registers *) ++ ++let hard_int_reg = ++ let v = Array.create 23 Reg.dummy in ++ for i = 0 to 22 do v.(i) <- Reg.at_location Int (Reg i) done; v ++ ++let hard_float_reg = ++ let v = Array.create 31 Reg.dummy in ++ for i = 0 to 30 do v.(i) <- Reg.at_location Float (Reg(100 + i)) done; v ++ ++let all_phys_regs = ++ Array.append hard_int_reg hard_float_reg ++ ++let phys_reg n = ++ if n < 100 then hard_int_reg.(n) else hard_float_reg.(n - 100) ++ ++let stack_slot slot ty = ++ Reg.at_location ty (Stack slot) ++ ++(* Calling conventions *) ++ ++let calling_conventions ++ first_int last_int first_float last_float make_stack stack_ofs arg = ++ let loc = Array.create (Array.length arg) Reg.dummy in ++ let int = ref first_int in ++ let float = ref first_float in ++ let ofs = ref stack_ofs in ++ for i = 0 to Array.length arg - 1 do ++ match arg.(i).typ with ++ Int | Addr as ty -> ++ if !int <= last_int then begin ++ loc.(i) <- phys_reg !int; ++ incr int ++ end else begin ++ loc.(i) <- stack_slot (make_stack !ofs) ty; ++ end; ++ ofs := !ofs + size_int ++ | Float -> ++ if !float <= last_float then begin ++ loc.(i) <- phys_reg !float; ++ incr float ++ end else begin ++ loc.(i) <- stack_slot (make_stack !ofs) Float; ++ end; ++ ofs := !ofs + size_float ++ done; ++ (loc, Misc.align !ofs 16) ++ (* Keep stack 16-aligned. *) ++ ++let incoming ofs = Incoming ofs ++let outgoing ofs = Outgoing ofs ++let not_supported ofs = fatal_error "Proc.loc_results: cannot call" ++ ++let loc_arguments arg = ++ calling_conventions 0 7 100 112 outgoing 48 arg ++let loc_parameters arg = ++ let (loc, ofs) = calling_conventions 0 7 100 112 incoming 0 arg in loc ++let loc_results res = ++ let (loc, ofs) = calling_conventions 0 7 100 112 not_supported 0 res in loc ++ ++(* C calling conventions under PowerOpen: ++ use GPR 3-10 and FPR 1-13 just like ML calling ++ conventions, but always reserve stack space for all arguments. ++ Also, using a float register automatically reserves two int registers ++ (in 32-bit mode) or one int register (in 64-bit mode). ++ (If we were to call a non-prototyped C function, each float argument ++ would have to go both in a float reg and in the matching pair ++ of integer regs.) ++ ++ C calling conventions under SVR4: ++ use GPR 3-10 and FPR 1-8 just like ML calling conventions. ++ Using a float register does not affect the int registers. ++ Always reserve 8 bytes at bottom of stack, plus whatever is needed ++ to hold the overflow arguments. *) ++ ++let poweropen_external_conventions first_int last_int ++ first_float last_float arg = ++ let loc = Array.create (Array.length arg) Reg.dummy in ++ let int = ref first_int in ++ let float = ref first_float in ++ let ofs = ref (14 * size_addr) in ++ for i = 0 to Array.length arg - 1 do ++ match arg.(i).typ with ++ Int | Addr as ty -> ++ if !int <= last_int then begin ++ loc.(i) <- phys_reg !int; ++ incr int ++ end else begin ++ loc.(i) <- stack_slot (Outgoing !ofs) ty; ++ ofs := !ofs + size_int ++ end ++ | Float -> ++ if !float <= last_float then begin ++ loc.(i) <- phys_reg !float; ++ incr float ++ end else begin ++ loc.(i) <- stack_slot (Outgoing !ofs) Float; ++ ofs := !ofs + size_float ++ end; ++ int := !int + 1 ++ done; ++ (loc, Misc.align !ofs 16) (* Keep stack 16-aligned *) ++ ++let loc_external_arguments = ++ match Config.system with ++ | "rhapsody" -> poweropen_external_conventions 0 7 100 112 ++ | "elf" | "bsd" -> calling_conventions 0 7 100 107 outgoing 48 ++ | _ -> assert false ++ ++let extcall_use_push = false ++ ++(* Results are in GPR 3 and FPR 1 *) ++ ++let loc_external_results res = ++ let (loc, ofs) = calling_conventions 0 0 100 100 not_supported 0 res in loc ++ ++(* Exceptions are in GPR 3 *) ++ ++let loc_exn_bucket = phys_reg 0 ++ ++(* Registers destroyed by operations *) ++ ++let destroyed_at_c_call = ++ Array.of_list(List.map phys_reg ++ [0; 1; 2; 3; 4; 5; 6; 7; ++ 100; 101; 102; 103; 104; 105; 106; 107; 108; 109; 110; 111; 112]) ++ ++let destroyed_at_oper = function ++ Iop(Icall_ind | Icall_imm _ | Iextcall(_, true)) -> all_phys_regs ++ | Iop(Iextcall(_, false)) -> destroyed_at_c_call ++ | _ -> [||] ++ ++let destroyed_at_raise = all_phys_regs ++ ++(* Maximal register pressure *) ++ ++let safe_register_pressure = function ++ Iextcall(_, _) -> 15 ++ | _ -> 23 ++ ++let max_register_pressure = function ++ Iextcall(_, _) -> [| 15; 18 |] ++ | _ -> [| 23; 30 |] ++ ++(* Layout of the stack *) ++ ++let num_stack_slots = [| 0; 0 |] ++let contains_calls = ref false ++ ++(* Calling the assembler *) ++ ++let assemble_file infile outfile = ++ Ccomp.command (Config.asm ^ " -o " ^ ++ Filename.quote outfile ^ " " ^ Filename.quote infile) ++ ++let init () = () +diff --git a/asmcomp/power64le/reload.ml b/asmcomp/power64le/reload.ml +new file mode 100644 +index 0000000..abcac6c +--- /dev/null ++++ b/asmcomp/power64le/reload.ml +@@ -0,0 +1,18 @@ ++(***********************************************************************) ++(* *) ++(* Objective Caml *) ++(* *) ++(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) ++(* *) ++(* 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. *) ++(* *) ++(***********************************************************************) ++ ++(* $Id: reload.ml 2553 1999-11-17 18:59:06Z xleroy $ *) ++ ++(* Reloading for the PowerPC *) ++ ++let fundecl f = ++ (new Reloadgen.reload_generic)#fundecl f +diff --git a/asmcomp/power64le/scheduling.ml b/asmcomp/power64le/scheduling.ml +new file mode 100644 +index 0000000..b7bba9b +--- /dev/null ++++ b/asmcomp/power64le/scheduling.ml +@@ -0,0 +1,65 @@ ++(***********************************************************************) ++(* *) ++(* Objective Caml *) ++(* *) ++(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) ++(* *) ++(* 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. *) ++(* *) ++(***********************************************************************) ++ ++(* $Id: scheduling.ml 9547 2010-01-22 12:48:24Z doligez $ *) ++ ++(* Instruction scheduling for the Power PC *) ++ ++open Arch ++open Mach ++ ++class scheduler = object ++ ++inherit Schedgen.scheduler_generic ++ ++(* Latencies (in cycles). Based roughly on the "common model". *) ++ ++method oper_latency = function ++ Ireload -> 2 ++ | Iload(_, _) -> 2 ++ | Iconst_float _ -> 2 (* turned into a load *) ++ | Iconst_symbol _ -> 1 ++ | Iintop Imul -> 9 ++ | Iintop_imm(Imul, _) -> 5 ++ | Iintop(Idiv | Imod) -> 36 ++ | Iaddf | Isubf -> 4 ++ | Imulf -> 5 ++ | Idivf -> 33 ++ | Ispecific(Imultaddf | Imultsubf) -> 5 ++ | _ -> 1 ++ ++method reload_retaddr_latency = 12 ++ (* If we can have that many cycles between the reloadretaddr and the ++ return, we can expect that the blr branch will be completely folded. *) ++ ++(* Issue cycles. Rough approximations. *) ++ ++method oper_issue_cycles = function ++ Iconst_float _ | Iconst_symbol _ -> 2 ++ | Iload(_, Ibased(_, _)) -> 2 ++ | Istore(_, Ibased(_, _)) -> 2 ++ | Ialloc _ -> 4 ++ | Iintop(Imod) -> 40 (* assuming full stall *) ++ | Iintop(Icomp _) -> 4 ++ | Iintop_imm(Idiv, _) -> 2 ++ | Iintop_imm(Imod, _) -> 4 ++ | Iintop_imm(Icomp _, _) -> 4 ++ | Ifloatofint -> 9 ++ | Iintoffloat -> 4 ++ | _ -> 1 ++ ++method reload_retaddr_issue_cycles = 3 ++ (* load then stalling mtlr *) ++ ++end ++ ++let fundecl f = (new scheduler)#schedule_fundecl f +diff --git a/asmcomp/power64le/selection.ml b/asmcomp/power64le/selection.ml +new file mode 100644 +index 0000000..6101d53 +--- /dev/null ++++ b/asmcomp/power64le/selection.ml +@@ -0,0 +1,101 @@ ++(***********************************************************************) ++(* *) ++(* Objective Caml *) ++(* *) ++(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) ++(* *) ++(* Copyright 1997 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. *) ++(* *) ++(***********************************************************************) ++ ++(* $Id: selection.ml 10296 2010-04-22 12:51:06Z xleroy $ *) ++ ++(* Instruction selection for the Power PC processor *) ++ ++open Cmm ++open Arch ++open Mach ++ ++(* Recognition of addressing modes *) ++ ++type addressing_expr = ++ Asymbol of string ++ | Alinear of expression ++ | Aadd of expression * expression ++ ++let rec select_addr = function ++ Cconst_symbol s -> ++ (Asymbol s, 0) ++ | Cop((Caddi | Cadda), [arg; Cconst_int m]) -> ++ let (a, n) = select_addr arg in (a, n + m) ++ | Cop((Caddi | Cadda), [Cconst_int m; arg]) -> ++ let (a, n) = select_addr arg in (a, n + m) ++ | Cop((Caddi | Cadda), [arg1; arg2]) -> ++ begin match (select_addr arg1, select_addr arg2) with ++ ((Alinear e1, n1), (Alinear e2, n2)) -> ++ (Aadd(e1, e2), n1 + n2) ++ | _ -> ++ (Aadd(arg1, arg2), 0) ++ end ++ | exp -> ++ (Alinear exp, 0) ++ ++(* Instruction selection *) ++ ++class selector = object (self) ++ ++inherit Selectgen.selector_generic as super ++ ++method is_immediate n = (n <= 32767) && (n >= -32768) ++ ++method select_addressing chunk exp = ++ match select_addr exp with ++ (Asymbol s, d) -> ++ (Ibased(s, d), Ctuple []) ++ | (Alinear e, d) -> ++ (Iindexed d, e) ++ | (Aadd(e1, e2), d) -> ++ if d = 0 ++ then (Iindexed2, Ctuple[e1; e2]) ++ else (Iindexed d, Cop(Cadda, [e1; e2])) ++ ++method! select_operation op args = ++ match (op, args) with ++ (* Prevent the recognition of (x / cst) and (x % cst) when cst is not ++ a power of 2, which do not correspond to an instruction. *) ++ (Cdivi, [arg; Cconst_int n]) when n = 1 lsl (Misc.log2 n) -> ++ (Iintop_imm(Idiv, n), [arg]) ++ | (Cdivi, _) -> ++ (Iintop Idiv, args) ++ | (Cmodi, [arg; Cconst_int n]) when n = 1 lsl (Misc.log2 n) -> ++ (Iintop_imm(Imod, n), [arg]) ++ | (Cmodi, _) -> ++ (Iintop Imod, args) ++ (* The and, or and xor instructions have a different range of immediate ++ operands than the other instructions *) ++ | (Cand, _) -> self#select_logical Iand args ++ | (Cor, _) -> self#select_logical Ior args ++ | (Cxor, _) -> self#select_logical Ixor args ++ (* Recognize mult-add and mult-sub instructions *) ++ | (Caddf, [Cop(Cmulf, [arg1; arg2]); arg3]) -> ++ (Ispecific Imultaddf, [arg1; arg2; arg3]) ++ | (Caddf, [arg3; Cop(Cmulf, [arg1; arg2])]) -> ++ (Ispecific Imultaddf, [arg1; arg2; arg3]) ++ | (Csubf, [Cop(Cmulf, [arg1; arg2]); arg3]) -> ++ (Ispecific Imultsubf, [arg1; arg2; arg3]) ++ | _ -> ++ super#select_operation op args ++ ++method select_logical op = function ++ [arg; Cconst_int n] when n >= 0 && n <= 0xFFFF -> ++ (Iintop_imm(op, n), [arg]) ++ | [Cconst_int n; arg] when n >= 0 && n <= 0xFFFF -> ++ (Iintop_imm(op, n), [arg]) ++ | args -> ++ (Iintop op, args) ++ ++end ++ ++let fundecl f = (new selector)#emit_fundecl f +diff --git a/asmrun/Makefile b/asmrun/Makefile +index 5da022c..c0362b6 100644 +--- a/asmrun/Makefile ++++ b/asmrun/Makefile +@@ -99,6 +99,12 @@ power64.o: power64-$(SYSTEM).o + power64.p.o: power64-$(SYSTEM).o + cp power64-$(SYSTEM).o power64.p.o + ++power64le.o: power64le-$(SYSTEM).o ++ cp power64le-$(SYSTEM).o power64le.o ++ ++power64le.p.o: power64le-$(SYSTEM).o ++ cp power64le-$(SYSTEM).o power64le.p.o ++ + main.c: ../byterun/main.c + ln -s ../byterun/main.c main.c + misc.c: ../byterun/misc.c +diff --git a/asmrun/power64-elf.S b/asmrun/power64-elf.S +index b2c24d6..98c42e2 100644 +--- a/asmrun/power64-elf.S ++++ b/asmrun/power64-elf.S +@@ -23,12 +23,16 @@ + addis tmp, 0, glob@ha; \ + std reg, glob@l(tmp) + ++#if _CALL_ELF == 2 ++ .abiversion 2 ++#endif + .section ".text" + + /* Invoke the garbage collector. */ + + .globl caml_call_gc + .type caml_call_gc, @function ++#if _CALL_ELF != 2 + .section ".opd","aw" + .align 3 + caml_call_gc: +@@ -36,6 +40,10 @@ caml_call_gc: + .previous + .align 2 + .L.caml_call_gc: ++#else ++caml_call_gc: ++ /* do not set r2 to tocbase */ ++#endif + /* Set up stack frame */ + mflr 0 + std 0, 16(1) +@@ -110,6 +118,7 @@ caml_call_gc: + stfdu 30, 8(11) + stfdu 31, 8(11) + /* Call the GC */ ++#if _CALL_ELF != 2 + std 2,40(1) + Addrglobal(11, caml_garbage_collection) + ld 2,8(11) +@@ -117,6 +126,13 @@ caml_call_gc: + mtlr 11 + blrl + ld 2,40(1) ++#else ++ std 2,24(1) ++ Addrglobal(12, caml_garbage_collection) ++ mtlr 12 ++ blrl ++ ld 2,24(1) ++#endif + /* Reload new allocation pointer and allocation limit */ + Loadglobal(31, caml_young_ptr, 11) + Loadglobal(30, caml_young_limit, 11) +@@ -188,12 +204,17 @@ caml_call_gc: + ld 1, 0(1) + /* Return */ + blr ++#if _CALL_ELF != 2 + .size .L.caml_call_gc,.-.L.caml_call_gc ++#else ++ .size caml_call_gc,.-caml_call_gc ++#endif + + /* Call a C function from Caml */ + + .globl caml_c_call + .type caml_c_call, @function ++#if _CALL_ELF != 2 + .section ".opd","aw" + .align 3 + caml_c_call: +@@ -201,13 +222,21 @@ caml_c_call: + .previous + .align 2 + .L.caml_c_call: ++#else ++caml_c_call: ++0: addis 2,12, .TOC.-0b@ha ++ addi 2, 2, .TOC.-0b@l ++ .localentry caml_c_call, .-caml_c_call ++#endif + .cfi_startproc + /* Save return address */ + mflr 25 + .cfi_register lr,25 + /* Get ready to call C function (address in 11) */ ++#if _CALL_ELF != 2 + ld 2, 8(11) + ld 11,0(11) ++#endif + mtlr 11 + /* Record lowest stack address and return address */ + Storeglobal(1, caml_bottom_of_stack, 12) +@@ -228,12 +257,17 @@ caml_c_call: + /* Return to caller */ + blr + .cfi_endproc ++#if _CALL_ELF != 2 + .size .L.caml_c_call,.-.L.caml_c_call ++#else ++ .size caml_c_call,.-caml_c_call ++#endif + + /* Raise an exception from C */ + + .globl caml_raise_exception + .type caml_raise_exception, @function ++#if _CALL_ELF != 2 + .section ".opd","aw" + .align 3 + caml_raise_exception: +@@ -241,6 +275,12 @@ caml_raise_exception: + .previous + .align 2 + .L.caml_raise_exception: ++#else ++caml_raise_exception: ++0: addis 2,12, .TOC.-0b@ha ++ addi 2, 2, .TOC.-0b@l ++ .localentry caml_raise_exception, .-caml_raise_exception ++#endif + /* Reload Caml global registers */ + Loadglobal(29, caml_exception_pointer, 11) + Loadglobal(31, caml_young_ptr, 11) +@@ -256,12 +296,17 @@ caml_raise_exception: + ld 29, 0(29) + /* Branch to handler */ + blr ++#if _CALL_ELF != 2 + .size .L.caml_raise_exception,.-.L.caml_raise_exception ++#else ++ .size caml_raise_exception,.-caml_raise_exception ++#endif + + /* Start the Caml program */ + + .globl caml_start_program + .type caml_start_program, @function ++#if _CALL_ELF != 2 + .section ".opd","aw" + .align 3 + caml_start_program: +@@ -269,6 +314,9 @@ caml_start_program: + .previous + .align 2 + .L.caml_start_program: ++#else ++caml_start_program: ++#endif + Addrglobal(12, caml_program) + + /* Code shared between caml_start_program and caml_callback */ +@@ -342,6 +390,7 @@ caml_start_program: + li 0, 0 + Storeglobal(0, caml_last_return_address, 11) + /* Call the Caml code */ ++#if _CALL_ELF != 2 + std 2,40(1) + ld 2,8(12) + ld 12,0(12) +@@ -349,6 +398,13 @@ caml_start_program: + .L105: + blrl + ld 2,40(1) ++#else ++ std 2,24(1) ++ mtlr 12 ++.L105: ++ blrl ++ ld 2,24(1) ++#endif + /* Pop the trap frame, restoring caml_exception_pointer */ + ld 9, 0x170(1) + Storeglobal(9, caml_exception_pointer, 11) +@@ -414,12 +470,17 @@ caml_start_program: + /* Encode exception bucket as an exception result and return it */ + ori 3, 3, 2 + b .L106 ++#if _CALL_ELF != 2 + .size .L.caml_start_program,.-.L.caml_start_program ++#else ++ .size caml_start_program,.-caml_start_program ++#endif + + /* Callback from C to Caml */ + + .globl caml_callback_exn + .type caml_callback_exn, @function ++#if _CALL_ELF != 2 + .section ".opd","aw" + .align 3 + caml_callback_exn: +@@ -427,17 +488,28 @@ caml_callback_exn: + .previous + .align 2 + .L.caml_callback_exn: ++#else ++caml_callback_exn: ++0: addis 2,12, .TOC.-0b@ha ++ addi 2, 2, .TOC.-0b@l ++ .localentry caml_callback_exn, .-caml_callback_exn ++#endif + /* Initial shuffling of arguments */ + mr 0, 3 /* Closure */ + mr 3, 4 /* Argument */ + mr 4, 0 + ld 12, 0(4) /* Code pointer */ + b .L102 ++#if _CALL_ELF != 2 + .size .L.caml_callback_exn,.-.L.caml_callback_exn ++#else ++ .size caml_callback_exn,.-caml_callback_exn ++#endif ++ + +- + .globl caml_callback2_exn + .type caml_callback2_exn, @function ++#if _CALL_ELF != 2 + .section ".opd","aw" + .align 3 + caml_callback2_exn: +@@ -445,17 +517,28 @@ caml_callback2_exn: + .previous + .align 2 + .L.caml_callback2_exn: ++#else ++caml_callback2_exn: ++0: addis 2,12, .TOC.-0b@ha ++ addi 2, 2, .TOC.-0b@l ++ .localentry caml_callback2_exn, .-caml_callback2_exn ++#endif + mr 0, 3 /* Closure */ + mr 3, 4 /* First argument */ + mr 4, 5 /* Second argument */ + mr 5, 0 + Addrglobal(12, caml_apply2) + b .L102 ++#if _CALL_ELF != 2 + .size .L.caml_callback2_exn,.-.L.caml_callback2_exn ++#else ++ .size caml_callback2_exn,.-caml_callback2_exn ++#endif + + + .globl caml_callback3_exn + .type caml_callback3_exn, @function ++#if _CALL_ELF != 2 + .section ".opd","aw" + .align 3 + caml_callback3_exn: +@@ -463,6 +546,12 @@ caml_callback3_exn: + .previous + .align 2 + .L.caml_callback3_exn: ++#else ++caml_callback3_exn: ++0: addis 2,12, .TOC.-0b@ha ++ addi 2, 2, .TOC.-0b@l ++ .localentry caml_callback3_exn, .-caml_callback3_exn ++#endif + mr 0, 3 /* Closure */ + mr 3, 4 /* First argument */ + mr 4, 5 /* Second argument */ +@@ -470,7 +559,11 @@ caml_callback3_exn: + mr 6, 0 + Addrglobal(12, caml_apply3) + b .L102 ++#if _CALL_ELF != 2 + .size .L.caml_callback3_exn,.-.L.caml_callback3_exn ++#else ++ .size caml_callback3_exn,.-caml_callback3_exn ++#endif + + /* Frame table */ + +diff --git a/asmrun/power64le-elf.S b/asmrun/power64le-elf.S +new file mode 120000 +index 0000000..f49d00c +--- /dev/null ++++ b/asmrun/power64le-elf.S +@@ -0,0 +1 @@ ++power64-elf.S +\ No newline at end of file +diff --git a/asmrun/stack.h b/asmrun/stack.h +index 5202c3a..94b81e4 100644 +--- a/asmrun/stack.h ++++ b/asmrun/stack.h +@@ -55,6 +55,15 @@ + #define Callback_link(sp) ((struct caml_context *)((sp) + Trap_frame_size)) + #endif + ++#ifdef TARGET_power64le ++#define Saved_return_address(sp) *((intnat *)((sp) +16)) ++#define Already_scanned(sp, retaddr) ((retaddr) & 1) ++#define Mark_scanned(sp, retaddr) (Saved_return_address(sp) = (retaddr) | 1) ++#define Mask_already_scanned(retaddr) ((retaddr) & ~1) ++#define Trap_frame_size 0x150 ++#define Callback_link(sp) ((struct caml_context *)((sp) + Trap_frame_size)) ++#endif ++ + #ifdef TARGET_arm + #define Saved_return_address(sp) *((intnat *)((sp) - 4)) + #define Callback_link(sp) ((struct caml_context *)((sp) + 8)) +diff --git a/config/gnu/config.guess b/config/gnu/config.guess +index b79252d..049652e 100755 +--- a/config/gnu/config.guess ++++ b/config/gnu/config.guess +@@ -992,6 +992,9 @@ EOF + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-${LIBC} + exit ;; ++ ppc64le:Linux:*:*) ++ echo powerpc64le-unknown-linux-gnu ++ exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-${LIBC} + exit ;; +diff --git a/configure b/configure +index 5f92bac..8b300a4 100755 +--- a/configure ++++ b/configure +@@ -808,6 +808,7 @@ case "$target" in + i[3456]86-*-gnu*) arch=i386; system=gnu;; + i[3456]86-*-mingw*) arch=i386; system=mingw;; + powerpc64-*-linux*) arch=power64; model=ppc64; system=elf;; ++ powerpc64le-*-linux*) arch=power64le; model=ppc64le; system=elf;; + powerpc*-*-linux*) arch=power; model=ppc; system=elf;; + powerpc-*-netbsd*) arch=power; model=ppc; system=elf;; + powerpc-*-openbsd*) arch=power; model=ppc; system=bsd_elf;; +@@ -889,6 +890,8 @@ case "$arch,$system" in + aspp="${TOOLPREF}gcc -c";; + power64,*,elf) as='${TOOLPREF}as -u -m ppc64' + aspp='${TOOLPREF}gcc -c';; ++ power64le,*,elf) as='${TOOLPREF}as -u -m ppc64' ++ aspp='${TOOLPREF}gcc -c';; + power,rhapsody) as="${TOOLPREF}as -arch $model" + aspp="$bytecc -c";; + sparc,solaris) as="${TOOLPREF}as" +-- +1.9.0 + diff --git a/0007-yacc-Use-mkstemp-instead-of-mktemp.patch b/0007-yacc-Use-mkstemp-instead-of-mktemp.patch deleted file mode 100644 index 0a2c140..0000000 --- a/0007-yacc-Use-mkstemp-instead-of-mktemp.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 761242718c3a7513d3b93ca96d24d1f61a4126f0 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Fri, 13 Sep 2013 21:29:58 +0100 -Subject: [PATCH 07/14] yacc: Use mkstemp instead of mktemp. - ---- - yacc/main.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/yacc/main.c b/yacc/main.c -index f6cac60..3067000 100644 ---- a/yacc/main.c -+++ b/yacc/main.c -@@ -53,7 +53,7 @@ char *text_file_name; - char *union_file_name; - char *verbose_file_name; - --#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) || (__APPLE__) -+#if defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) || (__APPLE__) - #define HAVE_MKSTEMP - #endif - --- -1.9.0 - diff --git a/0008-Port-to-the-ARM-64-bits-AArch64-architecture-experim.patch b/0008-Port-to-the-ARM-64-bits-AArch64-architecture-experim.patch deleted file mode 100644 index da6b5e3..0000000 --- a/0008-Port-to-the-ARM-64-bits-AArch64-architecture-experim.patch +++ /dev/null @@ -1,2280 +0,0 @@ -From a1297100a7898223fd9cdf3d37c4136376ee8f88 Mon Sep 17 00:00:00 2001 -From: Xavier Leroy -Date: Thu, 18 Jul 2013 16:09:20 +0000 -Subject: [PATCH 08/14] Port to the ARM 64-bits (AArch64) architecture - (experimental). Merge of branch branches/arm64. - -git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@13909 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02 -(cherry picked from commit 055d5c0379e42b4f561cb1fc5159659d8e9a7b6f) ---- - asmcomp/arm64/arch.ml | 146 ++++++++ - asmcomp/arm64/emit.mlp | 742 +++++++++++++++++++++++++++++++++++++++ - asmcomp/arm64/proc.ml | 212 +++++++++++ - asmcomp/arm64/reload.ml | 16 + - asmcomp/arm64/scheduling.ml | 18 + - asmcomp/arm64/selection.ml | 265 ++++++++++++++ - asmcomp/compilenv.ml | 9 + - asmcomp/compilenv.mli | 4 + - asmrun/arm64.S | 535 ++++++++++++++++++++++++++++ - asmrun/signals_osdep.h | 19 + - asmrun/stack.h | 5 + - byterun/interp.c | 6 + - configure | 5 +- - otherlibs/num/bng.c | 6 +- - otherlibs/num/bng_arm64.c | 20 ++ - testsuite/tests/asmcomp/Makefile | 2 +- - testsuite/tests/asmcomp/arm64.S | 52 +++ - testsuite/tests/asmcomp/main.ml | 1 + - 18 files changed, 2057 insertions(+), 6 deletions(-) - create mode 100644 asmcomp/arm64/arch.ml - create mode 100644 asmcomp/arm64/emit.mlp - create mode 100644 asmcomp/arm64/proc.ml - create mode 100644 asmcomp/arm64/reload.ml - create mode 100644 asmcomp/arm64/scheduling.ml - create mode 100644 asmcomp/arm64/selection.ml - create mode 100644 asmrun/arm64.S - create mode 100644 otherlibs/num/bng_arm64.c - create mode 100644 testsuite/tests/asmcomp/arm64.S - -diff --git a/asmcomp/arm64/arch.ml b/asmcomp/arm64/arch.ml -new file mode 100644 -index 0000000..a53251f ---- /dev/null -+++ b/asmcomp/arm64/arch.ml -@@ -0,0 +1,146 @@ -+(***********************************************************************) -+(* *) -+(* OCaml *) -+(* *) -+(* Xavier Leroy, projet Gallium, INRIA Rocquencourt *) -+(* Benedikt Meurer, University of Siegen *) -+(* *) -+(* Copyright 2013 Institut National de Recherche en Informatique *) -+(* et en Automatique. Copyright 2012 Benedikt Meurer. All rights *) -+(* reserved. This file is distributed under the terms of the Q *) -+(* Public License version 1.0. *) -+(* *) -+(***********************************************************************) -+ -+let command_line_options = [] -+ -+(* Specific operations for the ARM processor, 64-bit mode *) -+ -+open Format -+ -+let command_line_options = [] -+ -+(* Addressing modes *) -+ -+type addressing_mode = -+ | Iindexed of int (* reg + displ *) -+ | Ibased of string * int (* global var + displ *) -+ -+(* We do not support the reg + shifted reg addressing mode, because -+ what we really need is reg + shifted reg + displ, -+ and this is decomposed in two instructions (reg + shifted reg -> tmp, -+ then addressing tmp + displ). *) -+ -+(* Specific operations *) -+ -+type specific_operation = -+ | Ishiftarith of arith_operation * int -+ | Ishiftcheckbound of int -+ | Imuladd (* multiply and add *) -+ | Imulsub (* multiply and subtract *) -+ | Inegmulf (* floating-point negate and multiply *) -+ | Imuladdf (* floating-point multiply and add *) -+ | Inegmuladdf (* floating-point negate, multiply and add *) -+ | Imulsubf (* floating-point multiply and subtract *) -+ | Inegmulsubf (* floating-point negate, multiply and subtract *) -+ | Isqrtf (* floating-point square root *) -+ | Ibswap of int (* endianess conversion *) -+ -+and arith_operation = -+ Ishiftadd -+ | Ishiftsub -+ -+(* Sizes, endianness *) -+ -+let big_endian = false -+ -+let size_addr = 8 -+let size_int = 8 -+let size_float = 8 -+ -+let allow_unaligned_access = false -+ -+(* Behavior of division *) -+ -+let division_crashes_on_overflow = false -+ -+(* Operations on addressing modes *) -+ -+let identity_addressing = Iindexed 0 -+ -+let offset_addressing addr delta = -+ match addr with -+ | Iindexed n -> Iindexed(n + delta) -+ | Ibased(s, n) -> Ibased(s, n + delta) -+ -+let num_args_addressing = function -+ | Iindexed n -> 1 -+ | Ibased(s, n) -> 0 -+ -+(* Printing operations and addressing modes *) -+ -+let print_addressing printreg addr ppf arg = -+ match addr with -+ | Iindexed n -> -+ printreg ppf arg.(0); -+ if n <> 0 then fprintf ppf " + %i" n -+ | Ibased(s, 0) -> -+ fprintf ppf "\"%s\"" s -+ | Ibased(s, n) -> -+ fprintf ppf "\"%s\" + %i" s n -+ -+let print_specific_operation printreg op ppf arg = -+ match op with -+ | Ishiftarith(op, shift) -> -+ let op_name = function -+ | Ishiftadd -> "+" -+ | Ishiftsub -> "-" in -+ let shift_mark = -+ if shift >= 0 -+ then sprintf "<< %i" shift -+ else sprintf ">> %i" (-shift) in -+ fprintf ppf "%a %s %a %s" -+ 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) -+ | Imuladd -> -+ fprintf ppf "(%a * %a) + %a" -+ printreg arg.(0) -+ printreg arg.(1) -+ printreg arg.(2) -+ | Imulsub -> -+ fprintf ppf "-(%a * %a) + %a" -+ printreg arg.(0) -+ printreg arg.(1) -+ printreg arg.(2) -+ | Inegmulf -> -+ fprintf ppf "-f (%a *f %a)" -+ printreg arg.(0) -+ printreg arg.(1) -+ | Imuladdf -> -+ fprintf ppf "%a +f (%a *f %a)" -+ printreg arg.(0) -+ printreg arg.(1) -+ printreg arg.(2) -+ | Inegmuladdf -> -+ fprintf ppf "(-f %a) -f (%a *f %a)" -+ printreg arg.(0) -+ printreg arg.(1) -+ printreg arg.(2) -+ | Imulsubf -> -+ fprintf ppf "%a -f (%a *f %a)" -+ printreg arg.(0) -+ printreg arg.(1) -+ printreg arg.(2) -+ | Inegmulsubf -> -+ fprintf ppf "(-f %a) +f (%a *f %a)" -+ printreg arg.(0) -+ printreg arg.(1) -+ printreg arg.(2) -+ | Isqrtf -> -+ fprintf ppf "sqrtf %a" -+ printreg arg.(0) -+ | Ibswap n -> -+ fprintf ppf "bswap%i %a" n -+ printreg arg.(0) -+ -diff --git a/asmcomp/arm64/emit.mlp b/asmcomp/arm64/emit.mlp -new file mode 100644 -index 0000000..fc9649c ---- /dev/null -+++ b/asmcomp/arm64/emit.mlp -@@ -0,0 +1,742 @@ -+(***********************************************************************) -+(* *) -+(* OCaml *) -+(* *) -+(* Xavier Leroy, projet Gallium, INRIA Rocquencourt *) -+(* Benedikt Meurer, University of Siegen *) -+(* *) -+(* Copyright 2013 Institut National de Recherche en Informatique *) -+(* et en Automatique. Copyright 2012 Benedikt Meurer. All rights *) -+(* reserved. This file is distributed under the terms of the Q *) -+(* Public License version 1.0. *) -+(* *) -+(***********************************************************************) -+ -+(* Emission of ARM assembly code, 64-bit mode *) -+ -+open Misc -+open Cmm -+open Arch -+open Proc -+open Reg -+open Mach -+open Linearize -+open Emitaux -+ -+(* Tradeoff between code size and code speed *) -+ -+let fastcode_flag = ref true -+ -+(* Names for special regs *) -+ -+let reg_trap_ptr = phys_reg 23 -+let reg_alloc_ptr = phys_reg 24 -+let reg_alloc_limit = phys_reg 25 -+let reg_tmp1 = phys_reg 26 -+let reg_tmp2 = phys_reg 27 -+let reg_x15 = phys_reg 15 -+ -+(* Output a label *) -+ -+let emit_label lbl = -+ emit_string ".L"; emit_int lbl -+ -+let emit_data_label lbl = -+ emit_string ".Ld"; emit_int lbl -+ -+(* Symbols *) -+ -+let emit_symbol s = -+ Emitaux.emit_symbol '$' s -+ -+(* Output a pseudo-register *) -+ -+let emit_reg = function -+ {loc = Reg r} -> emit_string (register_name r) -+ | _ -> fatal_error "Emit.emit_reg" -+ -+(* Likewise, but with the 32-bit name of the register *) -+ -+let int_reg_name_w = -+ [| "w0"; "w1"; "w2"; "w3"; "w4"; "w5"; "w6"; "w7"; -+ "w8"; "w9"; "w10"; "w11"; "w12"; "w13"; "w14"; "w15"; -+ "w19"; "w20"; "w21"; "w22"; "w23"; "w24"; "w25"; -+ "w26"; "w27"; "w28"; "w16"; "w17" |] -+ -+let emit_wreg = function -+ {loc = Reg r} -> emit_string int_reg_name_w.(r) -+ | _ -> fatal_error "Emit.emit_wreg" -+ -+(* Layout of the stack frame *) -+ -+let stack_offset = ref 0 -+ -+let frame_size () = -+ let sz = -+ !stack_offset + -+ 8 * num_stack_slots.(0) + -+ 8 * num_stack_slots.(1) + -+ (if !contains_calls then 8 else 0) -+ in Misc.align sz 16 -+ -+let slot_offset loc cl = -+ match loc with -+ Incoming n -> -+ assert (n >= 0); -+ frame_size() + n -+ | Local n -> -+ !stack_offset + -+ (if cl = 0 -+ then n * 8 -+ else num_stack_slots.(0) * 8 + n * 8) -+ | Outgoing n -> -+ assert (n >= 0); -+ n -+ -+(* Output a stack reference *) -+ -+let emit_stack r = -+ match r.loc with -+ | Stack s -> -+ let ofs = slot_offset s (register_class r) in `[sp, #{emit_int ofs}]` -+ | _ -> fatal_error "Emit.emit_stack" -+ -+(* Output an addressing mode *) -+ -+let emit_symbol_offset s ofs = -+ emit_symbol s; -+ if ofs > 0 then `+{emit_int ofs}` -+ else if ofs < 0 then `-{emit_int (-ofs)}` -+ else () -+ -+let emit_addressing addr r = -+ match addr with -+ | Iindexed ofs -> -+ `[{emit_reg r}, #{emit_int ofs}]` -+ | Ibased(s, ofs) -> -+ `[{emit_reg r}, #:lo12:{emit_symbol_offset s ofs}]` -+ -+(* Record live pointers at call points *) -+ -+let record_frame_label live dbg = -+ let lbl = new_label() in -+ let live_offset = ref [] in -+ Reg.Set.iter -+ (function -+ {typ = Addr; loc = Reg r} -> -+ live_offset := ((r lsl 1) + 1) :: !live_offset -+ | {typ = Addr; loc = Stack s} as reg -> -+ live_offset := slot_offset s (register_class reg) :: !live_offset -+ | _ -> ()) -+ live; -+ frame_descriptors := -+ { fd_lbl = lbl; -+ fd_frame_size = frame_size(); -+ fd_live_offset = !live_offset; -+ fd_debuginfo = dbg } :: !frame_descriptors; -+ lbl -+ -+let record_frame live dbg = -+ let lbl = record_frame_label live dbg in `{emit_label lbl}:` -+ -+(* Record calls to the GC -- we've moved them out of the way *) -+ -+type gc_call = -+ { gc_lbl: label; (* Entry label *) -+ gc_return_lbl: label; (* Where to branch after GC *) -+ gc_frame_lbl: label } (* Label of frame descriptor *) -+ -+let call_gc_sites = ref ([] : gc_call list) -+ -+let emit_call_gc gc = -+ `{emit_label gc.gc_lbl}: bl {emit_symbol "caml_call_gc"}\n`; -+ `{emit_label gc.gc_frame_lbl}: b {emit_label gc.gc_return_lbl}\n` -+ -+(* Record calls to caml_ml_array_bound_error. -+ In debug mode, we maintain one call to caml_ml_array_bound_error -+ per bound check site. Otherwise, we can share a single call. *) -+ -+type bound_error_call = -+ { bd_lbl: label; (* Entry label *) -+ bd_frame_lbl: label } (* Label of frame descriptor *) -+ -+let bound_error_sites = ref ([] : bound_error_call list) -+ -+let bound_error_label dbg = -+ if !Clflags.debug || !bound_error_sites = [] then begin -+ let lbl_bound_error = new_label() in -+ let lbl_frame = record_frame_label Reg.Set.empty dbg in -+ bound_error_sites := -+ { bd_lbl = lbl_bound_error; -+ bd_frame_lbl = lbl_frame } :: !bound_error_sites; -+ lbl_bound_error -+ end else begin -+ let bd = List.hd !bound_error_sites in bd.bd_lbl -+ end -+ -+let emit_call_bound_error bd = -+ `{emit_label bd.bd_lbl}: bl {emit_symbol "caml_ml_array_bound_error"}\n`; -+ `{emit_label bd.bd_frame_lbl}:\n` -+ -+(* Names of various instructions *) -+ -+let name_for_comparison = function -+ | Isigned Ceq -> "eq" | Isigned Cne -> "ne" | Isigned Cle -> "le" -+ | Isigned Cge -> "ge" | Isigned Clt -> "lt" | Isigned Cgt -> "gt" -+ | Iunsigned Ceq -> "eq" | Iunsigned Cne -> "ne" | Iunsigned Cle -> "ls" -+ | Iunsigned Cge -> "cs" | Iunsigned Clt -> "cc" | Iunsigned Cgt -> "hi" -+ -+let name_for_int_operation = function -+ | Iadd -> "add" -+ | Isub -> "sub" -+ | Imul -> "mul" -+ | Idiv -> "sdiv" -+ | Iand -> "and" -+ | Ior -> "orr" -+ | Ixor -> "eor" -+ | Ilsl -> "lsl" -+ | Ilsr -> "lsr" -+ | Iasr -> "asr" -+ | _ -> assert false -+ -+(* Load an integer constant into a register *) -+ -+let emit_intconst dst n = -+ let rec emit_pos first shift = -+ if shift < 0 then begin -+ if first then ` mov {emit_reg dst}, xzr\n` -+ end else begin -+ let s = Nativeint.(logand (shift_right_logical n shift) 0xFFFFn) in -+ if s = 0n then emit_pos first (shift - 16) else begin -+ if first then -+ ` movz {emit_reg dst}, #{emit_nativeint s}, lsl #{emit_int shift}\n` -+ else -+ ` movk {emit_reg dst}, #{emit_nativeint s}, lsl #{emit_int shift}\n`; -+ emit_pos false (shift - 16) -+ end -+ end -+ and emit_neg first shift = -+ if shift < 0 then begin -+ if first then ` movn {emit_reg dst}, #0\n` -+ end else begin -+ let s = Nativeint.(logand (shift_right_logical n shift) 0xFFFFn) in -+ if s = 0xFFFFn then emit_neg first (shift - 16) else begin -+ if first then -+ ` movn {emit_reg dst}, #{emit_nativeint (Nativeint.logxor s 0xFFFFn)}, lsl #{emit_int shift}\n` -+ else -+ ` movk {emit_reg dst}, #{emit_nativeint s}, lsl #{emit_int shift}\n`; -+ emit_neg false (shift - 16) -+ end -+ end -+ in -+ if n < 0n then emit_neg true 48 else emit_pos true 48 -+ -+(* 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" *) -+ -+let is_immediate_float bits = -+ let exp = (Int64.(to_int (shift_right_logical bits 52)) land 0x7FF) - 1023 in -+ let mant = Int64.logand bits 0xF_FFFF_FFFF_FFFFL in -+ exp >= -3 && exp <= 4 && Int64.logand mant 0xF_0000_0000_0000L = mant -+ -+(* Adjust sp (up or down) by the given byte amount *) -+ -+let emit_stack_adjustment n = -+ let instr = if n < 0 then "sub" else "add" in -+ let m = abs n in -+ assert (m < 0x1_000_000); -+ let ml = m land 0xFFF and mh = m land 0xFFF_000 in -+ if mh <> 0 then ` {emit_string instr} sp, sp, #{emit_int mh}\n`; -+ if ml <> 0 then ` {emit_string instr} sp, sp, #{emit_int ml}\n`; -+ if n <> 0 then cfi_adjust_cfa_offset (-n) -+ -+(* Deallocate the stack frame and reload the return address -+ before a return or tail call *) -+ -+let output_epilogue f = -+ let n = frame_size() in -+ if !contains_calls then -+ ` ldr x30, [sp, #{emit_int (n-8)}]\n`; -+ if n > 0 then -+ emit_stack_adjustment n; -+ f(); -+ (* reset CFA back because function body may continue *) -+ if n > 0 then cfi_adjust_cfa_offset n -+ -+(* Name of current function *) -+let function_name = ref "" -+(* Entry point for tail recursive calls *) -+let tailrec_entry_point = ref 0 -+(* Pending floating-point literals *) -+let float_literals = ref ([] : (int64 * label) list) -+ -+(* Label a floating-point literal *) -+let float_literal f = -+ try -+ List.assoc f !float_literals -+ with Not_found -> -+ let lbl = new_label() in -+ float_literals := (f, lbl) :: !float_literals; -+ lbl -+ -+(* Emit all pending literals *) -+let emit_literals() = -+ if !float_literals <> [] then begin -+ ` .align 3\n`; -+ List.iter -+ (fun (f, lbl) -> -+ `{emit_label lbl}: .quad `; emit_printf "0x%Lx\n" f) -+ !float_literals; -+ float_literals := [] -+ end -+ -+(* Emit code to load the address of a symbol *) -+ -+let emit_load_symbol_addr dst s = -+ if (not !Clflags.dlcode) || Compilenv.symbol_in_current_unit s then begin -+ ` adrp {emit_reg dst}, {emit_symbol s}\n`; -+ ` add {emit_reg dst}, {emit_reg dst}, #:lo12:{emit_symbol s}\n` -+ end else begin -+ ` adrp {emit_reg dst}, :got:{emit_symbol s}\n`; -+ ` ldr {emit_reg dst}, [{emit_reg dst}, #:got_lo12:{emit_symbol s}]\n` -+ end -+ -+(* Output the assembly code for an instruction *) -+ -+let emit_instr i = -+ emit_debug_info i.dbg; -+ match i.desc with -+ | Lend -> () -+ | Lop(Imove | Ispill | Ireload) -> -+ let src = i.arg.(0) and dst = i.res.(0) in -+ if src.loc <> dst.loc then begin -+ match (src, dst) with -+ | {loc = Reg _; typ = Float}, {loc = Reg _} -> -+ ` fmov {emit_reg dst}, {emit_reg src}\n` -+ | {loc = Reg _}, {loc = Reg _} -> -+ ` mov {emit_reg dst}, {emit_reg src}\n` -+ | {loc = Reg _}, {loc = Stack _} -> -+ ` str {emit_reg src}, {emit_stack dst}\n` -+ | {loc = Stack _}, {loc = Reg _} -> -+ ` ldr {emit_reg dst}, {emit_stack src}\n` -+ | _ -> -+ assert false -+ end -+ | Lop(Iconst_int n) -> -+ emit_intconst i.res.(0) n -+ | Lop(Iconst_float f) -> -+ let b = Int64.bits_of_float(float_of_string f) in -+ if b = 0L then -+ ` fmov {emit_reg i.res.(0)}, xzr /* {emit_string f} */\n` -+ else if is_immediate_float b then -+ ` fmov {emit_reg i.res.(0)}, #{emit_printf "0x%Lx" b} /* {emit_string f} */\n` -+ else begin -+ let lbl = float_literal b in -+ ` adrp {emit_reg reg_tmp1}, {emit_label lbl}\n`; -+ ` ldr {emit_reg i.res.(0)}, [{emit_reg reg_tmp1}, #:lo12:{emit_label lbl}] /* {emit_string f} */\n` -+ end -+ | Lop(Iconst_symbol s) -> -+ emit_load_symbol_addr i.res.(0) s -+ | Lop(Icall_ind) -> -+ ` blr {emit_reg i.arg.(0)}\n`; -+ `{record_frame i.live i.dbg}\n` -+ | Lop(Icall_imm s) -> -+ ` bl {emit_symbol s}\n`; -+ `{record_frame i.live i.dbg}\n` -+ | Lop(Itailcall_ind) -> -+ output_epilogue (fun () -> ` br {emit_reg i.arg.(0)}\n`) -+ | Lop(Itailcall_imm s) -> -+ if s = !function_name then -+ ` b {emit_label !tailrec_entry_point}\n` -+ else -+ output_epilogue (fun () -> ` b {emit_symbol s}\n`) -+ | Lop(Iextcall(s, false)) -> -+ ` bl {emit_symbol s}\n` -+ | Lop(Iextcall(s, true)) -> -+ emit_load_symbol_addr reg_x15 s; -+ ` bl {emit_symbol "caml_c_call"}\n`; -+ `{record_frame i.live i.dbg}\n` -+ | Lop(Istackoffset n) -> -+ assert (n mod 16 = 0); -+ emit_stack_adjustment (-n); -+ stack_offset := !stack_offset + n -+ | Lop(Iload(size, addr)) -> -+ let dst = i.res.(0) in -+ let base = -+ match addr with -+ | Iindexed ofs -> i.arg.(0) -+ | Ibased(s, ofs) -> -+ ` adrp {emit_reg reg_tmp1}, {emit_symbol_offset s ofs}\n`; -+ reg_tmp1 in -+ begin match size with -+ | Byte_unsigned -> -+ ` ldrb {emit_wreg dst}, {emit_addressing addr base}\n` -+ | Byte_signed -> -+ ` ldrsb {emit_reg dst}, {emit_addressing addr base}\n` -+ | Sixteen_unsigned -> -+ ` ldrh {emit_wreg dst}, {emit_addressing addr base}\n` -+ | Sixteen_signed -> -+ ` ldrsh {emit_reg dst}, {emit_addressing addr base}\n` -+ | Thirtytwo_unsigned -> -+ ` ldr {emit_wreg dst}, {emit_addressing addr base}\n` -+ | Thirtytwo_signed -> -+ ` ldrsw {emit_reg dst}, {emit_addressing addr base}\n` -+ | Single -> -+ ` ldr s7, {emit_addressing addr base}\n`; -+ ` fcvt {emit_reg dst}, s7\n` -+ | Word | Double | Double_u -> -+ ` ldr {emit_reg dst}, {emit_addressing addr base}\n` -+ end -+ | Lop(Istore(size, addr)) -> -+ let src = i.arg.(0) in -+ let base = -+ match addr with -+ | Iindexed ofs -> i.arg.(1) -+ | Ibased(s, ofs) -> -+ ` adrp {emit_reg reg_tmp1}, {emit_symbol_offset s ofs}\n`; -+ reg_tmp1 in -+ begin match size with -+ | Byte_unsigned | Byte_signed -> -+ ` strb {emit_wreg src}, {emit_addressing addr base}\n` -+ | Sixteen_unsigned | Sixteen_signed -> -+ ` strh {emit_wreg src}, {emit_addressing addr base}\n` -+ | Thirtytwo_unsigned | Thirtytwo_signed -> -+ ` str {emit_wreg src}, {emit_addressing addr base}\n` -+ | Single -> -+ ` fcvt s7, {emit_reg src}\n`; -+ ` str s7, {emit_addressing addr base}\n`; -+ | Word | Double | Double_u -> -+ ` 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 -+ | 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` -+ | Lop(Iintop_imm(Icomp cmp, n)) -> -+ ` cmp {emit_reg i.arg.(0)}, #{emit_int n}\n`; -+ ` cset {emit_reg i.res.(0)}, {emit_string (name_for_comparison cmp)}\n` -+ | Lop(Iintop Icheckbound) -> -+ 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(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(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(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` -+ | Lop(Iintop_imm(Idiv, n)) -> (* n is a power of 2 *) -+ let l = Misc.log2 n in -+ ` asr {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, #63\n`; -+ ` add {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, {emit_reg reg_tmp1}, lsr {emit_int (64-l)}\n`; -+ ` asr {emit_reg i.res.(0)}, {emit_reg reg_tmp1}, {emit_int l}\n` -+ | Lop(Iintop_imm(Imod, n)) -> (* n is a power of 2 *) -+ let l = Misc.log2 n in -+ ` asr {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, #63\n`; -+ ` add {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, {emit_reg reg_tmp1}, lsr {emit_int (64-l)}\n`; -+ ` asr {emit_reg reg_tmp1}, {emit_reg reg_tmp1}, {emit_int l}\n`; -+ ` sub {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg reg_tmp1}, lsl {emit_int l}\n` -+ | Lop(Iintop op) -> -+ let instr = name_for_int_operation op in -+ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n` -+ | Lop(Iintop_imm(op, n)) -> -+ let instr = name_for_int_operation op in -+ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, #{emit_int n}\n` -+ | Lop(Ifloatofint | Iintoffloat | Iabsf | Inegf | Ispecific Isqrtf as op) -> -+ let instr = (match op with -+ | Ifloatofint -> "scvtf" -+ | Iintoffloat -> "fcvtzs" -+ | Iabsf -> "fabs" -+ | Inegf -> "fneg" -+ | Ispecific Isqrtf -> "fsqrt" -+ | _ -> assert false) in -+ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}\n` -+ | Lop(Iaddf | Isubf | Imulf | Idivf | Ispecific Inegmulf as op) -> -+ let instr = (match op with -+ | Iaddf -> "fadd" -+ | Isubf -> "fsub" -+ | Imulf -> "fmul" -+ | Idivf -> "fdiv" -+ | Ispecific Inegmulf -> "fnmul" -+ | _ -> assert false) in -+ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n` -+ | Lop(Ispecific(Imuladdf | Inegmuladdf | Imulsubf | Inegmulsubf as op)) -> -+ let instr = (match op with -+ | Imuladdf -> "fmadd" -+ | Inegmuladdf -> "fnmadd" -+ | Imulsubf -> "fmsub" -+ | Inegmulsubf -> "fnmsub" -+ | _ -> assert false) in -+ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(2)}, {emit_reg i.arg.(0)}\n` -+ | Lop(Ispecific(Ishiftarith(op, shift))) -> -+ let instr = (match op with -+ Ishiftadd -> "add" -+ | Ishiftsub -> "sub") in -+ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}`; -+ if shift >= 0 -+ then `, lsl #{emit_int shift}\n` -+ else `, asr #{emit_int (-shift)}\n` -+ | Lop(Ispecific(Imuladd | Imulsub as op)) -> -+ let instr = (match op with -+ Imuladd -> "madd" -+ | Imulsub -> "msub" -+ | _ -> assert false) in -+ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(2)}\n` -+ | Lop(Ispecific(Ibswap size)) -> -+ begin match size with -+ | 16 -> -+ ` rev16 {emit_wreg i.res.(0)}, {emit_wreg i.arg.(0)}\n`; -+ ` ubfm {emit_reg i.res.(0)}, {emit_reg i.res.(0)}, #0, #16\n` -+ | 32 -> -+ ` rev {emit_wreg i.res.(0)}, {emit_wreg i.arg.(0)}\n` -+ | 64 -> -+ ` rev {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}\n` -+ | _ -> -+ assert false -+ end -+ | Lreloadretaddr -> -+ () -+ | Lreturn -> -+ output_epilogue (fun () -> ` ret\n`) -+ | Llabel lbl -> -+ `{emit_label lbl}:\n` -+ | Lbranch lbl -> -+ ` b {emit_label lbl}\n` -+ | Lcondbranch(tst, lbl) -> -+ begin match tst with -+ | Itruetest -> -+ ` cbnz {emit_reg i.arg.(0)}, {emit_label lbl}\n` -+ | Ifalsetest -> -+ ` cbz {emit_reg i.arg.(0)}, {emit_label lbl}\n` -+ | Iinttest cmp -> -+ ` cmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; -+ let comp = name_for_comparison cmp in -+ ` b.{emit_string comp} {emit_label lbl}\n` -+ | Iinttest_imm(cmp, n) -> -+ ` cmp {emit_reg i.arg.(0)}, #{emit_int n}\n`; -+ let comp = name_for_comparison cmp in -+ ` b.{emit_string comp} {emit_label lbl}\n` -+ | Ifloattest(cmp, neg) -> -+ let comp = (match (cmp, neg) with -+ | (Ceq, false) | (Cne, true) -> "eq" -+ | (Cne, false) | (Ceq, true) -> "ne" -+ | (Clt, false) -> "cc" -+ | (Clt, true) -> "cs" -+ | (Cle, false) -> "ls" -+ | (Cle, true) -> "hi" -+ | (Cgt, false) -> "gt" -+ | (Cgt, true) -> "le" -+ | (Cge, false) -> "ge" -+ | (Cge, true) -> "lt") in -+ ` fcmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; -+ ` b.{emit_string comp} {emit_label lbl}\n` -+ | Ioddtest -> -+ ` tbnz {emit_reg i.arg.(0)}, #0, {emit_label lbl}\n` -+ | Ieventest -> -+ ` tbz {emit_reg i.arg.(0)}, #0, {emit_label lbl}\n` -+ end -+ | Lcondbranch3(lbl0, lbl1, lbl2) -> -+ ` cmp {emit_reg i.arg.(0)}, #1\n`; -+ begin match lbl0 with -+ None -> () -+ | Some lbl -> ` b.lt {emit_label lbl}\n` -+ end; -+ begin match lbl1 with -+ None -> () -+ | Some lbl -> ` b.eq {emit_label lbl}\n` -+ end; -+ begin match lbl2 with -+ None -> () -+ | Some lbl -> ` b.gt {emit_label lbl}\n` -+ end -+ | Lswitch jumptbl -> -+ let lbltbl = new_label() in -+ ` adr {emit_reg reg_tmp1}, {emit_label lbltbl}\n`; -+ ` add {emit_reg reg_tmp1}, {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, lsl #2\n`; -+ ` br {emit_reg reg_tmp1}\n`; -+ `{emit_label lbltbl}:`; -+ for j = 0 to Array.length jumptbl - 1 do -+ ` b {emit_label jumptbl.(j)}\n` -+ done -+(* Alternative: -+ let lbltbl = new_label() in -+ ` adr {emit_reg reg_tmp1}, {emit_label lbltbl}\n`; -+ ` ldr {emit_wreg reg_tmp2}, [{emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, lsl #2]\n`; -+ ` add {emit_reg reg_tmp1}, {emit_wreg reg_tmp2}, sxtb\n`; -+ ` br {emit_reg reg_tmp1}\n`; -+ `{emit_label lbltbl}:\n`; -+ for j = 0 to Array.length jumptbl - 1 do -+ ` .word {emit_label jumptbl.(j)} - {emit_label lbltbl}\n` -+ done -+*) -+ | Lsetuptrap lbl -> -+ let lblnext = new_label() in -+ ` adr {emit_reg reg_tmp1}, {emit_label lblnext}\n`; -+ ` b {emit_label lbl}\n`; -+ `{emit_label lblnext}:\n` -+ | Lpushtrap -> -+ stack_offset := !stack_offset + 16; -+ ` str {emit_reg reg_trap_ptr}, [sp, -16]!\n`; -+ ` str {emit_reg reg_tmp1}, [sp, #8]\n`; -+ cfi_adjust_cfa_offset 16; -+ ` mov {emit_reg reg_trap_ptr}, sp\n` -+ | Lpoptrap -> -+ ` ldr {emit_reg reg_trap_ptr}, [sp], 16\n`; -+ cfi_adjust_cfa_offset (-16); -+ stack_offset := !stack_offset - 16 -+ | Lraise -> -+ if !Clflags.debug then begin -+ ` bl {emit_symbol "caml_raise_exn"}\n`; -+ `{record_frame Reg.Set.empty i.dbg}\n` -+ end else begin -+ ` mov sp, {emit_reg reg_trap_ptr}\n`; -+ ` ldr {emit_reg reg_tmp1}, [sp, #8]\n`; -+ ` ldr {emit_reg reg_trap_ptr}, [sp], 16\n`; -+ ` br {emit_reg reg_tmp1}\n` -+ end -+ -+(* Emission of an instruction sequence *) -+ -+let rec emit_all i = -+ if i.desc = Lend then () else (emit_instr i; emit_all i.next) -+ -+(* Emission of the profiling prelude *) -+ -+let emit_profile() = () (* TODO *) -+(* -+ match Config.system with -+ "linux_eabi" | "linux_eabihf" -> -+ ` push \{lr}\n`; -+ ` {emit_call "__gnu_mcount_nc"}\n` -+ | _ -> () -+*) -+ -+(* Emission of a function declaration *) -+ -+let fundecl fundecl = -+ function_name := fundecl.fun_name; -+ fastcode_flag := fundecl.fun_fast; -+ tailrec_entry_point := new_label(); -+ float_literals := []; -+ stack_offset := 0; -+ call_gc_sites := []; -+ bound_error_sites := []; -+ ` .text\n`; -+ ` .align 2\n`; -+ ` .globl {emit_symbol fundecl.fun_name}\n`; -+ ` .type {emit_symbol fundecl.fun_name}, %function\n`; -+ `{emit_symbol fundecl.fun_name}:\n`; -+ emit_debug_info fundecl.fun_dbg; -+ cfi_startproc(); -+ if !Clflags.gprofile then emit_profile(); -+ let n = frame_size() in -+ if n > 0 then -+ emit_stack_adjustment (-n); -+ if !contains_calls then -+ ` str x30, [sp, #{emit_int (n-8)}]\n`; -+ `{emit_label !tailrec_entry_point}:\n`; -+ emit_all fundecl.fun_body; -+ List.iter emit_call_gc !call_gc_sites; -+ List.iter emit_call_bound_error !bound_error_sites; -+ cfi_endproc(); -+ ` .type {emit_symbol fundecl.fun_name}, %function\n`; -+ ` .size {emit_symbol fundecl.fun_name}, .-{emit_symbol fundecl.fun_name}\n`; -+ emit_literals() -+ -+(* Emission of data *) -+ -+let emit_item = function -+ | Cglobal_symbol s -> ` .globl {emit_symbol s}\n`; -+ | Cdefine_symbol s -> `{emit_symbol s}:\n` -+ | Cdefine_label lbl -> `{emit_data_label lbl}:\n` -+ | Cint8 n -> ` .byte {emit_int n}\n` -+ | Cint16 n -> ` .short {emit_int n}\n` -+ | Cint32 n -> ` .long {emit_nativeint n}\n` -+ | Cint n -> ` .quad {emit_nativeint n}\n` -+ | Csingle f -> emit_float32_directive ".long" f -+ | Cdouble f -> emit_float64_directive ".quad" f -+ | Csymbol_address s -> ` .quad {emit_symbol s}\n` -+ | Clabel_address lbl -> ` .quad {emit_data_label lbl}\n` -+ | Cstring s -> emit_string_directive " .ascii " s -+ | Cskip n -> if n > 0 then ` .space {emit_int n}\n` -+ | Calign n -> ` .align {emit_int(Misc.log2 n)}\n` -+ -+let data l = -+ ` .data\n`; -+ List.iter emit_item l -+ -+(* Beginning / end of an assembly file *) -+ -+let begin_assembly() = -+ reset_debug_info(); -+ let lbl_begin = Compilenv.make_symbol (Some "data_begin") in -+ ` .data\n`; -+ ` .globl {emit_symbol lbl_begin}\n`; -+ `{emit_symbol lbl_begin}:\n`; -+ let lbl_begin = Compilenv.make_symbol (Some "code_begin") in -+ ` .text\n`; -+ ` .globl {emit_symbol lbl_begin}\n`; -+ `{emit_symbol lbl_begin}:\n` -+ -+let end_assembly () = -+ let lbl_end = Compilenv.make_symbol (Some "code_end") in -+ ` .text\n`; -+ ` .globl {emit_symbol lbl_end}\n`; -+ `{emit_symbol lbl_end}:\n`; -+ let lbl_end = Compilenv.make_symbol (Some "data_end") in -+ ` .data\n`; -+ ` .globl {emit_symbol lbl_end}\n`; -+ `{emit_symbol lbl_end}:\n`; -+ ` .long 0\n`; -+ let lbl = Compilenv.make_symbol (Some "frametable") in -+ ` .globl {emit_symbol lbl}\n`; -+ `{emit_symbol lbl}:\n`; -+ emit_frames -+ { efa_label = (fun lbl -> -+ ` .type {emit_label lbl}, %function\n`; -+ ` .quad {emit_label lbl}\n`); -+ efa_16 = (fun n -> ` .short {emit_int n}\n`); -+ efa_32 = (fun n -> ` .long {emit_int32 n}\n`); -+ efa_word = (fun n -> ` .quad {emit_int n}\n`); -+ efa_align = (fun n -> ` .align {emit_int(Misc.log2 n)}\n`); -+ efa_label_rel = (fun lbl ofs -> -+ ` .long {emit_label lbl} - . + {emit_int32 ofs}\n`); -+ efa_def_label = (fun lbl -> `{emit_label lbl}:\n`); -+ efa_string = (fun s -> emit_string_directive " .asciz " s) }; -+ ` .type {emit_symbol lbl}, %object\n`; -+ ` .size {emit_symbol lbl}, .-{emit_symbol lbl}\n`; -+ begin match Config.system with -+ | "linux" -> -+ (* Mark stack as non-executable *) -+ ` .section .note.GNU-stack,\"\",%progbits\n` -+ | _ -> () -+ end -diff --git a/asmcomp/arm64/proc.ml b/asmcomp/arm64/proc.ml -new file mode 100644 -index 0000000..b52c2fd ---- /dev/null -+++ b/asmcomp/arm64/proc.ml -@@ -0,0 +1,212 @@ -+(***********************************************************************) -+(* *) -+(* OCaml *) -+(* *) -+(* Xavier Leroy, projet Gallium, INRIA Rocquencourt *) -+(* Benedikt Meurer, University of Siegen *) -+(* *) -+(* Copyright 2013 Institut National de Recherche en Informatique *) -+(* et en Automatique. Copyright 2012 Benedikt Meurer. All rights *) -+(* reserved. This file is distributed under the terms of the Q *) -+(* Public License version 1.0. *) -+(* *) -+(***********************************************************************) -+ -+(* Description of the ARM processor in 64-bit mode *) -+ -+open Misc -+open Cmm -+open Reg -+open Arch -+open Mach -+ -+(* Instruction selection *) -+ -+let word_addressed = false -+ -+(* Registers available for register allocation *) -+ -+(* Integer register map: -+ x0 - x15 general purpose (caller-save) -+ x16, x17 temporaries (used by call veeners) -+ x18 platform register (reserved) -+ x19 - x25 general purpose (callee-save) -+ x26 trap pointer -+ x27 alloc pointer -+ x28 alloc limit -+ x29 frame pointer -+ x30 return address -+ sp / xzr stack pointer / zero register -+ Floating-point register map: -+ d0 - d7 general purpose (caller-save) -+ d8 - d15 general purpose (callee-save) -+ d16 - d31 generat purpose (caller-save) -+*) -+ -+let int_reg_name = -+ [| "x0"; "x1"; "x2"; "x3"; "x4"; "x5"; "x6"; "x7"; -+ "x8"; "x9"; "x10"; "x11"; "x12"; "x13"; "x14"; "x15"; -+ "x19"; "x20"; "x21"; "x22"; "x23"; "x24"; "x25"; -+ "x26"; "x27"; "x28"; "x16"; "x17" |] -+ -+let float_reg_name = -+ [| "d0"; "d1"; "d2"; "d3"; "d4"; "d5"; "d6"; "d7"; -+ "d8"; "d9"; "d10"; "d11"; "d12"; "d13"; "d14"; "d15"; -+ "d16"; "d17"; "d18"; "d19"; "d20"; "d21"; "d22"; "d23"; -+ "d24"; "d25"; "d26"; "d27"; "d28"; "d29"; "d30"; "d31" |] -+ -+let num_register_classes = 2 -+ -+let register_class r = -+ match r.typ with -+ | (Int | Addr) -> 0 -+ | Float -> 1 -+ -+let num_available_registers = -+ [| 23; 32 |] (* first 23 int regs allocatable; all float regs allocatable *) -+ -+let first_available_register = -+ [| 0; 100 |] -+ -+let register_name r = -+ if r < 100 then int_reg_name.(r) else float_reg_name.(r - 100) -+ -+let rotate_registers = true -+ -+(* Representation of hard registers by pseudo-registers *) -+ -+let hard_int_reg = -+ let v = Array.create 28 Reg.dummy in -+ for i = 0 to 27 do -+ v.(i) <- Reg.at_location Int (Reg i) -+ done; -+ v -+ -+let hard_float_reg = -+ let v = Array.create 32 Reg.dummy in -+ for i = 0 to 31 do -+ v.(i) <- Reg.at_location Float (Reg(100 + i)) -+ done; -+ v -+ -+let all_phys_regs = -+ Array.append hard_int_reg hard_float_reg -+ -+let phys_reg n = -+ if n < 100 then hard_int_reg.(n) else hard_float_reg.(n - 100) -+ -+let reg_x15 = phys_reg 15 -+let reg_d7 = phys_reg 107 -+ -+let stack_slot slot ty = -+ Reg.at_location ty (Stack slot) -+ -+(* Calling conventions *) -+ -+let calling_conventions -+ first_int last_int first_float last_float make_stack arg = -+ let loc = Array.create (Array.length arg) Reg.dummy in -+ let int = ref first_int in -+ let float = ref first_float in -+ let ofs = ref 0 in -+ for i = 0 to Array.length arg - 1 do -+ match arg.(i).typ with -+ Int | Addr as ty -> -+ if !int <= last_int then begin -+ loc.(i) <- phys_reg !int; -+ incr int -+ end else begin -+ loc.(i) <- stack_slot (make_stack !ofs) ty; -+ ofs := !ofs + size_int -+ end -+ | Float -> -+ if !float <= last_float then begin -+ loc.(i) <- phys_reg !float; -+ incr float -+ end else begin -+ loc.(i) <- stack_slot (make_stack !ofs) Float; -+ ofs := !ofs + size_float -+ end -+ done; -+ (loc, Misc.align !ofs 16) (* keep stack 16-aligned *) -+ -+let incoming ofs = Incoming ofs -+let outgoing ofs = Outgoing ofs -+let not_supported ofs = fatal_error "Proc.loc_results: cannot call" -+ -+(* OCaml calling convention: -+ first integer args in r0...r15 -+ first float args in d0...d15 -+ remaining args on stack. -+ Return values in r0...r15 or d0...d15. *) -+ -+let loc_arguments arg = -+ calling_conventions 0 15 100 115 outgoing arg -+let loc_parameters arg = -+ let (loc, _) = calling_conventions 0 15 100 115 incoming arg in loc -+let loc_results res = -+ let (loc, _) = calling_conventions 0 15 100 115 not_supported res in loc -+ -+(* C calling convention: -+ first integer args in r0...r7 -+ first float args in d0...d7 -+ remaining args on stack. -+ Return values in r0...r1 or d0. *) -+ -+let loc_external_arguments arg = -+ calling_conventions 0 7 100 107 outgoing arg -+let loc_external_results res = -+ let (loc, _) = calling_conventions 0 1 100 100 not_supported res in loc -+ -+let loc_exn_bucket = phys_reg 0 -+ -+(* Registers destroyed by operations *) -+ -+let destroyed_at_c_call = -+ (* x19-x28, d8-d15 preserved *) -+ Array.of_list (List.map phys_reg -+ [0;1;2;3;4;5;6;7;8;9;10;11;12;13;14;15; -+ 100;101;102;103;104;105;106;107; -+ 116;117;118;119;120;121;122;123; -+ 124;125;126;127;128;129;130;131]) -+ -+let destroyed_at_oper = function -+ | Iop(Icall_ind | Icall_imm _) | Iop(Iextcall(_, true)) -> -+ all_phys_regs -+ | Iop(Iextcall(_, false)) -> -+ destroyed_at_c_call -+ | Iop(Ialloc _) -> -+ [| reg_x15 |] -+ | Iop(Iintoffloat | Ifloatofint | Iload(Single, _) | Istore(Single, _)) -> -+ [| reg_d7 |] (* d7 / s7 destroyed *) -+ | _ -> [||] -+ -+let destroyed_at_raise = all_phys_regs -+ -+(* Maximal register pressure *) -+ -+let safe_register_pressure = function -+ | Iextcall(_, _) -> 8 -+ | Ialloc _ -> 25 -+ | _ -> 26 -+ -+let max_register_pressure = function -+ | Iextcall(_, _) -> [| 10; 8 |] -+ | Ialloc _ -> [| 25; 32 |] -+ | Iintoffloat | Ifloatofint -+ | Iload(Single, _) | Istore(Single, _) -> [| 26; 31 |] -+ | _ -> [| 26; 32 |] -+ -+(* Layout of the stack *) -+ -+let num_stack_slots = [| 0; 0 |] -+let contains_calls = ref false -+ -+(* Calling the assembler *) -+ -+let assemble_file infile outfile = -+ Ccomp.command (Config.asm ^ " -o " ^ -+ Filename.quote outfile ^ " " ^ Filename.quote infile) -+ -+ -+let init () = () -diff --git a/asmcomp/arm64/reload.ml b/asmcomp/arm64/reload.ml -new file mode 100644 -index 0000000..ff9214e ---- /dev/null -+++ b/asmcomp/arm64/reload.ml -@@ -0,0 +1,16 @@ -+(***********************************************************************) -+(* *) -+(* OCaml *) -+(* *) -+(* Xavier Leroy, projet Gallium, INRIA Rocquencourt *) -+(* *) -+(* Copyright 2013 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. *) -+(* *) -+(***********************************************************************) -+ -+(* Reloading for the ARM 64 bits *) -+ -+let fundecl f = -+ (new Reloadgen.reload_generic)#fundecl f -diff --git a/asmcomp/arm64/scheduling.ml b/asmcomp/arm64/scheduling.ml -new file mode 100644 -index 0000000..cc244be ---- /dev/null -+++ b/asmcomp/arm64/scheduling.ml -@@ -0,0 +1,18 @@ -+(***********************************************************************) -+(* *) -+(* OCaml *) -+(* *) -+(* Xavier Leroy, projet Gallium, INRIA Rocquencourt *) -+(* *) -+(* Copyright 2013 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. *) -+(* *) -+(***********************************************************************) -+ -+let _ = let module M = Schedgen in () (* to create a dependency *) -+ -+(* Scheduling is turned off because the processor schedules dynamically -+ much better than what we could do. *) -+ -+let fundecl f = f -diff --git a/asmcomp/arm64/selection.ml b/asmcomp/arm64/selection.ml -new file mode 100644 -index 0000000..c74b282 ---- /dev/null -+++ b/asmcomp/arm64/selection.ml -@@ -0,0 +1,265 @@ -+(***********************************************************************) -+(* *) -+(* OCaml *) -+(* *) -+(* Xavier Leroy, projet Gallium, INRIA Rocquencourt *) -+(* Benedikt Meurer, University of Siegen *) -+(* *) -+(* Copyright 2013 Institut National de Recherche en Informatique *) -+(* et en Automatique. Copyright 2012 Benedikt Meurer. All rights *) -+(* reserved. This file is distributed under the terms of the Q *) -+(* Public License version 1.0. *) -+(* *) -+(***********************************************************************) -+ -+(* Instruction selection for the ARM processor *) -+ -+open Arch -+open Cmm -+open Mach -+ -+let is_offset chunk n = -+ (n >= -256 && n <= 255) (* 9 bits signed unscaled *) -+|| (n >= 0 && -+ match chunk with (* 12 bits unsigned, scaled by chunk size *) -+ | Byte_unsigned | Byte_signed -> -+ n < 0x1000 -+ | Sixteen_unsigned | Sixteen_signed -> -+ n land 1 = 0 && n lsr 1 < 0x1000 -+ | Thirtytwo_unsigned | Thirtytwo_signed | Single -> -+ n land 3 = 0 && n lsr 2 < 0x1000 -+ | Word | Double | Double_u -> -+ n land 7 = 0 && n lsr 3 < 0x1000) -+ -+(* An automaton to recognize ( 0+1+0* | 1+0+1* ) -+ -+ 0 1 0 -+ / \ / \ / \ -+ \ / \ / \ / -+ -0--> [1] --1--> [2] --0--> [3] -+ / -+ [0] -+ \ -+ -1--> [4] --0--> [5] --1--> [6] -+ / \ / \ / \ -+ \ / \ / \ / -+ 1 0 1 -+ -+The accepting states are 2, 3, 5 and 6. *) -+ -+let auto_table = [| (* accepting?, next on 0, next on 1 *) -+ (* state 0 *) (false, 1, 4); -+ (* state 1 *) (false, 1, 2); -+ (* state 2 *) (true, 3, 2); -+ (* state 3 *) (true, 3, 7); -+ (* state 4 *) (false, 5, 4); -+ (* state 5 *) (true, 5, 6); -+ (* state 6 *) (true, 7, 6); -+ (* state 7 *) (false, 7, 7) (* error state *) -+|] -+ -+let rec run_automata nbits state input = -+ let (acc, next0, next1) = auto_table.(state) in -+ if nbits <= 0 -+ then acc -+ else run_automata (nbits - 1) -+ (if input land 1 = 0 then next0 else next1) -+ (input asr 1) -+ -+(* We are very conservative wrt what ARM64 supports: we don't support -+ repetitions of a 000111000 or 1110000111 pattern, just a single -+ pattern of this kind. *) -+ -+let is_logical_immediate n = -+ n <> 0 && n <> -1 && run_automata 64 0 n -+ -+let is_intconst = function -+ Cconst_int _ -> true -+ | _ -> false -+ -+let inline_ops = -+ [ "sqrt"; "caml_bswap16_direct"; "caml_int32_direct_bswap"; -+ "caml_int64_direct_bswap"; "caml_nativeint_direct_bswap" ] -+ -+let use_direct_addressing symb = -+ (not !Clflags.dlcode) || Compilenv.symbol_in_current_unit symb -+ -+(* Instruction selection *) -+ -+class selector = object(self) -+ -+inherit Selectgen.selector_generic as super -+ -+method is_immediate n = -+ let mn = -n in -+ n land 0xFFF = n || n land 0xFFF_000 = n -+ || mn land 0xFFF = mn || mn land 0xFFF_000 = mn -+ -+method! is_simple_expr = function -+ (* inlined floating-point ops are simple if their arguments are *) -+ | Cop(Cextcall(fn, _, _, _), args) when List.mem fn inline_ops -> -+ List.for_all self#is_simple_expr args -+ | e -> super#is_simple_expr e -+ -+method select_addressing chunk = function -+ | Cop(Cadda, [Cconst_symbol s; Cconst_int n]) -+ when use_direct_addressing s -> -+ (Ibased(s, n), Ctuple []) -+ | Cop(Cadda, [arg; Cconst_int n]) -+ when is_offset chunk n -> -+ (Iindexed n, arg) -+ | Cop(Cadda, [arg1; Cop(Caddi, [arg2; Cconst_int n])]) -+ when is_offset chunk n -> -+ (Iindexed n, Cop(Cadda, [arg1; arg2])) -+ | Cconst_symbol s -+ when use_direct_addressing s -> -+ (Ibased(s, 0), Ctuple []) -+ | arg -> -+ (Iindexed 0, arg) -+ -+method! select_operation op args = -+ match op with -+ (* Integer addition *) -+ | Caddi | Cadda -> -+ begin match args with -+ (* Add immediate *) -+ | [arg; Cconst_int n] | [Cconst_int n; arg] when self#is_immediate n -> -+ ((if n >= 0 then Iintop_imm(Iadd, n) else Iintop_imm(Isub, -n)), -+ [arg]) -+ (* Shift-add *) -+ | [arg1; Cop(Clsl, [arg2; Cconst_int n])] when n > 0 && n < 64 -> -+ (Ispecific(Ishiftarith(Ishiftadd, n)), [arg1; arg2]) -+ | [arg1; Cop(Casr, [arg2; Cconst_int n])] when n > 0 && n < 64 -> -+ (Ispecific(Ishiftarith(Ishiftadd, -n)), [arg1; arg2]) -+ | [Cop(Clsl, [arg1; Cconst_int n]); arg2] when n > 0 && n < 64 -> -+ (Ispecific(Ishiftarith(Ishiftadd, n)), [arg2; arg1]) -+ | [Cop(Casr, [arg1; Cconst_int n]); arg2] when n > 0 && n < 64 -> -+ (Ispecific(Ishiftarith(Ishiftadd, -n)), [arg2; arg1]) -+ (* Multiply-add *) -+ | [arg1; Cop(Cmuli, args2)] | [Cop(Cmuli, args2); arg1] -> -+ begin match self#select_operation Cmuli args2 with -+ | (Iintop_imm(Ilsl, l), [arg3]) -> -+ (Ispecific(Ishiftarith(Ishiftadd, l)), [arg1; arg3]) -+ | (Iintop Imul, [arg3; arg4]) -> -+ (Ispecific Imuladd, [arg3; arg4; arg1]) -+ | _ -> -+ super#select_operation op args -+ end -+ | _ -> -+ super#select_operation op args -+ end -+ (* Integer subtraction *) -+ | Csubi | Csuba -> -+ begin match args with -+ (* Sub immediate *) -+ | [arg; Cconst_int n] when self#is_immediate n -> -+ ((if n >= 0 then Iintop_imm(Isub, n) else Iintop_imm(Iadd, -n)), -+ [arg]) -+ (* Shift-sub *) -+ | [arg1; Cop(Clsl, [arg2; Cconst_int n])] when n > 0 && n < 64 -> -+ (Ispecific(Ishiftarith(Ishiftsub, n)), [arg1; arg2]) -+ | [arg1; Cop(Casr, [arg2; Cconst_int n])] when n > 0 && n < 64 -> -+ (Ispecific(Ishiftarith(Ishiftsub, -n)), [arg1; arg2]) -+ (* Multiply-sub *) -+ | [arg1; Cop(Cmuli, args2)] -> -+ begin match self#select_operation Cmuli args2 with -+ | (Iintop_imm(Ilsl, l), [arg3]) -> -+ (Ispecific(Ishiftarith(Ishiftsub, l)), [arg1; arg3]) -+ | (Iintop Imul, [arg3; arg4]) -> -+ (Ispecific Imulsub, [arg3; arg4; arg1]) -+ | _ -> -+ super#select_operation op args -+ end -+ | _ -> -+ super#select_operation op args -+ end -+ (* Checkbounds *) -+ | Ccheckbound _ -> -+ begin match args with -+ | [Cop(Clsr, [arg1; Cconst_int n]); arg2] when n > 0 && n < 64 -> -+ (Ispecific(Ishiftcheckbound n), [arg1; arg2]) -+ | _ -> -+ super#select_operation op args -+ end -+ (* Integer multiplication *) -+ (* ARM does not support immediate operands for multiplication *) -+ | Cmuli -> -+ begin match args with -+ | [arg; Cconst_int n] | [Cconst_int n; arg] -> -+ let l = Misc.log2 n in -+ if n = 1 lsl l -+ then (Iintop_imm(Ilsl, l), [arg]) -+ else (Iintop Imul, args) -+ | _ -> -+ (Iintop Imul, args) -+ end -+ (* Division and modulus *) -+ (* Recognize (x / cst) and (x % cst) only if cst is a power of 2. *) -+ | Cdivi -> -+ begin match args with -+ | [arg; Cconst_int n] when n = 1 lsl Misc.log2 n -> -+ ((if n = 1 then Imove else Iintop_imm(Idiv, n)), [arg]) -+ | _ -> -+ (Iintop Idiv, args) -+ end -+ | Cmodi -> -+ begin match args with -+ | [arg; Cconst_int n] when n = 1 lsl Misc.log2 n -> -+ ((if n = 1 then Iconst_int 0n else Iintop_imm(Imod, n)), [arg]) -+ | _ -> -+ (Iintop Imod, args) -+ end -+ (* Bitwise logical operations have a different range of immediate -+ operands than the other instructions *) -+ | Cand -> self#select_logical Iand args -+ | Cor -> self#select_logical Ior args -+ | Cxor -> self#select_logical Ixor args -+ (* Recognize floating-point negate and multiply *) -+ | Cnegf -> -+ begin match args with -+ | [Cop(Cmulf, args)] -> (Ispecific Inegmulf, args) -+ | _ -> super#select_operation op args -+ end -+ (* Recognize floating-point multiply and add/sub *) -+ | Caddf -> -+ begin match args with -+ | [arg; Cop(Cmulf, args)] | [Cop(Cmulf, args); arg] -> -+ (Ispecific Imuladdf, arg :: args) -+ | _ -> -+ super#select_operation op args -+ end -+ | Csubf -> -+ begin match args with -+ | [arg; Cop(Cmulf, args)] -> -+ (Ispecific Imulsubf, arg :: args) -+ | [Cop(Cmulf, args); arg] -> -+ (Ispecific Inegmulsubf, arg :: args) -+ | _ -> -+ super#select_operation op args -+ end -+ (* Recognize floating-point square root *) -+ | Cextcall("sqrt", _, _, _) -> -+ (Ispecific Isqrtf, args) -+ (* Recognize bswap instructions *) -+ | Cextcall("caml_bswap16_direct", _, _, _) -> -+ (Ispecific(Ibswap 16), args) -+ | Cextcall("caml_int32_direct_bswap", _, _, _) -> -+ (Ispecific(Ibswap 32), args) -+ | Cextcall(("caml_int64_direct_bswap"|"caml_nativeint_direct_bswap"), -+ _, _, _) -> -+ (Ispecific (Ibswap 64), args) -+ (* Other operations are regular *) -+ | _ -> -+ super#select_operation op args -+ -+method select_logical op = function -+ | [arg; Cconst_int n] when is_logical_immediate n -> -+ (Iintop_imm(op, n), [arg]) -+ | [Cconst_int n; arg] when is_logical_immediate n -> -+ (Iintop_imm(op, n), [arg]) -+ | args -> -+ (Iintop op, args) -+ -+end -+ -+let fundecl f = (new selector)#emit_fundecl f -diff --git a/asmcomp/compilenv.ml b/asmcomp/compilenv.ml -index 17870c9..280b131 100644 ---- a/asmcomp/compilenv.ml -+++ b/asmcomp/compilenv.ml -@@ -83,6 +83,15 @@ let make_symbol ?(unitname = current_unit.ui_symbol) idopt = - | None -> prefix - | Some id -> prefix ^ "__" ^ id - -+let symbol_in_current_unit name = -+ let prefix = "caml" ^ current_unit.ui_symbol in -+ name = prefix || -+ (let lp = String.length prefix in -+ String.length name >= 2 + lp -+ && String.sub name 0 lp = prefix -+ && name.[lp] = '_' -+ && name.[lp + 1] = '_') -+ - let read_unit_info filename = - let ic = open_in_bin filename in - try -diff --git a/asmcomp/compilenv.mli b/asmcomp/compilenv.mli -index 51cb8c6..9ffb145 100644 ---- a/asmcomp/compilenv.mli -+++ b/asmcomp/compilenv.mli -@@ -31,6 +31,10 @@ val make_symbol: ?unitname:string -> string option -> string - corresponds to symbol [id] in the compilation unit [u] - (or the current unit). *) - -+val symbol_in_current_unit: string -> bool -+ (* Return true if the given asm symbol belongs to the -+ current compilation unit, false otherwise. *) -+ - val symbol_for_global: Ident.t -> string - (* Return the asm symbol that refers to the given global identifier *) - -diff --git a/asmrun/arm64.S b/asmrun/arm64.S -new file mode 100644 -index 0000000..de670e6 ---- /dev/null -+++ b/asmrun/arm64.S -@@ -0,0 +1,535 @@ -+/***********************************************************************/ -+/* */ -+/* OCaml */ -+/* */ -+/* Xavier Leroy, projet Gallium, INRIA Rocquencourt */ -+/* */ -+/* Copyright 2013 Institut National de Recherche en Informatique et */ -+/* en Automatique. All rights reserved. This file is distributed */ -+/* under the terms of the GNU Library General Public License, with */ -+/* the special exception on linking described in file ../LICENSE. */ -+/* */ -+/***********************************************************************/ -+ -+/* Asm part of the runtime system, ARM processor, 64-bit mode */ -+/* Must be preprocessed by cpp */ -+ -+/* Special registers */ -+ -+#define TRAP_PTR x26 -+#define ALLOC_PTR x27 -+#define ALLOC_LIMIT x28 -+#define ARG x15 -+#define TMP x16 -+#define TMP2 x17 -+ -+/* Support for CFI directives */ -+ -+#if defined(ASM_CFI_SUPPORTED) -+#define CFI_STARTPROC .cfi_startproc -+#define CFI_ENDPROC .cfi_endproc -+#define CFI_ADJUST(n) .cfi_adjust_cfa_offset n -+#else -+#define CFI_STARTPROC -+#define CFI_ENDPROC -+#define CFI_ADJUST(n) -+#endif -+ -+/* Support for profiling with gprof */ -+ -+#define PROFILE -+ -+/* Macros to load and store global variables. Destroy TMP2 */ -+ -+#if defined(__PIC__) -+ -+#define ADDRGLOBAL(reg,symb) \ -+ adrp TMP2, :got:symb; \ -+ ldr reg, [TMP2, #:got_lo12:symb] -+ -+#define LOADGLOBAL(reg,symb) \ -+ ADDRGLOBAL(TMP2,symb); \ -+ ldr reg, [TMP2] -+ -+#define STOREGLOBAL(reg,symb) \ -+ ADDRGLOBAL(TMP2,symb); \ -+ str reg, [TMP2] -+ -+#else -+ -+#define ADDRGLOBAL(reg,symb) \ -+ adrp reg, symb; \ -+ add reg, reg, #:lo12:symb -+ -+#define LOADGLOBAL(reg,symb) \ -+ adrp TMP2, symb; \ -+ ldr reg, [TMP2, #:lo12:symb] -+ -+#define STOREGLOBAL(reg,symb) \ -+ adrp TMP2, symb; \ -+ str reg, [TMP2, #:lo12:symb] -+ -+#endif -+ -+/* Allocation functions and GC interface */ -+ -+ .globl caml_system__code_begin -+caml_system__code_begin: -+ -+ .align 2 -+ .globl caml_call_gc -+caml_call_gc: -+ CFI_STARTPROC -+ PROFILE -+ /* Record return address */ -+ STOREGLOBAL(x30, caml_last_return_address) -+.Lcaml_call_gc: -+ /* Record lowest stack address */ -+ mov TMP, sp -+ STOREGLOBAL(TMP, caml_bottom_of_stack) -+ /* Set up stack space, saving return address and frame pointer */ -+ /* (2 regs RA/GP, 24 allocatable int regs, 24 caller-save float regs) * 8 */ -+ stp x29, x30, [sp, -400]! -+ CFI_ADJUST(400) -+ add x29, sp, #0 -+ /* Save allocatable integer registers on the stack, in the order -+ given in proc.ml */ -+ stp x0, x1, [sp, 16] -+ stp x2, x3, [sp, 32] -+ stp x4, x5, [sp, 48] -+ stp x6, x7, [sp, 64] -+ stp x8, x9, [sp, 80] -+ stp x10, x11, [sp, 96] -+ stp x12, x13, [sp, 112] -+ stp x14, x15, [sp, 128] -+ stp x19, x20, [sp, 144] -+ stp x21, x22, [sp, 160] -+ stp x23, x24, [sp, 176] -+ str x25, [sp, 192] -+ /* Save caller-save floating-point registers on the stack -+ (callee-saves are preserved by caml_garbage_collection) */ -+ stp d0, d1, [sp, 208] -+ stp d2, d3, [sp, 224] -+ stp d4, d5, [sp, 240] -+ stp d6, d7, [sp, 256] -+ stp d16, d17, [sp, 272] -+ stp d18, d19, [sp, 288] -+ stp d20, d21, [sp, 304] -+ stp d22, d23, [sp, 320] -+ stp d24, d25, [sp, 336] -+ stp d26, d27, [sp, 352] -+ stp d28, d29, [sp, 368] -+ stp d30, d31, [sp, 384] -+ /* Store pointer to saved integer registers in caml_gc_regs */ -+ add TMP, sp, #16 -+ STOREGLOBAL(TMP, caml_gc_regs) -+ /* Save current allocation pointer for debugging purposes */ -+ STOREGLOBAL(ALLOC_PTR, caml_young_ptr) -+ /* Save trap pointer in case an exception is raised during GC */ -+ STOREGLOBAL(TRAP_PTR, caml_exception_pointer) -+ /* Call the garbage collector */ -+ bl caml_garbage_collection -+ /* Restore registers */ -+ ldp x0, x1, [sp, 16] -+ ldp x2, x3, [sp, 32] -+ ldp x4, x5, [sp, 48] -+ ldp x6, x7, [sp, 64] -+ ldp x8, x9, [sp, 80] -+ ldp x10, x11, [sp, 96] -+ ldp x12, x13, [sp, 112] -+ ldp x14, x15, [sp, 128] -+ ldp x19, x20, [sp, 144] -+ ldp x21, x22, [sp, 160] -+ ldp x23, x24, [sp, 176] -+ ldr x25, [sp, 192] -+ ldp d0, d1, [sp, 208] -+ ldp d2, d3, [sp, 224] -+ ldp d4, d5, [sp, 240] -+ ldp d6, d7, [sp, 256] -+ ldp d16, d17, [sp, 272] -+ ldp d18, d19, [sp, 288] -+ ldp d20, d21, [sp, 304] -+ ldp d22, d23, [sp, 320] -+ ldp d24, d25, [sp, 336] -+ ldp d26, d27, [sp, 352] -+ ldp d28, d29, [sp, 368] -+ ldp d30, d31, [sp, 384] -+ /* Reload new allocation pointer and allocation limit */ -+ LOADGLOBAL(ALLOC_PTR, caml_young_ptr) -+ LOADGLOBAL(ALLOC_LIMIT, caml_young_limit) -+ /* Free stack space and return to caller */ -+ ldp x29, x30, [sp], 400 -+ ret -+ CFI_ENDPROC -+ .type caml_call_gc, %function -+ .size caml_call_gc, .-caml_call_gc -+ -+ .align 2 -+ .globl caml_alloc1 -+caml_alloc1: -+ CFI_STARTPROC -+ PROFILE -+1: sub ALLOC_PTR, ALLOC_PTR, #16 -+ cmp ALLOC_PTR, ALLOC_LIMIT -+ b.lo 2f -+ ret -+2: stp x29, x30, [sp, -16]! -+ CFI_ADJUST(16) -+ add x29, sp, #0 -+ /* Record return address */ -+ STOREGLOBAL(x30, caml_last_return_address) -+ /* Call GC */ -+ bl .Lcaml_call_gc -+ /* Restore return address */ -+ ldp x29, x30, [sp], 16 -+ CFI_ADJUST(-16) -+ /* Try again */ -+ b 1b -+ CFI_ENDPROC -+ .type caml_alloc1, %function -+ .size caml_alloc1, .-caml_alloc1 -+ -+ .align 2 -+ .globl caml_alloc2 -+caml_alloc2: -+ CFI_STARTPROC -+ PROFILE -+1: sub ALLOC_PTR, ALLOC_PTR, #24 -+ cmp ALLOC_PTR, ALLOC_LIMIT -+ b.lo 2f -+ ret -+2: stp x29, x30, [sp, -16]! -+ CFI_ADJUST(16) -+ add x29, sp, #0 -+ /* Record return address */ -+ STOREGLOBAL(x30, caml_last_return_address) -+ /* Call GC */ -+ bl .Lcaml_call_gc -+ /* Restore return address */ -+ ldp x29, x30, [sp], 16 -+ CFI_ADJUST(-16) -+ /* Try again */ -+ b 1b -+ CFI_ENDPROC -+ .type caml_alloc2, %function -+ .size caml_alloc2, .-caml_alloc2 -+ -+ .align 2 -+ .globl caml_alloc3 -+caml_alloc3: -+ CFI_STARTPROC -+ PROFILE -+1: sub ALLOC_PTR, ALLOC_PTR, #32 -+ cmp ALLOC_PTR, ALLOC_LIMIT -+ b.lo 2f -+ ret -+2: stp x29, x30, [sp, -16]! -+ CFI_ADJUST(16) -+ add x29, sp, #0 -+ /* Record return address */ -+ STOREGLOBAL(x30, caml_last_return_address) -+ /* Call GC */ -+ bl .Lcaml_call_gc -+ /* Restore return address */ -+ ldp x29, x30, [sp], 16 -+ CFI_ADJUST(-16) -+ /* Try again */ -+ b 1b -+ CFI_ENDPROC -+ .type caml_alloc2, %function -+ .size caml_alloc2, .-caml_alloc2 -+ -+ .align 2 -+ .globl caml_allocN -+caml_allocN: -+ CFI_STARTPROC -+ PROFILE -+1: sub ALLOC_PTR, ALLOC_PTR, ARG -+ cmp ALLOC_PTR, ALLOC_LIMIT -+ b.lo 2f -+ ret -+2: stp x29, x30, [sp, -16]! -+ CFI_ADJUST(16) -+ add x29, sp, #0 -+ /* Record return address */ -+ STOREGLOBAL(x30, caml_last_return_address) -+ /* Call GC. This preserves ARG */ -+ bl .Lcaml_call_gc -+ /* Restore return address */ -+ ldp x29, x30, [sp], 16 -+ CFI_ADJUST(-16) -+ /* Try again */ -+ b 1b -+ CFI_ENDPROC -+ .type caml_allocN, %function -+ .size caml_allocN, .-caml_allocN -+ -+/* Call a C function from OCaml */ -+/* Function to call is in ARG */ -+ -+ .align 2 -+ .globl caml_c_call -+caml_c_call: -+ CFI_STARTPROC -+ PROFILE -+ /* Preserve return address in callee-save register x19 */ -+ mov x19, x30 -+ /* Record lowest stack address and return address */ -+ STOREGLOBAL(x30, caml_last_return_address) -+ add TMP, sp, #0 -+ STOREGLOBAL(TMP, caml_bottom_of_stack) -+ /* Make the exception handler alloc ptr available to the C code */ -+ STOREGLOBAL(ALLOC_PTR, caml_young_ptr) -+ STOREGLOBAL(TRAP_PTR, caml_exception_pointer) -+ /* Call the function */ -+ blr ARG -+ /* Reload alloc ptr and alloc limit */ -+ LOADGLOBAL(ALLOC_PTR, caml_young_ptr) -+ LOADGLOBAL(ALLOC_LIMIT, caml_young_limit) -+ /* Return */ -+ ret x19 -+ CFI_ENDPROC -+ .type caml_c_call, %function -+ .size caml_c_call, .-caml_c_call -+ -+/* Start the OCaml program */ -+ -+ .align 2 -+ .globl caml_start_program -+caml_start_program: -+ CFI_STARTPROC -+ PROFILE -+ ADDRGLOBAL(ARG, caml_program) -+ -+/* Code shared with caml_callback* */ -+/* Address of OCaml code to call is in ARG */ -+/* Arguments to the OCaml code are in x0...x7 */ -+ -+.Ljump_to_caml: -+ /* Set up stack frame and save callee-save registers */ -+ stp x29, x30, [sp, -160]! -+ CFI_ADJUST(160) -+ add x29, sp, #0 -+ stp x19, x20, [sp, 16] -+ stp x21, x22, [sp, 32] -+ stp x23, x24, [sp, 48] -+ stp x25, x26, [sp, 64] -+ stp x27, x28, [sp, 80] -+ stp d8, d9, [sp, 96] -+ stp d10, d11, [sp, 112] -+ stp d12, d13, [sp, 128] -+ stp d14, d15, [sp, 144] -+ /* Setup a callback link on the stack */ -+ LOADGLOBAL(x8, caml_bottom_of_stack) -+ LOADGLOBAL(x9, caml_last_return_address) -+ LOADGLOBAL(x10, caml_gc_regs) -+ stp x8, x9, [sp, -32]! /* 16-byte alignment */ -+ CFI_ADJUST(32) -+ str x10, [sp, 16] -+ /* Setup a trap frame to catch exceptions escaping the OCaml code */ -+ LOADGLOBAL(x8, caml_exception_pointer) -+ adr x9, .Ltrap_handler -+ stp x8, x9, [sp, -16]! -+ CFI_ADJUST(16) -+ add TRAP_PTR, sp, #0 -+ /* Reload allocation pointers */ -+ LOADGLOBAL(ALLOC_PTR, caml_young_ptr) -+ LOADGLOBAL(ALLOC_LIMIT, caml_young_limit) -+ /* Call the OCaml code */ -+ blr ARG -+.Lcaml_retaddr: -+ /* Pop the trap frame, restoring caml_exception_pointer */ -+ ldr x8, [sp], 16 -+ CFI_ADJUST(-16) -+ STOREGLOBAL(x8, caml_exception_pointer) -+ /* Pop the callback link, restoring the global variables */ -+.Lreturn_result: -+ ldr x10, [sp, 16] -+ ldp x8, x9, [sp], 32 -+ CFI_ADJUST(-32) -+ STOREGLOBAL(x8, caml_bottom_of_stack) -+ STOREGLOBAL(x9, caml_last_return_address) -+ STOREGLOBAL(x10, caml_gc_regs) -+ /* Update allocation pointer */ -+ STOREGLOBAL(ALLOC_PTR, caml_young_ptr) -+ /* Reload callee-save registers and return address */ -+ ldp x19, x20, [sp, 16] -+ ldp x21, x22, [sp, 32] -+ ldp x23, x24, [sp, 48] -+ ldp x25, x26, [sp, 64] -+ ldp x27, x28, [sp, 80] -+ ldp d8, d9, [sp, 96] -+ ldp d10, d11, [sp, 112] -+ ldp d12, d13, [sp, 128] -+ ldp d14, d15, [sp, 144] -+ ldp x29, x30, [sp], 160 -+ CFI_ADJUST(-160) -+ /* Return to C caller */ -+ ret -+ CFI_ENDPROC -+ .type .Lcaml_retaddr, %function -+ .size .Lcaml_retaddr, .-.Lcaml_retaddr -+ .type caml_start_program, %function -+ .size caml_start_program, .-caml_start_program -+ -+/* The trap handler */ -+ -+ .align 2 -+.Ltrap_handler: -+ CFI_STARTPROC -+ /* Save exception pointer */ -+ STOREGLOBAL(TRAP_PTR, caml_exception_pointer) -+ /* Encode exception bucket as an exception result */ -+ orr x0, x0, #2 -+ /* Return it */ -+ b .Lreturn_result -+ CFI_ENDPROC -+ .type .Ltrap_handler, %function -+ .size .Ltrap_handler, .-.Ltrap_handler -+ -+/* Raise an exception from OCaml */ -+ -+ .align 2 -+ .globl caml_raise_exn -+caml_raise_exn: -+ CFI_STARTPROC -+ PROFILE -+ /* Test if backtrace is active */ -+ LOADGLOBAL(TMP, caml_backtrace_active) -+ cbnz TMP, 2f -+1: /* Cut stack at current trap handler */ -+ mov sp, TRAP_PTR -+ /* Pop previous handler and jump to it */ -+ ldr TMP, [sp, 8] -+ ldr TRAP_PTR, [sp], 16 -+ br TMP -+2: /* Preserve exception bucket in callee-save register x19 */ -+ mov x19, x0 -+ /* Stash the backtrace */ -+ /* arg1: exn bucket, already in x0 */ -+ mov x1, x30 /* arg2: pc of raise */ -+ add x2, sp, #0 /* arg3: sp of raise */ -+ mov x3, TRAP_PTR /* arg4: sp of handler */ -+ bl caml_stash_backtrace -+ /* Restore exception bucket and raise */ -+ mov x0, x19 -+ b 1b -+ CFI_ENDPROC -+ .type caml_raise_exn, %function -+ .size caml_raise_exn, .-caml_raise_exn -+ -+/* Raise an exception from C */ -+ -+ .align 2 -+ .globl caml_raise_exception -+caml_raise_exception: -+ CFI_STARTPROC -+ PROFILE -+ /* Reload trap ptr, alloc ptr and alloc limit */ -+ LOADGLOBAL(TRAP_PTR, caml_exception_pointer) -+ LOADGLOBAL(ALLOC_PTR, caml_young_ptr) -+ LOADGLOBAL(ALLOC_LIMIT, caml_young_limit) -+ /* Test if backtrace is active */ -+ LOADGLOBAL(TMP, caml_backtrace_active) -+ cbnz TMP, 2f -+1: /* Cut stack at current trap handler */ -+ mov sp, TRAP_PTR -+ /* Pop previous handler and jump to it */ -+ ldr TMP, [sp, 8] -+ ldr TRAP_PTR, [sp], 16 -+ br TMP -+2: /* Preserve exception bucket in callee-save register x19 */ -+ mov x19, x0 -+ /* Stash the backtrace */ -+ /* arg1: exn bucket, already in x0 */ -+ LOADGLOBAL(x1, caml_last_return_address) /* arg2: pc of raise */ -+ LOADGLOBAL(x2, caml_bottom_of_stack) /* arg3: sp of raise */ -+ mov x3, TRAP_PTR /* arg4: sp of handler */ -+ bl caml_stash_backtrace -+ /* Restore exception bucket and raise */ -+ mov x0, x19 -+ b 1b -+ CFI_ENDPROC -+ .type caml_raise_exception, %function -+ .size caml_raise_exception, .-caml_raise_exception -+ -+/* Callback from C to OCaml */ -+ -+ .align 2 -+ .globl caml_callback_exn -+caml_callback_exn: -+ CFI_STARTPROC -+ PROFILE -+ /* Initial shuffling of arguments (x0 = closure, x1 = first arg) */ -+ mov TMP, x0 -+ mov x0, x1 /* x0 = first arg */ -+ mov x1, TMP /* x1 = closure environment */ -+ ldr ARG, [TMP] /* code pointer */ -+ b .Ljump_to_caml -+ CFI_ENDPROC -+ .type caml_callback_exn, %function -+ .size caml_callback_exn, .-caml_callback_exn -+ -+ .align 2 -+ .globl caml_callback2_exn -+caml_callback2_exn: -+ CFI_STARTPROC -+ PROFILE -+ /* Initial shuffling of arguments (x0 = closure, x1 = arg1, x2 = arg2) */ -+ mov TMP, x0 -+ mov x0, x1 /* x0 = first arg */ -+ mov x1, x2 /* x1 = second arg -+ mov x2, TMP /* x2 = closure environment */ -+ ADDRGLOBAL(ARG, caml_apply2) -+ b .Ljump_to_caml -+ CFI_ENDPROC -+ .type caml_callback2_exn, %function -+ .size caml_callback2_exn, .-caml_callback2_exn -+ -+ .align 2 -+ .globl caml_callback3_exn -+caml_callback3_exn: -+ CFI_STARTPROC -+ PROFILE -+ /* Initial shuffling of arguments */ -+ /* (x0 = closure, x1 = arg1, x2 = arg2, x3 = arg3) */ -+ mov TMP, x0 -+ mov x0, x1 /* x0 = first arg */ -+ mov x1, x2 /* x1 = second arg */ -+ mov x2, x3 /* x2 = third arg */ -+ mov x3, TMP /* x3 = closure environment */ -+ ADDRGLOBAL(ARG, caml_apply3) -+ b .Ljump_to_caml -+ CFI_ENDPROC -+ .type caml_callback3_exn, %function -+ .size caml_callback3_exn, .-caml_callback3_exn -+ -+ .align 2 -+ .globl caml_ml_array_bound_error -+caml_ml_array_bound_error: -+ CFI_STARTPROC -+ PROFILE -+ /* Load address of [caml_array_bound_error] in ARG */ -+ ADDRGLOBAL(ARG, caml_array_bound_error) -+ /* Call that function */ -+ b caml_c_call -+ CFI_ENDPROC -+ .type caml_ml_array_bound_error, %function -+ .size caml_ml_array_bound_error, .-caml_ml_array_bound_error -+ -+ .globl caml_system__code_end -+caml_system__code_end: -+ -+/* GC roots for callback */ -+ -+ .data -+ .align 3 -+ .globl caml_system__frametable -+caml_system__frametable: -+ .quad 1 /* one descriptor */ -+ .quad .Lcaml_retaddr /* return address into callback */ -+ .short -1 /* negative frame size => use callback link */ -+ .short 0 /* no roots */ -+ .align 3 -+ .type caml_system__frametable, %object -+ .size caml_system__frametable, .-caml_system__frametable -diff --git a/asmrun/signals_osdep.h b/asmrun/signals_osdep.h -index ff19847..68ec837 100644 ---- a/asmrun/signals_osdep.h -+++ b/asmrun/signals_osdep.h -@@ -92,6 +92,25 @@ - #define CONTEXT_YOUNG_PTR (context->uc_mcontext.arm_r8) - #define CONTEXT_FAULTING_ADDRESS ((char *) context->uc_mcontext.fault_address) - -+/****************** ARM64, Linux */ -+ -+#elif defined(TARGET_arm64) && defined(SYS_linux) -+ -+ #include -+ -+ #define DECLARE_SIGNAL_HANDLER(name) \ -+ static void name(int sig, siginfo_t * info, ucontext_t * context) -+ -+ #define SET_SIGACT(sigact,name) \ -+ sigact.sa_sigaction = (void (*)(int,siginfo_t *,void *)) (name); \ -+ sigact.sa_flags = SA_SIGINFO -+ -+ typedef unsigned long context_reg; -+ #define CONTEXT_PC (context->uc_mcontext.pc) -+ #define CONTEXT_EXCEPTION_POINTER (context->uc_mcontext.regs[26]) -+ #define CONTEXT_YOUNG_PTR (context->uc_mcontext.regs[27]) -+ #define CONTEXT_FAULTING_ADDRESS ((char *) context->uc_mcontext.fault_address) -+ - /****************** AMD64, Solaris x86 */ - - #elif defined(TARGET_amd64) && defined (SYS_solaris) -diff --git a/asmrun/stack.h b/asmrun/stack.h -index 756db95..031e408 100644 ---- a/asmrun/stack.h -+++ b/asmrun/stack.h -@@ -65,6 +65,11 @@ - #define Callback_link(sp) ((struct caml_context *)((sp) + 16)) - #endif - -+#ifdef TARGET_arm64 -+#define Saved_return_address(sp) *((intnat *)((sp) - 8)) -+#define Callback_link(sp) ((struct caml_context *)((sp) + 16)) -+#endif -+ - /* Structure of OCaml callback contexts */ - - struct caml_context { -diff --git a/byterun/interp.c b/byterun/interp.c -index b99ed2f..af9fa0f 100644 ---- a/byterun/interp.c -+++ b/byterun/interp.c -@@ -173,6 +173,12 @@ sp is a local copy of the global variable caml_extern_sp. */ - #define SP_REG asm("%r14") - #define ACCU_REG asm("%r13") - #endif -+#ifdef __aarch64__ -+#define PC_REG asm("%x19") -+#define SP_REG asm("%x20") -+#define ACCU_REG asm("%x21") -+#define JUMPTBL_BASE_REG asm("%x22") -+#endif - #endif - - /* Division and modulus madness */ -diff --git a/configure b/configure -index 9b02664..36edfab 100755 ---- a/configure -+++ b/configure -@@ -657,6 +657,7 @@ if test $withsharedlibs = "yes"; then - x86_64-*-netbsd*) natdynlink=true;; - i386-*-gnu0.3) natdynlink=true;; - arm*-*-linux*) natdynlink=true;; -+ aarch64-*-linux*) natdynlink=true;; - esac - fi - -@@ -715,6 +716,7 @@ case "$host" in - x86_64-*-netbsd*) arch=amd64; system=netbsd;; - x86_64-*-openbsd*) arch=amd64; system=openbsd;; - x86_64-*-darwin*) arch=amd64; system=macosx;; -+ aarch64-*-linux*) arch=arm64; system=linux;; - esac - - # Some platforms exist both in 32-bit and 64-bit variants, not distinguished -@@ -767,7 +769,7 @@ case "$arch,$model,$system" in - aspp='gcc -m64 -c';; - amd64,*,*) as='as' - aspp='gcc -c';; -- arm,*,*) as='as'; -+ arm,*,*|arm64,*,*)as='as'; - aspp='gcc -c';; - i386,*,solaris) as='as' - aspp='/usr/ccs/bin/as -P';; -@@ -1193,6 +1195,7 @@ case "$arch" in - fi;; - power) bng_arch=ppc; bng_asm_level=1;; - amd64) bng_arch=amd64; bng_asm_level=1;; -+ arm64) bng_arch=arm64; bng_asm_level=1;; - *) bng_arch=generic; bng_asm_level=0;; - esac - -diff --git a/otherlibs/num/bng.c b/otherlibs/num/bng.c -index 5bbedb0..0483ef5 100644 ---- a/otherlibs/num/bng.c -+++ b/otherlibs/num/bng.c -@@ -23,12 +23,10 @@ - #include "bng_amd64.c" - #elif defined(BNG_ARCH_ppc) - #include "bng_ppc.c" --#elif defined (BNG_ARCH_alpha) --#include "bng_alpha.c" - #elif defined (BNG_ARCH_sparc) - #include "bng_sparc.c" --#elif defined (BNG_ARCH_mips) --#include "bng_mips.c" -+#elif defined (BNG_ARCH_arm64) -+#include "bng_arm64.c" - #endif - #endif - -diff --git a/otherlibs/num/bng_arm64.c b/otherlibs/num/bng_arm64.c -new file mode 100644 -index 0000000..50843a0 ---- /dev/null -+++ b/otherlibs/num/bng_arm64.c -@@ -0,0 +1,20 @@ -+/***********************************************************************/ -+/* */ -+/* OCaml */ -+/* */ -+/* Xavier Leroy, projet Gallium, INRIA Rocquencourt */ -+/* */ -+/* Copyright 2013 Institut National de Recherche en Informatique et */ -+/* en Automatique. All rights reserved. This file is distributed */ -+/* under the terms of the GNU Library General Public License, with */ -+/* the special exception on linking described in file ../../LICENSE. */ -+/* */ -+/***********************************************************************/ -+ -+/* Code specific for the ARM 64 (AArch64) architecture */ -+ -+#define BngMult(resh,resl,arg1,arg2) \ -+ asm("mul %0, %2, %3 \n\t" \ -+ "umulh %1, %2, %3" \ -+ : "=&r" (resl), "=&r" (resh) \ -+ : "r" (arg1), "r" (arg2)) -diff --git a/testsuite/tests/asmcomp/Makefile b/testsuite/tests/asmcomp/Makefile -index fd01d33..9dca023 100644 ---- a/testsuite/tests/asmcomp/Makefile -+++ b/testsuite/tests/asmcomp/Makefile -@@ -126,7 +126,7 @@ parsecmm.mli parsecmm.ml: parsecmm.mly - lexcmm.ml: lexcmm.mll - @$(OCAMLLEX) -q lexcmm.mll - --CASES=fib tak quicksort quicksort2 soli \ -+CASES=fib tak quicksort quicksort2 soli integr \ - arith checkbound tagged-fib tagged-integr tagged-quicksort tagged-tak - ARGS_fib=-DINT_INT -DFUN=fib main.c - ARGS_tak=-DUNIT_INT -DFUN=takmain main.c -diff --git a/testsuite/tests/asmcomp/arm64.S b/testsuite/tests/asmcomp/arm64.S -new file mode 100644 -index 0000000..3bb4110 ---- /dev/null -+++ b/testsuite/tests/asmcomp/arm64.S -@@ -0,0 +1,52 @@ -+/***********************************************************************/ -+/* */ -+/* OCaml */ -+/* */ -+/* Xavier Leroy, projet Gallium, INRIA Rocquencourt */ -+/* */ -+/* Copyright 2013 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. */ -+/* */ -+/***********************************************************************/ -+ -+ .globl call_gen_code -+ .align 2 -+call_gen_code: -+ /* Set up stack frame and save callee-save registers */ -+ stp x29, x30, [sp, -160]! -+ add x29, sp, #0 -+ stp x19, x20, [sp, 16] -+ stp x21, x22, [sp, 32] -+ stp x23, x24, [sp, 48] -+ stp x25, x26, [sp, 64] -+ stp x27, x28, [sp, 80] -+ stp d8, d9, [sp, 96] -+ stp d10, d11, [sp, 112] -+ stp d12, d13, [sp, 128] -+ stp d14, d15, [sp, 144] -+ /* Shuffle arguments */ -+ mov x8, x0 -+ mov x0, x1 -+ mov x1, x2 -+ mov x2, x3 -+ mov x3, x4 -+ /* Call generated asm */ -+ blr x8 -+ /* Reload callee-save registers and return address */ -+ ldp x19, x20, [sp, 16] -+ ldp x21, x22, [sp, 32] -+ ldp x23, x24, [sp, 48] -+ ldp x25, x26, [sp, 64] -+ ldp x27, x28, [sp, 80] -+ ldp d8, d9, [sp, 96] -+ ldp d10, d11, [sp, 112] -+ ldp d12, d13, [sp, 128] -+ ldp d14, d15, [sp, 144] -+ ldp x29, x30, [sp], 160 -+ ret -+ -+ .globl caml_c_call -+ .align 2 -+caml_c_call: -+ br x15 -diff --git a/testsuite/tests/asmcomp/main.ml b/testsuite/tests/asmcomp/main.ml -index d67a643..82b699e 100644 ---- a/testsuite/tests/asmcomp/main.ml -+++ b/testsuite/tests/asmcomp/main.ml -@@ -13,6 +13,7 @@ - open Clflags - - let compile_file filename = -+ Clflags.dlcode := false; - Compilenv.reset "test"; - Emit.begin_assembly(); - let ic = open_in filename in --- -1.9.0 - diff --git a/0008-arm-arm64-Mark-stack-as-non-executable.patch b/0008-arm-arm64-Mark-stack-as-non-executable.patch new file mode 100644 index 0000000..2b73aed --- /dev/null +++ b/0008-arm-arm64-Mark-stack-as-non-executable.patch @@ -0,0 +1,39 @@ +From 8db6171b43cf7d18340a68a2f636f9b2570236ac Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Sat, 10 May 2014 03:20:35 -0400 +Subject: [PATCH 08/10] arm, arm64: Mark stack as non-executable. + +The same fix as this one, which was only fully applied to +i686 & x86-64: + +http://caml.inria.fr/mantis/view.php?id=4564 +--- + asmrun/arm.S | 3 +++ + asmrun/arm64.S | 3 +++ + 2 files changed, 6 insertions(+) + +diff --git a/asmrun/arm.S b/asmrun/arm.S +index 2ce244a..90f5b6e 100644 +--- a/asmrun/arm.S ++++ b/asmrun/arm.S +@@ -489,3 +489,6 @@ caml_system__frametable: + .align 2 + .type caml_system__frametable, %object + .size caml_system__frametable, .-caml_system__frametable ++ ++ /* Mark stack as non-executable, PR#4564 */ ++ .section .note.GNU-stack,"",%progbits +diff --git a/asmrun/arm64.S b/asmrun/arm64.S +index 2c16a0e..a7d4953 100644 +--- a/asmrun/arm64.S ++++ b/asmrun/arm64.S +@@ -533,3 +533,6 @@ caml_system__frametable: + .align 3 + .type caml_system__frametable, %object + .size caml_system__frametable, .-caml_system__frametable ++ ++ /* Mark stack as non-executable, PR#4564 */ ++ .section .note.GNU-stack,"",%progbits +-- +1.9.0 + diff --git a/0009-Updated-with-latest-versions-from-FSF.patch b/0009-Updated-with-latest-versions-from-FSF.patch deleted file mode 100644 index 3f5a427..0000000 --- a/0009-Updated-with-latest-versions-from-FSF.patch +++ /dev/null @@ -1,716 +0,0 @@ -From 26114ba365c1ef63d9605efc719f6c220ad624eb Mon Sep 17 00:00:00 2001 -From: Xavier Leroy -Date: Thu, 18 Jul 2013 16:07:25 +0000 -Subject: [PATCH 09/14] Updated with latest versions from FSF. - -git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@13907 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02 -(cherry picked from commit 24bb4caeb35e49126aa3a4c0101a412db1091213) ---- - config/gnu/config.guess | 196 ++++++++++++++++++++++++++++-------------------- - config/gnu/config.sub | 117 +++++++++++++++++------------ - 2 files changed, 183 insertions(+), 130 deletions(-) - -diff --git a/config/gnu/config.guess b/config/gnu/config.guess -index 8152efd..b79252d 100755 ---- a/config/gnu/config.guess -+++ b/config/gnu/config.guess -@@ -1,14 +1,12 @@ - #! /bin/sh - # Attempt to guess a canonical system name. --# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, --# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, --# 2011 Free Software Foundation, Inc. -+# Copyright 1992-2013 Free Software Foundation, Inc. - --timestamp='2011-11-11' -+timestamp='2013-06-10' - - # This file is free software; you can redistribute it and/or modify it - # under the terms of the GNU General Public License as published by --# the Free Software Foundation; either version 2 of the License, or -+# the Free Software Foundation; either version 3 of the License, or - # (at your option) any later version. - # - # This program is distributed in the hope that it will be useful, but -@@ -17,26 +15,22 @@ timestamp='2011-11-11' - # General Public License for more details. - # - # You should have received a copy of the GNU General Public License --# along with this program; if not, write to the Free Software --# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA --# 02110-1301, USA. -+# along with this program; if not, see . - # - # As a special exception to the GNU General Public License, if you - # distribute this file as part of a program that contains a - # configuration script generated by Autoconf, you may include it under --# the same distribution terms that you use for the rest of that program. -- -- --# Originally written by Per Bothner. Please send patches (context --# diff format) to and include a ChangeLog --# entry. -+# the same distribution terms that you use for the rest of that -+# program. This Exception is an additional permission under section 7 -+# of the GNU General Public License, version 3 ("GPLv3"). - # --# This script attempts to guess a canonical system name similar to --# config.sub. If it succeeds, it prints the system name on stdout, and --# exits with 0. Otherwise, it exits with 1. -+# Originally written by Per Bothner. - # - # You can get the latest version of this script from: - # http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD -+# -+# Please send patches with a ChangeLog entry to config-patches@gnu.org. -+ - - me=`echo "$0" | sed -e 's,.*/,,'` - -@@ -56,9 +50,7 @@ version="\ - GNU config.guess ($timestamp) - - Originally written by Per Bothner. --Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, --2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free --Software Foundation, Inc. -+Copyright 1992-2013 Free Software Foundation, Inc. - - This is free software; see the source for copying conditions. There is NO - warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." -@@ -140,12 +132,33 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown - UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown - UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -+case "${UNAME_SYSTEM}" in -+Linux|GNU|GNU/*) -+ # If the system lacks a compiler, then just pick glibc. -+ # We could probably try harder. -+ LIBC=gnu -+ -+ eval $set_cc_for_build -+ cat <<-EOF > $dummy.c -+ #include -+ #if defined(__UCLIBC__) -+ LIBC=uclibc -+ #elif defined(__dietlibc__) -+ LIBC=dietlibc -+ #else -+ LIBC=gnu -+ #endif -+ EOF -+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` -+ ;; -+esac -+ - # Note: order is significant - the case branches are not exclusive. - - case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or -- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, -+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward -@@ -202,6 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; -+ *:Bitrig:*:*) -+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` -+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} -+ exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} -@@ -304,7 +321,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; -- arm:riscos:*:*|arm:RISCOS:*:*) -+ arm*:riscos:*:*|arm*:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) -@@ -803,6 +820,9 @@ EOF - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; -+ *:MINGW64*:*) -+ echo ${UNAME_MACHINE}-pc-mingw64 -+ exit ;; - *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; -@@ -854,15 +874,22 @@ EOF - exit ;; - *:GNU:*:*) - # the GNU system -- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` -+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland -- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu -+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; -+ aarch64:Linux:*:*) -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} -+ exit ;; -+ aarch64_be:Linux:*:*) -+ UNAME_MACHINE=aarch64_be -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} -+ exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; -@@ -874,59 +901,54 @@ EOF - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep -q ld.so.1 -- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi -- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} -+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} -+ exit ;; -+ arc:Linux:*:* | arceb:Linux:*:*) -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - arm*:Linux:*:*) - eval $set_cc_for_build - if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_EABI__ - then -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - else - if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep -q __ARM_PCS_VFP - then -- echo ${UNAME_MACHINE}-unknown-linux-gnueabi -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi - else -- echo ${UNAME_MACHINE}-unknown-linux-gnueabihf -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf - fi - fi - exit ;; - avr32*:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - cris:Linux:*:*) -- echo cris-axis-linux-gnu -+ echo ${UNAME_MACHINE}-axis-linux-${LIBC} - exit ;; - crisv32:Linux:*:*) -- echo crisv32-axis-linux-gnu -+ echo ${UNAME_MACHINE}-axis-linux-${LIBC} - exit ;; - frv:Linux:*:*) -- echo frv-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - hexagon:Linux:*:*) -- echo hexagon-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - i*86:Linux:*:*) -- LIBC=gnu -- eval $set_cc_for_build -- sed 's/^ //' << EOF >$dummy.c -- #ifdef __dietlibc__ -- LIBC=dietlibc -- #endif --EOF -- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'` -- echo "${UNAME_MACHINE}-pc-linux-${LIBC}" -+ echo ${UNAME_MACHINE}-pc-linux-${LIBC} - exit ;; - ia64:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - m32r*:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - m68*:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build -@@ -945,54 +967,63 @@ EOF - #endif - EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` -- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } -+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } - ;; -+ or1k:Linux:*:*) -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} -+ exit ;; - or32:Linux:*:*) -- echo or32-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - padre:Linux:*:*) -- echo sparc-unknown-linux-gnu -+ echo sparc-unknown-linux-${LIBC} - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) -- echo hppa64-unknown-linux-gnu -+ echo hppa64-unknown-linux-${LIBC} - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in -- PA7*) echo hppa1.1-unknown-linux-gnu ;; -- PA8*) echo hppa2.0-unknown-linux-gnu ;; -- *) echo hppa-unknown-linux-gnu ;; -+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; -+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; -+ *) echo hppa-unknown-linux-${LIBC} ;; - esac - exit ;; - ppc64:Linux:*:*) -- echo powerpc64-unknown-linux-gnu -+ echo powerpc64-unknown-linux-${LIBC} - exit ;; - ppc:Linux:*:*) -- echo powerpc-unknown-linux-gnu -+ echo powerpc-unknown-linux-${LIBC} -+ exit ;; -+ ppc64le:Linux:*:*) -+ echo powerpc64le-unknown-linux-${LIBC} -+ exit ;; -+ ppcle:Linux:*:*) -+ echo powerpcle-unknown-linux-${LIBC} - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) -- echo ${UNAME_MACHINE}-ibm-linux -+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC} - exit ;; - sh64*:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - sh*:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - tile*:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - vax:Linux:*:*) -- echo ${UNAME_MACHINE}-dec-linux-gnu -+ echo ${UNAME_MACHINE}-dec-linux-${LIBC} - exit ;; - x86_64:Linux:*:*) -- echo x86_64-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - xtensa*:Linux:*:*) -- echo ${UNAME_MACHINE}-unknown-linux-gnu -+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC} - exit ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. -@@ -1196,6 +1227,9 @@ EOF - BePC:Haiku:*:*) # Haiku running on Intel PC compatible. - echo i586-pc-haiku - exit ;; -+ x86_64:Haiku:*:*) -+ echo x86_64-unknown-haiku -+ exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; -@@ -1222,19 +1256,21 @@ EOF - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown -- case $UNAME_PROCESSOR in -- i386) -- eval $set_cc_for_build -- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then -- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ -- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ -- grep IS_64BIT_ARCH >/dev/null -- then -- UNAME_PROCESSOR="x86_64" -- fi -- fi ;; -- unknown) UNAME_PROCESSOR=powerpc ;; -- esac -+ eval $set_cc_for_build -+ if test "$UNAME_PROCESSOR" = unknown ; then -+ UNAME_PROCESSOR=powerpc -+ fi -+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then -+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ -+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ -+ grep IS_64BIT_ARCH >/dev/null -+ then -+ case $UNAME_PROCESSOR in -+ i386) UNAME_PROCESSOR=x86_64 ;; -+ powerpc) UNAME_PROCESSOR=powerpc64 ;; -+ esac -+ fi -+ fi - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) -@@ -1251,7 +1287,7 @@ EOF - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} - exit ;; -- NSE-?:NONSTOP_KERNEL:*:*) -+ NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) -@@ -1320,11 +1356,11 @@ EOF - i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros - exit ;; -+ x86_64:VMkernel:*:*) -+ echo ${UNAME_MACHINE}-unknown-esx -+ exit ;; - esac - --#echo '(No uname command or uname output not recognized.)' 1>&2 --#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 -- - eval $set_cc_for_build - cat >$dummy.c <. - # - # As a special exception to the GNU General Public License, if you - # distribute this file as part of a program that contains a - # configuration script generated by Autoconf, you may include it under --# the same distribution terms that you use for the rest of that program. -+# the same distribution terms that you use for the rest of that -+# program. This Exception is an additional permission under section 7 -+# of the GNU General Public License, version 3 ("GPLv3"). - - --# Please send patches to . Submit a context --# diff and a properly formatted GNU ChangeLog entry. -+# Please send patches with a ChangeLog entry to config-patches@gnu.org. - # - # Configuration subroutine to validate and canonicalize a configuration type. - # Supply the specified configuration type as an argument. -@@ -75,9 +68,7 @@ Report bugs and patches to ." - version="\ - GNU config.sub ($timestamp) - --Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, --2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free --Software Foundation, Inc. -+Copyright 1992-2013 Free Software Foundation, Inc. - - This is free software; see the source for copying conditions. There is NO - warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." -@@ -125,13 +116,17 @@ esac - maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` - case $maybe_os in - nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ -- linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ -+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ - knetbsd*-gnu* | netbsd*-gnu* | \ - kopensolaris*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; -+ android-linux) -+ os=-linux-android -+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown -+ ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] -@@ -154,7 +149,7 @@ case $os in - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ -- -apple | -axis | -knuth | -cray | -microblaze) -+ -apple | -axis | -knuth | -cray | -microblaze*) - os= - basic_machine=$1 - ;; -@@ -223,6 +218,12 @@ case $os in - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; -+ -lynx*178) -+ os=-lynxos178 -+ ;; -+ -lynx*5) -+ os=-lynxos5 -+ ;; - -lynx*) - os=-lynxos - ;; -@@ -247,11 +248,14 @@ case $basic_machine in - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ -+ | aarch64 | aarch64_be \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ -- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ -- | be32 | be64 \ -+ | arc | arceb \ -+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ -+ | avr | avr32 \ -+ | be32 | be64 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ -@@ -264,7 +268,7 @@ case $basic_machine in - | le32 | le64 \ - | lm32 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ -- | maxq | mb | microblaze | mcore | mep | metag \ -+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ -@@ -282,16 +286,17 @@ case $basic_machine in - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ -+ | mipsr5900 | mipsr5900el \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | moxie \ - | mt \ - | msp430 \ - | nds32 | nds32le | nds32be \ -- | nios | nios2 \ -+ | nios | nios2 | nios2eb | nios2el \ - | ns16k | ns32k \ - | open8 \ -- | or32 \ -+ | or1k | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle \ - | pyramid \ -@@ -319,8 +324,7 @@ case $basic_machine in - c6x) - basic_machine=tic6x-unknown - ;; -- m6811 | m68hc11 | m6812 | m68hc12 | picochip) -- # Motorola 68HC11/12. -+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | picochip) - basic_machine=$basic_machine-unknown - os=-none - ;; -@@ -333,7 +337,10 @@ case $basic_machine in - strongarm | thumb | xscale) - basic_machine=arm-unknown - ;; -- -+ xgate) -+ basic_machine=$basic_machine-unknown -+ os=-none -+ ;; - xscaleeb) - basic_machine=armeb-unknown - ;; -@@ -356,9 +363,10 @@ case $basic_machine in - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ -+ | aarch64-* | aarch64_be-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ -- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ -+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | be32-* | be64-* \ -@@ -377,7 +385,8 @@ case $basic_machine in - | lm32-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ -- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \ -+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ -+ | microblaze-* | microblazeel-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ -@@ -395,12 +404,13 @@ case $basic_machine in - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ -+ | mipsr5900-* | mipsr5900el-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nds32-* | nds32le-* | nds32be-* \ -- | nios-* | nios2-* \ -+ | nios-* | nios2-* | nios2eb-* | nios2el-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | open8-* \ - | orion-* \ -@@ -719,7 +729,6 @@ case $basic_machine in - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; --# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 -@@ -777,9 +786,13 @@ case $basic_machine in - basic_machine=ns32k-utek - os=-sysv - ;; -- microblaze) -+ microblaze*) - basic_machine=microblaze-xilinx - ;; -+ mingw64) -+ basic_machine=x86_64-pc -+ os=-mingw64 -+ ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 -@@ -1008,7 +1021,11 @@ case $basic_machine in - basic_machine=i586-unknown - os=-pw32 - ;; -- rdos) -+ rdos | rdos64) -+ basic_machine=x86_64-pc -+ os=-rdos -+ ;; -+ rdos32) - basic_machine=i386-pc - os=-rdos - ;; -@@ -1335,21 +1352,21 @@ case $os in - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ -- | -sym* | -kopensolaris* \ -+ | -sym* | -kopensolaris* | -plan9* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* | -aros* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ -- | -openbsd* | -solidbsd* \ -+ | -bitrig* | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ - | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ -- | -mingw32* | -linux-gnu* | -linux-android* \ -- | -linux-newlib* | -linux-uclibc* \ -+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ -+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ -@@ -1481,9 +1498,6 @@ case $os in - -aros*) - os=-aros - ;; -- -kaos*) -- os=-kaos -- ;; - -zvmoe) - os=-zvmoe - ;; -@@ -1532,6 +1546,9 @@ case $basic_machine in - c4x-* | tic4x-*) - os=-coff - ;; -+ hexagon-*) -+ os=-elf -+ ;; - tic54x-*) - os=-coff - ;; -@@ -1559,9 +1576,6 @@ case $basic_machine in - ;; - m68000-sun) - os=-sunos3 -- # This also exists in the configure program, but was not the -- # default. -- # os=-sunos4 - ;; - m68*-cisco) - os=-aout -@@ -1575,6 +1589,9 @@ case $basic_machine in - mips*-*) - os=-elf - ;; -+ or1k-*) -+ os=-elf -+ ;; - or32-*) - os=-coff - ;; --- -1.9.0 - diff --git a/0009-arg-Add-no_arg-and-get_arg-helper-functions.patch b/0009-arg-Add-no_arg-and-get_arg-helper-functions.patch new file mode 100644 index 0000000..290e7dd --- /dev/null +++ b/0009-arg-Add-no_arg-and-get_arg-helper-functions.patch @@ -0,0 +1,118 @@ +From 01298aadfd0bf571b9ce745a7a198015b2a20da9 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 1 Apr 2014 11:17:07 +0100 +Subject: [PATCH 09/10] 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. + +The get_arg function simple checks the next position on the command +line exists and returns that argument or raises a Arg.Missing. + +This patch should introduce no functional change, it is simply code +refactoring. + +In particular, this should not change the treatment of Arg.current +(see: http://caml.inria.fr/mantis/view.php?id=5197#c11147) +--- + stdlib/arg.ml | 47 ++++++++++++++++++++++++++--------------------- + 1 file changed, 26 insertions(+), 21 deletions(-) + +diff --git a/stdlib/arg.ml b/stdlib/arg.ml +index 0f6480b..a41e0a2 100644 +--- a/stdlib/arg.ml ++++ b/stdlib/arg.ml +@@ -134,56 +134,62 @@ let parse_argv_dynamic ?(current=current) argv speclist anonfun errmsg = + try assoc3 s !speclist + with Not_found -> stop (Unknown s) + in ++ let no_arg () = () in ++ let get_arg () = ++ if !current + 1 < l then argv.(!current + 1) ++ else stop (Missing s) ++ in + begin try + let rec treat_action = function +- | Unit f -> f (); +- | Bool f when !current + 1 < l -> +- let arg = argv.(!current + 1) in ++ | Unit f -> no_arg (); f (); ++ | Bool f -> ++ let arg = get_arg () in + begin try f (bool_of_string arg) + with Invalid_argument "bool_of_string" -> + raise (Stop (Wrong (s, arg, "a boolean"))) + end; + incr current; +- | Set r -> r := true; +- | Clear r -> r := false; +- | String f when !current + 1 < l -> +- f argv.(!current + 1); ++ | Set r -> no_arg (); r := true; ++ | Clear r -> no_arg (); r := false; ++ | String f -> ++ let arg = get_arg () in ++ f arg; + incr current; +- | Symbol (symb, f) when !current + 1 < l -> +- let arg = argv.(!current + 1) in ++ | Symbol (symb, f) -> ++ let arg = get_arg () in + if List.mem arg symb then begin +- f argv.(!current + 1); ++ f arg; + incr current; + end else begin + raise (Stop (Wrong (s, arg, "one of: " + ^ (make_symlist "" " " "" symb)))) + end +- | Set_string r when !current + 1 < l -> +- r := argv.(!current + 1); ++ | Set_string r -> ++ r := get_arg (); + incr current; +- | Int f when !current + 1 < l -> +- let arg = argv.(!current + 1) in ++ | Int f -> ++ let arg = get_arg () in + begin try f (int_of_string arg) + with Failure "int_of_string" -> + raise (Stop (Wrong (s, arg, "an integer"))) + end; + incr current; +- | Set_int r when !current + 1 < l -> +- let arg = argv.(!current + 1) in ++ | Set_int r -> ++ let arg = get_arg () in + begin try r := (int_of_string arg) + with Failure "int_of_string" -> + raise (Stop (Wrong (s, arg, "an integer"))) + end; + incr current; +- | Float f when !current + 1 < l -> +- let arg = argv.(!current + 1) in ++ | Float f -> ++ let arg = get_arg () in + begin try f (float_of_string arg); + with Failure "float_of_string" -> + raise (Stop (Wrong (s, arg, "a float"))) + end; + incr current; +- | Set_float r when !current + 1 < l -> +- let arg = argv.(!current + 1) in ++ | Set_float r -> ++ let arg = get_arg () in + begin try r := (float_of_string arg); + with Failure "float_of_string" -> + raise (Stop (Wrong (s, arg, "a float"))) +@@ -196,7 +202,6 @@ let parse_argv_dynamic ?(current=current) argv speclist anonfun errmsg = + f argv.(!current + 1); + incr current; + done; +- | _ -> raise (Stop (Missing s)) + in + treat_action action + with Bad m -> stop (Message m); +-- +1.9.0 + diff --git a/0010-arg-Allow-flags-such-as-flag-arg-as-well-as-flag-arg.patch b/0010-arg-Allow-flags-such-as-flag-arg-as-well-as-flag-arg.patch new file mode 100644 index 0000000..9a55cdd --- /dev/null +++ b/0010-arg-Allow-flags-such-as-flag-arg-as-well-as-flag-arg.patch @@ -0,0 +1,82 @@ +From 5af2eab80b969d88ecd5bdbe55f33e20753f9ceb Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 1 Apr 2014 11:21:40 +0100 +Subject: [PATCH 10/10] arg: Allow flags such as --flag=arg as well as --flag + arg. + +Allow flags to be followed directly by their argument, separated by an '=' +sign. This is consistent with what GNU getopt_long and many other +command line parsing libraries allow. + +Fix for the following issue: +http://caml.inria.fr/mantis/view.php?id=5197 +--- + stdlib/arg.ml | 28 ++++++++++++++++++++++------ + stdlib/arg.mli | 3 ++- + 2 files changed, 24 insertions(+), 7 deletions(-) + +diff --git a/stdlib/arg.ml b/stdlib/arg.ml +index a41e0a2..88b1306 100644 +--- a/stdlib/arg.ml ++++ b/stdlib/arg.ml +@@ -55,6 +55,12 @@ let rec assoc3 x l = + | _ :: t -> assoc3 x t + ;; + ++let split s = ++ let i = String.index s '=' in ++ let len = String.length s in ++ String.sub s 0 i, String.sub s (i+1) (len-(i+1)) ++;; ++ + let make_symlist prefix sep suffix l = + match l with + | [] -> "" +@@ -130,14 +136,24 @@ let parse_argv_dynamic ?(current=current) argv speclist anonfun errmsg = + while !current < l do + let s = argv.(!current) in + if String.length s >= 1 && s.[0] = '-' then begin +- let action = +- try assoc3 s !speclist +- with Not_found -> stop (Unknown s) ++ let action, follow = ++ try assoc3 s !speclist, None ++ with Not_found -> ++ try ++ let keyword, arg = split s in ++ assoc3 keyword !speclist, Some arg ++ with Not_found -> stop (Unknown s) + in +- let no_arg () = () in ++ let no_arg () = ++ match follow with ++ | None -> () ++ | Some arg -> stop (Wrong (s, arg, "no argument")) in + let get_arg () = +- if !current + 1 < l then argv.(!current + 1) +- else stop (Missing s) ++ match follow with ++ | None -> ++ if !current + 1 < l then argv.(!current + 1) ++ else stop (Missing s) ++ | Some arg -> arg + in + begin try + let rec treat_action = function +diff --git a/stdlib/arg.mli b/stdlib/arg.mli +index 22eda40..7078071 100644 +--- a/stdlib/arg.mli ++++ b/stdlib/arg.mli +@@ -25,7 +25,8 @@ + [Unit], [Set] and [Clear] keywords take no argument. A [Rest] + keyword takes the remaining of the command line as arguments. + Every other keyword takes the following word on the command line +- as argument. ++ as argument. For compatibility with GNU getopt_long, [keyword=arg] ++ is also allowed. + Arguments not preceded by a keyword are called anonymous arguments. + + Examples ([cmd] is assumed to be the command name): +-- +1.9.0 + diff --git a/0010-arm64-Align-code-and-data-to-8-bytes.patch b/0010-arm64-Align-code-and-data-to-8-bytes.patch deleted file mode 100644 index ac0d177..0000000 --- a/0010-arm64-Align-code-and-data-to-8-bytes.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 848ca220af9224a5cc7abb64f32b89ed54c21121 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Mon, 24 Mar 2014 05:50:28 -0500 -Subject: [PATCH 10/14] arm64: Align code and data to 8 bytes. - -Insufficient alignment seems to be the cause of relocation errors when -linking large native code OCaml programs: - - (.text+0xc): relocation truncated to fit: R_AARCH64_LDST64_ABS_LO12_NC against symbol `camlOdoc_type' defined in .data section in odoc_type.o -../stdlib/stdlib.a(listLabels.o): In function `camlListLabels__entry': -(.text+0x10): relocation truncated to fit: R_AARCH64_LDST64_ABS_LO12_NC against symbol `camlListLabels' defined in .data section in ../stdlib/stdlib.a(listLabels.o) - -PR#6283 http://caml.inria.fr/mantis/view.php?id=6283 ---- - asmcomp/arm64/emit.mlp | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/asmcomp/arm64/emit.mlp b/asmcomp/arm64/emit.mlp -index fc9649c..4e7c4b0 100644 ---- a/asmcomp/arm64/emit.mlp -+++ b/asmcomp/arm64/emit.mlp -@@ -651,7 +651,7 @@ let fundecl fundecl = - call_gc_sites := []; - bound_error_sites := []; - ` .text\n`; -- ` .align 2\n`; -+ ` .align 3\n`; - ` .globl {emit_symbol fundecl.fun_name}\n`; - ` .type {emit_symbol fundecl.fun_name}, %function\n`; - `{emit_symbol fundecl.fun_name}:\n`; -@@ -692,6 +692,7 @@ let emit_item = function - - let data l = - ` .data\n`; -+ ` .align 3\n`; - List.iter emit_item l - - (* Beginning / end of an assembly file *) --- -1.9.0 - 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 deleted file mode 100644 index 4173775..0000000 --- a/0011-arg-Add-no_arg-and-get_arg-helper-functions.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 251d3447bb10550320f43512d8886561c1298f74 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 1 Apr 2014 11:17:07 +0100 -Subject: [PATCH 11/14] 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. - -The get_arg function simple checks the next position on the command -line exists and returns that argument or raises a Arg.Missing. - -This patch should introduce no functional change, it is simply code -refactoring. - -In particular, this should not change the treatment of Arg.current -(see: http://caml.inria.fr/mantis/view.php?id=5197#c11147) ---- - stdlib/arg.ml | 47 ++++++++++++++++++++++++++--------------------- - 1 file changed, 26 insertions(+), 21 deletions(-) - -diff --git a/stdlib/arg.ml b/stdlib/arg.ml -index 8b64236..c8b3d44 100644 ---- a/stdlib/arg.ml -+++ b/stdlib/arg.ml -@@ -134,56 +134,62 @@ let parse_argv_dynamic ?(current=current) argv speclist anonfun errmsg = - try assoc3 s !speclist - with Not_found -> stop (Unknown s) - in -+ let no_arg () = () in -+ let get_arg () = -+ if !current + 1 < l then argv.(!current + 1) -+ else stop (Missing s) -+ in - begin try - let rec treat_action = function -- | Unit f -> f (); -- | Bool f when !current + 1 < l -> -- let arg = argv.(!current + 1) in -+ | Unit f -> no_arg (); f (); -+ | Bool f -> -+ let arg = get_arg () in - begin try f (bool_of_string arg) - with Invalid_argument "bool_of_string" -> - raise (Stop (Wrong (s, arg, "a boolean"))) - end; - incr current; -- | Set r -> r := true; -- | Clear r -> r := false; -- | String f when !current + 1 < l -> -- f argv.(!current + 1); -+ | Set r -> no_arg (); r := true; -+ | Clear r -> no_arg (); r := false; -+ | String f -> -+ let arg = get_arg () in -+ f arg; - incr current; -- | Symbol (symb, f) when !current + 1 < l -> -- let arg = argv.(!current + 1) in -+ | Symbol (symb, f) -> -+ let arg = get_arg () in - if List.mem arg symb then begin -- f argv.(!current + 1); -+ f arg; - incr current; - end else begin - raise (Stop (Wrong (s, arg, "one of: " - ^ (make_symlist "" " " "" symb)))) - end -- | Set_string r when !current + 1 < l -> -- r := argv.(!current + 1); -+ | Set_string r -> -+ r := get_arg (); - incr current; -- | Int f when !current + 1 < l -> -- let arg = argv.(!current + 1) in -+ | Int f -> -+ let arg = get_arg () in - begin try f (int_of_string arg) - with Failure "int_of_string" -> - raise (Stop (Wrong (s, arg, "an integer"))) - end; - incr current; -- | Set_int r when !current + 1 < l -> -- let arg = argv.(!current + 1) in -+ | Set_int r -> -+ let arg = get_arg () in - begin try r := (int_of_string arg) - with Failure "int_of_string" -> - raise (Stop (Wrong (s, arg, "an integer"))) - end; - incr current; -- | Float f when !current + 1 < l -> -- let arg = argv.(!current + 1) in -+ | Float f -> -+ let arg = get_arg () in - begin try f (float_of_string arg); - with Failure "float_of_string" -> - raise (Stop (Wrong (s, arg, "a float"))) - end; - incr current; -- | Set_float r when !current + 1 < l -> -- let arg = argv.(!current + 1) in -+ | Set_float r -> -+ let arg = get_arg () in - begin try r := (float_of_string arg); - with Failure "float_of_string" -> - raise (Stop (Wrong (s, arg, "a float"))) -@@ -196,7 +202,6 @@ let parse_argv_dynamic ?(current=current) argv speclist anonfun errmsg = - f argv.(!current + 1); - incr current; - done; -- | _ -> raise (Stop (Missing s)) - in - treat_action action - with Bad m -> stop (Message m); --- -1.9.0 - 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 deleted file mode 100644 index 4a1ba25..0000000 --- a/0012-arg-Allow-flags-such-as-flag-arg-as-well-as-flag-arg.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 57955b8a4d4cf7732cb87964f5e124ab713e084b Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Tue, 1 Apr 2014 11:21:40 +0100 -Subject: [PATCH 12/14] arg: Allow flags such as --flag=arg as well as --flag - arg. - -Allow flags to be followed directly by their argument, separated by an '=' -sign. This is consistent with what GNU getopt_long and many other -command line parsing libraries allow. - -Fix for the following issue: -http://caml.inria.fr/mantis/view.php?id=5197 ---- - stdlib/arg.ml | 28 ++++++++++++++++++++++------ - stdlib/arg.mli | 3 ++- - 2 files changed, 24 insertions(+), 7 deletions(-) - -diff --git a/stdlib/arg.ml b/stdlib/arg.ml -index c8b3d44..766de5f 100644 ---- a/stdlib/arg.ml -+++ b/stdlib/arg.ml -@@ -55,6 +55,12 @@ let rec assoc3 x l = - | _ :: t -> assoc3 x t - ;; - -+let split s = -+ let i = String.index s '=' in -+ let len = String.length s in -+ String.sub s 0 i, String.sub s (i+1) (len-(i+1)) -+;; -+ - let make_symlist prefix sep suffix l = - match l with - | [] -> "" -@@ -130,14 +136,24 @@ let parse_argv_dynamic ?(current=current) argv speclist anonfun errmsg = - while !current < l do - let s = argv.(!current) in - if String.length s >= 1 && String.get s 0 = '-' then begin -- let action = -- try assoc3 s !speclist -- with Not_found -> stop (Unknown s) -+ let action, follow = -+ try assoc3 s !speclist, None -+ with Not_found -> -+ try -+ let keyword, arg = split s in -+ assoc3 keyword !speclist, Some arg -+ with Not_found -> stop (Unknown s) - in -- let no_arg () = () in -+ let no_arg () = -+ match follow with -+ | None -> () -+ | Some arg -> stop (Wrong (s, arg, "no argument")) in - let get_arg () = -- if !current + 1 < l then argv.(!current + 1) -- else stop (Missing s) -+ match follow with -+ | None -> -+ if !current + 1 < l then argv.(!current + 1) -+ else stop (Missing s) -+ | Some arg -> arg - in - begin try - let rec treat_action = function -diff --git a/stdlib/arg.mli b/stdlib/arg.mli -index 869d030..b8c6f11 100644 ---- a/stdlib/arg.mli -+++ b/stdlib/arg.mli -@@ -25,7 +25,8 @@ - [Unit], [Set] and [Clear] keywords take no argument. A [Rest] - keyword takes the remaining of the command line as arguments. - Every other keyword takes the following word on the command line -- as argument. -+ as argument. For compatibility with GNU getopt_long, [keyword=arg] -+ is also allowed. - Arguments not preceded by a keyword are called anonymous arguments. - - Examples ([cmd] is assumed to be the command name): --- -1.9.0 - diff --git a/0013-Add-support-for-ppc64le.patch b/0013-Add-support-for-ppc64le.patch deleted file mode 100644 index d3b4e3b..0000000 --- a/0013-Add-support-for-ppc64le.patch +++ /dev/null @@ -1,1917 +0,0 @@ -From d9ec3ac29493999687b0f7daa23f4888bc57c7be Mon Sep 17 00:00:00 2001 -From: Michel Normand -Date: Tue, 18 Mar 2014 09:15:47 -0400 -Subject: [PATCH 13/14] Add support for ppc64le. - -Signed-off-by: Michel Normand ---- - asmcomp/power64le/arch.ml | 88 ++++ - asmcomp/power64le/emit.mlp | 981 ++++++++++++++++++++++++++++++++++++++++ - asmcomp/power64le/proc.ml | 240 ++++++++++ - asmcomp/power64le/reload.ml | 18 + - asmcomp/power64le/scheduling.ml | 65 +++ - asmcomp/power64le/selection.ml | 101 +++++ - asmrun/Makefile | 6 + - asmrun/power64-elf.S | 95 +++- - asmrun/power64le-elf.S | 1 + - asmrun/stack.h | 9 + - config/gnu/config.guess | 3 + - configure | 3 + - 12 files changed, 1609 insertions(+), 1 deletion(-) - create mode 100644 asmcomp/power64le/arch.ml - create mode 100644 asmcomp/power64le/emit.mlp - create mode 100644 asmcomp/power64le/proc.ml - create mode 100644 asmcomp/power64le/reload.ml - create mode 100644 asmcomp/power64le/scheduling.ml - create mode 100644 asmcomp/power64le/selection.ml - create mode 120000 asmrun/power64le-elf.S - -diff --git a/asmcomp/power64le/arch.ml b/asmcomp/power64le/arch.ml -new file mode 100644 -index 0000000..586534b ---- /dev/null -+++ b/asmcomp/power64le/arch.ml -@@ -0,0 +1,88 @@ -+(***********************************************************************) -+(* *) -+(* Objective Caml *) -+(* *) -+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) -+(* *) -+(* 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. *) -+(* *) -+(***********************************************************************) -+ -+(* $Id: arch.ml 9547 2010-01-22 12:48:24Z doligez $ *) -+ -+(* Specific operations for the PowerPC processor *) -+ -+open Format -+ -+(* Machine-specific command-line options *) -+ -+let command_line_options = [] -+ -+(* Specific operations *) -+ -+type specific_operation = -+ Imultaddf (* multiply and add *) -+ | Imultsubf (* multiply and subtract *) -+ | Ialloc_far of int (* allocation in large functions *) -+ -+(* Addressing modes *) -+ -+type addressing_mode = -+ Ibased of string * int (* symbol + displ *) -+ | Iindexed of int (* reg + displ *) -+ | Iindexed2 (* reg + reg *) -+ -+(* Sizes, endianness *) -+ -+let big_endian = false -+ -+let size_addr = 8 -+let size_int = size_addr -+let size_float = 8 -+ -+let allow_unaligned_access = false -+ -+(* Behavior of division *) -+ -+let division_crashes_on_overflow = false -+ -+(* Operations on addressing modes *) -+ -+let identity_addressing = Iindexed 0 -+ -+let offset_addressing addr delta = -+ match addr with -+ Ibased(s, n) -> Ibased(s, n + delta) -+ | Iindexed n -> Iindexed(n + delta) -+ | Iindexed2 -> assert false -+ -+let num_args_addressing = function -+ Ibased(s, n) -> 0 -+ | Iindexed n -> 1 -+ | Iindexed2 -> 2 -+ -+(* Printing operations and addressing modes *) -+ -+let print_addressing printreg addr ppf arg = -+ match addr with -+ | Ibased(s, n) -> -+ let idx = if n <> 0 then Printf.sprintf " + %i" n else "" in -+ fprintf ppf "\"%s\"%s" s idx -+ | Iindexed n -> -+ let idx = if n <> 0 then Printf.sprintf " + %i" n else "" in -+ fprintf ppf "%a%s" printreg arg.(0) idx -+ | Iindexed2 -> -+ fprintf ppf "%a + %a" printreg arg.(0) printreg arg.(1) -+ -+let print_specific_operation printreg op ppf arg = -+ match op with -+ | Imultaddf -> -+ fprintf ppf "%a *f %a +f %a" -+ printreg arg.(0) printreg arg.(1) printreg arg.(2) -+ | Imultsubf -> -+ fprintf ppf "%a *f %a -f %a" -+ printreg arg.(0) printreg arg.(1) printreg arg.(2) -+ | Ialloc_far n -> -+ fprintf ppf "alloc_far %d" n -diff --git a/asmcomp/power64le/emit.mlp b/asmcomp/power64le/emit.mlp -new file mode 100644 -index 0000000..5736a18 ---- /dev/null -+++ b/asmcomp/power64le/emit.mlp -@@ -0,0 +1,981 @@ -+(***********************************************************************) -+(* *) -+(* Objective Caml *) -+(* *) -+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) -+(* *) -+(* 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. *) -+(* *) -+(***********************************************************************) -+ -+(* $Id: emit.mlp 9547 2010-01-22 12:48:24Z doligez $ *) -+ -+(* Emission of PowerPC assembly code *) -+ -+module StringSet = Set.Make(struct type t = string let compare = compare end) -+ -+open Misc -+open Cmm -+open Arch -+open Proc -+open Reg -+open Mach -+open Linearize -+open Emitaux -+ -+(* Layout of the stack. The stack is kept 16-aligned. *) -+ -+let stack_size_lbl = ref 0 -+let stack_slot_lbl = ref 0 -+let stack_args_size = ref 0 -+let stack_traps_size = ref 0 -+ -+(* We have a stack frame of our own if we call other functions (including -+ use of exceptions, or if we need more than the red zone *) -+let has_stack_frame () = -+ if !contains_calls || (num_stack_slots.(0) + num_stack_slots.(1)) > (288-16)/8 then -+ true -+ else -+ false -+ -+let frame_size_sans_args () = -+ let size = 8 * num_stack_slots.(0) + 8 * num_stack_slots.(1) + 48 in -+ Misc.align size 16 -+ -+let slot_offset loc cls = -+ match loc with -+ Local n -> -+ if cls = 0 -+ then (!stack_slot_lbl, num_stack_slots.(1) * 8 + n * 8) -+ else (!stack_slot_lbl, n * 8) -+ | Incoming n -> ((if has_stack_frame() then !stack_size_lbl else 0), 48 + n) -+ | Outgoing n -> (0, n) -+ -+(* Output a symbol *) -+ -+let emit_symbol = -+ match Config.system with -+ | "elf" | "bsd" -> (fun s -> Emitaux.emit_symbol '.' s) -+ | "rhapsody" -> (fun s -> emit_char '_'; Emitaux.emit_symbol '$' s) -+ | _ -> assert false -+ -+(* Output a label *) -+ -+let label_prefix = -+ match Config.system with -+ | "elf" | "bsd" -> ".L" -+ | "rhapsody" -> "L" -+ | _ -> assert false -+ -+let emit_label lbl = -+ emit_string label_prefix; emit_int lbl -+ -+(* Section switching *) -+ -+let toc_space = -+ match Config.system with -+ | "elf" | "bsd" -> " .section \".toc\",\"aw\"\n" -+ | "rhapsody" -> " .toc\n" -+ | _ -> assert false -+ -+let data_space = -+ match Config.system with -+ | "elf" | "bsd" -> " .section \".data\"\n" -+ | "rhapsody" -> " .data\n" -+ | _ -> assert false -+ -+let abiversion = -+ match Config.system with -+ | "elf" | "bsd" -> " .abiversion 2\n" -+ | _ -> assert false -+ -+let code_space = -+ match Config.system with -+ | "elf" | "bsd" -> " .section \".text\"\n" -+ | "rhapsody" -> " .text\n" -+ | _ -> assert false -+ -+let rodata_space = -+ match Config.system with -+ | "elf" | "bsd" -> " .section \".rodata\"\n" -+ | "rhapsody" -> " .const\n" -+ | _ -> assert false -+ -+(* Output a pseudo-register *) -+ -+let emit_reg r = -+ match r.loc with -+ Reg r -> emit_string (register_name r) -+ | _ -> fatal_error "Emit.emit_reg" -+ -+let use_full_regnames = -+ Config.system = "rhapsody" -+ -+let emit_gpr r = -+ if use_full_regnames then emit_char 'r'; -+ emit_int r -+ -+let emit_fpr r = -+ if use_full_regnames then emit_char 'f'; -+ emit_int r -+ -+let emit_ccr r = -+ if use_full_regnames then emit_string "cr"; -+ emit_int r -+ -+(* Output a stack reference *) -+ -+let emit_stack r = -+ match r.loc with -+ Stack s -> -+ let lbl, ofs = slot_offset s (register_class r) in -+ if lbl > 0 then -+ `{emit_label lbl}+`; -+ `{emit_int ofs}({emit_gpr 1})` -+ | _ -> fatal_error "Emit.emit_stack" -+ -+(* Split a 32-bit integer constants in two 16-bit halves *) -+ -+let low n = n land 0xFFFF -+let high n = n asr 16 -+ -+let nativelow n = Nativeint.to_int n land 0xFFFF -+let nativehigh n = Nativeint.to_int (Nativeint.shift_right n 16) -+ -+let is_immediate n = -+ n <= 32767 && n >= -32768 -+ -+let is_native_immediate n = -+ n <= 32767n && n >= -32768n -+ -+ -+type tocentry = -+ TocSymOfs of (string * int) -+ | TocLabel of int -+ | TocInt of nativeint -+ | TocFloat of string -+ -+(* List of all labels in tocref (reverse order) *) -+let tocref_entries = ref [] -+ -+(* Output a TOC reference *) -+ -+let emit_symbol_offset (s, d) = -+ emit_symbol s; -+ if d > 0 then `+`; -+ if d <> 0 then emit_int d -+ -+let emit_tocentry entry = -+ match entry with -+ TocSymOfs(s,d) -> emit_symbol_offset(s,d) -+ | TocInt i -> emit_nativeint i -+ | TocFloat f -> emit_string f -+ | TocLabel lbl -> emit_label lbl -+ -+ let rec tocref_label = function -+ ( [] , content ) -> -+ let lbl = new_label() in -+ tocref_entries := (lbl, content) :: !tocref_entries; -+ lbl -+ | ( (lbl, o_content) :: lst, content) -> -+ if content = o_content then -+ lbl -+ else -+ tocref_label (lst, content) -+ -+let emit_tocref entry = -+ let lbl = tocref_label (!tocref_entries,entry) in -+ emit_label lbl; emit_string "@toc(2) #"; emit_tocentry entry -+ -+ -+(* Output a load or store operation *) -+ -+let valid_offset instr ofs = -+ ofs land 3 = 0 || (instr <> "ld" && instr <> "std") -+ -+let emit_load_store instr addressing_mode addr n arg = -+ match addressing_mode with -+ Ibased(s, d) -> -+ let dd = (d + 0x8000) in (* We can only offset by -0x8000 .. +0x7fff *) -+ let a = (dd land -0x10000) in -+ let b = (dd land 0xffff) - 0x8000 in -+ ` ld {emit_gpr 11}, {emit_tocref (TocSymOfs (s,a))}\n`; -+ ` {emit_string instr} {emit_reg arg}, {emit_int b}({emit_gpr 11})\n` -+ | Iindexed ofs -> -+ if is_immediate ofs && valid_offset instr ofs then -+ ` {emit_string instr} {emit_reg arg}, {emit_int ofs}({emit_reg addr.(n)})\n` -+ else begin -+ ` lis {emit_gpr 0}, {emit_int(high ofs)}\n`; -+ if low ofs <> 0 then -+ ` ori {emit_gpr 0}, {emit_gpr 0}, {emit_int(low ofs)}\n`; -+ ` {emit_string instr}x {emit_reg arg}, {emit_reg addr.(n)}, {emit_gpr 0}\n` -+ end -+ | Iindexed2 -> -+ ` {emit_string instr}x {emit_reg arg}, {emit_reg addr.(n)}, {emit_reg addr.(n+1)}\n` -+ -+(* After a comparison, extract the result as 0 or 1 *) -+ -+let emit_set_comp cmp res = -+ ` mfcr {emit_gpr 0}\n`; -+ let bitnum = -+ match cmp with -+ Ceq | Cne -> 2 -+ | Cgt | Cle -> 1 -+ | Clt | Cge -> 0 in -+` rlwinm {emit_reg res}, {emit_gpr 0}, {emit_int(bitnum+1)}, 31, 31\n`; -+ begin match cmp with -+ Cne | Cle | Cge -> ` xori {emit_reg res}, {emit_reg res}, 1\n` -+ | _ -> () -+ end -+ -+(* Record live pointers at call points *) -+ -+type frame_descr = -+ { fd_lbl: int; (* Return address *) -+ fd_frame_size_lbl: int; (* Size of stack frame *) -+ fd_live_offset: (int * int) list } (* Offsets/regs of live addresses *) -+ -+let frame_descriptors = ref([] : frame_descr list) -+ -+let record_frame live = -+ let lbl = new_label() in -+ let live_offset = ref [] in -+ Reg.Set.iter -+ (function -+ {typ = Addr; loc = Reg r} -> -+ live_offset := (0, (r lsl 1) + 1) :: !live_offset -+ | {typ = Addr; loc = Stack s} as reg -> -+ live_offset := slot_offset s (register_class reg) :: !live_offset -+ | _ -> ()) -+ live; -+ frame_descriptors := -+ { fd_lbl = lbl; -+ fd_frame_size_lbl = !stack_size_lbl; (* frame_size *) -+ fd_live_offset = !live_offset } :: !frame_descriptors; -+ `{emit_label lbl}:\n` -+ -+let emit_frame fd = -+ ` .quad {emit_label fd.fd_lbl} + 4\n`; -+ ` .short {emit_label fd.fd_frame_size_lbl}\n`; -+ ` .short {emit_int (List.length fd.fd_live_offset)}\n`; -+ List.iter -+ (fun (lbl,n) -> -+ ` .short `; -+ if lbl > 0 then `{emit_label lbl}+`; -+ `{emit_int n}\n`) -+ fd.fd_live_offset; -+ ` .align 3\n` -+ -+(* Record external C functions to be called in a position-independent way -+ (for MacOSX) *) -+ -+let pic_externals = (Config.system = "rhapsody") -+ -+let external_functions = ref StringSet.empty -+ -+let emit_external s = -+ ` .non_lazy_symbol_pointer\n`; -+ `L{emit_symbol s}$non_lazy_ptr:\n`; -+ ` .indirect_symbol {emit_symbol s}\n`; -+ ` .quad 0\n` -+ -+(* Names for conditional branches after comparisons *) -+ -+let branch_for_comparison = function -+ Ceq -> "beq" | Cne -> "bne" -+ | Cle -> "ble" | Cgt -> "bgt" -+ | Cge -> "bge" | Clt -> "blt" -+ -+let name_for_int_comparison = function -+ Isigned cmp -> ("cmpd", branch_for_comparison cmp) -+ | Iunsigned cmp -> ("cmpld", branch_for_comparison cmp) -+ -+(* Names for various instructions *) -+ -+let name_for_intop = function -+ Iadd -> "add" -+ | Imul -> "mulld" -+ | Idiv -> "divd" -+ | Iand -> "and" -+ | Ior -> "or" -+ | Ixor -> "xor" -+ | Ilsl -> "sld" -+ | Ilsr -> "srd" -+ | Iasr -> "srad" -+ | _ -> Misc.fatal_error "Emit.Intop" -+ -+let name_for_intop_imm = function -+ Iadd -> "addi" -+ | Imul -> "mulli" -+ | Iand -> "andi." -+ | Ior -> "ori" -+ | Ixor -> "xori" -+ | Ilsl -> "sldi" -+ | Ilsr -> "srdi" -+ | Iasr -> "sradi" -+ | _ -> Misc.fatal_error "Emit.Intop_imm" -+ -+let name_for_floatop1 = function -+ Inegf -> "fneg" -+ | Iabsf -> "fabs" -+ | _ -> Misc.fatal_error "Emit.Iopf1" -+ -+let name_for_floatop2 = function -+ Iaddf -> "fadd" -+ | Isubf -> "fsub" -+ | Imulf -> "fmul" -+ | Idivf -> "fdiv" -+ | _ -> Misc.fatal_error "Emit.Iopf2" -+ -+let name_for_specific = function -+ Imultaddf -> "fmadd" -+ | Imultsubf -> "fmsub" -+ | _ -> Misc.fatal_error "Emit.Ispecific" -+ -+(* Name of current function *) -+let function_name = ref "" -+(* Entry point for tail recursive calls *) -+let tailrec_entry_point = ref 0 -+(* Names of functions defined in the current file *) -+let defined_functions = ref StringSet.empty -+(* Label of glue code for calling the GC *) -+let call_gc_label = ref 0 -+(* Label of jump table *) -+let lbl_jumptbl = ref 0 -+(* List of all labels in jumptable (reverse order) *) -+let jumptbl_entries = ref [] -+(* Number of jumptable entries *) -+let num_jumptbl_entries = ref 0 -+ -+(* Fixup conditional branches that exceed hardware allowed range *) -+ -+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) -> if is_native_immediate n then 1 else 2 -+ | Lop(Iconst_float s) -> 2 -+ | Lop(Iconst_symbol s) -> 2 -+ | Lop(Icall_ind) -> 4 -+ | Lop(Icall_imm s) -> 5 -+ | Lop(Itailcall_ind) -> if !contains_calls then 5 else if has_stack_frame() then 3 else 2 -+ | Lop(Itailcall_imm s) -> if s = !function_name then 1 else -+ if !contains_calls then 6 else -+ if has_stack_frame() then 4 else 3 -+ | Lop(Iextcall(s, true)) -> 6 -+ | Lop(Iextcall(s, false)) -> 5 -+ | Lop(Istackoffset n) -> 0 -+ | 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(Idiv, n)) -> 2 -+ | Lop(Iintop_imm(Imod, n)) -> 4 -+ | Lop(Iintop_imm(Icomp cmp, n)) -> 4 -+ | Lop(Iintop_imm(op, n)) -> 1 -+ | Lop(Inegf | Iabsf | Iaddf | Isubf | Imulf | Idivf) -> 1 -+ | Lop(Ifloatofint) -> 3 -+ | Lop(Iintoffloat) -> 3 -+ | Lop(Ispecific sop) -> 1 -+ | Lreloadretaddr -> 2 -+ | Lreturn -> if has_stack_frame() then 2 else 1 -+ | 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 -> 7 -+ | Lsetuptrap lbl -> 1 -+ | Lpushtrap -> 7 -+ | Lpoptrap -> 1 -+ | 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 () -+ -+ -+(* Output the assembly code for an instruction *) -+ -+let rec emit_instr i dslot = -+ match i.desc with -+ Lend -> () -+ | Lop(Imove | Ispill | Ireload) -> -+ let src = i.arg.(0) and dst = i.res.(0) in -+ if src.loc <> dst.loc then begin -+ match (src, dst) with -+ {loc = Reg rs; typ = (Int | Addr)}, {loc = Reg rd} -> -+ ` mr {emit_reg dst}, {emit_reg src}\n` -+ | {loc = Reg rs; typ = Float}, {loc = Reg rd; typ = Float} -> -+ ` fmr {emit_reg dst}, {emit_reg src}\n` -+ | {loc = Reg rs; typ = (Int | Addr)}, {loc = Stack sd} -> -+ ` std {emit_reg src}, {emit_stack dst}\n` -+ | {loc = Reg rs; typ = Float}, {loc = Stack sd} -> -+ ` stfd {emit_reg src}, {emit_stack dst}\n` -+ | {loc = Stack ss; typ = (Int | Addr)}, {loc = Reg rd} -> -+ ` ld {emit_reg dst}, {emit_stack src}\n` -+ | {loc = Stack ss; typ = Float}, {loc = Reg rd} -> -+ ` lfd {emit_reg dst}, {emit_stack src}\n` -+ | (_, _) -> -+ fatal_error "Emit: Imove" -+ end -+ | Lop(Iconst_int n) -> -+ if is_native_immediate n then -+ ` li {emit_reg i.res.(0)}, {emit_nativeint n}\n` -+ else if n >= -0x8000_0000n && n <= 0x7FFF_FFFFn then begin -+ ` lis {emit_reg i.res.(0)}, {emit_int(nativehigh n)}\n`; -+ if nativelow n <> 0 then -+ ` ori {emit_reg i.res.(0)}, {emit_reg i.res.(0)}, {emit_int(nativelow n)}\n` -+ end else begin -+ ` ld {emit_reg i.res.(0)}, {emit_tocref (TocInt n)}\n` -+ end -+ | Lop(Iconst_float s) -> -+ ` lfd {emit_reg i.res.(0)}, {emit_tocref (TocFloat s)}\n` -+ | Lop(Iconst_symbol s) -> -+ ` ld {emit_reg i.res.(0)}, {emit_tocref (TocSymOfs (s,0))}\n` -+ | Lop(Icall_ind) -> -+ ` std {emit_gpr 2},24({emit_gpr 1})\n`; -+ ` mtctr {emit_reg i.arg.(0)}\n`; -+ record_frame i.live; -+ ` bctrl\n`; -+ ` ld {emit_gpr 2},24({emit_gpr 1})\n` -+ | Lop(Icall_imm s) -> -+ ` ld {emit_gpr 12}, {emit_tocref (TocSymOfs (s,0))}\n`; -+ ` std {emit_gpr 2},24({emit_gpr 1})\n`; -+ ` mtctr {emit_gpr 12}\n`; -+ record_frame i.live; -+ ` bctrl\n`; -+ ` ld {emit_gpr 2},24({emit_gpr 1})\n` -+ | Lop(Itailcall_ind) -> -+ ` mtctr {emit_reg i.arg.(0)}\n`; -+ if has_stack_frame() then -+ ` ld {emit_gpr 1}, 0({emit_gpr 1})\n`; -+ if !contains_calls then begin -+ ` ld {emit_gpr 12}, 16({emit_gpr 1})\n`; -+ ` mtlr {emit_gpr 12}\n` -+ end; -+ ` bctr\n` -+ | Lop(Itailcall_imm s) -> -+ if s = !function_name then -+ ` b {emit_label !tailrec_entry_point}\n` -+ else begin -+ if has_stack_frame() then -+ ` ld {emit_gpr 1}, 0({emit_gpr 1})\n`; -+ if !contains_calls then begin -+ ` ld {emit_gpr 12}, 16({emit_gpr 1})\n`; -+ ` mtlr {emit_gpr 12}\n` -+ end; -+ ` ld {emit_gpr 12}, {emit_tocref (TocSymOfs (s,0))}\n`; -+ ` mtctr {emit_gpr 12}\n`; -+ ` bctr\n` -+ end -+ | Lop(Iextcall(s, alloc)) -> -+ if alloc then begin -+ ` ld {emit_gpr 11}, {emit_tocref (TocSymOfs (s,0))}\n`; -+ ` ld {emit_gpr 12}, {emit_tocref (TocSymOfs ("caml_c_call",0))}\n`; -+ end else -+ ` ld {emit_gpr 12}, {emit_tocref (TocSymOfs (s,0))}\n`; -+ ` std {emit_gpr 2}, 24({emit_gpr 1})\n`; -+ ` mtctr {emit_gpr 12}\n`; -+ if alloc then record_frame i.live; -+ ` bctrl\n`; -+ ` ld {emit_gpr 2}, 24({emit_gpr 1})\n` -+ | Lop(Istackoffset n) -> -+ if n > !stack_args_size then -+ stack_args_size := n -+ | Lop(Iload(chunk, addr)) -> -+ let loadinstr = -+ match chunk with -+ Byte_unsigned -> "lbz" -+ | Byte_signed -> "lbz" -+ | Sixteen_unsigned -> "lhz" -+ | Sixteen_signed -> "lha" -+ | Thirtytwo_unsigned -> "lwz" -+ | Thirtytwo_signed -> "lwa" -+ | Word -> "ld" -+ | Single -> "lfs" -+ | Double | Double_u -> "lfd" in -+ emit_load_store loadinstr addr i.arg 0 i.res.(0); -+ if chunk = Byte_signed then -+ ` extsb {emit_reg i.res.(0)}, {emit_reg i.res.(0)}\n` -+ | Lop(Istore(chunk, addr)) -> -+ let storeinstr = -+ match chunk with -+ Byte_unsigned | Byte_signed -> "stb" -+ | Sixteen_unsigned | Sixteen_signed -> "sth" -+ | Thirtytwo_unsigned | Thirtytwo_signed -> "stw" -+ | Word -> "std" -+ | Single -> "stfs" -+ | Double | Double_u -> "stfd" in -+ emit_load_store storeinstr addr i.arg 1 i.arg.(0) -+ | Lop(Ialloc n) -> -+ if !call_gc_label = 0 then call_gc_label := new_label(); -+ ` addi {emit_gpr 31}, {emit_gpr 31}, {emit_int(-n)}\n`; -+ ` cmpld {emit_gpr 31}, {emit_gpr 30}\n`; -+ ` addi {emit_reg i.res.(0)}, {emit_gpr 31}, 8\n`; -+ record_frame i.live; -+ ` bltl {emit_label !call_gc_label}\n` (* Must be 4 insns to restart *) -+ | Lop(Ispecific(Ialloc_far n)) -> -+ if !call_gc_label = 0 then call_gc_label := new_label(); -+ let lbl = new_label() in -+ ` addi {emit_gpr 31}, {emit_gpr 31}, {emit_int(-n)}\n`; -+ ` cmpld {emit_gpr 31}, {emit_gpr 30}\n`; -+ ` bge {emit_label lbl}\n`; -+ record_frame i.live; -+ ` bl {emit_label !call_gc_label}\n`; (* Must be 4 insns to restart *) -+ `{emit_label lbl}: addi {emit_reg i.res.(0)}, {emit_gpr 31}, {emit_int size_addr}\n` -+ | Lop(Iintop Isub) -> (* subfc has swapped arguments *) -+ ` subfc {emit_reg i.res.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n` -+ | Lop(Iintop Imod) -> -+ ` divd {emit_gpr 0}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; -+ ` mulld {emit_gpr 0}, {emit_gpr 0}, {emit_reg i.arg.(1)}\n`; -+ ` subfc {emit_reg i.res.(0)}, {emit_gpr 0}, {emit_reg i.arg.(0)}\n` -+ | Lop(Iintop(Icomp cmp)) -> -+ begin match cmp with -+ Isigned c -> -+ ` cmpd {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; -+ emit_set_comp c i.res.(0) -+ | Iunsigned c -> -+ ` cmpld {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; -+ emit_set_comp c i.res.(0) -+ end -+ | Lop(Iintop Icheckbound) -> -+ ` tdlle {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n` -+ | Lop(Iintop op) -> -+ let instr = name_for_intop op in -+ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n` -+ | Lop(Iintop_imm(Isub, n)) -> -+ ` addi {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_int(-n)}\n` -+ | Lop(Iintop_imm(Idiv, n)) -> (* n is guaranteed to be a power of 2 *) -+ let l = Misc.log2 n in -+ ` sradi {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_int l}\n`; -+ ` addze {emit_reg i.res.(0)}, {emit_reg i.res.(0)}\n` -+ | Lop(Iintop_imm(Imod, n)) -> (* n is guaranteed to be a power of 2 *) -+ let l = Misc.log2 n in -+ ` sradi {emit_gpr 0}, {emit_reg i.arg.(0)}, {emit_int l}\n`; -+ ` addze {emit_gpr 0}, {emit_gpr 0}\n`; -+ ` sldi {emit_gpr 0}, {emit_gpr 0}, {emit_int l}\n`; -+ ` subfc {emit_reg i.res.(0)}, {emit_gpr 0}, {emit_reg i.arg.(0)}\n` -+ | Lop(Iintop_imm(Icomp cmp, n)) -> -+ begin match cmp with -+ Isigned c -> -+ ` cmpdi {emit_reg i.arg.(0)}, {emit_int n}\n`; -+ emit_set_comp c i.res.(0) -+ | Iunsigned c -> -+ ` cmpldi {emit_reg i.arg.(0)}, {emit_int n}\n`; -+ emit_set_comp c i.res.(0) -+ end -+ | Lop(Iintop_imm(Icheckbound, n)) -> -+ ` tdllei {emit_reg i.arg.(0)}, {emit_int n}\n` -+ | Lop(Iintop_imm(op, n)) -> -+ let instr = name_for_intop_imm op in -+ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_int n}\n` -+ | Lop(Inegf | Iabsf as op) -> -+ let instr = name_for_floatop1 op in -+ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}\n` -+ | Lop(Iaddf | Isubf | Imulf | Idivf as op) -> -+ let instr = name_for_floatop2 op in -+ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n` -+ | Lop(Ifloatofint) -> -+ let ofs = if has_stack_frame() then 16 else 8 * (2 + num_stack_slots.(0) + num_stack_slots.(1)) in -+ ` std {emit_reg i.arg.(0)}, -{emit_int ofs}({emit_gpr 1})\n`; -+ ` lfd {emit_reg i.res.(0)}, -{emit_int ofs}({emit_gpr 1})\n`; -+ ` fcfid {emit_reg i.res.(0)}, {emit_reg i.res.(0)}\n` -+ | Lop(Iintoffloat) -> -+ let ofs = if has_stack_frame() then 16 else 8 * (2 + num_stack_slots.(0) + num_stack_slots.(1)) in -+ ` fctidz {emit_fpr 0}, {emit_reg i.arg.(0)}\n`; -+ ` stfd {emit_fpr 0}, -{emit_int ofs}({emit_gpr 1})\n`; -+ ` ld {emit_reg i.res.(0)}, -{emit_int ofs}({emit_gpr 1})\n` -+ | Lop(Ispecific sop) -> -+ let instr = name_for_specific sop in -+ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(2)}\n` -+ | Lreloadretaddr -> -+ if has_stack_frame() then begin -+ ` ld {emit_gpr 12}, {emit_label !stack_size_lbl}+16({emit_gpr 1})\n`; -+ ` mtlr {emit_gpr 12}\n` -+ end -+ | Lreturn -> -+ if has_stack_frame() then -+ ` ld {emit_gpr 1}, 0({emit_gpr 1})\n`; -+ ` blr\n` -+ | Llabel lbl -> -+ `{emit_label lbl}:\n` -+ | Lbranch lbl -> -+ ` b {emit_label lbl}\n` -+ | Lcondbranch(tst, lbl) -> -+ begin match tst with -+ Itruetest -> -+ ` cmpdi {emit_reg i.arg.(0)}, 0\n`; -+ emit_delay dslot; -+ ` bne {emit_label lbl}\n` -+ | Ifalsetest -> -+ ` cmpdi {emit_reg i.arg.(0)}, 0\n`; -+ emit_delay dslot; -+ ` beq {emit_label lbl}\n` -+ | Iinttest cmp -> -+ let (comp, branch) = name_for_int_comparison cmp in -+ ` {emit_string comp} {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; -+ emit_delay dslot; -+ ` {emit_string branch} {emit_label lbl}\n` -+ | Iinttest_imm(cmp, n) -> -+ let (comp, branch) = name_for_int_comparison cmp in -+ ` {emit_string comp}i {emit_reg i.arg.(0)}, {emit_int n}\n`; -+ emit_delay dslot; -+ ` {emit_string branch} {emit_label lbl}\n` -+ | Ifloattest(cmp, neg) -> -+ ` fcmpu {emit_ccr 0}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; -+ (* bit 0 = lt, bit 1 = gt, bit 2 = eq *) -+ let (bitnum, negtst) = -+ match cmp with -+ Ceq -> (2, neg) -+ | Cne -> (2, not neg) -+ | Cle -> ` cror 3, 0, 2\n`; (* lt or eq *) -+ (3, neg) -+ | Cgt -> (1, neg) -+ | Cge -> ` cror 3, 1, 2\n`; (* gt or eq *) -+ (3, neg) -+ | Clt -> (0, neg) in -+ emit_delay dslot; -+ if negtst -+ then ` bf {emit_int bitnum}, {emit_label lbl}\n` -+ else ` bt {emit_int bitnum}, {emit_label lbl}\n` -+ | Ioddtest -> -+ ` andi. {emit_gpr 0}, {emit_reg i.arg.(0)}, 1\n`; -+ emit_delay dslot; -+ ` bne {emit_label lbl}\n` -+ | Ieventest -> -+ ` andi. {emit_gpr 0}, {emit_reg i.arg.(0)}, 1\n`; -+ emit_delay dslot; -+ ` beq {emit_label lbl}\n` -+ end -+ | Lcondbranch3(lbl0, lbl1, lbl2) -> -+ ` cmpdi {emit_reg i.arg.(0)}, 1\n`; -+ emit_delay dslot; -+ begin match lbl0 with -+ None -> () -+ | Some lbl -> ` blt {emit_label lbl}\n` -+ end; -+ begin match lbl1 with -+ None -> () -+ | Some lbl -> ` beq {emit_label lbl}\n` -+ end; -+ begin match lbl2 with -+ None -> () -+ | Some lbl -> ` bgt {emit_label lbl}\n` -+ end -+ | Lswitch jumptbl -> -+ if !lbl_jumptbl = 0 then lbl_jumptbl := new_label(); -+ ` ld {emit_gpr 11}, {emit_tocref (TocLabel !lbl_jumptbl)}\n`; -+ ` addi {emit_gpr 0}, {emit_reg i.arg.(0)}, {emit_int !num_jumptbl_entries}\n`; -+ ` sldi {emit_gpr 0}, {emit_gpr 0}, 2\n`; -+ ` lwax {emit_gpr 0}, {emit_gpr 11}, {emit_gpr 0}\n`; -+ ` add {emit_gpr 0}, {emit_gpr 11}, {emit_gpr 0}\n`; -+ ` mtctr {emit_gpr 0}\n`; -+ ` bctr\n`; -+ for i = 0 to Array.length jumptbl - 1 do -+ jumptbl_entries := jumptbl.(i) :: !jumptbl_entries; -+ incr num_jumptbl_entries -+ done -+ | Lsetuptrap lbl -> -+ ` bl {emit_label lbl}\n`; -+ | Lpushtrap -> -+ stack_traps_size := !stack_traps_size + 32; -+ ` addi {emit_gpr 11}, {emit_gpr 1}, {emit_label !stack_size_lbl}-{emit_int !stack_traps_size}\n`; -+ ` mflr {emit_gpr 0}\n`; -+ ` std {emit_gpr 29}, 0({emit_gpr 11})\n`; -+ ` std {emit_gpr 0}, 8({emit_gpr 11})\n`; -+ ` std {emit_gpr 1}, 16({emit_gpr 11})\n`; -+ ` std {emit_gpr 2}, 24({emit_gpr 11})\n`; -+ ` mr {emit_gpr 29}, {emit_gpr 11}\n` -+ | Lpoptrap -> -+ ` ld {emit_gpr 29}, 0({emit_gpr 29})\n` -+ | Lraise -> -+ ` ld {emit_gpr 0}, 8({emit_gpr 29})\n`; -+ ` ld {emit_gpr 1}, 16({emit_gpr 29})\n`; -+ ` ld {emit_gpr 2}, 24({emit_gpr 29})\n`; -+ ` mtlr {emit_gpr 0}\n`; -+ ` ld {emit_gpr 29}, 0({emit_gpr 29})\n`; -+ ` blr\n` -+ -+and emit_delay = function -+ None -> () -+ | Some i -> emit_instr i None -+ -+(* Checks if a pseudo-instruction expands to instructions -+ that do not branch and do not affect CR0 nor R12. *) -+ -+let is_simple_instr i = -+ match i.desc with -+ Lop op -> -+ begin match op with -+ Icall_imm _ | Icall_ind | Itailcall_imm _ | Itailcall_ind | -+ Iextcall(_, _) -> false -+ | Ialloc(_) -> false -+ | Iintop(Icomp _) -> false -+ | Iintop_imm(Iand, _) -> false -+ | Iintop_imm(Icomp _, _) -> false -+ | _ -> true -+ end -+ | Lreloadretaddr -> true -+ | _ -> false -+ -+let no_interference res arg = -+ try -+ for i = 0 to Array.length arg - 1 do -+ for j = 0 to Array.length res - 1 do -+ if arg.(i).loc = res.(j).loc then raise Exit -+ done -+ done; -+ true -+ with Exit -> -+ false -+ -+(* Emit a sequence of instructions, trying to fill delay slots for branches *) -+ -+let rec emit_all i = -+ match i with -+ {desc = Lend} -> () -+ | {next = {desc = (Lcondbranch(_, _) | Lcondbranch3(_, _, _))}} -+ when is_simple_instr i && no_interference i.res i.next.arg -> -+ emit_instr i.next (Some i); -+ emit_all i.next.next -+ | _ -> -+ emit_instr i None; -+ emit_all i.next -+ -+(* Emission of a function declaration *) -+ -+let fundecl fundecl = -+ function_name := fundecl.fun_name; -+ defined_functions := StringSet.add fundecl.fun_name !defined_functions; -+ tailrec_entry_point := new_label(); -+ if has_stack_frame() then -+ stack_size_lbl := new_label(); -+ stack_slot_lbl := new_label(); -+ stack_args_size := 0; -+ stack_traps_size := 0; -+ call_gc_label := 0; -+ ` .globl {emit_symbol fundecl.fun_name}\n`; -+ begin match Config.system with -+ | "elf" | "bsd" -> -+ ` .type {emit_symbol fundecl.fun_name}, @function\n`; -+ emit_string code_space; -+ `{emit_symbol fundecl.fun_name}:\n`; -+ | _ -> -+ ` .align 2\n`; -+ emit_string code_space; -+ `{emit_symbol fundecl.fun_name}:\n` -+ end; -+ (* r2 to be setup to current toc *) -+ `0: addis {emit_gpr 2}, {emit_gpr 12},.TOC.-0b@ha\n`; -+ ` addi {emit_gpr 2}, {emit_gpr 2},.TOC.-0b@l\n`; -+ ` .localentry {emit_symbol fundecl.fun_name}, .-{emit_symbol fundecl.fun_name}\n`; -+ if !contains_calls then begin -+ ` mflr {emit_gpr 0}\n`; -+ ` std {emit_gpr 0}, 16({emit_gpr 1})\n` -+ end; -+ if has_stack_frame() then -+ ` stdu {emit_gpr 1}, -{emit_label !stack_size_lbl}({emit_gpr 1})\n`; -+ `{emit_label !tailrec_entry_point}:\n`; -+ branch_normalization fundecl.fun_body; -+ emit_all fundecl.fun_body; -+ ` .size {emit_symbol fundecl.fun_name}, .-{emit_symbol fundecl.fun_name}\n`; -+ if has_stack_frame() then begin -+ ` .set {emit_label !stack_size_lbl},{emit_int (frame_size_sans_args() + !stack_args_size + !stack_traps_size)} # stack size including traps\n`; -+ ` .set {emit_label !stack_slot_lbl},{emit_int (48 + !stack_args_size)} # stack slot offset\n` -+ end else (* leave 8 bytes for float <-> conversions *) -+ ` .set {emit_label !stack_slot_lbl},{emit_int (40-frame_size_sans_args())} # stack slot offset (negative)\n`; -+ -+ (* Emit the glue code to call the GC *) -+ if !call_gc_label > 0 then begin -+ `{emit_label !call_gc_label}:\n`; -+ ` ld {emit_gpr 12}, {emit_tocref (TocSymOfs ("caml_call_gc",0))}\n`; -+ ` mtctr {emit_gpr 12}\n`; -+ ` bctr\n`; -+ end -+ -+(* Emission of data *) -+ -+let declare_global_data s = -+ ` .globl {emit_symbol s}\n`; -+ if Config.system = "elf" || Config.system = "bsd" then -+ ` .type {emit_symbol s}, @object\n` -+ -+let emit_item = function -+ Cglobal_symbol s -> -+ declare_global_data s -+ | Cdefine_symbol s -> -+ `{emit_symbol s}:\n`; -+ | Cdefine_label lbl -> -+ `{emit_label (lbl + 100000)}:\n` -+ | Cint8 n -> -+ ` .byte {emit_int n}\n` -+ | Cint16 n -> -+ ` .short {emit_int n}\n` -+ | Cint32 n -> -+ ` .long {emit_nativeint n}\n` -+ | Cint n -> -+ ` .quad {emit_nativeint n}\n` -+ | Csingle f -> -+ ` .float 0d{emit_string f}\n` -+ | Cdouble f -> -+ ` .double 0d{emit_string f}\n` -+ | Csymbol_address s -> -+ ` .quad {emit_symbol s}\n` -+ | Clabel_address lbl -> -+ ` .quad {emit_label (lbl + 100000)}\n` -+ | Cstring s -> -+ emit_bytes_directive " .byte " s -+ | Cskip n -> -+ if n > 0 then ` .space {emit_int n}\n` -+ | Calign n -> -+ ` .align {emit_int (Misc.log2 n)}\n` -+ -+let data l = -+ emit_string data_space; -+ List.iter emit_item l -+ -+(* Beginning / end of an assembly file *) -+ -+let begin_assembly() = -+ defined_functions := StringSet.empty; -+ external_functions := StringSet.empty; -+ tocref_entries := []; -+ num_jumptbl_entries := 0; -+ jumptbl_entries := []; -+ lbl_jumptbl := 0; -+ (* Emit the beginning of the segments *) -+ let lbl_begin = Compilenv.make_symbol (Some "data_begin") in -+ emit_string data_space; -+ declare_global_data lbl_begin; -+ emit_string abiversion; -+ `{emit_symbol lbl_begin}:\n`; -+ let lbl_begin = Compilenv.make_symbol (Some "code_begin") in -+ emit_string code_space; -+ declare_global_data lbl_begin; -+ `{emit_symbol lbl_begin}:\n` -+ -+let end_assembly() = -+ (* Emit the jump table *) -+ if !num_jumptbl_entries > 0 then begin -+ emit_string code_space; -+ `{emit_label !lbl_jumptbl}:\n`; -+ List.iter -+ (fun lbl -> ` .long {emit_label lbl} - {emit_label !lbl_jumptbl}\n`) -+ (List.rev !jumptbl_entries); -+ jumptbl_entries := [] -+ end; -+ if !tocref_entries <> [] then begin -+ emit_string toc_space; -+ List.iter -+ (fun (lbl, entry) -> -+ `{emit_label lbl}:\n`; -+ match entry with -+ TocFloat f -> -+ ` .double {emit_tocentry entry}\n` -+ | _ -> -+ ` .tc {emit_label lbl}[TC],{emit_tocentry entry}\n` -+ ) -+ !tocref_entries; -+ tocref_entries := [] -+ end; -+ if pic_externals then -+ (* Emit the pointers to external functions *) -+ StringSet.iter emit_external !external_functions; -+ (* Emit the end of the segments *) -+ emit_string code_space; -+ let lbl_end = Compilenv.make_symbol (Some "code_end") in -+ declare_global_data lbl_end; -+ `{emit_symbol lbl_end}:\n`; -+ ` .long 0\n`; -+ emit_string data_space; -+ let lbl_end = Compilenv.make_symbol (Some "data_end") in -+ declare_global_data lbl_end; -+ `{emit_symbol lbl_end}:\n`; -+ ` .quad 0\n`; -+ (* Emit the frame descriptors *) -+ emit_string rodata_space; -+ let lbl = Compilenv.make_symbol (Some "frametable") in -+ declare_global_data lbl; -+ `{emit_symbol lbl}:\n`; -+ ` .quad {emit_int (List.length !frame_descriptors)}\n`; -+ List.iter emit_frame !frame_descriptors; -+ frame_descriptors := [] -diff --git a/asmcomp/power64le/proc.ml b/asmcomp/power64le/proc.ml -new file mode 100644 -index 0000000..9b98577 ---- /dev/null -+++ b/asmcomp/power64le/proc.ml -@@ -0,0 +1,240 @@ -+(***********************************************************************) -+(* *) -+(* Objective Caml *) -+(* *) -+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) -+(* *) -+(* 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. *) -+(* *) -+(***********************************************************************) -+ -+(* $Id: proc.ml 9547 2010-01-22 12:48:24Z doligez $ *) -+ -+(* Description of the Power PC *) -+ -+open Misc -+open Cmm -+open Reg -+open Arch -+open Mach -+ -+(* Instruction selection *) -+ -+let word_addressed = false -+ -+(* Registers available for register allocation *) -+ -+(* Integer register map: -+ 0 temporary, null register for some operations -+ 1 stack pointer -+ 2 pointer to table of contents -+ 3 - 10 function arguments and results -+ 11 - 12 temporaries -+ 13 pointer to small data area -+ 14 - 28 general purpose, preserved by C -+ 29 trap pointer -+ 30 allocation limit -+ 31 allocation pointer -+ Floating-point register map: -+ 0 temporary -+ 1 - 13 function arguments and results -+ 14 - 31 general purpose, preserved by C -+*) -+ -+let int_reg_name = -+ if Config.system = "rhapsody" then -+ [| "r3"; "r4"; "r5"; "r6"; "r7"; "r8"; "r9"; "r10"; -+ "r14"; "r15"; "r16"; "r17"; "r18"; "r19"; "r20"; "r21"; -+ "r22"; "r23"; "r24"; "r25"; "r26"; "r27"; "r28" |] -+ else -+ [| "3"; "4"; "5"; "6"; "7"; "8"; "9"; "10"; -+ "14"; "15"; "16"; "17"; "18"; "19"; "20"; "21"; -+ "22"; "23"; "24"; "25"; "26"; "27"; "28" |] -+ -+let float_reg_name = -+ if Config.system = "rhapsody" then -+ [| "f1"; "f2"; "f3"; "f4"; "f5"; "f6"; "f7"; "f8"; -+ "f9"; "f10"; "f11"; "f12"; "f13"; "f14"; "f15"; "f16"; -+ "f17"; "f18"; "f19"; "f20"; "f21"; "f22"; "f23"; "f24"; -+ "f25"; "f26"; "f27"; "f28"; "f29"; "f30"; "f31" |] -+ else -+ [| "1"; "2"; "3"; "4"; "5"; "6"; "7"; "8"; -+ "9"; "10"; "11"; "12"; "13"; "14"; "15"; "16"; -+ "17"; "18"; "19"; "20"; "21"; "22"; "23"; "24"; -+ "25"; "26"; "27"; "28"; "29"; "30"; "31" |] -+ -+let num_register_classes = 2 -+ -+let register_class r = -+ match r.typ with -+ Int -> 0 -+ | Addr -> 0 -+ | Float -> 1 -+ -+let num_available_registers = [| 23; 31 |] -+ -+let first_available_register = [| 0; 100 |] -+ -+let register_name r = -+ if r < 100 then int_reg_name.(r) else float_reg_name.(r - 100) -+ -+let rotate_registers = true -+ -+(* Representation of hard registers by pseudo-registers *) -+ -+let hard_int_reg = -+ let v = Array.create 23 Reg.dummy in -+ for i = 0 to 22 do v.(i) <- Reg.at_location Int (Reg i) done; v -+ -+let hard_float_reg = -+ let v = Array.create 31 Reg.dummy in -+ for i = 0 to 30 do v.(i) <- Reg.at_location Float (Reg(100 + i)) done; v -+ -+let all_phys_regs = -+ Array.append hard_int_reg hard_float_reg -+ -+let phys_reg n = -+ if n < 100 then hard_int_reg.(n) else hard_float_reg.(n - 100) -+ -+let stack_slot slot ty = -+ Reg.at_location ty (Stack slot) -+ -+(* Calling conventions *) -+ -+let calling_conventions -+ first_int last_int first_float last_float make_stack stack_ofs arg = -+ let loc = Array.create (Array.length arg) Reg.dummy in -+ let int = ref first_int in -+ let float = ref first_float in -+ let ofs = ref stack_ofs in -+ for i = 0 to Array.length arg - 1 do -+ match arg.(i).typ with -+ Int | Addr as ty -> -+ if !int <= last_int then begin -+ loc.(i) <- phys_reg !int; -+ incr int -+ end else begin -+ loc.(i) <- stack_slot (make_stack !ofs) ty; -+ end; -+ ofs := !ofs + size_int -+ | Float -> -+ if !float <= last_float then begin -+ loc.(i) <- phys_reg !float; -+ incr float -+ end else begin -+ loc.(i) <- stack_slot (make_stack !ofs) Float; -+ end; -+ ofs := !ofs + size_float -+ done; -+ (loc, Misc.align !ofs 16) -+ (* Keep stack 16-aligned. *) -+ -+let incoming ofs = Incoming ofs -+let outgoing ofs = Outgoing ofs -+let not_supported ofs = fatal_error "Proc.loc_results: cannot call" -+ -+let loc_arguments arg = -+ calling_conventions 0 7 100 112 outgoing 48 arg -+let loc_parameters arg = -+ let (loc, ofs) = calling_conventions 0 7 100 112 incoming 0 arg in loc -+let loc_results res = -+ let (loc, ofs) = calling_conventions 0 7 100 112 not_supported 0 res in loc -+ -+(* C calling conventions under PowerOpen: -+ use GPR 3-10 and FPR 1-13 just like ML calling -+ conventions, but always reserve stack space for all arguments. -+ Also, using a float register automatically reserves two int registers -+ (in 32-bit mode) or one int register (in 64-bit mode). -+ (If we were to call a non-prototyped C function, each float argument -+ would have to go both in a float reg and in the matching pair -+ of integer regs.) -+ -+ C calling conventions under SVR4: -+ use GPR 3-10 and FPR 1-8 just like ML calling conventions. -+ Using a float register does not affect the int registers. -+ Always reserve 8 bytes at bottom of stack, plus whatever is needed -+ to hold the overflow arguments. *) -+ -+let poweropen_external_conventions first_int last_int -+ first_float last_float arg = -+ let loc = Array.create (Array.length arg) Reg.dummy in -+ let int = ref first_int in -+ let float = ref first_float in -+ let ofs = ref (14 * size_addr) in -+ for i = 0 to Array.length arg - 1 do -+ match arg.(i).typ with -+ Int | Addr as ty -> -+ if !int <= last_int then begin -+ loc.(i) <- phys_reg !int; -+ incr int -+ end else begin -+ loc.(i) <- stack_slot (Outgoing !ofs) ty; -+ ofs := !ofs + size_int -+ end -+ | Float -> -+ if !float <= last_float then begin -+ loc.(i) <- phys_reg !float; -+ incr float -+ end else begin -+ loc.(i) <- stack_slot (Outgoing !ofs) Float; -+ ofs := !ofs + size_float -+ end; -+ int := !int + 1 -+ done; -+ (loc, Misc.align !ofs 16) (* Keep stack 16-aligned *) -+ -+let loc_external_arguments = -+ match Config.system with -+ | "rhapsody" -> poweropen_external_conventions 0 7 100 112 -+ | "elf" | "bsd" -> calling_conventions 0 7 100 107 outgoing 48 -+ | _ -> assert false -+ -+let extcall_use_push = false -+ -+(* Results are in GPR 3 and FPR 1 *) -+ -+let loc_external_results res = -+ let (loc, ofs) = calling_conventions 0 0 100 100 not_supported 0 res in loc -+ -+(* Exceptions are in GPR 3 *) -+ -+let loc_exn_bucket = phys_reg 0 -+ -+(* Registers destroyed by operations *) -+ -+let destroyed_at_c_call = -+ Array.of_list(List.map phys_reg -+ [0; 1; 2; 3; 4; 5; 6; 7; -+ 100; 101; 102; 103; 104; 105; 106; 107; 108; 109; 110; 111; 112]) -+ -+let destroyed_at_oper = function -+ Iop(Icall_ind | Icall_imm _ | Iextcall(_, true)) -> all_phys_regs -+ | Iop(Iextcall(_, false)) -> destroyed_at_c_call -+ | _ -> [||] -+ -+let destroyed_at_raise = all_phys_regs -+ -+(* Maximal register pressure *) -+ -+let safe_register_pressure = function -+ Iextcall(_, _) -> 15 -+ | _ -> 23 -+ -+let max_register_pressure = function -+ Iextcall(_, _) -> [| 15; 18 |] -+ | _ -> [| 23; 30 |] -+ -+(* Layout of the stack *) -+ -+let num_stack_slots = [| 0; 0 |] -+let contains_calls = ref false -+ -+(* Calling the assembler *) -+ -+let assemble_file infile outfile = -+ Ccomp.command (Config.asm ^ " -o " ^ -+ Filename.quote outfile ^ " " ^ Filename.quote infile) -+ -+let init () = () -diff --git a/asmcomp/power64le/reload.ml b/asmcomp/power64le/reload.ml -new file mode 100644 -index 0000000..abcac6c ---- /dev/null -+++ b/asmcomp/power64le/reload.ml -@@ -0,0 +1,18 @@ -+(***********************************************************************) -+(* *) -+(* Objective Caml *) -+(* *) -+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) -+(* *) -+(* 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. *) -+(* *) -+(***********************************************************************) -+ -+(* $Id: reload.ml 2553 1999-11-17 18:59:06Z xleroy $ *) -+ -+(* Reloading for the PowerPC *) -+ -+let fundecl f = -+ (new Reloadgen.reload_generic)#fundecl f -diff --git a/asmcomp/power64le/scheduling.ml b/asmcomp/power64le/scheduling.ml -new file mode 100644 -index 0000000..b7bba9b ---- /dev/null -+++ b/asmcomp/power64le/scheduling.ml -@@ -0,0 +1,65 @@ -+(***********************************************************************) -+(* *) -+(* Objective Caml *) -+(* *) -+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) -+(* *) -+(* 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. *) -+(* *) -+(***********************************************************************) -+ -+(* $Id: scheduling.ml 9547 2010-01-22 12:48:24Z doligez $ *) -+ -+(* Instruction scheduling for the Power PC *) -+ -+open Arch -+open Mach -+ -+class scheduler = object -+ -+inherit Schedgen.scheduler_generic -+ -+(* Latencies (in cycles). Based roughly on the "common model". *) -+ -+method oper_latency = function -+ Ireload -> 2 -+ | Iload(_, _) -> 2 -+ | Iconst_float _ -> 2 (* turned into a load *) -+ | Iconst_symbol _ -> 1 -+ | Iintop Imul -> 9 -+ | Iintop_imm(Imul, _) -> 5 -+ | Iintop(Idiv | Imod) -> 36 -+ | Iaddf | Isubf -> 4 -+ | Imulf -> 5 -+ | Idivf -> 33 -+ | Ispecific(Imultaddf | Imultsubf) -> 5 -+ | _ -> 1 -+ -+method reload_retaddr_latency = 12 -+ (* If we can have that many cycles between the reloadretaddr and the -+ return, we can expect that the blr branch will be completely folded. *) -+ -+(* Issue cycles. Rough approximations. *) -+ -+method oper_issue_cycles = function -+ Iconst_float _ | Iconst_symbol _ -> 2 -+ | Iload(_, Ibased(_, _)) -> 2 -+ | Istore(_, Ibased(_, _)) -> 2 -+ | Ialloc _ -> 4 -+ | Iintop(Imod) -> 40 (* assuming full stall *) -+ | Iintop(Icomp _) -> 4 -+ | Iintop_imm(Idiv, _) -> 2 -+ | Iintop_imm(Imod, _) -> 4 -+ | Iintop_imm(Icomp _, _) -> 4 -+ | Ifloatofint -> 9 -+ | Iintoffloat -> 4 -+ | _ -> 1 -+ -+method reload_retaddr_issue_cycles = 3 -+ (* load then stalling mtlr *) -+ -+end -+ -+let fundecl f = (new scheduler)#schedule_fundecl f -diff --git a/asmcomp/power64le/selection.ml b/asmcomp/power64le/selection.ml -new file mode 100644 -index 0000000..6101d53 ---- /dev/null -+++ b/asmcomp/power64le/selection.ml -@@ -0,0 +1,101 @@ -+(***********************************************************************) -+(* *) -+(* Objective Caml *) -+(* *) -+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *) -+(* *) -+(* Copyright 1997 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. *) -+(* *) -+(***********************************************************************) -+ -+(* $Id: selection.ml 10296 2010-04-22 12:51:06Z xleroy $ *) -+ -+(* Instruction selection for the Power PC processor *) -+ -+open Cmm -+open Arch -+open Mach -+ -+(* Recognition of addressing modes *) -+ -+type addressing_expr = -+ Asymbol of string -+ | Alinear of expression -+ | Aadd of expression * expression -+ -+let rec select_addr = function -+ Cconst_symbol s -> -+ (Asymbol s, 0) -+ | Cop((Caddi | Cadda), [arg; Cconst_int m]) -> -+ let (a, n) = select_addr arg in (a, n + m) -+ | Cop((Caddi | Cadda), [Cconst_int m; arg]) -> -+ let (a, n) = select_addr arg in (a, n + m) -+ | Cop((Caddi | Cadda), [arg1; arg2]) -> -+ begin match (select_addr arg1, select_addr arg2) with -+ ((Alinear e1, n1), (Alinear e2, n2)) -> -+ (Aadd(e1, e2), n1 + n2) -+ | _ -> -+ (Aadd(arg1, arg2), 0) -+ end -+ | exp -> -+ (Alinear exp, 0) -+ -+(* Instruction selection *) -+ -+class selector = object (self) -+ -+inherit Selectgen.selector_generic as super -+ -+method is_immediate n = (n <= 32767) && (n >= -32768) -+ -+method select_addressing chunk exp = -+ match select_addr exp with -+ (Asymbol s, d) -> -+ (Ibased(s, d), Ctuple []) -+ | (Alinear e, d) -> -+ (Iindexed d, e) -+ | (Aadd(e1, e2), d) -> -+ if d = 0 -+ then (Iindexed2, Ctuple[e1; e2]) -+ else (Iindexed d, Cop(Cadda, [e1; e2])) -+ -+method! select_operation op args = -+ match (op, args) with -+ (* Prevent the recognition of (x / cst) and (x % cst) when cst is not -+ a power of 2, which do not correspond to an instruction. *) -+ (Cdivi, [arg; Cconst_int n]) when n = 1 lsl (Misc.log2 n) -> -+ (Iintop_imm(Idiv, n), [arg]) -+ | (Cdivi, _) -> -+ (Iintop Idiv, args) -+ | (Cmodi, [arg; Cconst_int n]) when n = 1 lsl (Misc.log2 n) -> -+ (Iintop_imm(Imod, n), [arg]) -+ | (Cmodi, _) -> -+ (Iintop Imod, args) -+ (* The and, or and xor instructions have a different range of immediate -+ operands than the other instructions *) -+ | (Cand, _) -> self#select_logical Iand args -+ | (Cor, _) -> self#select_logical Ior args -+ | (Cxor, _) -> self#select_logical Ixor args -+ (* Recognize mult-add and mult-sub instructions *) -+ | (Caddf, [Cop(Cmulf, [arg1; arg2]); arg3]) -> -+ (Ispecific Imultaddf, [arg1; arg2; arg3]) -+ | (Caddf, [arg3; Cop(Cmulf, [arg1; arg2])]) -> -+ (Ispecific Imultaddf, [arg1; arg2; arg3]) -+ | (Csubf, [Cop(Cmulf, [arg1; arg2]); arg3]) -> -+ (Ispecific Imultsubf, [arg1; arg2; arg3]) -+ | _ -> -+ super#select_operation op args -+ -+method select_logical op = function -+ [arg; Cconst_int n] when n >= 0 && n <= 0xFFFF -> -+ (Iintop_imm(op, n), [arg]) -+ | [Cconst_int n; arg] when n >= 0 && n <= 0xFFFF -> -+ (Iintop_imm(op, n), [arg]) -+ | args -> -+ (Iintop op, args) -+ -+end -+ -+let fundecl f = (new selector)#emit_fundecl f -diff --git a/asmrun/Makefile b/asmrun/Makefile -index 6a8ed98..1ff256f 100644 ---- a/asmrun/Makefile -+++ b/asmrun/Makefile -@@ -96,6 +96,12 @@ power64.o: power64-$(SYSTEM).o - power64.p.o: power64-$(SYSTEM).o - cp power64-$(SYSTEM).o power64.p.o - -+power64le.o: power64le-$(SYSTEM).o -+ cp power64le-$(SYSTEM).o power64le.o -+ -+power64le.p.o: power64le-$(SYSTEM).o -+ cp power64le-$(SYSTEM).o power64le.p.o -+ - main.c: ../byterun/main.c - ln -s ../byterun/main.c main.c - misc.c: ../byterun/misc.c -diff --git a/asmrun/power64-elf.S b/asmrun/power64-elf.S -index b2c24d6..98c42e2 100644 ---- a/asmrun/power64-elf.S -+++ b/asmrun/power64-elf.S -@@ -23,12 +23,16 @@ - addis tmp, 0, glob@ha; \ - std reg, glob@l(tmp) - -+#if _CALL_ELF == 2 -+ .abiversion 2 -+#endif - .section ".text" - - /* Invoke the garbage collector. */ - - .globl caml_call_gc - .type caml_call_gc, @function -+#if _CALL_ELF != 2 - .section ".opd","aw" - .align 3 - caml_call_gc: -@@ -36,6 +40,10 @@ caml_call_gc: - .previous - .align 2 - .L.caml_call_gc: -+#else -+caml_call_gc: -+ /* do not set r2 to tocbase */ -+#endif - /* Set up stack frame */ - mflr 0 - std 0, 16(1) -@@ -110,6 +118,7 @@ caml_call_gc: - stfdu 30, 8(11) - stfdu 31, 8(11) - /* Call the GC */ -+#if _CALL_ELF != 2 - std 2,40(1) - Addrglobal(11, caml_garbage_collection) - ld 2,8(11) -@@ -117,6 +126,13 @@ caml_call_gc: - mtlr 11 - blrl - ld 2,40(1) -+#else -+ std 2,24(1) -+ Addrglobal(12, caml_garbage_collection) -+ mtlr 12 -+ blrl -+ ld 2,24(1) -+#endif - /* Reload new allocation pointer and allocation limit */ - Loadglobal(31, caml_young_ptr, 11) - Loadglobal(30, caml_young_limit, 11) -@@ -188,12 +204,17 @@ caml_call_gc: - ld 1, 0(1) - /* Return */ - blr -+#if _CALL_ELF != 2 - .size .L.caml_call_gc,.-.L.caml_call_gc -+#else -+ .size caml_call_gc,.-caml_call_gc -+#endif - - /* Call a C function from Caml */ - - .globl caml_c_call - .type caml_c_call, @function -+#if _CALL_ELF != 2 - .section ".opd","aw" - .align 3 - caml_c_call: -@@ -201,13 +222,21 @@ caml_c_call: - .previous - .align 2 - .L.caml_c_call: -+#else -+caml_c_call: -+0: addis 2,12, .TOC.-0b@ha -+ addi 2, 2, .TOC.-0b@l -+ .localentry caml_c_call, .-caml_c_call -+#endif - .cfi_startproc - /* Save return address */ - mflr 25 - .cfi_register lr,25 - /* Get ready to call C function (address in 11) */ -+#if _CALL_ELF != 2 - ld 2, 8(11) - ld 11,0(11) -+#endif - mtlr 11 - /* Record lowest stack address and return address */ - Storeglobal(1, caml_bottom_of_stack, 12) -@@ -228,12 +257,17 @@ caml_c_call: - /* Return to caller */ - blr - .cfi_endproc -+#if _CALL_ELF != 2 - .size .L.caml_c_call,.-.L.caml_c_call -+#else -+ .size caml_c_call,.-caml_c_call -+#endif - - /* Raise an exception from C */ - - .globl caml_raise_exception - .type caml_raise_exception, @function -+#if _CALL_ELF != 2 - .section ".opd","aw" - .align 3 - caml_raise_exception: -@@ -241,6 +275,12 @@ caml_raise_exception: - .previous - .align 2 - .L.caml_raise_exception: -+#else -+caml_raise_exception: -+0: addis 2,12, .TOC.-0b@ha -+ addi 2, 2, .TOC.-0b@l -+ .localentry caml_raise_exception, .-caml_raise_exception -+#endif - /* Reload Caml global registers */ - Loadglobal(29, caml_exception_pointer, 11) - Loadglobal(31, caml_young_ptr, 11) -@@ -256,12 +296,17 @@ caml_raise_exception: - ld 29, 0(29) - /* Branch to handler */ - blr -+#if _CALL_ELF != 2 - .size .L.caml_raise_exception,.-.L.caml_raise_exception -+#else -+ .size caml_raise_exception,.-caml_raise_exception -+#endif - - /* Start the Caml program */ - - .globl caml_start_program - .type caml_start_program, @function -+#if _CALL_ELF != 2 - .section ".opd","aw" - .align 3 - caml_start_program: -@@ -269,6 +314,9 @@ caml_start_program: - .previous - .align 2 - .L.caml_start_program: -+#else -+caml_start_program: -+#endif - Addrglobal(12, caml_program) - - /* Code shared between caml_start_program and caml_callback */ -@@ -342,6 +390,7 @@ caml_start_program: - li 0, 0 - Storeglobal(0, caml_last_return_address, 11) - /* Call the Caml code */ -+#if _CALL_ELF != 2 - std 2,40(1) - ld 2,8(12) - ld 12,0(12) -@@ -349,6 +398,13 @@ caml_start_program: - .L105: - blrl - ld 2,40(1) -+#else -+ std 2,24(1) -+ mtlr 12 -+.L105: -+ blrl -+ ld 2,24(1) -+#endif - /* Pop the trap frame, restoring caml_exception_pointer */ - ld 9, 0x170(1) - Storeglobal(9, caml_exception_pointer, 11) -@@ -414,12 +470,17 @@ caml_start_program: - /* Encode exception bucket as an exception result and return it */ - ori 3, 3, 2 - b .L106 -+#if _CALL_ELF != 2 - .size .L.caml_start_program,.-.L.caml_start_program -+#else -+ .size caml_start_program,.-caml_start_program -+#endif - - /* Callback from C to Caml */ - - .globl caml_callback_exn - .type caml_callback_exn, @function -+#if _CALL_ELF != 2 - .section ".opd","aw" - .align 3 - caml_callback_exn: -@@ -427,17 +488,28 @@ caml_callback_exn: - .previous - .align 2 - .L.caml_callback_exn: -+#else -+caml_callback_exn: -+0: addis 2,12, .TOC.-0b@ha -+ addi 2, 2, .TOC.-0b@l -+ .localentry caml_callback_exn, .-caml_callback_exn -+#endif - /* Initial shuffling of arguments */ - mr 0, 3 /* Closure */ - mr 3, 4 /* Argument */ - mr 4, 0 - ld 12, 0(4) /* Code pointer */ - b .L102 -+#if _CALL_ELF != 2 - .size .L.caml_callback_exn,.-.L.caml_callback_exn -+#else -+ .size caml_callback_exn,.-caml_callback_exn -+#endif -+ - -- - .globl caml_callback2_exn - .type caml_callback2_exn, @function -+#if _CALL_ELF != 2 - .section ".opd","aw" - .align 3 - caml_callback2_exn: -@@ -445,17 +517,28 @@ caml_callback2_exn: - .previous - .align 2 - .L.caml_callback2_exn: -+#else -+caml_callback2_exn: -+0: addis 2,12, .TOC.-0b@ha -+ addi 2, 2, .TOC.-0b@l -+ .localentry caml_callback2_exn, .-caml_callback2_exn -+#endif - mr 0, 3 /* Closure */ - mr 3, 4 /* First argument */ - mr 4, 5 /* Second argument */ - mr 5, 0 - Addrglobal(12, caml_apply2) - b .L102 -+#if _CALL_ELF != 2 - .size .L.caml_callback2_exn,.-.L.caml_callback2_exn -+#else -+ .size caml_callback2_exn,.-caml_callback2_exn -+#endif - - - .globl caml_callback3_exn - .type caml_callback3_exn, @function -+#if _CALL_ELF != 2 - .section ".opd","aw" - .align 3 - caml_callback3_exn: -@@ -463,6 +546,12 @@ caml_callback3_exn: - .previous - .align 2 - .L.caml_callback3_exn: -+#else -+caml_callback3_exn: -+0: addis 2,12, .TOC.-0b@ha -+ addi 2, 2, .TOC.-0b@l -+ .localentry caml_callback3_exn, .-caml_callback3_exn -+#endif - mr 0, 3 /* Closure */ - mr 3, 4 /* First argument */ - mr 4, 5 /* Second argument */ -@@ -470,7 +559,11 @@ caml_callback3_exn: - mr 6, 0 - Addrglobal(12, caml_apply3) - b .L102 -+#if _CALL_ELF != 2 - .size .L.caml_callback3_exn,.-.L.caml_callback3_exn -+#else -+ .size caml_callback3_exn,.-caml_callback3_exn -+#endif - - /* Frame table */ - -diff --git a/asmrun/power64le-elf.S b/asmrun/power64le-elf.S -new file mode 120000 -index 0000000..f49d00c ---- /dev/null -+++ b/asmrun/power64le-elf.S -@@ -0,0 +1 @@ -+power64-elf.S -\ No newline at end of file -diff --git a/asmrun/stack.h b/asmrun/stack.h -index 031e408..f1890c1 100644 ---- a/asmrun/stack.h -+++ b/asmrun/stack.h -@@ -55,6 +55,15 @@ - #define Callback_link(sp) ((struct caml_context *)((sp) + Trap_frame_size)) - #endif - -+#ifdef TARGET_power64le -+#define Saved_return_address(sp) *((intnat *)((sp) +16)) -+#define Already_scanned(sp, retaddr) ((retaddr) & 1) -+#define Mark_scanned(sp, retaddr) (Saved_return_address(sp) = (retaddr) | 1) -+#define Mask_already_scanned(retaddr) ((retaddr) & ~1) -+#define Trap_frame_size 0x150 -+#define Callback_link(sp) ((struct caml_context *)((sp) + Trap_frame_size)) -+#endif -+ - #ifdef TARGET_arm - #define Saved_return_address(sp) *((intnat *)((sp) - 4)) - #define Callback_link(sp) ((struct caml_context *)((sp) + 8)) -diff --git a/config/gnu/config.guess b/config/gnu/config.guess -index b79252d..049652e 100755 ---- a/config/gnu/config.guess -+++ b/config/gnu/config.guess -@@ -992,6 +992,9 @@ EOF - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-${LIBC} - exit ;; -+ ppc64le:Linux:*:*) -+ echo powerpc64le-unknown-linux-gnu -+ exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-${LIBC} - exit ;; -diff --git a/configure b/configure -index 36edfab..8a22078 100755 ---- a/configure -+++ b/configure -@@ -696,6 +696,7 @@ case "$host" in - fi;; - i[3456]86-*-gnu*) arch=i386; system=gnu;; - powerpc64-*-linux*) arch=power64; model=ppc64; system=elf;; -+ powerpc64le-*-linux*) arch=power64le; model=ppc64le; system=elf;; - powerpc*-*-linux*) arch=power; model=ppc; system=elf;; - powerpc-*-netbsd*) arch=power; model=ppc; system=elf;; - powerpc-*-openbsd*) arch=power; model=ppc; system=bsd_elf;; -@@ -781,6 +782,8 @@ case "$arch,$model,$system" in - aspp='gcc -c';; - power64,*,elf) as='as -u -m ppc64' - aspp='gcc -c';; -+ power64le,*,elf) as='as -u -m ppc64' -+ aspp='gcc -c';; - power,*,rhapsody) as="as -arch $model" - aspp="$bytecc -c";; - sparc,*,solaris) as='as' --- -1.9.0 - diff --git a/0014-arm-arm64-Mark-stack-as-non-executable.patch b/0014-arm-arm64-Mark-stack-as-non-executable.patch deleted file mode 100644 index 7767b40..0000000 --- a/0014-arm-arm64-Mark-stack-as-non-executable.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 64da031fc17ca93efd5beabcf0b7ea49bcd645a0 Mon Sep 17 00:00:00 2001 -From: "Richard W.M. Jones" -Date: Sat, 10 May 2014 03:20:35 -0400 -Subject: [PATCH 14/14] arm, arm64: Mark stack as non-executable. - -The same fix as this one, which was only fully applied to -i686 & x86-64: - -http://caml.inria.fr/mantis/view.php?id=4564 ---- - asmrun/arm.S | 3 +++ - asmrun/arm64.S | 3 +++ - 2 files changed, 6 insertions(+) - -diff --git a/asmrun/arm.S b/asmrun/arm.S -index 2ce244a..90f5b6e 100644 ---- a/asmrun/arm.S -+++ b/asmrun/arm.S -@@ -489,3 +489,6 @@ caml_system__frametable: - .align 2 - .type caml_system__frametable, %object - .size caml_system__frametable, .-caml_system__frametable -+ -+ /* Mark stack as non-executable, PR#4564 */ -+ .section .note.GNU-stack,"",%progbits -diff --git a/asmrun/arm64.S b/asmrun/arm64.S -index de670e6..84e18ba 100644 ---- a/asmrun/arm64.S -+++ b/asmrun/arm64.S -@@ -533,3 +533,6 @@ caml_system__frametable: - .align 3 - .type caml_system__frametable, %object - .size caml_system__frametable, .-caml_system__frametable -+ -+ /* Mark stack as non-executable, PR#4564 */ -+ .section .note.GNU-stack,"",%progbits --- -1.9.0 - diff --git a/ocaml.spec b/ocaml.spec index 77c693d..16eda5b 100644 --- a/ocaml.spec +++ b/ocaml.spec @@ -15,9 +15,12 @@ %global natdynlink 0 %endif +%global gitcommit 8c1e5cdf9154b7c4f979327a554bdde5c8f76436 +%global shortcommit 8c1e5cdf + Name: ocaml -Version: 4.01.0 -Release: 20%{?dist} +Version: 4.02.0 +Release: 0.1.git%{shortcommit}%{?dist} Summary: OCaml compiler and programming environment @@ -25,10 +28,10 @@ License: QPL and (LGPLv2+ with exceptions) URL: http://www.ocaml.org -Source0: http://caml.inria.fr/pub/distrib/ocaml-4.01/ocaml-%{version}.tar.gz -Source1: http://caml.inria.fr/pub/distrib/ocaml-4.01/ocaml-4.01-refman-html.tar.gz -Source2: http://caml.inria.fr/pub/distrib/ocaml-4.01/ocaml-4.01-refman.pdf -Source3: http://caml.inria.fr/pub/distrib/ocaml-4.01/ocaml-4.01-refman.info.tar.gz +Source0: https://github.com/ocaml/%{name}/archive/%{gitcommit}/%{name}-%{gitcommit}.tar.gz +Source1: http://caml.inria.fr/pub/distrib/ocaml-4.02/ocaml-4.02beta-refman-html.tar.gz +Source2: http://caml.inria.fr/pub/distrib/ocaml-4.02/ocaml-4.02beta-refman.pdf +Source3: http://caml.inria.fr/pub/distrib/ocaml-4.02/ocaml-4.02beta-refman.info.tar.gz # IMPORTANT NOTE: # @@ -39,40 +42,28 @@ Source3: http://caml.inria.fr/pub/distrib/ocaml-4.01/ocaml-4.01-refman.in # # https://git.fedorahosted.org/cgit/fedora-ocaml.git/ # +# Current branch: fedora-22-4.02 +# # ALTERNATIVELY add a patch to the end of the list (leaving the # existing patches unchanged) adding a comment to note that it should # be incorporated into the git repo at a later time. # -Patch0001: 0001-Add-.gitignore-file-to-ignore-generated-files.patch +Patch0001: 0001-Don-t-ignore-.-configure-it-s-a-real-git-file.patch Patch0002: 0002-Ensure-empty-compilerlibs-directory-is-created-by-gi.patch -Patch0003: 0003-ocamlbyteinfo-ocamlplugininfo-Useful-utilities-from-.patch -Patch0004: 0004-Don-t-add-rpaths-to-libraries.patch +Patch0003: 0003-Don-t-add-rpaths-to-libraries.patch +Patch0004: 0004-ocamlbyteinfo-ocamlplugininfo-Useful-utilities-from-.patch Patch0005: 0005-configure-Allow-user-defined-C-compiler-flags.patch Patch0006: 0006-Add-support-for-ppc64.patch -Patch0007: 0007-yacc-Use-mkstemp-instead-of-mktemp.patch - -# Aarch64 patches. -Patch0008: 0008-Port-to-the-ARM-64-bits-AArch64-architecture-experim.patch -Patch0009: 0009-Updated-with-latest-versions-from-FSF.patch -Patch0010: 0010-arm64-Align-code-and-data-to-8-bytes.patch - -# NON-upstream patch to allow '--flag=arg' as an alternative to '--flag arg'. -Patch0011: 0011-arg-Add-no_arg-and-get_arg-helper-functions.patch -Patch0012: 0012-arg-Allow-flags-such-as-flag-arg-as-well-as-flag-arg.patch - -# ppc64le support (Michel Normand). -Patch0013: 0013-Add-support-for-ppc64le.patch - -# ARM & Aarch64 non-executable stack. -Patch0014: 0014-arm-arm64-Mark-stack-as-non-executable.patch +Patch0007: 0007-Add-support-for-ppc64le.patch +Patch0008: 0008-arm-arm64-Mark-stack-as-non-executable.patch +Patch0009: 0009-arg-Add-no_arg-and-get_arg-helper-functions.patch +Patch0010: 0010-arg-Allow-flags-such-as-flag-arg-as-well-as-flag-arg.patch # Add BFD support so that ocamlobjinfo supports *.cmxs format (RHBZ#1113735). BuildRequires: binutils-devel BuildRequires: ncurses-devel BuildRequires: gdbm-devel -BuildRequires: tcl-devel -BuildRequires: tk-devel BuildRequires: emacs BuildRequires: gawk BuildRequires: perl @@ -111,7 +102,7 @@ programming language from the ML family of languages. This package comprises two batch compilers (a fast bytecode compiler and an optimizing native-code compiler), an interactive toplevel system, -parsing tools (Lex,Yacc,Camlp4), a replay debugger, a documentation generator, +parsing tools (Lex,Yacc), a replay debugger, a documentation generator, and a comprehensive library. @@ -145,56 +136,6 @@ Requires: libX11-devel X11 support for OCaml. -%package labltk -Summary: Tk bindings for OCaml -Requires: ocaml-runtime = %{version}-%{release} - -%description labltk -Labltk is a library for interfacing OCaml with the scripting language -Tcl/Tk. - -This package contains the runtime files. - - -%package labltk-devel -Summary: Development files for labltk -Requires: ocaml = %{version}-%{release} -Requires: %{name}-labltk = %{version}-%{release} -Requires: libX11-devel -Requires: tcl-devel -Requires: tk-devel - -%description labltk-devel -Labltk is a library for interfacing OCaml with the scripting language -Tcl/Tk. - -This package contains the development files. It includes the ocaml -browser for code editing and library browsing. - - -%package camlp4 -Summary: Pre-Processor-Pretty-Printer for OCaml -Requires: ocaml-runtime = %{version}-%{release} - -%description camlp4 -Camlp4 is a Pre-Processor-Pretty-Printer for OCaml, parsing a source -file and printing some result on standard output. - -This package contains the runtime files. - - -%package camlp4-devel -Summary: Pre-Processor-Pretty-Printer for OCaml -Requires: ocaml = %{version}-%{release} -Requires: %{name}-camlp4 = %{version}-%{release} - -%description camlp4-devel -Camlp4 is a Pre-Processor-Pretty-Printer for OCaml, parsing a source -file and printing some result on standard output. - -This package contains the development files. - - %package ocamldoc Summary: Documentation generator for OCaml Requires: ocaml = %{version}-%{release} @@ -244,15 +185,16 @@ may not be portable between versions. %prep -%setup -q -T -b 0 -n %{name}-%{version} -%setup -q -T -D -a 1 -n %{name}-%{version} -%setup -q -T -D -a 3 -n %{name}-%{version} +%setup -q -T -b 0 -n %{name}-%{gitcommit} +%setup -q -T -D -a 1 -n %{name}-%{gitcommit} +%setup -q -T -D -a 3 -n %{name}-%{gitcommit} cp %{SOURCE2} refman.pdf git init git config user.email "noone@example.com" git config user.name "no one" git add . +git add -f configure ;# required because .gitignore lists this file git commit -a -q -m "%{version} baseline" git am %{patches} - 4.02.0-0.1 +- Update to 4.02.0-beta1 + patches from the upstream 4.02 branch. +- REMOVED labltk and camlp4 packages, since these are now packaged + separately upstream. +- Upstream includes fix for stack alignment issues on i686, so remove hack. +- Upstream now uses mkstemp where available, so patch removed. +- Upstream includes Aarch64 backend, so remove our own backport. +- Drop BR on ocaml-srpm-macros, since it is now included in Fedora. + * Thu Jun 26 2014 Richard W.M. Jones - 4.01.0-20 - BR binutils-devel so ocamlobjinfo supports *.cmxs files (RHBZ#1113735). diff --git a/sources b/sources index ab191f4..65dc833 100644 --- a/sources +++ b/sources @@ -1,4 +1,4 @@ -04dfdd7da189462a4f10ec6530359cef ocaml-4.01.0.tar.gz -73f4657680baeb200135720fbc84eb4b ocaml-4.01-refman-html.tar.gz -f4605c5cf0dbf90395331997e600e159 ocaml-4.01-refman.info.tar.gz -f14652070cfb984c75de1919085b6915 ocaml-4.01-refman.pdf +c308e831a1c5d6b3024bb339fcee72f4 ocaml-4.02beta-refman-html.tar.gz +672044269cea28b661fca5c0edadc195 ocaml-4.02beta-refman.info.tar.gz +d05fc06025d7bad2a969a659f6de1c83 ocaml-4.02beta-refman.pdf +053f03be03e82407f76ca0eb92bf2adf ocaml-8c1e5cdf9154b7c4f979327a554bdde5c8f76436.tar.gz