commit 1d0fbf8595072d076bbba917a0659a064ca4e030 Author: CentOS Sources Date: Thu Aug 1 13:32:25 2019 -0400 import ocaml-4.07.0-3.el8 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0e08c13 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/ocaml-4.07.0.tar.xz diff --git a/.ocaml.metadata b/.ocaml.metadata new file mode 100644 index 0000000..3cb24b2 --- /dev/null +++ b/.ocaml.metadata @@ -0,0 +1 @@ +9dd56728f2ceea4784e6d574612fbcee2aa4c611 SOURCES/ocaml-4.07.0.tar.xz diff --git a/SOURCES/0001-Don-t-add-rpaths-to-libraries.patch b/SOURCES/0001-Don-t-add-rpaths-to-libraries.patch new file mode 100644 index 0000000..6665489 --- /dev/null +++ b/SOURCES/0001-Don-t-add-rpaths-to-libraries.patch @@ -0,0 +1,27 @@ +From 8ddacdf1283fe3d7054f51a4b764bc6b44d7a342 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 24 Jun 2014 10:00:15 +0100 +Subject: [PATCH 1/8] Don't add rpaths to libraries. + +--- + tools/Makefile | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tools/Makefile b/tools/Makefile +index 78d2a1068..fbec019ed 100644 +--- a/tools/Makefile ++++ b/tools/Makefile +@@ -157,8 +157,8 @@ $(call byte_and_opt,ocamlmklib,ocamlmklibconfig.cmo config.cmo misc.cmo \ + ocamlmklibconfig.ml: ../config/Makefile Makefile + (echo 'let bindir = "$(BINDIR)"'; \ + echo 'let supports_shared_libraries = $(SUPPORTS_SHARED_LIBRARIES)';\ +- echo 'let default_rpath = "$(RPATH)"'; \ +- echo 'let mksharedlibrpath = "$(MKSHAREDLIBRPATH)"'; \ ++ echo 'let default_rpath = ""'; \ ++ echo 'let mksharedlibrpath = ""'; \ + echo 'let toolpref = "$(TOOLPREF)"'; \ + sed -n -e 's/^#ml //p' ../config/Makefile) \ + > ocamlmklibconfig.ml +-- +2.17.1 + diff --git a/SOURCES/0002-ocamlbyteinfo-ocamlplugininfo-Useful-utilities-from-.patch b/SOURCES/0002-ocamlbyteinfo-ocamlplugininfo-Useful-utilities-from-.patch new file mode 100644 index 0000000..9195dce --- /dev/null +++ b/SOURCES/0002-ocamlbyteinfo-ocamlplugininfo-Useful-utilities-from-.patch @@ -0,0 +1,240 @@ +From 118057a71576cb39d71633bf80a37815bf4ff932 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 29 May 2012 20:40:36 +0100 +Subject: [PATCH 2/8] 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 000000000..0a537e4d5 +--- /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 = Bytes.create len in ++ let _ = really_input ic sect 0 len in ++ get_string_list (Bytes.to_string 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 000000000..e28800f31 +--- /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 +-- +2.17.1 + diff --git a/SOURCES/0003-configure-Allow-user-defined-C-compiler-flags.patch b/SOURCES/0003-configure-Allow-user-defined-C-compiler-flags.patch new file mode 100644 index 0000000..5fb4967 --- /dev/null +++ b/SOURCES/0003-configure-Allow-user-defined-C-compiler-flags.patch @@ -0,0 +1,27 @@ +From 8ddd2fb4909bf6ed1a3506723126432da8fcf0c4 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 29 May 2012 20:44:18 +0100 +Subject: [PATCH 3/8] configure: Allow user defined C compiler flags. + +--- + configure | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/configure b/configure +index 1316b3c1e..53f45f85b 100755 +--- a/configure ++++ b/configure +@@ -2050,6 +2050,10 @@ if $flat_float_array; then + echo "#define FLAT_FLOAT_ARRAY" >> m.h + fi + ++# Allow user defined C Compiler flags ++bytecccompopts="$bytecccompopts $CFLAGS" ++nativecccompopts="$nativecccompopts $CFLAGS" ++ + # Finish generated files + + cclibs="$cclibs $mathlib" +-- +2.17.1 + diff --git a/SOURCES/0004-Add-RISC-V-backend.patch b/SOURCES/0004-Add-RISC-V-backend.patch new file mode 100644 index 0000000..22d8fe3 --- /dev/null +++ b/SOURCES/0004-Add-RISC-V-backend.patch @@ -0,0 +1,1768 @@ +From 38ac4778744fb7137e04708998d4e856ada1c8b8 Mon Sep 17 00:00:00 2001 +From: Nicolas Ojeda Bar +Date: Fri, 27 Oct 2017 17:05:25 +0200 +Subject: [PATCH 4/8] Add RISC-V backend + +--- + README.adoc | 1 + + asmcomp/riscv/CSE.ml | 36 ++ + asmcomp/riscv/arch.ml | 87 +++++ + asmcomp/riscv/emit.mlp | 653 ++++++++++++++++++++++++++++++++++++ + asmcomp/riscv/proc.ml | 301 +++++++++++++++++ + asmcomp/riscv/reload.ml | 16 + + asmcomp/riscv/scheduling.ml | 19 ++ + asmcomp/riscv/selection.ml | 72 ++++ + asmrun/riscv.S | 424 +++++++++++++++++++++++ + byterun/caml/stack.h | 5 + + config/gnu/config.guess | 5 +- + configure | 5 +- + 12 files changed, 1622 insertions(+), 2 deletions(-) + create mode 100644 asmcomp/riscv/CSE.ml + create mode 100644 asmcomp/riscv/arch.ml + create mode 100644 asmcomp/riscv/emit.mlp + create mode 100644 asmcomp/riscv/proc.ml + create mode 100644 asmcomp/riscv/reload.ml + create mode 100644 asmcomp/riscv/scheduling.ml + create mode 100644 asmcomp/riscv/selection.ml + create mode 100644 asmrun/riscv.S + +diff --git a/README.adoc b/README.adoc +index 74d1ec258..ac6c6eac3 100644 +--- a/README.adoc ++++ b/README.adoc +@@ -47,6 +47,7 @@ AMD64:: FreeBSD, OpenBSD, NetBSD + IA32 (Pentium):: NetBSD, OpenBSD, Solaris 9 + PowerPC:: NetBSD + ARM:: NetBSD ++RISC-V:: Linux + + Other operating systems for the processors above have not been tested, but + the compiler may work under other operating systems with little work. +diff --git a/asmcomp/riscv/CSE.ml b/asmcomp/riscv/CSE.ml +new file mode 100644 +index 000000000..302811a99 +--- /dev/null ++++ b/asmcomp/riscv/CSE.ml +@@ -0,0 +1,36 @@ ++(***********************************************************************) ++(* *) ++(* OCaml *) ++(* *) ++(* Nicolas Ojeda Bar *) ++(* *) ++(* Copyright 2106 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. *) ++(* *) ++(***********************************************************************) ++ ++(* CSE for the RISC-V *) ++ ++open Arch ++open Mach ++open CSEgen ++ ++class cse = object (_self) ++ ++inherit cse_generic as super ++ ++method! class_of_operation op = ++ match op with ++ | Ispecific(Imultaddf _ | Imultsubf _) -> Op_pure ++ | _ -> super#class_of_operation op ++ ++method! is_cheap_operation op = ++ match op with ++ | Iconst_int n -> n <= 0x7FFn && n >= -0x800n ++ | _ -> false ++ ++end ++ ++let fundecl f = ++ (new cse)#fundecl f +diff --git a/asmcomp/riscv/arch.ml b/asmcomp/riscv/arch.ml +new file mode 100644 +index 000000000..22c807c49 +--- /dev/null ++++ b/asmcomp/riscv/arch.ml +@@ -0,0 +1,87 @@ ++(***********************************************************************) ++(* *) ++(* OCaml *) ++(* *) ++(* Nicolas Ojeda Bar *) ++(* *) ++(* Copyright 2016 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. *) ++(* *) ++(***********************************************************************) ++ ++(* Specific operations for the RISC-V processor *) ++ ++open Format ++ ++(* Machine-specific command-line options *) ++ ++let command_line_options = [] ++ ++(* Specific operations *) ++ ++type specific_operation = ++ | Imultaddf of bool (* multiply, optionally negate, and add *) ++ | Imultsubf of bool (* multiply, optionally negate, and subtract *) ++ ++let spacetime_node_hole_pointer_is_live_before = function ++ | Imultaddf _ | Imultsubf _ -> false ++ ++(* Addressing modes *) ++ ++type addressing_mode = ++ | Iindexed of int (* reg + displ *) ++ ++let is_immediate n = ++ (n <= 2047) && (n >= -2048) ++ ++(* Sizes, endianness *) ++ ++let big_endian = false ++ ++let rv64 = ++ match Config.model with "riscv64" -> true | "riscv32" -> false | _ -> assert false ++ ++let size_addr = if rv64 then 8 else 4 ++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 ++ | Iindexed n -> Iindexed(n + delta) ++ ++let num_args_addressing = function ++ | Iindexed _ -> 1 ++ ++(* Printing operations and addressing modes *) ++ ++let print_addressing printreg addr ppf arg = ++ match addr with ++ | Iindexed n -> ++ let idx = if n <> 0 then Printf.sprintf " + %i" n else "" in ++ fprintf ppf "%a%s" printreg arg.(0) idx ++ ++let print_specific_operation printreg op ppf arg = ++ match op with ++ | Imultaddf false -> ++ fprintf ppf "%a *f %a +f %a" ++ printreg arg.(0) printreg arg.(1) printreg arg.(2) ++ | Imultaddf true -> ++ fprintf ppf "-f (%a *f %a +f %a)" ++ printreg arg.(0) printreg arg.(1) printreg arg.(2) ++ | Imultsubf false -> ++ fprintf ppf "%a *f %a -f %a" ++ printreg arg.(0) printreg arg.(1) printreg arg.(2) ++ | Imultsubf true -> ++ fprintf ppf "-f (%a *f %a -f %a)" ++ printreg arg.(0) printreg arg.(1) printreg arg.(2) +diff --git a/asmcomp/riscv/emit.mlp b/asmcomp/riscv/emit.mlp +new file mode 100644 +index 000000000..51165d0f1 +--- /dev/null ++++ b/asmcomp/riscv/emit.mlp +@@ -0,0 +1,653 @@ ++(***********************************************************************) ++(* *) ++(* OCaml *) ++(* *) ++(* Nicolas Ojeda Bar *) ++(* *) ++(* Copyright 2016 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. *) ++(* *) ++(***********************************************************************) ++ ++(* Emission of RISC-V assembly code *) ++ ++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_offset = ref 0 ++ ++let frame_size () = ++ let size = ++ !stack_offset + (* Trap frame, outgoing parameters *) ++ size_int * num_stack_slots.(0) + (* Local int variables *) ++ size_float * num_stack_slots.(1) + (* Local float variables *) ++ (if !contains_calls then size_addr else 0) in (* The return address *) ++ Misc.align size 16 ++ ++let slot_offset loc cls = ++ match loc with ++ | Local n -> ++ if cls = 0 ++ then !stack_offset + num_stack_slots.(1) * size_float + n * size_int ++ else !stack_offset + n * size_float ++ | Incoming n -> frame_size() + n ++ | Outgoing n -> n ++ ++(* Output a symbol *) ++ ++let emit_symbol s = ++ Emitaux.emit_symbol '.' s ++ ++(* Output a label *) ++ ++let label_prefix = "L" ++ ++let emit_label lbl = ++ emit_string label_prefix; emit_int lbl ++ ++(* Section switching *) ++ ++let data_space = ++ ".section .data" ++ ++let code_space = ++ ".section .text" ++ ++let rodata_space = ++ ".section .rodata" ++ ++let reg_tmp1 = phys_reg 21 (* used by the assembler *) ++let reg_tmp2 = phys_reg 22 ++let reg_t2 = phys_reg 16 ++(* let reg_fp = phys_reg 23 *) ++let reg_trap = phys_reg 24 ++let reg_alloc_ptr = phys_reg 25 ++let reg_alloc_lim = phys_reg 26 ++ ++(* Names of instructions that differ in 32 and 64-bit modes *) ++ ++let lg = if rv64 then "ld" else "lw" ++let stg = if rv64 then "sd" else "sw" ++let datag = if rv64 then ".quad" else ".long" ++ ++(* Output a pseudo-register *) ++ ++let emit_reg = function ++ | {loc = Reg r} -> emit_string (register_name r) ++ | _ -> fatal_error "Emit.emit_reg" ++ ++(* Adjust sp by the given byte amount *) ++ ++let emit_stack_adjustment = function ++ | 0 -> () ++ | n when is_immediate n -> ++ ` addi sp, sp, {emit_int n}\n` ++ | n -> ++ ` li {emit_reg reg_tmp1}, {emit_int n}\n`; ++ ` add sp, sp, {emit_reg reg_tmp1}\n` ++ ++let reload_ra n = ++ let ofs = n - size_addr in ++ if is_immediate ofs then ++ ` {emit_string lg} ra, {emit_int ofs}(sp)\n` ++ else begin ++ ` li {emit_reg reg_tmp1}, {emit_int ofs}\n`; ++ ` add {emit_reg reg_tmp1}, sp, {emit_reg reg_tmp1}\n`; ++ ` {emit_string lg} ra, 0({emit_reg reg_tmp1})\n` ++ end ++ ++let store_ra n = ++ let ofs = n - size_addr in ++ if is_immediate ofs then ++ ` {emit_string stg} ra, {emit_int(n - size_addr)}(sp)\n` ++ else begin ++ ` li {emit_reg reg_tmp1}, {emit_int ofs}\n`; ++ ` add {emit_reg reg_tmp1}, sp, {emit_reg reg_tmp1}\n`; ++ ` {emit_string stg} ra, 0({emit_reg reg_tmp1})\n` ++ end ++ ++let emit_store stg src ofs = ++ if is_immediate ofs then ++ ` {emit_string stg} {emit_reg src}, {emit_int ofs}(sp)\n` ++ else begin ++ ` li {emit_reg reg_tmp1}, {emit_int ofs}\n`; ++ ` add {emit_reg reg_tmp1}, sp, {emit_reg reg_tmp1}\n`; ++ ` {emit_string stg} {emit_reg src}, 0({emit_reg reg_tmp1})\n` ++ end ++ ++let emit_load lg dst ofs = ++ if is_immediate ofs then ++ ` {emit_string lg} {emit_reg dst}, {emit_int ofs}(sp)\n` ++ else begin ++ ` li {emit_reg reg_tmp1}, {emit_int ofs}\n`; ++ ` add {emit_reg reg_tmp1}, sp, {emit_reg reg_tmp1}\n`; ++ ` {emit_string lg} {emit_reg dst}, 0({emit_reg reg_tmp1})\n` ++ end ++ ++(* Record live pointers at call points *) ++ ++let record_frame_label ?label live raise_ dbg = ++ let lbl = ++ match label with ++ | None -> new_label() ++ | Some label -> label ++ in ++ let live_offset = ref [] in ++ Reg.Set.iter ++ (function ++ {typ = Val; loc = Reg r} -> ++ live_offset := (r lsl 1) + 1 :: !live_offset ++ | {typ = Val; loc = Stack s} as reg -> ++ live_offset := slot_offset s (register_class reg) :: !live_offset ++ | {typ = Addr} as r -> ++ Misc.fatal_error ("bad GC root " ^ Reg.name r) ++ | _ -> () ++ ) ++ live; ++ record_frame_descr ~label:lbl ~frame_size:(frame_size()) ++ ~live_offset:!live_offset ~raise_frame:raise_ dbg; ++ lbl ++ ++let record_frame ?label live raise_ dbg = ++ let lbl = record_frame_label ?label live raise_ dbg in ++ `{emit_label lbl}:\n` ++ ++(* 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}:\n`; ++ ` call {emit_symbol "caml_call_gc"}\n`; ++ `{emit_label gc.gc_frame_lbl}:\n`; ++ ` j {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 ?label dbg = ++ if !Clflags.debug || !bound_error_sites = [] then begin ++ let lbl_bound_error = new_label() in ++ let lbl_frame = record_frame_label ?label Reg.Set.empty false dbg in ++ bound_error_sites := ++ { bd_lbl = lbl_bound_error; ++ bd_frame_lbl = lbl_frame } :: !bound_error_sites; ++ lbl_bound_error ++ end else ++ let bd = List.hd !bound_error_sites in ++ bd.bd_lbl ++ ++let emit_call_bound_error bd = ++ `{emit_label bd.bd_lbl}:\n`; ++ ` call {emit_symbol "caml_ml_array_bound_error"}\n`; ++ `{emit_label bd.bd_frame_lbl}:\n` ++ ++(* Record floating-point literals *) ++ ++let float_literals = ref ([] : (int64 * int) list) ++ ++(* Names for various instructions *) ++ ++let name_for_intop = function ++ | Iadd -> "add" ++ | Isub -> "sub" ++ | Imul -> "mul" ++ | Imulh -> "mulh" ++ | Idiv -> "div" ++ | Iand -> "and" ++ | Ior -> "or" ++ | Ixor -> "xor" ++ | Ilsl -> "sll" ++ | Ilsr -> "srl" ++ | Iasr -> "sra" ++ | Imod -> "rem" ++ | _ -> fatal_error "Emit.Intop" ++ ++let name_for_intop_imm = function ++ | Iadd -> "addi" ++ | Iand -> "andi" ++ | Ior -> "ori" ++ | Ixor -> "xori" ++ | Ilsl -> "slli" ++ | Ilsr -> "srli" ++ | Iasr -> "srai" ++ | _ -> fatal_error "Emit.Intop_imm" ++ ++let name_for_floatop1 = function ++ | Inegf -> "fneg.d" ++ | Iabsf -> "fabs.d" ++ | _ -> fatal_error "Emit.Iopf1" ++ ++let name_for_floatop2 = function ++ | Iaddf -> "fadd.d" ++ | Isubf -> "fsub.d" ++ | Imulf -> "fmul.d" ++ | Idivf -> "fdiv.d" ++ | _ -> fatal_error "Emit.Iopf2" ++ ++let name_for_specific = function ++ | Imultaddf false -> "fmadd.d" ++ | Imultaddf true -> "fnmadd.d" ++ | Imultsubf false -> "fmsub.d" ++ | Imultsubf true -> "fnmsub.d" ++ ++(* Name of current function *) ++let function_name = ref "" ++ ++(* Entry point for tail recursive calls *) ++let tailrec_entry_point = ref 0 ++ ++(* Output the assembly code for an instruction *) ++ ++let emit_instr i = ++ 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 = (Val | Int | Addr)}, {loc = Reg _} -> ++ ` mv {emit_reg dst}, {emit_reg src}\n` ++ | {loc = Reg _; typ = Float}, {loc = Reg _; typ = Float} -> ++ ` fmv.d {emit_reg dst}, {emit_reg src}\n` ++ | {loc = Reg _; typ = (Val | Int | Addr)}, {loc = Stack s} -> ++ let ofs = slot_offset s (register_class dst) in ++ emit_store stg src ofs ++ | {loc = Reg _; typ = Float}, {loc = Stack s} -> ++ let ofs = slot_offset s (register_class dst) in ++ emit_store "fsd" src ofs ++ | {loc = Stack s; typ = (Val | Int | Addr)}, {loc = Reg _} -> ++ let ofs = slot_offset s (register_class src) in ++ emit_load lg dst ofs ++ | {loc = Stack s; typ = Float}, {loc = Reg _} -> ++ let ofs = slot_offset s (register_class src) in ++ emit_load "fld" dst ofs ++ | _ -> ++ fatal_error "Emit: Imove" ++ end ++ | Lop(Iconst_int n) -> ++ ` li {emit_reg i.res.(0)}, {emit_nativeint n}\n` ++ | Lop(Iconst_float f) -> ++ let lbl = new_label() in ++ float_literals := (f, lbl) :: !float_literals; ++ ` fld {emit_reg i.res.(0)}, {emit_label lbl}, {emit_reg reg_tmp1}\n` ++ | Lop(Iconst_symbol s) -> ++ ` la {emit_reg i.res.(0)}, {emit_symbol s}\n` ++ | Lop(Icall_ind {label_after = label}) -> ++ ` jalr {emit_reg i.arg.(0)}\n`; ++ record_frame ~label i.live false i.dbg ++ | Lop(Icall_imm {func; label_after = label}) -> ++ ` call {emit_symbol func}\n`; ++ record_frame ~label i.live false i.dbg ++ | Lop(Itailcall_ind {label_after = _}) -> ++ let n = frame_size() in ++ if !contains_calls then reload_ra n; ++ emit_stack_adjustment n; ++ ` jr {emit_reg i.arg.(0)}\n` ++ | Lop(Itailcall_imm {func; label_after = _}) -> ++ if func = !function_name then begin ++ ` j {emit_label !tailrec_entry_point}\n` ++ end else begin ++ let n = frame_size() in ++ if !contains_calls then reload_ra n; ++ emit_stack_adjustment n; ++ ` tail {emit_symbol func}\n` ++ end ++ | Lop(Iextcall{func; alloc = true; label_after = label}) -> ++ ` la {emit_reg reg_t2}, {emit_symbol func}\n`; ++ ` call {emit_symbol "caml_c_call"}\n`; ++ record_frame ~label i.live false i.dbg ++ | Lop(Iextcall{func; alloc = false; label_after = _}) -> ++ ` call {emit_symbol func}\n` ++ | Lop(Istackoffset n) -> ++ assert (n mod 16 = 0); ++ emit_stack_adjustment (-n); ++ stack_offset := !stack_offset + n ++ | Lop(Iload(Single, Iindexed ofs)) -> ++ ` flw {emit_reg i.res.(0)}, {emit_int ofs}({emit_reg i.arg.(0)})\n`; ++ ` fcvt.d.s {emit_reg i.res.(0)}, {emit_reg i.res.(0)}\n` ++ | Lop(Iload(chunk, Iindexed ofs)) -> ++ let instr = ++ match chunk with ++ | Byte_unsigned -> "lbu" ++ | Byte_signed -> "lb" ++ | Sixteen_unsigned -> "lhu" ++ | Sixteen_signed -> "lh" ++ | Thirtytwo_unsigned -> if rv64 then "lwu" else "lw" ++ | Thirtytwo_signed -> "lw" ++ | Word_int | Word_val -> lg ++ | Single -> assert false ++ | Double | Double_u -> "fld" ++ in ++ ` {emit_string instr} {emit_reg i.res.(0)}, {emit_int ofs}({emit_reg i.arg.(0)})\n` ++ | Lop(Istore(Single, Iindexed ofs, _)) -> ++ ` fmv.x.d {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}\n`; ++ ` fcvt.s.d {emit_reg i.arg.(0)}, {emit_reg i.arg.(0)}\n`; ++ ` fsw {emit_reg i.arg.(0)}, {emit_int ofs}({emit_reg i.arg.(1)})\n`; ++ ` fmv.d.x {emit_reg i.arg.(0)}, {emit_reg reg_tmp1}\n` ++ | Lop(Istore(chunk, Iindexed ofs, _)) -> ++ let instr = ++ match chunk with ++ | Byte_unsigned | Byte_signed -> "sb" ++ | Sixteen_unsigned | Sixteen_signed -> "sh" ++ | Thirtytwo_unsigned | Thirtytwo_signed -> "sw" ++ | Word_int | Word_val -> stg ++ | Single -> assert false ++ | Double | Double_u -> "fsd" ++ in ++ ` {emit_string instr} {emit_reg i.arg.(0)}, {emit_int ofs}({emit_reg i.arg.(1)})\n` ++ | Lop(Ialloc {words = n; label_after_call_gc = label; _}) -> ++ let lbl_frame_lbl = record_frame_label ?label i.live false i.dbg in ++ let lbl_redo = new_label () in ++ let lbl_call_gc = new_label () in ++ `{emit_label lbl_redo}:\n`; ++ ` addi {emit_reg reg_alloc_ptr}, {emit_reg reg_alloc_ptr}, -{emit_int n}\n`; ++ ` addi {emit_reg i.res.(0)}, {emit_reg reg_alloc_ptr}, {emit_int size_addr}\n`; ++ ` bltu {emit_reg reg_alloc_ptr}, {emit_reg reg_alloc_lim}, {emit_label lbl_call_gc}\n`; ++ call_gc_sites := ++ { gc_lbl = lbl_call_gc; ++ gc_return_lbl = lbl_redo; ++ gc_frame_lbl = lbl_frame_lbl } :: !call_gc_sites ++ | Lop(Iintop(Icomp cmp)) -> ++ begin match cmp with ++ | Isigned Clt -> ++ ` slt {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n` ++ | Isigned Cge -> ++ ` slt {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; ++ ` xori {emit_reg i.res.(0)}, {emit_reg i.res.(0)}, 1\n`; ++ | Isigned Cgt -> ++ ` slt {emit_reg i.res.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n` ++ | Isigned Cle -> ++ ` slt {emit_reg i.res.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n`; ++ ` xori {emit_reg i.res.(0)}, {emit_reg i.res.(0)}, 1\n`; ++ | Isigned Ceq | Iunsigned Ceq -> ++ ` sub {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; ++ ` seqz {emit_reg i.res.(0)}, {emit_reg i.res.(0)}\n` ++ | Isigned Cne | Iunsigned Cne -> ++ ` sub {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; ++ ` snez {emit_reg i.res.(0)}, {emit_reg i.res.(0)}\n` ++ | Iunsigned Clt -> ++ ` sltu {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n` ++ | Iunsigned Cge -> ++ ` sltu {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; ++ ` xori {emit_reg i.res.(0)}, {emit_reg i.res.(0)}, 1\n`; ++ | Iunsigned Cgt -> ++ ` sltu {emit_reg i.res.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n` ++ | Iunsigned Cle -> ++ ` sltu {emit_reg i.res.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n`; ++ ` xori {emit_reg i.res.(0)}, {emit_reg i.res.(0)}, 1\n`; ++ end ++ | Lop(Iintop (Icheckbound {label_after_error = label; _})) -> ++ let lbl = bound_error_label ?label i.dbg in ++ ` bleu {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_label lbl}\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(Icomp _, _)) -> ++ fatal_error "Emit.emit_instr (Iintop_imm (Icomp _, _))" ++ | Lop(Iintop_imm(Icheckbound {label_after_error = label; _}, n)) -> ++ let lbl = bound_error_label ?label i.dbg in ++ ` li {emit_reg reg_tmp1}, {emit_int n}\n`; ++ ` bleu {emit_reg i.arg.(0)}, {emit_reg reg_tmp1}, {emit_label lbl}\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 name = if rv64 then "fcvt.d.l" else "fcvt.d.w" in ++ ` {emit_string name} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}\n` ++ | Lop(Iintoffloat) -> ++ let name = if rv64 then "fcvt.l.d" else "fcvt.w.d" in ++ ` {emit_string name} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}\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` ++ | Lop (Iname_for_debugger _) -> ++ () ++ | Lreloadretaddr -> ++ let n = frame_size () in ++ reload_ra n ++ | Lreturn -> ++ let n = frame_size() in ++ emit_stack_adjustment n; ++ ` ret\n` ++ | Llabel lbl -> ++ `{emit_label lbl}:\n` ++ | Lbranch lbl -> ++ ` j {emit_label lbl}\n` ++ | Lcondbranch(tst, lbl) -> ++ begin match tst with ++ | Itruetest -> ++ ` bnez {emit_reg i.arg.(0)}, {emit_label lbl}\n` ++ | Ifalsetest -> ++ ` beqz {emit_reg i.arg.(0)}, {emit_label lbl}\n` ++ | Iinttest cmp -> ++ let name = match cmp with ++ | Iunsigned Ceq | Isigned Ceq -> "beq" ++ | Iunsigned Cne | Isigned Cne -> "bne" ++ | Iunsigned Cle -> "bleu" | Isigned Cle -> "ble" ++ | Iunsigned Cge -> "bgeu" | Isigned Cge -> "bge" ++ | Iunsigned Clt -> "bltu" | Isigned Clt -> "blt" ++ | Iunsigned Cgt -> "bgtu" | Isigned Cgt -> "bgt" ++ in ++ ` {emit_string name} {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_label lbl}\n` ++ | Iinttest_imm _ -> ++ fatal_error "Emit.emit_instr (Iinttest_imm _)" ++ | Ifloattest(cmp, neg) -> ++ let neg = match cmp with ++ | Ceq -> ` feq.d {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; neg ++ | Cne -> ` feq.d {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; not neg ++ | Clt -> ` flt.d {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; neg ++ | Cgt -> ` flt.d {emit_reg reg_tmp1}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n`; neg ++ | Cle -> ` fle.d {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; neg ++ | Cge -> ` fle.d {emit_reg reg_tmp1}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n`; neg ++ in ++ if neg then ++ ` beqz {emit_reg reg_tmp1}, {emit_label lbl}\n` ++ else ++ ` bnez {emit_reg reg_tmp1}, {emit_label lbl}\n` ++ | Ioddtest -> ++ ` andi {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, 1\n`; ++ ` bnez {emit_reg reg_tmp1}, {emit_label lbl}\n` ++ | Ieventest -> ++ ` andi {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, 1\n`; ++ ` beqz {emit_reg reg_tmp1}, {emit_label lbl}\n` ++ end ++ | Lcondbranch3(lbl0, lbl1, lbl2) -> ++ ` addi {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, -1\n`; ++ begin match lbl0 with ++ | None -> () ++ | Some lbl -> ` bltz {emit_reg reg_tmp1}, {emit_label lbl}\n` ++ end; ++ begin match lbl1 with ++ | None -> () ++ | Some lbl -> ` beqz {emit_reg reg_tmp1}, {emit_label lbl}\n` ++ end; ++ begin match lbl2 with ++ | None -> () ++ | Some lbl -> ` bgtz {emit_reg reg_tmp1}, {emit_label lbl}\n` ++ end ++ | Lswitch jumptbl -> (* FIXME FIXME ? *) ++ let lbl = new_label() in ++ ` la {emit_reg reg_tmp1}, {emit_label lbl}\n`; ++ ` slli {emit_reg reg_tmp2}, {emit_reg i.arg.(0)}, 2\n`; ++ ` add {emit_reg reg_tmp1}, {emit_reg reg_tmp1}, {emit_reg reg_tmp2}\n`; ++ ` jr {emit_reg reg_tmp1}\n`; ++ `{emit_label lbl}:\n`; ++ for i = 0 to Array.length jumptbl - 1 do ++ ` j {emit_label jumptbl.(i)}\n` ++ done ++ | Lsetuptrap lbl -> ++ ` addi sp, sp, -16\n`; ++ ` jal {emit_label lbl}\n` ++ | Lpushtrap -> ++ stack_offset := !stack_offset + 16; ++ ` {emit_string stg} ra, {emit_int size_addr}(sp)\n`; ++ ` {emit_string stg} {emit_reg reg_trap}, 0(sp)\n`; ++ ` mv {emit_reg reg_trap}, sp\n` ++ | Lpoptrap -> ++ ` {emit_string lg} {emit_reg reg_trap}, 0(sp)\n`; ++ ` addi sp, sp, 16\n`; ++ stack_offset := !stack_offset - 16 ++ | Lraise k -> ++ begin match !Clflags.debug, k with ++ | true, Cmm.Raise_withtrace -> ++ ` call {emit_symbol "caml_raise_exn"}\n`; ++ record_frame Reg.Set.empty true i.dbg ++ | false, _ ++ | true, Cmm.Raise_notrace -> ++ ` mv sp, {emit_reg reg_trap}\n`; ++ ` {emit_string lg} {emit_reg reg_tmp1}, {emit_int size_addr}(sp)\n`; ++ ` {emit_string lg} {emit_reg reg_trap}, 0(sp)\n`; ++ ` addi sp, sp, 16\n`; ++ ` jalr {emit_reg reg_tmp1}\n` ++ end ++ ++(* Emit a sequence of instructions *) ++ ++let rec emit_all = function ++ | {desc = Lend} -> () | i -> emit_instr i; emit_all i.next ++ ++(* Emission of a function declaration *) ++ ++let fundecl fundecl = ++ function_name := fundecl.fun_name; ++ tailrec_entry_point := new_label(); ++ stack_offset := 0; ++ call_gc_sites := []; ++ bound_error_sites := []; ++ float_literals := []; ++ ` .globl {emit_symbol fundecl.fun_name}\n`; ++ ` .type {emit_symbol fundecl.fun_name}, @function\n`; ++ ` {emit_string code_space}\n`; ++ ` .align 2\n`; ++ `{emit_symbol fundecl.fun_name}:\n`; ++ let n = frame_size() in ++ emit_stack_adjustment (-n); ++ if !contains_calls then store_ra 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; ++ ` .size {emit_symbol fundecl.fun_name}, .-{emit_symbol fundecl.fun_name}\n`; ++ (* Emit the float literals *) ++ if !float_literals <> [] then begin ++ ` {emit_string rodata_space}\n`; ++ ` .align 3\n`; ++ List.iter ++ (fun (f, lbl) -> ++ `{emit_label lbl}:\n`; ++ if rv64 ++ then emit_float64_directive ".quad" f ++ else emit_float64_split_directive ".long" f) ++ !float_literals; ++ end ++ ++(* Emission of data *) ++ ++let declare_global_data s = ++ ` .globl {emit_symbol s}\n`; ++ ` .type {emit_symbol s}, @object\n` ++ ++let emit_item = function ++ | Cglobal_symbol s -> ++ declare_global_data s ++ | Cdefine_symbol s -> ++ `{emit_symbol s}:\n`; ++ | Cint8 n -> ++ ` .byte {emit_int n}\n` ++ | Cint16 n -> ++ ` .short {emit_int n}\n` ++ | Cint32 n -> ++ ` .long {emit_nativeint n}\n` ++ | Cint n -> ++ ` {emit_string datag} {emit_nativeint n}\n` ++ | Csingle f -> ++ emit_float32_directive ".long" (Int32.bits_of_float f) ++ | Cdouble f -> ++ if rv64 ++ then emit_float64_directive ".quad" (Int64.bits_of_float f) ++ else emit_float64_split_directive ".long" (Int64.bits_of_float f) ++ | Csymbol_address s -> ++ ` {emit_string datag} {emit_symbol s}\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}\n`; ++ List.iter emit_item l ++ ++(* Beginning / end of an assembly file *) ++ ++let begin_assembly() = ++ ` .file \"\"\n`; (* PR#7073 *) ++ (* Emit the beginning of the segments *) ++ let lbl_begin = Compilenv.make_symbol (Some "data_begin") in ++ ` {emit_string data_space}\n`; ++ declare_global_data lbl_begin; ++ `{emit_symbol lbl_begin}:\n`; ++ let lbl_begin = Compilenv.make_symbol (Some "code_begin") in ++ ` {emit_string code_space}\n`; ++ declare_global_data lbl_begin; ++ `{emit_symbol lbl_begin}:\n` ++ ++let end_assembly() = ++ ` {emit_string code_space}\n`; ++ 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}\n`; ++ let lbl_end = Compilenv.make_symbol (Some "data_end") in ++ declare_global_data lbl_end; ++ `{emit_symbol lbl_end}:\n`; ++ ` {emit_string datag} 0\n`; ++ (* Emit the frame descriptors *) ++ ` {emit_string rodata_space}\n`; ++ let lbl = Compilenv.make_symbol (Some "frametable") in ++ declare_global_data lbl; ++ `{emit_symbol lbl}:\n`; ++ emit_frames ++ { efa_code_label = (fun l -> ` {emit_string datag} {emit_label l}\n`); ++ efa_data_label = (fun l -> ` {emit_string datag} {emit_label l}\n`); ++ efa_16 = (fun n -> ` .short {emit_int n}\n`); ++ efa_32 = (fun n -> ` .long {emit_int32 n}\n`); ++ efa_word = (fun n -> ` {emit_string datag} {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 l -> `{emit_label l}:\n`); ++ efa_string = (fun s -> emit_bytes_directive " .byte " (s ^ "\000")) ++ } +diff --git a/asmcomp/riscv/proc.ml b/asmcomp/riscv/proc.ml +new file mode 100644 +index 000000000..c0b0dcdb8 +--- /dev/null ++++ b/asmcomp/riscv/proc.ml +@@ -0,0 +1,301 @@ ++(***********************************************************************) ++(* *) ++(* OCaml *) ++(* *) ++(* Nicolas Ojeda Bar *) ++(* *) ++(* Copyright 2016 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. *) ++(* *) ++(***********************************************************************) ++ ++(* Description of the RISC-V *) ++ ++open Misc ++open Cmm ++open Reg ++open Arch ++open Mach ++ ++(* Instruction selection *) ++ ++let word_addressed = false ++ ++(* Registers available for register allocation *) ++ ++(* Integer register map: ++ zero always zero ++ ra return address ++ sp, gp, tp stack pointer, global pointer, thread pointer (preserved by C) ++ a0 - a7 0 - 7 arguments/results ++ s2 - s9 8 - 15 arguments/results (preserved by C) ++ t2 - t6 16 - 20 temporary ++ t0 21 temporary (used by assembler) ++ t1 22 temporary (reserved for code gen) ++ s0 23 frame pointer (preserved by C) ++ s1 24 trap pointer (preserved by C) ++ s10 25 allocation pointer (preserved by C) ++ s11 26 allocation limit (preserved by C) ++ Floating-point register map: ++ ft0 - ft7 100 - 107 temporary ++ fs0 - fs1 108 - 109 general purpose (preserved by C) ++ fa0 - fa7 110 - 117 arguments/results ++ fs2 - fs9 118 - 125 arguments/results (preserved by C) ++ fs10 - fs11 126 - 127 general purpose (preserved by C) ++ ft8 - ft11 128 - 131 temporary ++*) ++ ++let int_reg_name = ++ [| "a0"; "a1"; "a2"; "a3"; "a4"; "a5"; "a6"; "a7"; ++ "s2"; "s3"; "s4"; "s5"; "s6"; "s7"; "s8"; "s9"; ++ "t2"; "t3"; "t4"; "t5"; "t6"; ++ "t0"; "t1"; ++ "s0"; "s1"; "s10"; "s11" |] ++ ++let float_reg_name = ++ [| "ft0"; "ft1"; "ft2"; "ft3"; "ft4"; "ft5"; "ft6"; "ft7"; ++ "fs0"; "fs1"; ++ "fa0"; "fa1"; "fa2"; "fa3"; "fa4"; "fa5"; "fa6"; "fa7"; ++ "fs2"; "fs3"; "fs4"; "fs5"; "fs6"; "fs7"; "fs8"; "fs9"; "fs10"; "fs11"; ++ "ft8"; "ft9"; "ft10"; "ft11" |] ++ ++let num_register_classes = 2 ++ ++let register_class r = ++ match r.typ with ++ | Val | Int | Addr -> 0 ++ | Float -> 1 ++ ++let num_available_registers = [| 21; 32 |] ++ ++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.make 27 Reg.dummy in ++ for i = 0 to 26 do ++ v.(i) <- Reg.at_location Int (Reg i) ++ done; ++ v ++ ++let hard_float_reg = ++ let v = Array.make 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 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.make (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 ++ | Val | 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 _ = fatal_error "Proc.loc_results: cannot call" ++ ++let max_arguments_for_tailcalls = 16 ++ ++let loc_spacetime_node_hole = Reg.dummy (* Spacetime unsupported *) ++ ++(* OCaml calling convention: ++ first integer args in a0 .. a7, s2 .. s9 ++ first float args in fa0 .. fa7, fs2 .. fs9 ++ remaining args on stack. ++ Return values in a0 .. a7, s2 .. s9 or fa0 .. fa7, fs2 .. fs9. *) ++ ++let single_regs arg = Array.map (fun arg -> [| arg |]) arg ++let ensure_single_regs res = ++ Array.map (function ++ | [| res |] -> res ++ | _ -> failwith "proc.ensure_single_regs" ++ ) res ++ ++let loc_arguments arg = ++ calling_conventions 0 15 110 125 outgoing arg ++ ++let loc_parameters arg = ++ let (loc, _ofs) = ++ calling_conventions 0 15 110 125 incoming arg ++ in ++ loc ++ ++let loc_results res = ++ let (loc, _ofs) = ++ calling_conventions 0 15 110 125 not_supported res ++ in ++ loc ++ ++(* C calling convention: ++ first integer args in a0 .. a7 ++ first float args in fa0 .. fa7 ++ remaining args on stack. ++ Return values in a0 .. a1 or fa0 .. fa1. *) ++ ++let external_calling_conventions ++ first_int last_int first_float last_float make_stack arg = ++ let loc = Array.make (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) with ++ | [| arg |] -> ++ begin match arg.typ with ++ | Val | Int | Addr as ty -> ++ if !int <= last_int then begin ++ loc.(i) <- [| phys_reg !int |]; ++ incr int; ++ incr float; ++ 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; ++ incr int; ++ end else begin ++ loc.(i) <- [| stack_slot (make_stack !ofs) Float |]; ++ ofs := !ofs + size_float ++ end ++ end ++ | [| arg1; arg2 |] -> ++ (* Passing of 64-bit quantities to external functions on 32-bit ++ platform. *) ++ assert (size_int = 4); ++ begin match arg1.typ, arg2.typ with ++ | Int, Int -> ++ int := Misc.align !int 2; ++ if !int <= last_int - 1 then begin ++ let reg_lower = phys_reg !int in ++ let reg_upper = phys_reg (!int + 1) in ++ loc.(i) <- [| reg_lower; reg_upper |]; ++ int := !int + 2 ++ end else begin ++ let size_int64 = 8 in ++ ofs := Misc.align !ofs size_int64; ++ let ofs_lower = !ofs in ++ let ofs_upper = !ofs + size_int in ++ let stack_lower = stack_slot (make_stack ofs_lower) Int in ++ let stack_upper = stack_slot (make_stack ofs_upper) Int in ++ loc.(i) <- [| stack_lower; stack_upper |]; ++ ofs := !ofs + size_int64 ++ end ++ | _ -> ++ let f = function Int -> "I" | Addr -> "A" | Val -> "V" | Float -> "F" in ++ fatal_error (Printf.sprintf "Proc.calling_conventions: bad register \ ++ type(s) for multi-register argument: %s, %s" ++ (f arg1.typ) (f arg2.typ)) ++ end ++ | _ -> ++ fatal_error "Proc.calling_conventions: bad number of register for \ ++ multi-register argument" ++ done; ++ (loc, Misc.align !ofs 16) (* Keep stack 16-aligned. *) ++ ++let loc_external_arguments arg = ++ external_calling_conventions 0 7 110 117 outgoing arg ++ ++let loc_external_results res = ++ let (loc, _ofs) = ++ external_calling_conventions 0 1 110 111 not_supported (single_regs res) ++ in ++ ensure_single_regs loc ++ ++(* Exceptions are in GPR 3 *) ++ ++let loc_exn_bucket = phys_reg 0 ++ ++(* Volatile registers: none *) ++ ++let regs_are_volatile _ = false ++ ++(* Registers destroyed by operations *) ++ ++let destroyed_at_c_call = ++ Array.of_list(List.map phys_reg ++ [0; 1; 2; 3; 4; 5; 6; 7; 16; 17; 18; 19; 20; (* 21; 22; *) ++ 100; 101; 102; 103; 104; 105; 106; 107; 110; 111; 112; 113; 114; 115; 116; ++ 117; 128; 129; 130; 131]) ++ ++let destroyed_at_oper = function ++ | Iop(Icall_ind _ | Icall_imm _ | Iextcall{alloc = true; _}) -> all_phys_regs ++ | Iop(Iextcall{alloc = false; _}) -> destroyed_at_c_call ++ | _ -> [||] ++ ++let destroyed_at_raise = all_phys_regs ++ ++(* Maximal register pressure *) ++ ++let safe_register_pressure = function ++ | Iextcall _ -> 15 ++ | _ -> 21 ++ ++let max_register_pressure = function ++ | Iextcall _ -> [| 15; 18 |] ++ | _ -> [| 21; 30 |] ++ ++(* Pure operations (without any side effect besides updating their result ++ registers). *) ++ ++let op_is_pure = function ++ | Icall_ind _ | Icall_imm _ | Itailcall_ind _ | Itailcall_imm _ ++ | Iextcall _ | Istackoffset _ | Istore _ | Ialloc _ ++ | Iintop(Icheckbound _) | Iintop_imm(Icheckbound _, _) -> false ++ | Ispecific(Imultaddf _ | Imultsubf _) -> true ++ | _ -> true ++ ++(* 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/riscv/reload.ml b/asmcomp/riscv/reload.ml +new file mode 100644 +index 000000000..85b970342 +--- /dev/null ++++ b/asmcomp/riscv/reload.ml +@@ -0,0 +1,16 @@ ++(***********************************************************************) ++(* *) ++(* OCaml *) ++(* *) ++(* Nicolas Ojeda Bar *) ++(* *) ++(* Copyright 2016 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 RISC-V *) ++ ++let fundecl f = ++ (new Reloadgen.reload_generic)#fundecl f +diff --git a/asmcomp/riscv/scheduling.ml b/asmcomp/riscv/scheduling.ml +new file mode 100644 +index 000000000..e436be1cc +--- /dev/null ++++ b/asmcomp/riscv/scheduling.ml +@@ -0,0 +1,19 @@ ++(***********************************************************************) ++(* *) ++(* OCaml *) ++(* *) ++(* Nicolas Ojeda Bar *) ++(* *) ++(* Copyright 2016 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. *) ++(* *) ++(***********************************************************************) ++ ++(* Instruction scheduling for the RISC-V *) ++ ++let _ = let module M = Schedgen in () (* to create a dependency *) ++ ++(* Scheduling is turned off. *) ++ ++let fundecl f = f +diff --git a/asmcomp/riscv/selection.ml b/asmcomp/riscv/selection.ml +new file mode 100644 +index 000000000..092ca88aa +--- /dev/null ++++ b/asmcomp/riscv/selection.ml +@@ -0,0 +1,72 @@ ++(***********************************************************************) ++(* *) ++(* OCaml *) ++(* *) ++(* Nicolas Ojeda Bar *) ++(* *) ++(* Copyright 2016 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. *) ++(* *) ++(***********************************************************************) ++ ++(* Instruction selection for the RISC-V processor *) ++ ++open Cmm ++open Arch ++open Mach ++ ++(* Instruction selection *) ++ ++class selector = object (self) ++ ++inherit Selectgen.selector_generic as super ++ ++method is_immediate n = is_immediate n ++ ++method select_addressing _ = function ++ | Cop(Cadda, [arg; Cconst_int n], _) when self#is_immediate n -> ++ (Iindexed n, arg) ++ | Cop(Cadda, [arg1; Cop(Caddi, [arg2; Cconst_int n], _)], dbg) when self#is_immediate n -> ++ (Iindexed n, Cop(Caddi, [arg1; arg2], dbg)) ++ | arg -> ++ (Iindexed 0, arg) ++ ++method! select_operation op args dbg = ++ match (op, args) with ++ (* RISC-V does not support immediate operands for multiply high *) ++ | (Cmulhi, _) -> (Iintop Imulh, args) ++ (* Recognize (neg-)mult-add and (neg-)mult-sub instructions *) ++ | (Caddf, [Cop(Cmulf, [arg1; arg2], _); arg3]) ++ | (Caddf, [arg3; Cop(Cmulf, [arg1; arg2], _)]) -> ++ (Ispecific (Imultaddf false), [arg1; arg2; arg3]) ++ | (Csubf, [Cop(Cmulf, [arg1; arg2], _); arg3]) -> ++ (Ispecific (Imultsubf false), [arg1; arg2; arg3]) ++ | (Cnegf, [Cop(Csubf, [Cop(Cmulf, [arg1; arg2], _); arg3], _)]) -> ++ (Ispecific (Imultsubf true), [arg1; arg2; arg3]) ++ | (Cnegf, [Cop(Caddf, [Cop(Cmulf, [arg1; arg2], _); arg3], _)]) -> ++ (Ispecific (Imultaddf true), [arg1; arg2; arg3]) ++ (* RISC-V does not support immediate operands for comparison operators *) ++ | (Ccmpi comp, args) -> (Iintop(Icomp (Isigned comp)), args) ++ | (Ccmpa comp, args) -> (Iintop(Icomp (Iunsigned comp)), args) ++ | (Cmuli, _) -> (Iintop Imul, args) ++ | _ -> ++ super#select_operation op args dbg ++ ++(* Instruction selection for conditionals *) ++ ++method! select_condition = function ++ | Cop(Ccmpi cmp, args, _) -> ++ (Iinttest(Isigned cmp), Ctuple args) ++ | Cop(Ccmpa cmp, args, _) -> ++ (Iinttest(Iunsigned cmp), Ctuple args) ++ | Cop(Ccmpf cmp, args, _) -> ++ (Ifloattest(cmp, false), Ctuple args) ++ | Cop(Cand, [arg; Cconst_int 1], _) -> ++ (Ioddtest, arg) ++ | arg -> ++ (Itruetest, arg) ++ ++end ++ ++let fundecl f = (new selector)#emit_fundecl f +diff --git a/asmrun/riscv.S b/asmrun/riscv.S +new file mode 100644 +index 000000000..a82048efc +--- /dev/null ++++ b/asmrun/riscv.S +@@ -0,0 +1,424 @@ ++/***********************************************************************/ ++/* */ ++/* OCaml */ ++/* */ ++/* Nicolas Ojeda Bar */ ++/* */ ++/* Copyright 1996 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, RISC-V processor, 64-bit mode */ ++/* Must be preprocessed by cpp */ ++ ++#define TRAP_PTR s1 ++#define ALLOC_PTR s10 ++#define ALLOC_LIMIT s11 ++#define TMP0 t0 ++#define TMP1 t1 ++#define ARG t2 ++ ++#if defined(MODEL_riscv64) ++#define store sd ++#define load ld ++#define WSZ 8 ++#else ++#define store sw ++#define load lw ++#define WSZ 4 ++#endif ++ ++#if defined(__PIC__) ++ .option pic ++#else ++ .option nopic ++#endif ++ ++ .section .text ++/* Invoke the garbage collector. */ ++ ++ .globl caml_system__code_begin ++caml_system__code_begin: ++ ++ .align 2 ++ .globl caml_call_gc ++ .type caml_call_gc, @function ++caml_call_gc: ++ /* Record return address */ ++ store ra, caml_last_return_address, TMP0 ++ /* Record lowest stack address */ ++ mv TMP1, sp ++ store sp, caml_bottom_of_stack, TMP0 ++.Lcaml_call_gc: ++ /* Set up stack space, saving return address */ ++ /* (1 reg for RA, 1 reg for FP, 21 allocatable int regs, 20 caller-save float regs) * 8 */ ++ /* + 1 for alignment */ ++ addi sp, sp, -0x160 ++ mv s0, sp ++ store ra, 0x8(sp) ++ store s0, 0x0(sp) ++ /* Save allocatable integer registers on the stack, ++ in the order given in proc.ml */ ++ store a0, 0x10(sp) ++ store a1, 0x18(sp) ++ store a2, 0x20(sp) ++ store a3, 0x28(sp) ++ store a4, 0x30(sp) ++ store a5, 0x38(sp) ++ store a6, 0x40(sp) ++ store a7, 0x48(sp) ++ store s2, 0x50(sp) ++ store s3, 0x58(sp) ++ store s4, 0x60(sp) ++ store s5, 0x68(sp) ++ store s6, 0x70(sp) ++ store s7, 0x78(sp) ++ store s8, 0x80(sp) ++ store s9, 0x88(sp) ++ store t2, 0x90(sp) ++ store t3, 0x98(sp) ++ store t4, 0xa0(sp) ++ store t5, 0xa8(sp) ++ store t6, 0xb0(sp) ++ /* Save caller-save floating-point registers on the stack ++ (callee-saves are preserved by caml_garbage_collection) */ ++ fsd ft0, 0xb8(sp) ++ fsd ft1, 0xc0(sp) ++ fsd ft2, 0xc8(sp) ++ fsd ft3, 0xd0(sp) ++ fsd ft4, 0xd8(sp) ++ fsd ft5, 0xe0(sp) ++ fsd ft6, 0xe8(sp) ++ fsd ft7, 0xf0(sp) ++ fsd fa0, 0xf8(sp) ++ fsd fa1, 0x100(sp) ++ fsd fa2, 0x108(sp) ++ fsd fa3, 0x110(sp) ++ fsd fa4, 0x118(sp) ++ fsd fa5, 0x120(sp) ++ fsd fa6, 0x128(sp) ++ fsd fa7, 0x130(sp) ++ fsd ft8, 0x138(sp) ++ fsd ft9, 0x140(sp) ++ fsd ft9, 0x148(sp) ++ fsd ft10, 0x150(sp) ++ fsd ft11, 0x158(sp) ++ /* Store pointer to saved integer registers in caml_gc_regs */ ++ addi TMP1, sp, 16 ++ store TMP1, caml_gc_regs, TMP0 ++ /* Save current allocation pointer for debugging purposes */ ++ store ALLOC_PTR, caml_young_ptr, TMP0 ++ /* Save trap pointer in case an exception is raised during GC */ ++ store TRAP_PTR, caml_exception_pointer, TMP0 ++ /* Call the garbage collector */ ++ call caml_garbage_collection ++ /* Restore registers */ ++ load a0, 0x10(sp) ++ load a1, 0x18(sp) ++ load a2, 0x20(sp) ++ load a3, 0x28(sp) ++ load a4, 0x30(sp) ++ load a5, 0x38(sp) ++ load a6, 0x40(sp) ++ load a7, 0x48(sp) ++ load s2, 0x50(sp) ++ load s3, 0x58(sp) ++ load s4, 0x60(sp) ++ load s5, 0x68(sp) ++ load s6, 0x70(sp) ++ load s7, 0x78(sp) ++ load s8, 0x80(sp) ++ load s9, 0x88(sp) ++ load t2, 0x90(sp) ++ load t3, 0x98(sp) ++ load t4, 0xa0(sp) ++ load t5, 0xa8(sp) ++ load t6, 0xb0(sp) ++ fld ft0, 0xb8(sp) ++ fld ft1, 0xc0(sp) ++ fld ft2, 0xc8(sp) ++ fld ft3, 0xd0(sp) ++ fld ft4, 0xd8(sp) ++ fld ft5, 0xe0(sp) ++ fld ft6, 0xe8(sp) ++ fld ft7, 0xf0(sp) ++ fld fa0, 0xf8(sp) ++ fld fa1, 0x100(sp) ++ fld fa2, 0x108(sp) ++ fld fa3, 0x110(sp) ++ fld fa4, 0x118(sp) ++ fld fa5, 0x120(sp) ++ fld fa6, 0x128(sp) ++ fld fa7, 0x130(sp) ++ fld ft8, 0x138(sp) ++ fld ft9, 0x140(sp) ++ fld ft9, 0x148(sp) ++ fld ft10, 0x150(sp) ++ fld ft11, 0x158(sp) ++ /* Reload new allocation pointer and allocation limit */ ++ load ALLOC_PTR, caml_young_ptr ++ load ALLOC_LIMIT, caml_young_limit ++ /* Free stack space and return to caller */ ++ load ra, 0x8(sp) ++ load s0, 0x0(sp) ++ addi sp, sp, 0x160 ++ ret ++ .size caml_call_gc, .-caml_call_gc ++ ++/* Call a C function from OCaml */ ++/* Function to call is in ARG */ ++ ++ .align 2 ++ .globl caml_c_call ++ .type caml_c_call, @function ++caml_c_call: ++ /* Preserve return address in callee-save register s2 */ ++ mv s2, ra ++ /* Record lowest stack address and return address */ ++ store ra, caml_last_return_address, TMP0 ++ store sp, caml_bottom_of_stack, TMP0 ++ /* Make the exception handler alloc ptr available to the C code */ ++ store ALLOC_PTR, caml_young_ptr, TMP0 ++ store TRAP_PTR, caml_exception_pointer, TMP0 ++ /* Call the function */ ++ jalr ARG ++ /* Reload alloc ptr and alloc limit */ ++ load ALLOC_PTR, caml_young_ptr ++ load TRAP_PTR, caml_exception_pointer ++ /* Return */ ++ jr s2 ++ .size caml_c_call, .-caml_c_call ++ ++/* Raise an exception from OCaml */ ++ .align 2 ++ .globl caml_raise_exn ++ .type caml_raise_exn, @function ++caml_raise_exn: ++ /* Test if backtrace is active */ ++ load TMP1, caml_backtrace_active ++ bnez TMP1, 2f ++1: /* Cut stack at current trap handler */ ++ mv sp, TRAP_PTR ++ /* Pop previous handler and jump to it */ ++ load TMP1, 8(sp) ++ load TRAP_PTR, 0(sp) ++ addi sp, sp, 16 ++ jr TMP1 ++2: /* Preserve exception bucket in callee-save register s2 */ ++ mv s2, a0 ++ /* Stash the backtrace */ ++ mv a1, ra ++ mv a2, sp ++ mv a3, TRAP_PTR ++ call caml_stash_backtrace ++ /* Restore exception bucket and raise */ ++ mv a0, s2 ++ j 1b ++ .size caml_raise_exn, .-caml_raise_exn ++ ++ .globl caml_reraise_exn ++ .type caml_reraise_exn, @function ++ ++/* Raise an exception from C */ ++ ++ .align 2 ++ .globl caml_raise_exception ++ .type caml_raise_exception, @function ++caml_raise_exception: ++ load TRAP_PTR, caml_exception_pointer ++ load ALLOC_PTR, caml_young_ptr ++ load ALLOC_LIMIT, caml_young_limit ++ load TMP1, caml_backtrace_active ++ bnez TMP1, 2f ++1: /* Cut stack at current trap handler */ ++ mv sp, TRAP_PTR ++ load TMP1, 8(sp) ++ load TRAP_PTR, 0(sp) ++ addi sp, sp, 16 ++ jr TMP1 ++2: /* Preserve exception bucket in callee-save register s2 */ ++ mv s2, a0 ++ load a1, caml_last_return_address ++ load a2, caml_bottom_of_stack ++ mv a3, TRAP_PTR ++ call caml_stash_backtrace ++ mv a0, s2 ++ j 1b ++ .size caml_raise_exception, .-caml_raise_exception ++ ++/* Start the OCaml program */ ++ ++ .align 2 ++ .globl caml_start_program ++ .type caml_start_program, @function ++caml_start_program: ++ ++ la ARG, caml_program ++ /* Code shared with caml_callback* */ ++ /* Address of OCaml code to call is in ARG */ ++ /* Arguments to the OCaml code are in a0 ... a7 */ ++.Ljump_to_caml: ++ /* Set up stack frame and save callee-save registers */ ++ addi sp, sp, -0xd0 ++ store ra, 0xc0(sp) ++ store s0, 0x0(sp) ++ store s1, 0x8(sp) ++ store s2, 0x10(sp) ++ store s3, 0x18(sp) ++ store s4, 0x20(sp) ++ store s5, 0x28(sp) ++ store s6, 0x30(sp) ++ store s7, 0x38(sp) ++ store s8, 0x40(sp) ++ store s9, 0x48(sp) ++ store s10, 0x50(sp) ++ store s11, 0x58(sp) ++ fsd fs0, 0x60(sp) ++ fsd fs1, 0x68(sp) ++ fsd fs2, 0x70(sp) ++ fsd fs3, 0x78(sp) ++ fsd fs4, 0x80(sp) ++ fsd fs5, 0x88(sp) ++ fsd fs6, 0x90(sp) ++ fsd fs7, 0x98(sp) ++ fsd fs8, 0xa0(sp) ++ fsd fs9, 0xa8(sp) ++ fsd fs10, 0xb0(sp) ++ fsd fs11, 0xb8(sp) ++ addi sp, sp, -32 ++ /* Setup a callback link on the stack */ ++ load TMP1, caml_bottom_of_stack ++ store TMP1, 0(sp) ++ load TMP1, caml_last_return_address ++ store TMP1, 8(sp) ++ load TMP1, caml_gc_regs ++ store TMP1, 16(sp) ++ /* set up a trap frame */ ++ addi sp, sp, -16 ++ load TMP1, caml_exception_pointer ++ store TMP1, 0(sp) ++ lla TMP0, .Ltrap_handler ++ store TMP0, 8(sp) ++ mv TRAP_PTR, sp ++ load ALLOC_PTR, caml_young_ptr ++ load ALLOC_LIMIT, caml_young_limit ++ store x0, caml_last_return_address, TMP0 ++ jalr ARG ++.Lcaml_retaddr: /* pop trap frame, restoring caml_exception_pointer */ ++ load TMP1, 0(sp) ++ store TMP1, caml_exception_pointer, TMP0 ++ addi sp, sp, 16 ++.Lreturn_result: /* pop callback link, restoring global variables */ ++ load TMP1, 0(sp) ++ store TMP1, caml_bottom_of_stack, TMP0 ++ load TMP1, 8(sp) ++ store TMP1, caml_last_return_address, TMP0 ++ load TMP1, 16(sp) ++ store TMP1, caml_gc_regs, TMP0 ++ addi sp, sp, 32 ++ /* Update allocation pointer */ ++ store ALLOC_PTR, caml_young_ptr, TMP0 ++ /* reload callee-save registers and return */ ++ load ra, 0xc0(sp) ++ load s0, 0x0(sp) ++ load s1, 0x8(sp) ++ load s2, 0x10(sp) ++ load s3, 0x18(sp) ++ load s4, 0x20(sp) ++ load s5, 0x28(sp) ++ load s6, 0x30(sp) ++ load s7, 0x38(sp) ++ load s8, 0x40(sp) ++ load s9, 0x48(sp) ++ load s10, 0x50(sp) ++ load s11, 0x58(sp) ++ fld fs0, 0x60(sp) ++ fld fs1, 0x68(sp) ++ fld fs2, 0x70(sp) ++ fld fs3, 0x78(sp) ++ fld fs4, 0x80(sp) ++ fld fs5, 0x88(sp) ++ fld fs6, 0x90(sp) ++ fld fs7, 0x98(sp) ++ fld fs8, 0xa0(sp) ++ fld fs9, 0xa8(sp) ++ fld fs10, 0xb0(sp) ++ fld fs11, 0xb8(sp) ++ addi sp, sp, 0xd0 ++ ret ++.Ltrap_handler: ++ store TRAP_PTR, caml_exception_pointer, TMP0 ++ ori a0, a0, 2 ++ j .Lreturn_result ++ .size caml_start_program, .-caml_start_program ++ ++/* Callback from C to OCaml */ ++ ++ .align 2 ++ .globl caml_callback_exn ++ .type caml_callback_exn, @function ++caml_callback_exn: ++ /* Initial shuffling of arguments (a0 = closure, a1 = first arg) */ ++ mv TMP1, a0 ++ mv a0, a1 /* a0 = first arg */ ++ mv a1, TMP1 /* a1 = closure environment */ ++ load ARG, 0(TMP1) /* code pointer */ ++ j .Ljump_to_caml ++ .size caml_callback_exn, .-caml_callback_exn ++ ++ .align 2 ++ .globl caml_callback2_exn ++ .type caml_callback2_exn, @function ++caml_callback2_exn: ++ /* Initial shuffling of arguments (a0 = closure, a1 = arg1, a2 = arg2) */ ++ mv TMP1, a0 ++ mv a0, a1 ++ mv a1, a2 ++ mv a2, TMP1 ++ la ARG, caml_apply2 ++ j .Ljump_to_caml ++ .size caml_callback2_exn, .-caml_callback2_exn ++ ++ .align 2 ++ .globl caml_callback3_exn ++ .type caml_callback3_exn, @function ++caml_callback3_exn: ++ /* Initial shuffling of argumnets */ ++ /* (a0 = closure, a1 = arg1, a2 = arg2, a3 = arg3) */ ++ mv TMP1, a0 ++ mv a0, a1 ++ mv a1, a2 ++ mv a2, a3 ++ mv a3, TMP1 ++ la ARG, caml_apply3 ++ j .Ljump_to_caml ++ .size caml_callback3_exn, .-caml_callback3_exn ++ ++ .align 2 ++ .globl caml_ml_array_bound_error ++ .type caml_ml_array_bound_error, @function ++caml_ml_array_bound_error: ++ /* Load address of [caml_array_bound_error] in ARG */ ++ la ARG, caml_array_bound_error ++ /* Call that function */ ++ j caml_c_call ++ ++ .globl caml_system__code_end ++caml_system__code_end: ++ ++/* GC roots for callback */ ++ ++ .section .data ++ .align 3 ++ .globl caml_system__frametable ++ .type caml_system__frametable, @object ++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 ++ .size caml_system__frametable, .-caml_system__frametable +diff --git a/byterun/caml/stack.h b/byterun/caml/stack.h +index 266863986..e198be0a6 100644 +--- a/byterun/caml/stack.h ++++ b/byterun/caml/stack.h +@@ -70,6 +70,11 @@ + #define Callback_link(sp) ((struct caml_context *)((sp) + 16)) + #endif + ++#ifdef TARGET_riscv /* FIXME FIXME */ ++#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/config/gnu/config.guess b/config/gnu/config.guess +index b79252d6b..8335398b2 100755 +--- a/config/gnu/config.guess ++++ b/config/gnu/config.guess +@@ -2,7 +2,7 @@ + # Attempt to guess a canonical system name. + # Copyright 1992-2013 Free Software Foundation, Inc. + +-timestamp='2013-06-10' ++timestamp='2016-10-23' + + # 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 +@@ -1001,6 +1001,9 @@ EOF + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-${LIBC} + exit ;; ++ riscv*:Linux:*:*) ++ echo ${UNAME_MACHINE}-unknown-linux ++ exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + exit ;; +diff --git a/configure b/configure +index 53f45f85b..cf5a4a02a 100755 +--- a/configure ++++ b/configure +@@ -928,6 +928,7 @@ if $with_sharedlibs; then + arm*-*-freebsd*) natdynlink=true;; + earm*-*-netbsd*) natdynlink=true;; + aarch64-*-linux*) natdynlink=true;; ++ riscv*-*-linux*) natdynlink=true;; + esac + fi + +@@ -1004,6 +1005,8 @@ case "$target" in + x86_64-*-mingw*) arch=amd64; system=mingw;; + aarch64-*-linux*) arch=arm64; system=linux;; + x86_64-*-cygwin*) arch=amd64; system=cygwin;; ++ riscv32-*-linux*) arch=riscv; model=riscv32; system=linux;; ++ riscv64-*-linux*) arch=riscv; model=riscv64; system=linux;; + esac + + # Some platforms exist both in 32-bit and 64-bit variants, not distinguished +@@ -1062,7 +1065,7 @@ case "$arch,$system" in + aspp="${TOOLPREF}cc -c";; + *,freebsd) as="${TOOLPREF}as" + aspp="${TOOLPREF}cc -c";; +- amd64,*|arm,*|arm64,*|i386,*|power,bsd*|power,netbsd) ++ amd64,*|arm,*|arm64,*|i386,*|power,bsd*|power,netbsd|riscv,*) + as="${TOOLPREF}as" + case "$ccfamily" in + clang-*) +-- +2.17.1 + diff --git a/SOURCES/0005-Copyright-untabify.patch b/SOURCES/0005-Copyright-untabify.patch new file mode 100644 index 0000000..da7749a --- /dev/null +++ b/SOURCES/0005-Copyright-untabify.patch @@ -0,0 +1,717 @@ +From 2e4038b6b8073f55012613f18cb19a4c99e8219d Mon Sep 17 00:00:00 2001 +From: Nicolas Ojeda Bar +Date: Fri, 1 Dec 2017 14:39:46 +0100 +Subject: [PATCH 5/8] Copyright, untabify + +--- + asmrun/riscv.S | 608 ++++++++++++++++++++++++------------------------- + 1 file changed, 304 insertions(+), 304 deletions(-) + +diff --git a/asmrun/riscv.S b/asmrun/riscv.S +index a82048efc..88d7ab924 100644 +--- a/asmrun/riscv.S ++++ b/asmrun/riscv.S +@@ -4,7 +4,7 @@ + /* */ + /* Nicolas Ojeda Bar */ + /* */ +-/* Copyright 1996 Institut National de Recherche en Informatique et */ ++/* Copyright 2017 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. */ +@@ -37,388 +37,388 @@ + .option nopic + #endif + +- .section .text ++ .section .text + /* Invoke the garbage collector. */ + +- .globl caml_system__code_begin ++ .globl caml_system__code_begin + caml_system__code_begin: + +- .align 2 +- .globl caml_call_gc +- .type caml_call_gc, @function ++ .align 2 ++ .globl caml_call_gc ++ .type caml_call_gc, @function + caml_call_gc: + /* Record return address */ +- store ra, caml_last_return_address, TMP0 ++ store ra, caml_last_return_address, TMP0 + /* Record lowest stack address */ +- mv TMP1, sp +- store sp, caml_bottom_of_stack, TMP0 ++ mv TMP1, sp ++ store sp, caml_bottom_of_stack, TMP0 + .Lcaml_call_gc: +- /* Set up stack space, saving return address */ ++ /* Set up stack space, saving return address */ + /* (1 reg for RA, 1 reg for FP, 21 allocatable int regs, 20 caller-save float regs) * 8 */ + /* + 1 for alignment */ +- addi sp, sp, -0x160 +- mv s0, sp +- store ra, 0x8(sp) +- store s0, 0x0(sp) ++ addi sp, sp, -0x160 ++ mv s0, sp ++ store ra, 0x8(sp) ++ store s0, 0x0(sp) + /* Save allocatable integer registers on the stack, + in the order given in proc.ml */ +- store a0, 0x10(sp) +- store a1, 0x18(sp) +- store a2, 0x20(sp) +- store a3, 0x28(sp) +- store a4, 0x30(sp) +- store a5, 0x38(sp) +- store a6, 0x40(sp) +- store a7, 0x48(sp) +- store s2, 0x50(sp) +- store s3, 0x58(sp) +- store s4, 0x60(sp) +- store s5, 0x68(sp) +- store s6, 0x70(sp) +- store s7, 0x78(sp) +- store s8, 0x80(sp) +- store s9, 0x88(sp) +- store t2, 0x90(sp) +- store t3, 0x98(sp) +- store t4, 0xa0(sp) +- store t5, 0xa8(sp) +- store t6, 0xb0(sp) ++ store a0, 0x10(sp) ++ store a1, 0x18(sp) ++ store a2, 0x20(sp) ++ store a3, 0x28(sp) ++ store a4, 0x30(sp) ++ store a5, 0x38(sp) ++ store a6, 0x40(sp) ++ store a7, 0x48(sp) ++ store s2, 0x50(sp) ++ store s3, 0x58(sp) ++ store s4, 0x60(sp) ++ store s5, 0x68(sp) ++ store s6, 0x70(sp) ++ store s7, 0x78(sp) ++ store s8, 0x80(sp) ++ store s9, 0x88(sp) ++ store t2, 0x90(sp) ++ store t3, 0x98(sp) ++ store t4, 0xa0(sp) ++ store t5, 0xa8(sp) ++ store t6, 0xb0(sp) + /* Save caller-save floating-point registers on the stack + (callee-saves are preserved by caml_garbage_collection) */ +- fsd ft0, 0xb8(sp) +- fsd ft1, 0xc0(sp) +- fsd ft2, 0xc8(sp) +- fsd ft3, 0xd0(sp) +- fsd ft4, 0xd8(sp) +- fsd ft5, 0xe0(sp) +- fsd ft6, 0xe8(sp) +- fsd ft7, 0xf0(sp) +- fsd fa0, 0xf8(sp) +- fsd fa1, 0x100(sp) +- fsd fa2, 0x108(sp) +- fsd fa3, 0x110(sp) +- fsd fa4, 0x118(sp) +- fsd fa5, 0x120(sp) +- fsd fa6, 0x128(sp) +- fsd fa7, 0x130(sp) +- fsd ft8, 0x138(sp) +- fsd ft9, 0x140(sp) +- fsd ft9, 0x148(sp) +- fsd ft10, 0x150(sp) +- fsd ft11, 0x158(sp) ++ fsd ft0, 0xb8(sp) ++ fsd ft1, 0xc0(sp) ++ fsd ft2, 0xc8(sp) ++ fsd ft3, 0xd0(sp) ++ fsd ft4, 0xd8(sp) ++ fsd ft5, 0xe0(sp) ++ fsd ft6, 0xe8(sp) ++ fsd ft7, 0xf0(sp) ++ fsd fa0, 0xf8(sp) ++ fsd fa1, 0x100(sp) ++ fsd fa2, 0x108(sp) ++ fsd fa3, 0x110(sp) ++ fsd fa4, 0x118(sp) ++ fsd fa5, 0x120(sp) ++ fsd fa6, 0x128(sp) ++ fsd fa7, 0x130(sp) ++ fsd ft8, 0x138(sp) ++ fsd ft9, 0x140(sp) ++ fsd ft9, 0x148(sp) ++ fsd ft10, 0x150(sp) ++ fsd ft11, 0x158(sp) + /* Store pointer to saved integer registers in caml_gc_regs */ +- addi TMP1, sp, 16 +- store TMP1, caml_gc_regs, TMP0 ++ addi TMP1, sp, 16 ++ store TMP1, caml_gc_regs, TMP0 + /* Save current allocation pointer for debugging purposes */ +- store ALLOC_PTR, caml_young_ptr, TMP0 ++ store ALLOC_PTR, caml_young_ptr, TMP0 + /* Save trap pointer in case an exception is raised during GC */ +- store TRAP_PTR, caml_exception_pointer, TMP0 ++ store TRAP_PTR, caml_exception_pointer, TMP0 + /* Call the garbage collector */ +- call caml_garbage_collection ++ call caml_garbage_collection + /* Restore registers */ +- load a0, 0x10(sp) +- load a1, 0x18(sp) +- load a2, 0x20(sp) +- load a3, 0x28(sp) +- load a4, 0x30(sp) +- load a5, 0x38(sp) +- load a6, 0x40(sp) +- load a7, 0x48(sp) +- load s2, 0x50(sp) +- load s3, 0x58(sp) +- load s4, 0x60(sp) +- load s5, 0x68(sp) +- load s6, 0x70(sp) +- load s7, 0x78(sp) +- load s8, 0x80(sp) +- load s9, 0x88(sp) +- load t2, 0x90(sp) +- load t3, 0x98(sp) +- load t4, 0xa0(sp) +- load t5, 0xa8(sp) +- load t6, 0xb0(sp) +- fld ft0, 0xb8(sp) +- fld ft1, 0xc0(sp) +- fld ft2, 0xc8(sp) +- fld ft3, 0xd0(sp) +- fld ft4, 0xd8(sp) +- fld ft5, 0xe0(sp) +- fld ft6, 0xe8(sp) +- fld ft7, 0xf0(sp) +- fld fa0, 0xf8(sp) +- fld fa1, 0x100(sp) +- fld fa2, 0x108(sp) +- fld fa3, 0x110(sp) +- fld fa4, 0x118(sp) +- fld fa5, 0x120(sp) +- fld fa6, 0x128(sp) +- fld fa7, 0x130(sp) +- fld ft8, 0x138(sp) +- fld ft9, 0x140(sp) +- fld ft9, 0x148(sp) +- fld ft10, 0x150(sp) +- fld ft11, 0x158(sp) ++ load a0, 0x10(sp) ++ load a1, 0x18(sp) ++ load a2, 0x20(sp) ++ load a3, 0x28(sp) ++ load a4, 0x30(sp) ++ load a5, 0x38(sp) ++ load a6, 0x40(sp) ++ load a7, 0x48(sp) ++ load s2, 0x50(sp) ++ load s3, 0x58(sp) ++ load s4, 0x60(sp) ++ load s5, 0x68(sp) ++ load s6, 0x70(sp) ++ load s7, 0x78(sp) ++ load s8, 0x80(sp) ++ load s9, 0x88(sp) ++ load t2, 0x90(sp) ++ load t3, 0x98(sp) ++ load t4, 0xa0(sp) ++ load t5, 0xa8(sp) ++ load t6, 0xb0(sp) ++ fld ft0, 0xb8(sp) ++ fld ft1, 0xc0(sp) ++ fld ft2, 0xc8(sp) ++ fld ft3, 0xd0(sp) ++ fld ft4, 0xd8(sp) ++ fld ft5, 0xe0(sp) ++ fld ft6, 0xe8(sp) ++ fld ft7, 0xf0(sp) ++ fld fa0, 0xf8(sp) ++ fld fa1, 0x100(sp) ++ fld fa2, 0x108(sp) ++ fld fa3, 0x110(sp) ++ fld fa4, 0x118(sp) ++ fld fa5, 0x120(sp) ++ fld fa6, 0x128(sp) ++ fld fa7, 0x130(sp) ++ fld ft8, 0x138(sp) ++ fld ft9, 0x140(sp) ++ fld ft9, 0x148(sp) ++ fld ft10, 0x150(sp) ++ fld ft11, 0x158(sp) + /* Reload new allocation pointer and allocation limit */ +- load ALLOC_PTR, caml_young_ptr +- load ALLOC_LIMIT, caml_young_limit ++ load ALLOC_PTR, caml_young_ptr ++ load ALLOC_LIMIT, caml_young_limit + /* Free stack space and return to caller */ +- load ra, 0x8(sp) +- load s0, 0x0(sp) +- addi sp, sp, 0x160 ++ load ra, 0x8(sp) ++ load s0, 0x0(sp) ++ addi sp, sp, 0x160 + ret +- .size caml_call_gc, .-caml_call_gc ++ .size caml_call_gc, .-caml_call_gc + + /* Call a C function from OCaml */ + /* Function to call is in ARG */ + +- .align 2 +- .globl caml_c_call +- .type caml_c_call, @function ++ .align 2 ++ .globl caml_c_call ++ .type caml_c_call, @function + caml_c_call: + /* Preserve return address in callee-save register s2 */ +- mv s2, ra ++ mv s2, ra + /* Record lowest stack address and return address */ +- store ra, caml_last_return_address, TMP0 +- store sp, caml_bottom_of_stack, TMP0 ++ store ra, caml_last_return_address, TMP0 ++ store sp, caml_bottom_of_stack, TMP0 + /* Make the exception handler alloc ptr available to the C code */ +- store ALLOC_PTR, caml_young_ptr, TMP0 +- store TRAP_PTR, caml_exception_pointer, TMP0 ++ store ALLOC_PTR, caml_young_ptr, TMP0 ++ store TRAP_PTR, caml_exception_pointer, TMP0 + /* Call the function */ +- jalr ARG ++ jalr ARG + /* Reload alloc ptr and alloc limit */ +- load ALLOC_PTR, caml_young_ptr +- load TRAP_PTR, caml_exception_pointer ++ load ALLOC_PTR, caml_young_ptr ++ load TRAP_PTR, caml_exception_pointer + /* Return */ +- jr s2 +- .size caml_c_call, .-caml_c_call ++ jr s2 ++ .size caml_c_call, .-caml_c_call + + /* Raise an exception from OCaml */ +- .align 2 +- .globl caml_raise_exn +- .type caml_raise_exn, @function ++ .align 2 ++ .globl caml_raise_exn ++ .type caml_raise_exn, @function + caml_raise_exn: + /* Test if backtrace is active */ +- load TMP1, caml_backtrace_active +- bnez TMP1, 2f ++ load TMP1, caml_backtrace_active ++ bnez TMP1, 2f + 1: /* Cut stack at current trap handler */ +- mv sp, TRAP_PTR ++ mv sp, TRAP_PTR + /* Pop previous handler and jump to it */ +- load TMP1, 8(sp) +- load TRAP_PTR, 0(sp) +- addi sp, sp, 16 +- jr TMP1 ++ load TMP1, 8(sp) ++ load TRAP_PTR, 0(sp) ++ addi sp, sp, 16 ++ jr TMP1 + 2: /* Preserve exception bucket in callee-save register s2 */ +- mv s2, a0 ++ mv s2, a0 + /* Stash the backtrace */ +- mv a1, ra +- mv a2, sp +- mv a3, TRAP_PTR +- call caml_stash_backtrace ++ mv a1, ra ++ mv a2, sp ++ mv a3, TRAP_PTR ++ call caml_stash_backtrace + /* Restore exception bucket and raise */ +- mv a0, s2 +- j 1b +- .size caml_raise_exn, .-caml_raise_exn ++ mv a0, s2 ++ j 1b ++ .size caml_raise_exn, .-caml_raise_exn + +- .globl caml_reraise_exn +- .type caml_reraise_exn, @function ++ .globl caml_reraise_exn ++ .type caml_reraise_exn, @function + + /* Raise an exception from C */ + +- .align 2 +- .globl caml_raise_exception +- .type caml_raise_exception, @function ++ .align 2 ++ .globl caml_raise_exception ++ .type caml_raise_exception, @function + caml_raise_exception: +- load TRAP_PTR, caml_exception_pointer +- load ALLOC_PTR, caml_young_ptr +- load ALLOC_LIMIT, caml_young_limit +- load TMP1, caml_backtrace_active +- bnez TMP1, 2f ++ load TRAP_PTR, caml_exception_pointer ++ load ALLOC_PTR, caml_young_ptr ++ load ALLOC_LIMIT, caml_young_limit ++ load TMP1, caml_backtrace_active ++ bnez TMP1, 2f + 1: /* Cut stack at current trap handler */ +- mv sp, TRAP_PTR +- load TMP1, 8(sp) +- load TRAP_PTR, 0(sp) +- addi sp, sp, 16 +- jr TMP1 ++ mv sp, TRAP_PTR ++ load TMP1, 8(sp) ++ load TRAP_PTR, 0(sp) ++ addi sp, sp, 16 ++ jr TMP1 + 2: /* Preserve exception bucket in callee-save register s2 */ +- mv s2, a0 +- load a1, caml_last_return_address +- load a2, caml_bottom_of_stack +- mv a3, TRAP_PTR +- call caml_stash_backtrace +- mv a0, s2 +- j 1b +- .size caml_raise_exception, .-caml_raise_exception ++ mv s2, a0 ++ load a1, caml_last_return_address ++ load a2, caml_bottom_of_stack ++ mv a3, TRAP_PTR ++ call caml_stash_backtrace ++ mv a0, s2 ++ j 1b ++ .size caml_raise_exception, .-caml_raise_exception + + /* Start the OCaml program */ + +- .align 2 +- .globl caml_start_program +- .type caml_start_program, @function ++ .align 2 ++ .globl caml_start_program ++ .type caml_start_program, @function + caml_start_program: + +- la ARG, caml_program ++ la ARG, caml_program + /* Code shared with caml_callback* */ + /* Address of OCaml code to call is in ARG */ + /* Arguments to the OCaml code are in a0 ... a7 */ + .Ljump_to_caml: +- /* Set up stack frame and save callee-save registers */ +- addi sp, sp, -0xd0 +- store ra, 0xc0(sp) +- store s0, 0x0(sp) +- store s1, 0x8(sp) +- store s2, 0x10(sp) +- store s3, 0x18(sp) +- store s4, 0x20(sp) +- store s5, 0x28(sp) +- store s6, 0x30(sp) +- store s7, 0x38(sp) +- store s8, 0x40(sp) +- store s9, 0x48(sp) +- store s10, 0x50(sp) +- store s11, 0x58(sp) +- fsd fs0, 0x60(sp) +- fsd fs1, 0x68(sp) +- fsd fs2, 0x70(sp) +- fsd fs3, 0x78(sp) +- fsd fs4, 0x80(sp) +- fsd fs5, 0x88(sp) +- fsd fs6, 0x90(sp) +- fsd fs7, 0x98(sp) +- fsd fs8, 0xa0(sp) +- fsd fs9, 0xa8(sp) +- fsd fs10, 0xb0(sp) +- fsd fs11, 0xb8(sp) +- addi sp, sp, -32 ++ /* Set up stack frame and save callee-save registers */ ++ addi sp, sp, -0xd0 ++ store ra, 0xc0(sp) ++ store s0, 0x0(sp) ++ store s1, 0x8(sp) ++ store s2, 0x10(sp) ++ store s3, 0x18(sp) ++ store s4, 0x20(sp) ++ store s5, 0x28(sp) ++ store s6, 0x30(sp) ++ store s7, 0x38(sp) ++ store s8, 0x40(sp) ++ store s9, 0x48(sp) ++ store s10, 0x50(sp) ++ store s11, 0x58(sp) ++ fsd fs0, 0x60(sp) ++ fsd fs1, 0x68(sp) ++ fsd fs2, 0x70(sp) ++ fsd fs3, 0x78(sp) ++ fsd fs4, 0x80(sp) ++ fsd fs5, 0x88(sp) ++ fsd fs6, 0x90(sp) ++ fsd fs7, 0x98(sp) ++ fsd fs8, 0xa0(sp) ++ fsd fs9, 0xa8(sp) ++ fsd fs10, 0xb0(sp) ++ fsd fs11, 0xb8(sp) ++ addi sp, sp, -32 + /* Setup a callback link on the stack */ +- load TMP1, caml_bottom_of_stack +- store TMP1, 0(sp) +- load TMP1, caml_last_return_address +- store TMP1, 8(sp) +- load TMP1, caml_gc_regs +- store TMP1, 16(sp) +- /* set up a trap frame */ +- addi sp, sp, -16 +- load TMP1, caml_exception_pointer +- store TMP1, 0(sp) +- lla TMP0, .Ltrap_handler +- store TMP0, 8(sp) +- mv TRAP_PTR, sp +- load ALLOC_PTR, caml_young_ptr +- load ALLOC_LIMIT, caml_young_limit +- store x0, caml_last_return_address, TMP0 +- jalr ARG +-.Lcaml_retaddr: /* pop trap frame, restoring caml_exception_pointer */ +- load TMP1, 0(sp) +- store TMP1, caml_exception_pointer, TMP0 +- addi sp, sp, 16 +-.Lreturn_result: /* pop callback link, restoring global variables */ +- load TMP1, 0(sp) +- store TMP1, caml_bottom_of_stack, TMP0 +- load TMP1, 8(sp) +- store TMP1, caml_last_return_address, TMP0 +- load TMP1, 16(sp) +- store TMP1, caml_gc_regs, TMP0 +- addi sp, sp, 32 +- /* Update allocation pointer */ +- store ALLOC_PTR, caml_young_ptr, TMP0 +- /* reload callee-save registers and return */ +- load ra, 0xc0(sp) +- load s0, 0x0(sp) +- load s1, 0x8(sp) +- load s2, 0x10(sp) +- load s3, 0x18(sp) +- load s4, 0x20(sp) +- load s5, 0x28(sp) +- load s6, 0x30(sp) +- load s7, 0x38(sp) +- load s8, 0x40(sp) +- load s9, 0x48(sp) +- load s10, 0x50(sp) +- load s11, 0x58(sp) +- fld fs0, 0x60(sp) +- fld fs1, 0x68(sp) +- fld fs2, 0x70(sp) +- fld fs3, 0x78(sp) +- fld fs4, 0x80(sp) +- fld fs5, 0x88(sp) +- fld fs6, 0x90(sp) +- fld fs7, 0x98(sp) +- fld fs8, 0xa0(sp) +- fld fs9, 0xa8(sp) +- fld fs10, 0xb0(sp) +- fld fs11, 0xb8(sp) +- addi sp, sp, 0xd0 +- ret ++ load TMP1, caml_bottom_of_stack ++ store TMP1, 0(sp) ++ load TMP1, caml_last_return_address ++ store TMP1, 8(sp) ++ load TMP1, caml_gc_regs ++ store TMP1, 16(sp) ++ /* set up a trap frame */ ++ addi sp, sp, -16 ++ load TMP1, caml_exception_pointer ++ store TMP1, 0(sp) ++ lla TMP0, .Ltrap_handler ++ store TMP0, 8(sp) ++ mv TRAP_PTR, sp ++ load ALLOC_PTR, caml_young_ptr ++ load ALLOC_LIMIT, caml_young_limit ++ store x0, caml_last_return_address, TMP0 ++ jalr ARG ++.Lcaml_retaddr: /* pop trap frame, restoring caml_exception_pointer */ ++ load TMP1, 0(sp) ++ store TMP1, caml_exception_pointer, TMP0 ++ addi sp, sp, 16 ++.Lreturn_result: /* pop callback link, restoring global variables */ ++ load TMP1, 0(sp) ++ store TMP1, caml_bottom_of_stack, TMP0 ++ load TMP1, 8(sp) ++ store TMP1, caml_last_return_address, TMP0 ++ load TMP1, 16(sp) ++ store TMP1, caml_gc_regs, TMP0 ++ addi sp, sp, 32 ++ /* Update allocation pointer */ ++ store ALLOC_PTR, caml_young_ptr, TMP0 ++ /* reload callee-save registers and return */ ++ load ra, 0xc0(sp) ++ load s0, 0x0(sp) ++ load s1, 0x8(sp) ++ load s2, 0x10(sp) ++ load s3, 0x18(sp) ++ load s4, 0x20(sp) ++ load s5, 0x28(sp) ++ load s6, 0x30(sp) ++ load s7, 0x38(sp) ++ load s8, 0x40(sp) ++ load s9, 0x48(sp) ++ load s10, 0x50(sp) ++ load s11, 0x58(sp) ++ fld fs0, 0x60(sp) ++ fld fs1, 0x68(sp) ++ fld fs2, 0x70(sp) ++ fld fs3, 0x78(sp) ++ fld fs4, 0x80(sp) ++ fld fs5, 0x88(sp) ++ fld fs6, 0x90(sp) ++ fld fs7, 0x98(sp) ++ fld fs8, 0xa0(sp) ++ fld fs9, 0xa8(sp) ++ fld fs10, 0xb0(sp) ++ fld fs11, 0xb8(sp) ++ addi sp, sp, 0xd0 ++ ret + .Ltrap_handler: +- store TRAP_PTR, caml_exception_pointer, TMP0 +- ori a0, a0, 2 +- j .Lreturn_result +- .size caml_start_program, .-caml_start_program ++ store TRAP_PTR, caml_exception_pointer, TMP0 ++ ori a0, a0, 2 ++ j .Lreturn_result ++ .size caml_start_program, .-caml_start_program + + /* Callback from C to OCaml */ + +- .align 2 +- .globl caml_callback_exn +- .type caml_callback_exn, @function ++ .align 2 ++ .globl caml_callback_exn ++ .type caml_callback_exn, @function + caml_callback_exn: + /* Initial shuffling of arguments (a0 = closure, a1 = first arg) */ +- mv TMP1, a0 +- mv a0, a1 /* a0 = first arg */ +- mv a1, TMP1 /* a1 = closure environment */ +- load ARG, 0(TMP1) /* code pointer */ +- j .Ljump_to_caml +- .size caml_callback_exn, .-caml_callback_exn ++ mv TMP1, a0 ++ mv a0, a1 /* a0 = first arg */ ++ mv a1, TMP1 /* a1 = closure environment */ ++ load ARG, 0(TMP1) /* code pointer */ ++ j .Ljump_to_caml ++ .size caml_callback_exn, .-caml_callback_exn + +- .align 2 +- .globl caml_callback2_exn +- .type caml_callback2_exn, @function ++ .align 2 ++ .globl caml_callback2_exn ++ .type caml_callback2_exn, @function + caml_callback2_exn: + /* Initial shuffling of arguments (a0 = closure, a1 = arg1, a2 = arg2) */ +- mv TMP1, a0 +- mv a0, a1 +- mv a1, a2 +- mv a2, TMP1 +- la ARG, caml_apply2 +- j .Ljump_to_caml +- .size caml_callback2_exn, .-caml_callback2_exn ++ mv TMP1, a0 ++ mv a0, a1 ++ mv a1, a2 ++ mv a2, TMP1 ++ la ARG, caml_apply2 ++ j .Ljump_to_caml ++ .size caml_callback2_exn, .-caml_callback2_exn + +- .align 2 +- .globl caml_callback3_exn +- .type caml_callback3_exn, @function ++ .align 2 ++ .globl caml_callback3_exn ++ .type caml_callback3_exn, @function + caml_callback3_exn: + /* Initial shuffling of argumnets */ + /* (a0 = closure, a1 = arg1, a2 = arg2, a3 = arg3) */ +- mv TMP1, a0 +- mv a0, a1 +- mv a1, a2 +- mv a2, a3 +- mv a3, TMP1 +- la ARG, caml_apply3 +- j .Ljump_to_caml +- .size caml_callback3_exn, .-caml_callback3_exn ++ mv TMP1, a0 ++ mv a0, a1 ++ mv a1, a2 ++ mv a2, a3 ++ mv a3, TMP1 ++ la ARG, caml_apply3 ++ j .Ljump_to_caml ++ .size caml_callback3_exn, .-caml_callback3_exn + +- .align 2 +- .globl caml_ml_array_bound_error +- .type caml_ml_array_bound_error, @function ++ .align 2 ++ .globl caml_ml_array_bound_error ++ .type caml_ml_array_bound_error, @function + caml_ml_array_bound_error: + /* Load address of [caml_array_bound_error] in ARG */ +- la ARG, caml_array_bound_error ++ la ARG, caml_array_bound_error + /* Call that function */ +- j caml_c_call ++ j caml_c_call + +- .globl caml_system__code_end ++ .globl caml_system__code_end + caml_system__code_end: + + /* GC roots for callback */ + +- .section .data +- .align 3 +- .globl caml_system__frametable +- .type caml_system__frametable, @object ++ .section .data ++ .align 3 ++ .globl caml_system__frametable ++ .type caml_system__frametable, @object + 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 +- .size 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 ++ .size caml_system__frametable, .-caml_system__frametable +-- +2.17.1 + diff --git a/SOURCES/0006-fix-caml_c_call-reload-caml_young_limit.patch b/SOURCES/0006-fix-caml_c_call-reload-caml_young_limit.patch new file mode 100644 index 0000000..a41c53c --- /dev/null +++ b/SOURCES/0006-fix-caml_c_call-reload-caml_young_limit.patch @@ -0,0 +1,25 @@ +From 207fbbc2616ee44e048dd5bb133e52f252cd1caf Mon Sep 17 00:00:00 2001 +From: Nicolas Ojeda Bar +Date: Sat, 2 Dec 2017 10:44:41 +0100 +Subject: [PATCH 6/8] fix caml_c_call: reload caml_young_limit + +--- + asmrun/riscv.S | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/asmrun/riscv.S b/asmrun/riscv.S +index 88d7ab924..121f8ba71 100644 +--- a/asmrun/riscv.S ++++ b/asmrun/riscv.S +@@ -187,7 +187,7 @@ caml_c_call: + jalr ARG + /* Reload alloc ptr and alloc limit */ + load ALLOC_PTR, caml_young_ptr +- load TRAP_PTR, caml_exception_pointer ++ load ALLOC_LIMIT, caml_young_limit + /* Return */ + jr s2 + .size caml_c_call, .-caml_c_call +-- +2.17.1 + diff --git a/SOURCES/0007-Adapt-to-4.07.patch b/SOURCES/0007-Adapt-to-4.07.patch new file mode 100644 index 0000000..0cda82d --- /dev/null +++ b/SOURCES/0007-Adapt-to-4.07.patch @@ -0,0 +1,67 @@ +From a89427d52a20633be40056fe008b7eeec5ded7dd Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Nicol=C3=A1s=20Ojeda=20B=C3=A4r?= +Date: Tue, 15 May 2018 07:17:06 +0000 +Subject: [PATCH 7/8] Adapt to 4.07 + +--- + asmcomp/riscv/emit.mlp | 28 +++++++++++++++++----------- + asmcomp/riscv/selection.ml | 2 +- + 2 files changed, 18 insertions(+), 12 deletions(-) + +diff --git a/asmcomp/riscv/emit.mlp b/asmcomp/riscv/emit.mlp +index 51165d0f1..718dca080 100644 +--- a/asmcomp/riscv/emit.mlp ++++ b/asmcomp/riscv/emit.mlp +@@ -461,19 +461,25 @@ let emit_instr i = + ` {emit_string name} {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}, {emit_label lbl}\n` + | Iinttest_imm _ -> + fatal_error "Emit.emit_instr (Iinttest_imm _)" +- | Ifloattest(cmp, neg) -> +- let neg = match cmp with +- | Ceq -> ` feq.d {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; neg +- | Cne -> ` feq.d {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; not neg +- | Clt -> ` flt.d {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; neg +- | Cgt -> ` flt.d {emit_reg reg_tmp1}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n`; neg +- | Cle -> ` fle.d {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`; neg +- | Cge -> ` fle.d {emit_reg reg_tmp1}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n`; neg +- in +- if neg then ++ | Ifloattest cmp -> ++ begin match cmp with ++ | CFeq | CFneq -> ++ ` feq.d {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n` ++ | CFlt | CFnlt -> ++ ` flt.d {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n` ++ | CFgt | CFngt -> ++ ` flt.d {emit_reg reg_tmp1}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n` ++ | CFle | CFnle -> ++ ` fle.d {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n` ++ | CFge | CFnge -> ++ ` fle.d {emit_reg reg_tmp1}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n` ++ end; ++ begin match cmp with ++ | CFneq | CFnlt | CFngt | CFnle | CFnge -> + ` beqz {emit_reg reg_tmp1}, {emit_label lbl}\n` +- else ++ | CFeq | CFlt | CFgt | CFle | CFge -> + ` bnez {emit_reg reg_tmp1}, {emit_label lbl}\n` ++ end + | Ioddtest -> + ` andi {emit_reg reg_tmp1}, {emit_reg i.arg.(0)}, 1\n`; + ` bnez {emit_reg reg_tmp1}, {emit_label lbl}\n` +diff --git a/asmcomp/riscv/selection.ml b/asmcomp/riscv/selection.ml +index 092ca88aa..1f0af6abc 100644 +--- a/asmcomp/riscv/selection.ml ++++ b/asmcomp/riscv/selection.ml +@@ -61,7 +61,7 @@ method! select_condition = function + | Cop(Ccmpa cmp, args, _) -> + (Iinttest(Iunsigned cmp), Ctuple args) + | Cop(Ccmpf cmp, args, _) -> +- (Ifloattest(cmp, false), Ctuple args) ++ (Ifloattest cmp, Ctuple args) + | Cop(Cand, [arg; Cconst_int 1], _) -> + (Ioddtest, arg) + | arg -> +-- +2.17.1 + diff --git a/SOURCES/0008-riscv-Emit-debug-info.patch b/SOURCES/0008-riscv-Emit-debug-info.patch new file mode 100644 index 0000000..6d72833 --- /dev/null +++ b/SOURCES/0008-riscv-Emit-debug-info.patch @@ -0,0 +1,40 @@ +From af276d83f41cb9eb9f1e50a75a9be205c9b2fee6 Mon Sep 17 00:00:00 2001 +From: "Richard W.M. Jones" +Date: Tue, 5 Jun 2018 19:48:08 +0000 +Subject: [PATCH 8/8] riscv: Emit debug info. + +--- + asmcomp/riscv/emit.mlp | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/asmcomp/riscv/emit.mlp b/asmcomp/riscv/emit.mlp +index 718dca080..e42ee9770 100644 +--- a/asmcomp/riscv/emit.mlp ++++ b/asmcomp/riscv/emit.mlp +@@ -261,6 +261,7 @@ let tailrec_entry_point = ref 0 + (* 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) -> +@@ -560,6 +561,7 @@ let fundecl fundecl = + emit_stack_adjustment (-n); + if !contains_calls then store_ra n; + `{emit_label !tailrec_entry_point}:\n`; ++ emit_debug_info fundecl.fun_dbg; + emit_all fundecl.fun_body; + List.iter emit_call_gc !call_gc_sites; + List.iter emit_call_bound_error !bound_error_sites; +@@ -619,6 +621,7 @@ let data l = + + let begin_assembly() = + ` .file \"\"\n`; (* PR#7073 *) ++ reset_debug_info (); + (* Emit the beginning of the segments *) + let lbl_begin = Compilenv.make_symbol (Some "data_begin") in + ` {emit_string data_space}\n`; +-- +2.17.1 + diff --git a/SPECS/ocaml.spec b/SPECS/ocaml.spec new file mode 100644 index 0000000..fd16478 --- /dev/null +++ b/SPECS/ocaml.spec @@ -0,0 +1,1054 @@ +# OCaml has a bytecode backend that works on anything with a C +# compiler, and a native code backend available on a subset of +# architectures. A further subset of architectures support native +# dynamic linking. + +%ifarch %{ocaml_native_compiler} +%global native_compiler 1 +%else +%global native_compiler 0 +%endif + +%ifarch %{ocaml_natdynlink} +%global natdynlink 1 +%else +%global natdynlink 0 +%endif + +# These are all the architectures that the tests run on. The tests +# take a long time to run, so don't run them on slow machines. +%global test_arches aarch64 %{power64} x86_64 +# These are the architectures for which the tests must pass otherwise +# the build will fail. +%global test_arches_required aarch64 x86_64 + +# Architectures where parallel builds fail. +#%global no_parallel_build_arches aarch64 + +Name: ocaml +Version: 4.07.0 +Release: 3%{?dist} + +Summary: OCaml compiler and programming environment + +License: QPL and (LGPLv2+ with exceptions) + +URL: http://www.ocaml.org + +Source0: http://caml.inria.fr/pub/distrib/ocaml-4.07/ocaml-%{version}.tar.xz + +# IMPORTANT NOTE: +# +# These patches are generated from unpacked sources stored in a +# pagure.io git repository. If you change the patches here, they will +# be OVERWRITTEN by the next update. Instead, request commit access +# to the pagure project: +# +# https://pagure.io/fedora-ocaml +# +# Current branch: fedora-29-4.07.0 +# +# 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. +# + +# Fedora-specific downstream patches. +Patch0001: 0001-Don-t-add-rpaths-to-libraries.patch +Patch0002: 0002-ocamlbyteinfo-ocamlplugininfo-Useful-utilities-from-.patch +Patch0003: 0003-configure-Allow-user-defined-C-compiler-flags.patch + +# Out of tree patch for RISC-V support. +# https://github.com/nojb/riscv-ocaml +Patch0004: 0004-Add-RISC-V-backend.patch +Patch0005: 0005-Copyright-untabify.patch +Patch0006: 0006-fix-caml_c_call-reload-caml_young_limit.patch +Patch0007: 0007-Adapt-to-4.07.patch + +# RISC-V patch to add debuginfo (DWARF) generation. +# Sent upstream 2018-06-05. +Patch0008: 0008-riscv-Emit-debug-info.patch + +BuildRequires: gcc +BuildRequires: binutils-devel +BuildRequires: ncurses-devel +BuildRequires: gdbm-devel +BuildRequires: emacs +BuildRequires: gawk +BuildRequires: perl-interpreter +BuildRequires: util-linux +BuildRequires: libICE-devel +BuildRequires: libSM-devel +BuildRequires: libX11-devel +BuildRequires: libXaw-devel +BuildRequires: libXext-devel +BuildRequires: libXft-devel +BuildRequires: libXmu-devel +BuildRequires: libXrender-devel +BuildRequires: libXt-devel +BuildRequires: chrpath + +Requires: gcc + +# Because we pass -c flag to ocaml-find-requires (to avoid circular +# dependencies) we also have to explicitly depend on the right version +# of ocaml-runtime. +Requires: ocaml-runtime = %{version}-%{release} + +# Bundles an MD5 implementation in byterun/md5.{c,h} +Provides: bundled(md5-plumb) + +Provides: ocaml(compiler) = %{version} + +%global __ocaml_requires_opts -c -f '%{buildroot}%{_bindir}/ocamlrun %{buildroot}%{_bindir}/ocamlobjinfo.byte' +%global __ocaml_provides_opts -f '%{buildroot}%{_bindir}/ocamlrun %{buildroot}%{_bindir}/ocamlobjinfo.byte' + + +%description +OCaml is a high-level, strongly-typed, functional and object-oriented +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), a replay debugger, a documentation generator, +and a comprehensive library. + + +%package runtime +Summary: OCaml runtime environment +Requires: util-linux +Provides: ocaml(runtime) = %{version} + +%description runtime +OCaml is a high-level, strongly-typed, functional and object-oriented +programming language from the ML family of languages. + +This package contains the runtime environment needed to run OCaml +bytecode. + + +%package source +Summary: Source code for OCaml libraries +Requires: ocaml = %{version}-%{release} + +%description source +Source code for OCaml libraries. + + +%package x11 +Summary: X11 support for OCaml +Requires: ocaml-runtime = %{version}-%{release} +Requires: libX11-devel + +%description x11 +X11 support for OCaml. + + +%package ocamldoc +Summary: Documentation generator for OCaml +Requires: ocaml = %{version}-%{release} +Provides: ocamldoc + +%description ocamldoc +Documentation generator for OCaml. + + +%package emacs +Summary: Emacs mode for OCaml +Requires: ocaml = %{version}-%{release} +Requires: emacs(bin) + +%description emacs +Emacs mode for OCaml. + + +%package docs +Summary: Documentation for OCaml +Requires: ocaml = %{version}-%{release} +Requires(post): /sbin/install-info +Requires(preun): /sbin/install-info + + +%description docs +OCaml is a high-level, strongly-typed, functional and object-oriented +programming language from the ML family of languages. + +This package contains man pages. + + +%package compiler-libs +Summary: Compiler libraries for OCaml +Requires: ocaml = %{version}-%{release} + + +%description compiler-libs +OCaml is a high-level, strongly-typed, functional and object-oriented +programming language from the ML family of languages. + +This package contains some modules used internally by the OCaml +compilers, useful for the development of some OCaml applications. +Note that this exposes internal details of the OCaml compiler which +may not be portable between versions. + + +%prep +%setup -q -T -b 0 -n %{name}-%{version} +%autopatch -p1 + + +%build +%ifnarch %{no_parallel_build_arches} +make="make %{?_smp_mflags}" +%else +unset MAKEFLAGS +make=make +%endif + +CFLAGS="$RPM_OPT_FLAGS -fno-strict-aliasing" \ +./configure \ + -bindir %{_bindir} \ + -libdir %{_libdir}/ocaml \ + -x11lib %{_libdir} \ + -x11include %{_includedir} \ + -mandir %{_mandir}/man1 \ + -no-curses +$make world +%if %{native_compiler} +$make opt +$make opt.opt +%endif +make -C emacs ocamltags + +# Currently these tools are supplied by Debian, but are expected +# to go upstream at some point. +includes="-nostdlib -I stdlib -I utils -I parsing -I typing -I bytecomp -I asmcomp -I driver -I otherlibs/unix -I otherlibs/str -I otherlibs/dynlink" +boot/ocamlrun ./ocamlc $includes dynlinkaux.cmo ocamlbyteinfo.ml -o ocamlbyteinfo +# ocamlplugininfo doesn't compile because it needs 'dynheader' (type +# decl) and I have no idea where that comes from +#cp otherlibs/dynlink/natdynlink.ml . +#boot/ocamlrun ./ocamlopt $includes unix.cmxa str.cmxa natdynlink.ml ocamlplugininfo.ml -o ocamlplugininfo + + +%check +%ifarch %{test_arches} +cd testsuite + +%ifarch %{test_arches_required} +make -j1 all +%else +make -j1 all ||: +%endif +%endif + + +%install +make install \ + BINDIR=$RPM_BUILD_ROOT%{_bindir} \ + LIBDIR=$RPM_BUILD_ROOT%{_libdir}/ocaml \ + MANDIR=$RPM_BUILD_ROOT%{_mandir} +perl -pi -e "s|^$RPM_BUILD_ROOT||" $RPM_BUILD_ROOT%{_libdir}/ocaml/ld.conf + +( + # install emacs files + cd emacs; + make install \ + BINDIR=$RPM_BUILD_ROOT%{_bindir} \ + EMACSDIR=$RPM_BUILD_ROOT%{_datadir}/emacs/site-lisp + make install-ocamltags BINDIR=$RPM_BUILD_ROOT%{_bindir} +) + +echo %{version} > $RPM_BUILD_ROOT%{_libdir}/ocaml/fedora-ocaml-release + +# Remove rpaths from stublibs .so files. +chrpath --delete $RPM_BUILD_ROOT%{_libdir}/ocaml/stublibs/*.so + +install -m 0755 ocamlbyteinfo $RPM_BUILD_ROOT%{_bindir} +#install -m 0755 ocamlplugininfo $RPM_BUILD_ROOT%{_bindir} + +find $RPM_BUILD_ROOT -name .ignore -delete + +# Remove .cmt and .cmti files, for now. We could package them later. +# See also: http://www.ocamlpro.com/blog/2012/08/20/ocamlpro-and-4.00.0.html +find $RPM_BUILD_ROOT \( -name '*.cmt' -o -name '*.cmti' \) -a -delete + + +%files +%doc LICENSE +%{_bindir}/ocaml + +%{_bindir}/ocamlbyteinfo +%{_bindir}/ocamlcmt +%{_bindir}/ocamldebug +%{_bindir}/ocaml-instr-graph +%{_bindir}/ocaml-instr-report +#%{_bindir}/ocamlplugininfo +%{_bindir}/ocamlyacc + +# symlink to either .byte or .opt version +%{_bindir}/ocamlc +%{_bindir}/ocamlcp +%{_bindir}/ocamldep +%{_bindir}/ocamllex +%{_bindir}/ocamlmklib +%{_bindir}/ocamlmktop +%{_bindir}/ocamlobjinfo +%{_bindir}/ocamloptp +%{_bindir}/ocamlprof + +# bytecode versions +%{_bindir}/ocamlc.byte +%{_bindir}/ocamlcp.byte +%{_bindir}/ocamldep.byte +%{_bindir}/ocamllex.byte +%{_bindir}/ocamlmklib.byte +%{_bindir}/ocamlmktop.byte +%{_bindir}/ocamlobjinfo.byte +%{_bindir}/ocamloptp.byte +%{_bindir}/ocamlprof.byte + +%if %{native_compiler} +# native code versions +%{_bindir}/ocamlc.opt +%{_bindir}/ocamlcp.opt +%{_bindir}/ocamldep.opt +%{_bindir}/ocamllex.opt +%{_bindir}/ocamlmklib.opt +%{_bindir}/ocamlmktop.opt +%{_bindir}/ocamlobjinfo.opt +%{_bindir}/ocamloptp.opt +%{_bindir}/ocamlprof.opt +%endif + +%if %{native_compiler} +%{_bindir}/ocamlopt +%{_bindir}/ocamlopt.byte +%{_bindir}/ocamlopt.opt +%endif + +#%{_libdir}/ocaml/addlabels +#%{_libdir}/ocaml/scrapelabels +%{_libdir}/ocaml/camlheader +%{_libdir}/ocaml/camlheader_ur +%{_libdir}/ocaml/expunge +%{_libdir}/ocaml/extract_crc +%{_libdir}/ocaml/ld.conf +%{_libdir}/ocaml/Makefile.config +%{_libdir}/ocaml/*.a +%if %{natdynlink} +%{_libdir}/ocaml/*.cmxs +%endif +%if %{native_compiler} +%{_libdir}/ocaml/*.cmxa +%{_libdir}/ocaml/*.cmx +%{_libdir}/ocaml/*.o +%{_libdir}/ocaml/libasmrun_shared.so +%endif +%{_libdir}/ocaml/*.mli +%{_libdir}/ocaml/libcamlrun_shared.so +%{_libdir}/ocaml/objinfo_helper +%{_libdir}/ocaml/vmthreads/*.mli +%{_libdir}/ocaml/vmthreads/*.a +%if %{native_compiler} +%{_libdir}/ocaml/threads/*.a +%{_libdir}/ocaml/threads/*.cmxa +%{_libdir}/ocaml/threads/*.cmx +%endif +%{_libdir}/ocaml/caml +%exclude %{_libdir}/ocaml/graphicsX11.mli + + +%files runtime +%doc README.adoc LICENSE Changes +%{_bindir}/ocamlrun +%{_bindir}/ocamlrund +%{_bindir}/ocamlruni +%dir %{_libdir}/ocaml +%{_libdir}/ocaml/VERSION +%{_libdir}/ocaml/*.cmo +%{_libdir}/ocaml/*.cmi +%{_libdir}/ocaml/*.cma +%{_libdir}/ocaml/stublibs +%{_libdir}/ocaml/target_camlheaderd +%{_libdir}/ocaml/target_camlheaderi +%dir %{_libdir}/ocaml/vmthreads +%{_libdir}/ocaml/vmthreads/*.cmi +%{_libdir}/ocaml/vmthreads/*.cma +%dir %{_libdir}/ocaml/threads +%{_libdir}/ocaml/threads/*.cmi +%{_libdir}/ocaml/threads/*.cma +%{_libdir}/ocaml/fedora-ocaml-release +%exclude %{_libdir}/ocaml/graphicsX11.cmi + + +%files source +%doc LICENSE +%{_libdir}/ocaml/*.ml + + +%files x11 +%doc LICENSE +%{_libdir}/ocaml/graphicsX11.cmi +%{_libdir}/ocaml/graphicsX11.mli + + +%files ocamldoc +%doc LICENSE +%doc ocamldoc/Changes.txt +%{_bindir}/ocamldoc* +%{_libdir}/ocaml/ocamldoc + + +%files docs +%{_mandir}/man1/* +%{_mandir}/man3/* + + +%files emacs +%doc emacs/README +%{_datadir}/emacs/site-lisp/* +%{_bindir}/ocamltags + + +%files compiler-libs +%doc LICENSE +%dir %{_libdir}/ocaml/compiler-libs +%{_libdir}/ocaml/compiler-libs/*.mli +%{_libdir}/ocaml/compiler-libs/*.cmi +%{_libdir}/ocaml/compiler-libs/*.cmo +%{_libdir}/ocaml/compiler-libs/*.cma +%if %{native_compiler} +%{_libdir}/ocaml/compiler-libs/*.a +%{_libdir}/ocaml/compiler-libs/*.cmxa +%{_libdir}/ocaml/compiler-libs/*.cmx +%{_libdir}/ocaml/compiler-libs/*.o +%endif + + +%changelog +* Tue Jul 31 2018 Richard W.M. Jones - 4.07.0-3 +- Disable unreliable tests on ppc64le. + +* Fri Jul 13 2018 Fedora Release Engineering - 4.07.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + +* Wed Jul 11 2018 Richard W.M. Jones - 4.07.0-1 +- OCaml 4.07.0 (RHBZ#1536734). + +* Tue Jun 26 2018 Richard W.M. Jones - 4.07.0-0.rc1.3 +- Enable emacs again on riscv64. + +* Tue Jun 19 2018 Richard W.M. Jones - 4.07.0-0.rc1.2 +- OCaml 4.07.0-rc1 (RHBZ#1536734). + +* Tue Jun 5 2018 Richard W.M. Jones - 4.07.0-0.beta2.1 +- Add RISC-V patch to add debuginfo (DWARF) generation. + +* Thu Apr 26 2018 Richard W.M. Jones - 4.07.0-0.beta2.0 +- OCaml 4.07.0-beta2 (RHBZ#1536734). + +* Sun Feb 25 2018 Richard W.M. Jones - 4.06.0-5 +- Add another couple of RISC-V patches from nojb branch. + +* Sat Feb 24 2018 Richard W.M. Jones - 4.06.0-4 +- Remove mesa* dependencies which are not needed. + +* Thu Feb 08 2018 Fedora Release Engineering - 4.06.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild + +* Wed Jan 10 2018 Richard W.M. Jones - 4.06.0-2 +- Drop non-free documentation (RHBZ#1530647). + +* Mon Nov 06 2017 Richard W.M. Jones - 4.06.0-1 +- New upstream version 4.06.0. +- Enable parallel builds again. +- Rebase patches. +- New binary ocamlcmt. + +* Wed Sep 13 2017 Richard W.M. Jones - 4.05.0-4 +- Add final upstream fix for aarch64/binutils relocation problems. + https://github.com/ocaml/ocaml/pull/1330 + +* Wed Sep 06 2017 Richard W.M. Jones - 4.05.0-3 +- Include interim fix for aarch64/binutils relocation problems. + +* Sat Aug 05 2017 Richard W.M. Jones - 4.05.0-2 +- New upstream version 4.05.0. +- Disable parallel builds for now. +- *.mli files are now included in ocaml-compiler-libs. +- Add possible fix for aarch64 with new binutils. + +* Sat Aug 05 2017 Richard W.M. Jones - 4.04.2-4 +- Disable tests on aarch64 (https://caml.inria.fr/mantis/view.php?id=7602) + +* Thu Aug 03 2017 Fedora Release Engineering - 4.04.2-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + +* Thu Jul 27 2017 Fedora Release Engineering - 4.04.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + +* Mon Jun 26 2017 Richard W.M. Jones - 4.04.2-1 +- New upstream version 4.04.2. +- Fix: ocaml: Insufficient sanitisation allows privilege escalation for + setuid binaries (CVE-2017-9772) (RHBZ#1464920). + +* Wed May 10 2017 Richard W.M. Jones - 4.04.1-1 +- New upstream version 4.04.1. + +* Sat Feb 11 2017 Fedora Release Engineering - 4.04.0-9 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Thu Jan 12 2017 Igor Gnatenko - 4.04.0-8 +- Rebuild for readline 7.x + +* Wed Nov 23 2016 Richard W.M. Jones - 4.04.0-7 +- riscv: Further fixes for https://github.com/nojb/riscv-ocaml/issues/2 + +* Tue Nov 22 2016 Richard W.M. Jones - 4.04.0-5 +- Update RISC-V support to fix + https://github.com/nojb/riscv-ocaml/issues/2 + +* Fri Nov 11 2016 Richard W.M. Jones - 4.04.0-4 +- riscv64: Fix intermediate operands. + (https://github.com/nojb/riscv-ocaml/issues/1) +- Temporarily disable emacs subpackage on riscv64. + +* Wed Nov 09 2016 Richard W.M. Jones - 4.04.0-3 +- s390x: Fix address of caml_raise_exn in native dynlink modules. + (https://caml.inria.fr/mantis/view.php?id=7405) + +* Tue Nov 08 2016 Richard W.M. Jones - 4.04.0-2 +- Add support for RISC-V using out of tree support from: + https://github.com/nojb/riscv-ocaml + +* Fri Nov 04 2016 Richard W.M. Jones - 4.04.0-1 +- New upstream version 4.04.0. + +* Thu Nov 03 2016 Richard W.M. Jones - 4.04.0-0.1.beta2 +- New upstream version 4.04.0+beta2. +- Remove our downstream ppc64 backends, and switch to upstream power backend. +- Use autopatch instead of git for patching. +- Allow parallel builds again. +- Restore ppc stack limits. +- Remove ocamlbuild. +- Add *.byte bytecode binaries. + +* Wed May 04 2016 Richard W.M. Jones - 4.02.3-3 +- CVE-2015-8869 ocaml: sizes arguments are sign-extended from + 32 to 64 bits (RHBZ#1332090) + +* Thu Feb 04 2016 Fedora Release Engineering - 4.02.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + +* Tue Jul 28 2015 Richard W.M. Jones - 4.02.3-1 +- New upstream version: 4.02.3. + +* Mon Jun 29 2015 Richard W.M. Jones - 4.02.2-4 +- Couple of minor build fixes for ppc64 and ppc64le. +- ppc64/ppc64le: Fix behaviour of Int64.max_int ÷ -1 (RHBZ#1236615). + +* Fri Jun 26 2015 Richard W.M. Jones - 4.02.2-2 +- Enable the test suite during the build. Currently the results are + only advisory. + +* Tue Jun 23 2015 Richard W.M. Jones - 4.02.2-1 +- New upstream version: 4.02.2. +- No need for a mass rebuild, since this version is identical to RC1. + +* Tue Jun 16 2015 Richard W.M. Jones - 4.02.2-0.rc1.1 +- New upstream version: 4.02.2+rc1. +- Dropped two aarch64 patches which are now included upstream. +- Includes libasmrun_shared.so (RHBZ#1195025). + +* Wed Jun 10 2015 Richard W.M. Jones - 4.02.1-7 +- aarch64: Use upstream version of patch that fixes RHBZ#1224815. + +* Tue Jun 09 2015 Richard W.M. Jones - 4.02.1-6 +- aarch64: AArch64 backend generates invalid asm: conditional branch + out of range (RHBZ#1224815). + +* Thu May 28 2015 Richard W.M. Jones - 4.02.1-5 +- ppc64le: Fix calling convention of external functions with > 8 parameters + (RHBZ#1225995). + +* Wed May 6 2015 Richard W.M. Jones - 4.02.1-4 +- Fix gdb stack traces on aarch64 (upstream PR6490). Thanks: Mark Shinwell. + +* Thu Apr 23 2015 Richard W.M. Jones - 4.02.1-3 +- ppc, ppc64, ppc64le: Properly mark stack as non-executable. + The upstream fix was not applied completely. + +* Thu Feb 26 2015 Richard W.M. Jones - 4.02.1-2 +- Kill dependency on rpm-build. Added in 2009, apparently by accident. + (Thanks: Jon Ludlam) + +* Mon Feb 16 2015 Richard W.M. Jones - 4.02.1-1 +- New upstream version 4.02.1. +- Rebase patches on top. + +* Fri Oct 24 2014 Richard W.M. Jones - 4.02.0-6 +- Fixes for ppc64/ppc64le (RHBZ#1156300). + +* Mon Oct 20 2014 Richard W.M. Jones - 4.02.0-4 +- ocaml-emacs should require emacs(bin) (RHBZ#1154513). + +* Thu Sep 11 2014 Richard W.M. Jones - 4.02.0-3 +- Use -fno-strict-aliasing when building the compiler (RHBZ#990540). +- ppc, ppc64, ppc64le: Mark stack as non-executable. + +* Tue Sep 9 2014 Richard W.M. Jones - 4.02.0-2 +- Fix bug in argument parsing (RHBZ#1139790). + +* Sat Aug 30 2014 Richard W.M. Jones - 4.02.0-1 +- New upstream OCaml 4.02.0 final. +- Add patch for ocaml-camlimages + (see http://caml.inria.fr/mantis/view.php?id=6517) + +* Fri Aug 22 2014 Richard W.M. Jones - 4.02.0-0.11.gitc48fc015 +- Rebase on top of OCaml 4.02+rc1 (same as git commit c48fc015). + +* Sun Aug 17 2014 Fedora Release Engineering - 4.02.0-0.10.git10e45753 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Fri Aug 08 2014 Richard W.M. Jones - 4.02.0-0.9 +- Add fix for Coq build issue: + http://caml.inria.fr/mantis/view.php?id=6507 + +* Fri Aug 01 2014 Richard W.M. Jones - 4.02.0-0.8 +- Rebase on top of 4.02.0 beta commit 10e45753. + +* Sat Jul 19 2014 Richard W.M. Jones - 4.02.0-0.7 +- Rebase on top of 4.02.0 beta commit c4f3a6c7. +- Remove the patch to disable CSE, since that problem is fixed upstream. +- Remove the patch fixing caml_callback2 on aarch64 since that patch is + now upstream. +- Make the compiler depend on ocaml-runtime explicitly. + +* Tue Jul 15 2014 Richard W.M. Jones - 4.02.0-0.5 +- Disable CSE optimization which is broken on armv7hl and aarch64. +- Fix broken caml_callback2 on aarch64 + http://caml.inria.fr/mantis/view.php?id=6489 + +* Sat Jul 12 2014 Richard W.M. Jones - 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). + +* Sat Jun 07 2014 Fedora Release Engineering - 4.01.0-19 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + +* Wed May 21 2014 Jaroslav Škarvada - 4.01.0-18 +- Rebuilt for https://fedoraproject.org/wiki/Changes/f21tcl86 + +* Sat May 10 2014 Richard W.M. Jones - 4.01.0-17 +- Mark stack as non-executable on ARM (32 bit) and Aarch64. + +* Tue Apr 22 2014 Richard W.M. Jones - 4.01.0-16 +- Remove ocaml-srpm-macros subpackage. + This is now a separate package, see RHBZ#1087893. + +* Tue Apr 15 2014 Richard W.M. Jones - 4.01.0-15 +- Fix s390x builds (no native compiler). + +* Tue Apr 15 2014 Richard W.M. Jones - 4.01.0-14 +- Remove ExclusiveArch. +- Add ocaml-srpm-macros subpackage containing arch macros. +- See: RHBZ#1087794 + +* Mon Apr 14 2014 Richard W.M. Jones - 4.01.0-13 +- Fix aarch64 relocation problems again. + Earlier patch was dropped accidentally. + +* Wed Apr 9 2014 Richard W.M. Jones - 4.01.0-12 +- Add ppc64le support (thanks: Michel Normand) (RHBZ#1077767). + +* Tue Apr 1 2014 Richard W.M. Jones - 4.01.0-11 +- Fix --flag=arg patch (thanks: Anton Lavrik, Ignas Vyšniauskas). + +* Mon Mar 24 2014 Richard W.M. Jones - 4.01.0-10 +- Include a fix for aarch64 relocation problems + http://caml.inria.fr/mantis/view.php?id=6283 + +* Wed Jan 8 2014 Richard W.M. Jones - 4.01.0-8 +- Don't use ifarch around Patch lines, as it means the patch files + don't get included in the spec file. + +* Mon Jan 6 2014 Richard W.M. Jones - 4.01.0-7 +- Work around gcc stack alignment issues, see + http://caml.inria.fr/mantis/view.php?id=5700 + +* Tue Dec 31 2013 Richard W.M. Jones - 4.01.0-6 +- Add aarch64 (arm64) code generator. + +* Thu Nov 21 2013 Richard W.M. Jones - 4.01.0-4 +- Add bundled(md5-plumb) (thanks: Tomas Mraz). +- Add NON-upstream (but being sent upstream) patch to allow --flag=arg + as an alternative to --flag arg (RHBZ#1028650). + +* Sat Sep 14 2013 Richard W.M. Jones - 4.01.0-3 +- Disable -lcurses. This is not actually used, just linked with unnecessarily. + +* Sat Sep 14 2013 Richard W.M. Jones - 4.01.0-2 +- Fix the build on ppc64. + +* Fri Sep 13 2013 Richard W.M. Jones - 4.01.0-1 +- Update to new major version OCaml 4.01.0. +- Rebase patches. +- Remove bogus Requires 'ncurses-devel'. The base ocaml package already + pulls in the library implicitly. +- Remove bogus Requires 'gdbm-devel'. Nothing in the source mentions gdbm. +- Use mkstemp instead of mktemp in ocamlyacc. +- Add LICENSE as doc to some subpackages to keep rpmlint happy. +- Remove .ignore file from some packages. +- Remove period from end of Summary. + +* Sat Aug 03 2013 Fedora Release Engineering - 4.00.1-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild + +* Thu Feb 14 2013 Fedora Release Engineering - 4.00.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Tue Oct 16 2012 Richard W.M. Jones - 4.00.1-1 +- Update to upstream version 4.00.1. +- Clean up the spec file further. + +* Thu Aug 16 2012 Richard W.M. Jones - 4.00.0-2 +- ppc supports natdynlink. + +* Sat Jul 28 2012 Richard W.M. Jones - 4.00.0-1 +- Upgrade to OCaml 4.00.0 official release. +- Remove one patch (add -lpthread) which went upstream. + +* Fri Jul 20 2012 Fedora Release Engineering - 4.00.0-0.6.beta2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Sun Jun 10 2012 Richard W.M. Jones - 4.00.0-0.5.beta2 +- No change, just fix up changelog. + +* Thu Jun 7 2012 Richard W.M. Jones 4.00.0-0.3.beta2 +- Upgrade to OCaml 4.00.0 beta 2. +- The language is now officially called OCaml (not Objective Caml, O'Caml etc) +- Rebase patches on top: + . New ARM backend patch no longer required, since upstream. + . Replacement config.guess, config.sub no longer required, since upstream + versions are newer. +- PPC64 backend rebased and fixed. + . Increase the default size of the stack when compiling. +- New tool: ocamloptp (ocamlopt profiler). +- New VERSION file in ocaml-runtime package. +- New ocaml-compiler-libs subpackage. +- Rearrange ExclusiveArch alphanumerically. +- alpha, ia64 native backends have been removed upstream, so they are + no longer supported as native compiler targets. +- Remove defattr. +- Make OCaml dependency generator self-contained so it doesn't need + previous version of OCaml around. + +* Wed Jun 6 2012 Richard W.M. Jones 3.12.1-12 +- ppc64: Include fix for minor heap corruption because of unaligned + minor heap register (RHBZ#826649). +- Unset MAKEFLAGS before running build. + +* Wed Jun 6 2012 Richard W.M. Jones 3.12.1-11 +- ppc64: Fix position of stack arguments to external C functions + when there are more than 8 parameters. + +* Tue Jun 5 2012 Richard W.M. Jones 3.12.1-10 +- Include patch to link dllthreads.so with -lpthread explicitly, to + fix problem with 'pthread_atfork' symbol missing (statically linked) + on ppc64. + +* Sun Jun 3 2012 Richard W.M. Jones 3.12.1-9 +- Include svn rev 12548 to fix invalid generation of Thumb-2 branch + instruction TBH (upstream PR#5623, RHBZ#821153). + +* Wed May 30 2012 Richard W.M. Jones 3.12.1-8 +- Modify the ppc64 patch to reduce the delta between power64 and + upstream power backends. +- Clean up the spec file and bring it up to modern standards. + * Remove patch fuzz directive. + * Remove buildroot directive. + * Rearrange source unpacking. + * Remove chmod of GNU config.* files, since git does it. + * Don't need to remove buildroot in install section. + * Remove clean section. + * git am 3.12.1-6 +- Move patches to external git repo: + http://git.fedorahosted.org/git/?p=fedora-ocaml.git + There should be no change introduced here. + +* Tue May 15 2012 Karsten Hopp 3.12.1-4 +- ppc64 got broken by the new ARM backend, add a minor patch + +* Sat Apr 28 2012 Richard W.M. Jones 3.12.1-3 +- New ARM backend by Benedikt Meurer, backported to OCaml 3.12.1. + This has several advantages, including enabling natdynlink on ARM. +- Provide updated config.guess and config.sub (from OCaml upstream tree). + +* Thu Jan 12 2012 Richard W.M. Jones 3.12.1-2 +- add back ocaml-ppc64.patch for ppc secondary arch, drop .cmxs files + from file list on ppc (cherry picked from F16 - this should have + gone into Rawhide originally then been cherry picked back to F16) + +* Fri Jan 6 2012 Richard W.M. Jones - 3.12.1-1 +- New upstream version 3.12.1. This is a bugfix update. + +* Thu Dec 8 2011 Richard W.M. Jones - 3.12.0-7 +- Allow this package to be compiled on platforms without native + support and/or natdynlink, specifically ppc64. This updates (and + hopefully does not break) DJ's previous *.cmxs change for arm. + +* Fri Sep 23 2011 DJ Delorie - 3.12.0-6 +- Add arm type directive patch. +- Allow more arm arches. +- Don't package *.cmxs on arm. + +* Wed Mar 30 2011 Richard W.M. Jones - 3.12.0-5 +- Fix for invalid assembler generation (RHBZ#691896). + +* Tue Feb 08 2011 Fedora Release Engineering - 3.12.0-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Wed Jan 5 2011 Richard W.M. Jones - 3.12.0-3 +- Rebuild with self. + +* Tue Jan 4 2011 Richard W.M. Jones - 3.12.0-2 +- Try depending on OCaml BR to fix: + /usr/lib/rpm/ocaml-find-provides.sh: /builddir/build/BUILDROOT/ocaml-3.12.0-1.fc15.i386/usr/bin/ocamlobjinfo: /usr/bin/ocamlrun: bad interpreter: No such file or directory + +* Tue Jan 4 2011 Richard W.M. Jones - 3.12.0-1 +- New upstream version 3.12.0. + http://fedoraproject.org/wiki/Features/OCaml3.12 +- Remove ppc64 support patch. +- Rebase rpath removal patch. +- ocamlobjinfo is now an official tool, so no need to compile it by hand. + Add objinfo_helper. +- Disable ocamlplugininfo. +- Remove addlabels, scrapelabels. +- Remove ocaml/stublibs/dlltkanim.so. + +* Fri Jan 29 2010 Richard W.M. Jones - 3.11.2-2 +- Update reference manual to latest version from website. + +* Wed Jan 20 2010 Richard W.M. Jones - 3.11.2-1 +- Update to 3.11.2 official release. + +* Tue Jan 5 2010 Richard W.M. Jones - 3.11.2-0.rc1.2 +- ocaml-labltk-devel should require tcl-devel and tk-devel. + +* Tue Dec 29 2009 Richard W.M. Jones - 3.11.2-0.rc1.1 +- Update to (release candidate) 3.11.2+rc1. + +* Wed Dec 16 2009 Richard W.M. Jones - 3.11.1-8 +- Use __ocaml_requires_opts / __ocaml_provides_opts. + +* Wed Dec 16 2009 Richard W.M. Jones - 3.11.1-7 +- Remove ocaml-find-{requires,provides}.sh from this package. These are + now in upstream RPM 4.8 (RHBZ#545116). +- define -> global in a few places. + +* Thu Nov 05 2009 Dennis Gilmore - 3.11.1-6 +- include sparcv9 in the arch list + +* Tue Oct 27 2009 Richard W.M. Jones - 3.11.1-5 +- Install ocaml.info files correctly (RHBZ#531204). + +* Fri Oct 16 2009 Richard W.M. Jones - 3.11.1-4 +- Set includes so building the *info programs works without + having OCaml already installed. + +* Fri Oct 16 2009 Richard W.M. Jones - 3.11.1-3 +- Add ocamlbyteinfo and ocamlplugininfo programs from Debian. + +* Sun Oct 4 2009 Richard W.M. Jones - 3.11.1-2 +- ocaml-find-requires.sh: Calculate runtime version using ocamlrun + -version instead of fedora-ocaml-release file. + +* Wed Sep 30 2009 Richard W.M. Jones - 3.11.1-1 +- OCaml 3.11.1 (this is virtually the same as the release candidate + that we were using for Fedora 12). + +* Sat Jul 25 2009 Fedora Release Engineering - 3.11.1-0.rc1.2.1 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Wed Jun 3 2009 Richard W.M. Jones - 3.11.1-0.rc1.2 +- Remember to upload the source this time. + +* Wed Jun 3 2009 Richard W.M. Jones - 3.11.1-0.rc1.1 +- New upstream release candidate 3.11.1+rc1. +- Remove ocamlbuild -where patch (now upstream). + +* Tue Jun 2 2009 Richard W.M. Jones - 3.11.1-0.rc0.3 +- Move dllgraphics.so into runtime package (RHBZ#468506). + +* Tue May 26 2009 Richard W.M. Jones - 3.11.1-0.rc0.2 +- Backport ocamlbuild -where fix. + +* Fri May 22 2009 Richard W.M. Jones - 3.11.1-0.rc0.1 +- 3.11.1 release candidate 0. + +* Wed Feb 25 2009 Fedora Release Engineering - 3.11.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Thu Dec 4 2008 Richard W.M. Jones - 3.11.0-1 +- Official release of 3.11.0. + +* Thu Dec 4 2008 Richard W.M. Jones - 3.11.0-0.6.rc1 +- Fixed sources file. + +* Thu Dec 4 2008 Richard W.M. Jones - 3.11.0-0.5.rc1 +- New upstream version 3.11.0+rc1. + +* Mon Nov 24 2008 Richard W.M. Jones - 3.11.0-0.4.beta1 +- Rebuild. + +* Thu Nov 20 2008 Rex Dieter - 3.11.0-0.3.beta1 +- fix NVR to match packaging guidelines + +* Thu Nov 20 2008 Richard W.M. Jones - 3.11.0+beta1-2 +- Fix Invalid_argument("String.index_from") with patch from upstream. + +* Tue Nov 18 2008 Richard W.M. Jones - 3.11.0+beta1-1 +- Rebuild for major new upstream release of 3.11.0 for Fedora 11. + +* Fri Aug 29 2008 Richard W.M. Jones - 3.10.2-5 +- Rebuild with patch fuzz. + +* Mon Jun 9 2008 Richard W.M. Jones - 3.10.2-4 +- Add ocaml-3.11-dev12-no-executable-stack.patch (bz #450551). + +* Wed Jun 4 2008 Richard W.M. Jones - 3.10.2-3 +- ocaml-ocamldoc provides ocamldoc (bz #449931). +- REMOVED provides of labltk, camlp4. Those are libraries and all + packages should now depend on ocaml-labltk / ocaml-camlp4 / -devel + as appropriate. + +* Thu May 8 2008 Richard W.M. Jones - 3.10.2-2 +- Pass MAP_32BIT to mmap (bz #445545). + +* Mon Apr 21 2008 Richard W.M. Jones - 3.10.2-1 +- New upstream version 3.10.2 for Fedora 10. +- Cleaned up several rpmlint errors & warnings. + +* Fri Feb 29 2008 David Woodhouse - 3.10.1-2 +- ppc64 port + +* Tue Feb 12 2008 Richard W.M. Jones - 3.10.1-1 +- new upstream version 3.10.1 + +* Fri Jan 4 2008 Gerard Milmeister - 3.10.0-8 +- patch for building with tcl/tk 8.5 + +* Thu Sep 6 2007 Richard W.M. Jones - 3.10.0-7 +- Run chrpath to delete rpaths used on some of the stublibs. +- Ignore Parsetree module in dependency calculation. +- Fixed ocaml-find-{requires,provides}.sh regexp calculation so it doesn't + over-match module names. + +* Mon Sep 3 2007 Richard W.M. Jones - 3.10.0-6 +- ocaml-runtime provides ocaml(runtime) = 3.10.0, and + ocaml-find-requires.sh modified so that it adds this requires + to other packages. Now can upgrade base ocaml packages without + needing to rebuild everything else. + +* Mon Sep 3 2007 Richard W.M. Jones - 3.10.0-5 +- Don't include the release number in fedora-ocaml-release file, so + that packages built against this won't depend on the Fedora release. + +* Wed Aug 29 2007 Gerard Milmeister - 3.10.0-4 +- added BR util-linux-ng + +* Wed Aug 29 2007 Gerard Milmeister - 3.10.0-3 +- added BR gawk + +* Tue Aug 28 2007 Fedora Release Engineering - 3.10.0-2 +- Rebuild for selinux ppc32 issue. + +* Sat Jun 2 2007 Gerard Milmeister - 3.10.0-1 +- new version 3.10.0 +- split off devel packages +- rename subpackages to use ocaml- prefix + +* Thu May 24 2007 Gerard Milmeister - 3.09.3-2 +- added ocamlobjinfo + +* Sat Dec 2 2006 Gerard Milmeister - 3.09.3-1 +- new version 3.09.3 + +* Mon Aug 28 2006 Gerard Milmeister - 3.09.2-2 +- Rebuild for FE6 + +* Sun Apr 30 2006 Gerard Milmeister - 3.09.2-1 +- new version 3.09.2 + +* Fri Feb 17 2006 Gerard Milmeister - 3.09.1-2 +- Rebuild for Fedora Extras 5 + +* Thu Jan 5 2006 Gerard Milmeister - 3.09.1-1 +- new version 3.09.1 + +* Sun Jan 1 2006 Gerard Milmeister - 3.09.0-1 +- new version 3.09.0 + +* Sun Sep 11 2005 Gerard Milmeister - 3.08.4-1 +- New Version 3.08.4 + +* Wed May 25 2005 Toshio Kuratomi - 3.08.3-5 +- Bump and re-release as last build failed due to rawhide syncing. + +* Sun May 22 2005 Toshio Kuratomi - 3.08.3-4 +- Fix for gcc4 and the 32 bit assembly in otherlibs/num. +- Fix to allow compilation with RPM_OPT_FLAG defined -O level. + +* Sun May 22 2005 Jeremy Katz - 3.08.3-3 +- rebuild on all arches + +* Fri Apr 8 2005 Michael Schwendt +- rebuilt + +* Sat Mar 26 2005 Gerard Milmeister - 3.08.3-1 +- New Version 3.08.3 + +* Sat Feb 12 2005 Gerard Milmeister - 0:3.08.2-2 +- Added patch for removing rpath from shared libs + +* Sat Feb 12 2005 Gerard Milmeister - 0:3.08.2-1 +- New Version 3.08.2 + +* Thu Dec 30 2004 Thorsten Leemhuis - 0:3.07-6 +- add -x11lib _prefix/X11R6/_lib to configure; fixes labltk build + on x86_64 + +* Tue Dec 2 2003 Gerard Milmeister - 0:3.07-0.fdr.5 +- ocamldoc -> ocaml-ocamldoc +- ocaml-doc -> ocaml-docs + +* Fri Nov 28 2003 Gerard Milmeister - 0:3.07-0.fdr.4 +- Make separate packages for labltk, camlp4, ocamldoc, emacs and documentation + +* Thu Nov 27 2003 Gerard Milmeister - 0:3.07-0.fdr.2 +- Changed license tag +- Register info files +- Honor RPM_OPT_FLAGS +- New Patch + +* Fri Oct 31 2003 Gerard Milmeister - 0:3.07-0.fdr.1 +- First Fedora release + +* Mon Oct 13 2003 Axel Thimm +- Updated to 3.07. + +* Wed Apr 9 2003 Axel Thimm +- Rebuilt for Red Hat 9. + +* Tue Nov 26 2002 Axel Thimm +- Added _mandir/mano/* entry