* Re: [Caml-list] OCaml + mingw-w64
[not found] <2017975850.988226.1290427453930.JavaMail.root@zmbs1.inria.fr>
@ 2010-11-22 15:33 ` Damien Doligez
2010-11-23 16:31 ` Christoph Cullmann
0 siblings, 1 reply; 4+ messages in thread
From: Damien Doligez @ 2010-11-22 15:33 UTC (permalink / raw)
To: OCaml mailing list
On 2010-11-22, at 13:04, Christoph Cullmann wrote:
> In ocaml 3.12, in byterun/major_gc.h, there is:
>
> intnat caml_major_collection_slice (long howmuch)
>
> whereas in the .c file that is:
>
> intnat caml_major_collection_slice (intnat howmuch)
>
> As intnat is with mingw-w64 long long, this doesn't match.
> Should not the header use intnat, too?
You're right. This will be fixed in 3.12.1.
-- Damien
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Caml-list] OCaml + mingw-w64
2010-11-22 15:33 ` [Caml-list] OCaml + mingw-w64 Damien Doligez
@ 2010-11-23 16:31 ` Christoph Cullmann
2010-11-24 7:14 ` Christoph Cullmann
0 siblings, 1 reply; 4+ messages in thread
From: Christoph Cullmann @ 2010-11-23 16:31 UTC (permalink / raw)
To: caml-list
On Monday, November 22, 2010 04:33:08 pm Damien Doligez wrote:
> On 2010-11-22, at 13:04, Christoph Cullmann wrote:
> > In ocaml 3.12, in byterun/major_gc.h, there is:
> >
> >
> > intnat caml_major_collection_slice (long howmuch)
> >
> >
> >
> > whereas in the .c file that is:
> >
> >
> > intnat caml_major_collection_slice (intnat howmuch)
> >
> >
> >
> > As intnat is with mingw-w64 long long, this doesn't match.
> > Should not the header use intnat, too?
>
> You're right. This will be fixed in 3.12.1.
Thanks.
We just started here to port ocaml to mingw-w64, question arises:
Which files need adoption?
I have seen that in asmrun the amd64.S needs patches and in asmcomp the emit
and proc mls.
Do I miss files?
Greetings
Christoph
--
-------------------------------------- Christoph Cullmann ---------
AbsInt Angewandte Informatik GmbH Email: cullmann@AbsInt.com
Science Park 1 Tel: +49-681-38360-22
66123 Saarbrücken Fax: +49-681-38360-20
GERMANY WWW: http://www.AbsInt.com
--------------------------------------------------------------------
Geschäftsführung: Dr.-Ing. Christian Ferdinand
Eingetragen im Handelsregister des Amtsgerichts Saarbrücken, HRB 11234
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Caml-list] OCaml + mingw-w64
2010-11-23 16:31 ` Christoph Cullmann
@ 2010-11-24 7:14 ` Christoph Cullmann
0 siblings, 0 replies; 4+ messages in thread
From: Christoph Cullmann @ 2010-11-24 7:14 UTC (permalink / raw)
To: caml-list
[-- Attachment #1: Type: Text/Plain, Size: 1673 bytes --]
On Tuesday, November 23, 2010 05:31:12 pm Christoph Cullmann wrote:
> On Monday, November 22, 2010 04:33:08 pm Damien Doligez wrote:
> > On 2010-11-22, at 13:04, Christoph Cullmann wrote:
> > > In ocaml 3.12, in byterun/major_gc.h, there is:
> > >
> > >
> > > intnat caml_major_collection_slice (long howmuch)
> > >
> > >
> > >
> > > whereas in the .c file that is:
> > >
> > >
> > > intnat caml_major_collection_slice (intnat howmuch)
> > >
> > >
> > >
> > > As intnat is with mingw-w64 long long, this doesn't match.
> > > Should not the header use intnat, too?
> >
> > You're right. This will be fixed in 3.12.1.
>
> Thanks.
>
> We just started here to port ocaml to mingw-w64, question arises:
>
> Which files need adoption?
>
> I have seen that in asmrun the amd64.S needs patches and in asmcomp the
> emit and proc mls.
>
> Do I miss files?
We started to have some version that at least links (with patched flexdll) but
runs in a nice segfault already ;)
Attached are the current changed states, any ideas where to look?
Atm not seeing the obvious fault :/
Greetings
Christoph
--
-------------------------------------- Christoph Cullmann ---------
AbsInt Angewandte Informatik GmbH Email: cullmann@AbsInt.com
Science Park 1 Tel: +49-681-38360-22
66123 Saarbrücken Fax: +49-681-38360-20
GERMANY WWW: http://www.AbsInt.com
--------------------------------------------------------------------
Geschäftsführung: Dr.-Ing. Christian Ferdinand
Eingetragen im Handelsregister des Amtsgerichts Saarbrücken, HRB 11234
[-- Attachment #2: flexdll.0.26.diff --]
[-- Type: text/x-patch, Size: 4661 bytes --]
diff --combined ocaml/flexdll/cmdline.ml
index eccd13e,ae96a0e..0000000
--- a/ocaml/flexdll/cmdline.ml
+++ b/ocaml/flexdll/cmdline.ml
@@@ -18,7 -18,7 +18,7 @@@ let use_default_libs = ref tru
let subsystem = ref "console"
let explain = ref false
let builtin_linker = ref false
-let toolchain : [ `MSVC | `MSVC64 | `MINGW | `CYGWIN | `LIGHTLD ] ref = ref `MSVC
+let toolchain : [ `MSVC | `MSVC64 | `MINGW | `MINGW64 | `CYGWIN | `LIGHTLD ] ref = ref `MSVC
let save_temps = ref false
let show_exports = ref false
let show_imports = ref false
@@@ -87,7 -87,7 +87,7 @@@ let specs =
"-l", Arg.String (fun s -> files := ("-l" ^ s) :: !files),
"<lib> Library file";
- "-chain", Arg.Symbol (["msvc";"msvc64";"cygwin";"mingw";"ld"],
+ "-chain", Arg.Symbol (["msvc";"msvc64";"cygwin";"mingw";"mingw64";"ld"],
(fun s ->
machine := `x86; underscore := true;
toolchain := match s with
@@@ -95,7 -95,6 +95,7 @@@
| "msvc64" -> machine := `x64; underscore := false; `MSVC64
| "cygwin" -> `CYGWIN
| "mingw" -> `MINGW
+ | "mingw64" -> machine := `x64; underscore := false; `MINGW64
| "ld" -> `LIGHTLD
| _ -> assert false)),
" Choose which linker to use";
diff --combined ocaml/flexdll/reloc.ml
index eb331dc,9a37b5b..0000000
--- a/ocaml/flexdll/reloc.ml
+++ b/ocaml/flexdll/reloc.ml
@@@ -112,7 -112,7 +112,7 @@@ type cmdline =
let new_cmdline () =
let rf = match !toolchain with
| `MSVC | `MSVC64 | `LIGHTLD -> true
- | `MINGW | `CYGWIN -> false
+ | `MINGW | `MINGW64 | `CYGWIN -> false
in
{
may_use_response_file = rf;
@@@ -160,7 -160,7 +160,7 @@@ let cygpath l
let gcclib () =
let extra = match !toolchain with
- | `MINGW -> "-mno-cygwin "
+ | `MINGW | `MINGW64 -> "-mno-cygwin "
| _ -> ""
in
Filename.dirname (get_output1 ~use_bash:(!toolchain = `CYGWIN) (Printf.sprintf "gcc %s-print-libgcc-file-name" extra))
@@@ -492,7 -492,7 +492,7 @@@ let parse_dll_exports fn
let dll_exports fn = match !toolchain with
| `MSVC | `MSVC64 | `LIGHTLD ->
failwith "Creation of import library not supported for this toolchain"
- | `CYGWIN | `MINGW ->
+ | `CYGWIN | `MINGW | `MINGW64 ->
let dmp = temp_file "dyndll" ".dmp" in
if cmd_verbose (Printf.sprintf "objdump -p %s > %s" fn dmp) <> 0
then failwith "Error while extracting exports from a DLL";
@@@ -898,7 -898,7 +898,7 @@@ let build_dll link_exe output_file file
files
def_file
extra_args
- | `MINGW ->
+ | `MINGW | `MINGW64 ->
let def_file =
if main_pgm then ""
else
@@@ -911,7 -911,7 +911,7 @@@
"gcc -mno-cygwin -m%s %s%s -L. %s %s -o %s %s %s %s %s %s"
!subsystem
(if link_exe = `EXE then "" else "-shared ")
- (if main_pgm then "" else if !noentry then "-Wl,-e0 " else "-Wl,-e_FlexDLLiniter@12 ")
+ (if main_pgm then "" else if !noentry then "-Wl,-e0 " else match !machine with | `x86 -> "-Wl,-e_FlexDLLiniter@12 " | `x64 -> "-Wl,-e_FlexDLLiniter " )
(mk_dirs_opt "-I")
(mk_dirs_opt "-L")
(Filename.quote output_file)
@@@ -983,7 -983,7 +983,7 @@@ let setup_toolchain ()
parse_libpath (try Sys.getenv "LIB" with Not_found -> "");
if not !custom_crt then
default_libs := ["msvcrt.lib"]
- | `MINGW ->
+ | `MINGW | `MINGW64 ->
search_path :=
!dirs @
[ "/lib/mingw";
@@@ -1015,7 -1015,7 +1015,7 @@@ let compile_if_needed file
(Filename.quote tmp_obj)
(mk_dirs_opt "-I")
file
- | `MINGW ->
+ | `MINGW | `MINGW64 ->
Printf.sprintf
"gcc -mno-cygwin -c -o %s %s %s"
(Filename.quote tmp_obj)
@@@ -1054,7 -1054,6 +1054,7 @@@ let all_files ()
| `MSVC -> "msvc.obj"
| `MSVC64 -> "msvc64.obj"
| `CYGWIN -> "cygwin.o"
+ | `MINGW64 -> "mingw64.o"
| `MINGW | `LIGHTLD -> "mingw.o" in
if !exe_mode <> `DLL then
if !add_flexdll_obj then f ("flexdll_" ^ tc) :: files
@@@ -1073,7 -1072,7 +1073,7 @@@ let main ()
| _, `Yes -> true
| _, `No -> false
| `CYGWIN, `None -> (Sys.command "cygpath -v 2>/dev/null >/dev/null" = 0)
- | `MINGW, `None -> (Sys.command "cygpath -v 2>NUL >NUL" = 0)
+ | (`MINGW|`MINGW64), `None -> (Sys.command "cygpath -v 2>NUL >NUL" = 0)
| (`MSVC|`MSVC64|`LIGHTLD), `None -> false
end;
diff --git a/ocaml/flexdll/version.ml b/ocaml/flexdll/version.ml
new file mode 100755
index 0000000..47eaa2f
--- /dev/null
+++ b/ocaml/flexdll/version.ml
@@ -0,0 +1 @@
+let version = "0.26"
[-- Attachment #3: ocaml.3.12.diff --]
[-- Type: text/x-patch, Size: 53021 bytes --]
diff --combined ocaml/3.12/asmrun/Makefile.nt
index 7d72312,f9ed767..0000000
--- a/ocaml/3.12/asmrun/Makefile.nt
+++ b/ocaml/3.12/asmrun/Makefile.nt
@@@ -54,9 -54,6 +54,9 @@@ amd64nt.obj: amd64nt.as
i386.o: i386.S
$(CC) -c -DSYS_$(SYSTEM) i386.S
+amd64.o: amd64.S
+ $(CC) -c -DSYS_$(SYSTEM) amd64.S
+
install:
cp libasmrun.$(A) $(LIBDIR)
diff --combined ocaml/3.12/asmrun/amd64.S
index abf74ee,8eb4ebf..0000000
--- a/ocaml/3.12/asmrun/amd64.S
+++ b/ocaml/3.12/asmrun/amd64.S
@@@ -31,21 -31,6 +31,21 @@@
.align FUNCTION_ALIGN; \
name:
+#elif defined(SYS_mingw64)
+
+#undef __PIC__
+
+#define G(r) r
+#define GREL(r) r
+#define GCALL(r) r
+#define FUNCTION_ALIGN 16
+#define EIGHT_ALIGN 8
+#define SIXTEEN_ALIGN 16
+#define FUNCTION(name) \
+ .globl name; \
+ .align FUNCTION_ALIGN; \
+ name:
+
#else
#define G(r) r
@@@ -106,7 -91,7 +106,7 @@@
popq %r11
#else
-
+
/* Non-PIC operations on global variables. Slightly faster. */
#define STORE_VAR(srcreg,dstlabel) \
@@@ -179,13 -164,7 +179,13 @@@ FUNCTION(G(caml_call_gc)
movlpd %xmm14, 14*8(%rsp)
movlpd %xmm15, 15*8(%rsp)
/* Call the garbage collector */
+#ifdef SYS_mingw64
+ subq $32, %rsp /* PR#5008: bottom 32 bytes are reserved for callee */
+#endif
call GCALL(caml_garbage_collection)
+#ifdef SYS_mingw64
+ addq $32, %rsp /* PR#5008 */
+#endif
/* Restore caml_young_ptr, caml_exception_pointer */
LOAD_VAR(caml_young_ptr, %r15)
LOAD_VAR(caml_exception_pointer, %r14)
@@@ -298,28 -277,6 +298,28 @@@ FUNCTION(G(caml_c_call)
/* Start the Caml program */
FUNCTION(G(caml_start_program))
+#ifdef SYS_mingw64
+ /* Save callee-save registers */
+ pushq %rbx
+ pushq %rbp
+ pushq %rsi
+ pushq %rdi
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ subq $(8+10*16), %rsp /* stack 16-aligned + 10 saved xmm regs */
+ movapd %xmm6, 0*16(%rsp)
+ movapd %xmm7, 1*16(%rsp)
+ movapd %xmm8, 2*16(%rsp)
+ movapd %xmm9, 3*16(%rsp)
+ movapd %xmm10, 4*16(%rsp)
+ movapd %xmm11, 5*16(%rsp)
+ movapd %xmm12, 6*16(%rsp)
+ movapd %xmm13, 7*16(%rsp)
+ movapd %xmm14, 8*16(%rsp)
+ movapd %xmm15, 9*16(%rsp)
+#else
/* Save callee-save registers */
pushq %rbx
pushq %rbp
@@@ -328,7 -285,6 +328,7 @@@
pushq %r14
pushq %r15
subq $8, %rsp /* stack 16-aligned */
+#endif
/* Initial entry point is G(caml_program) */
leaq GCALL(caml_program)(%rip), %r12
/* Common code for caml_start_program and caml_callback* */
@@@ -361,28 -317,6 +361,28 @@@
POP_VAR(caml_last_return_address)
POP_VAR(caml_gc_regs)
addq $8, %rsp
+#ifdef SYS_mingw64
+ /* Restore callee-save registers. */
+ movapd 0*16(%rsp), %xmm6
+ movapd 1*16(%rsp), %xmm7
+ movapd 2*16(%rsp), %xmm8
+ movapd 3*16(%rsp), %xmm9
+ movapd 4*16(%rsp), %xmm10
+ movapd 5*16(%rsp), %xmm11
+ movapd 6*16(%rsp), %xmm12
+ movapd 7*16(%rsp), %xmm13
+ movapd 8*16(%rsp), %xmm14
+ movapd 9*16(%rsp), %xmm15
+ addq $(8+10*16), %rsp
+ popq %r15
+ popq %r14
+ popq %r13
+ popq %r12
+ popq %rdi
+ popq %rsi
+ popq %rbp
+ popq %rbx
+#else
/* Restore callee-save registers. */
addq $8, %rsp
popq %r15
@@@ -391,7 -325,6 +391,7 @@@
popq %r12
popq %rbp
popq %rbx
+#endif
/* Return to caller. */
ret
.L108:
@@@ -409,20 -342,11 +409,20 @@@ FUNCTION(G(caml_raise_exn)
popq %r14
ret
.L110:
+#ifdef SYS_mingw64
+ movq %rax, %r12 /* Save exception bucket in r12 */
+ movq %rax, %rcx /* Arg 1: exception bucket */
+ movq 0(%rsp), %rdx /* arg 2: pc of raise */
+ leaq 8(%rsp), %r8 /* arg 3: sp of raise */
+ movq %r14, %r9 /* arg 4: sp of handler */
+ subq $32, %rsp /* PR#5008: bottom 32 bytes are reserved for callee */
+#else
movq %rax, %r12 /* Save exception bucket */
movq %rax, %rdi /* arg 1: exception bucket */
movq 0(%rsp), %rsi /* arg 2: pc of raise */
leaq 8(%rsp), %rdx /* arg 3: sp of raise */
movq %r14, %rcx /* arg 4: sp of handler */
+#endif
call GCALL(caml_stash_backtrace)
movq %r12, %rax /* Recover exception bucket */
movq %r14, %rsp
@@@ -434,30 -358,17 +434,30 @@@
FUNCTION(G(caml_raise_exception))
TESTL_VAR($1, caml_backtrace_active)
jne .L111
+#ifdef SYS_mingw64
+ movq %rcx, %rax
+#else
movq %rdi, %rax
+#endif
LOAD_VAR(caml_exception_pointer, %rsp) /* Cut stack */
popq %r14 /* Recover previous exception handler */
LOAD_VAR(caml_young_ptr, %r15) /* Reload alloc ptr */
ret
.L111:
+#ifdef SYS_mingw64
+ movq %rcx, %r12 /* Save exception bucket */
+ /* arg 1: exception bucket */
+ LOAD_VAR(caml_last_return_address,%rdx) /* arg 2: pc of raise */
+ LOAD_VAR(caml_bottom_of_stack,%r8) /* arg 3: sp of raise */
+ LOAD_VAR(caml_exception_pointer,%r9) /* arg 4: sp of handler */
+ subq $32, %rsp /* PR#5008: bottom 32 bytes are reserved for callee */
+#else
movq %rdi, %r12 /* Save exception bucket */
/* arg 1: exception bucket */
- LOAD_VAR(caml_last_return_address,%rsi) /* arg 2: pc of raise */
+ LOAD_VAR(caml_last_return_address,%rsi) /* arg 2: pc of raise */
LOAD_VAR(caml_bottom_of_stack,%rdx) /* arg 3: sp of raise */
LOAD_VAR(caml_exception_pointer,%rcx) /* arg 4: sp of handler */
+#endif
call GCALL(caml_stash_backtrace)
movq %r12, %rax /* Recover exception bucket */
LOAD_VAR(caml_exception_pointer,%rsp)
@@@ -468,31 -379,6 +468,31 @@@
/* Callback from C to Caml */
FUNCTION(G(caml_callback_exn))
+#ifdef SYS_mingw64
+ /* Save callee-save registers */
+ pushq %rbx
+ pushq %rbp
+ pushq %rsi
+ pushq %rdi
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ subq $(8+10*16), %rsp /* stack 16-aligned + 10 saved xmm regs */
+ movapd %xmm6, 0*16(%rsp)
+ movapd %xmm7, 1*16(%rsp)
+ movapd %xmm8, 2*16(%rsp)
+ movapd %xmm9, 3*16(%rsp)
+ movapd %xmm10, 4*16(%rsp)
+ movapd %xmm11, 5*16(%rsp)
+ movapd %xmm12, 6*16(%rsp)
+ movapd %xmm13, 7*16(%rsp)
+ movapd %xmm14, 8*16(%rsp)
+ movapd %xmm15, 9*16(%rsp)
+ /* Initial loading of arguments */
+ movq %rcx, %rbx /* closure */
+ movq %rdx, %rax /* argument */
+#else
/* Save callee-save registers */
pushq %rbx
pushq %rbp
@@@ -500,41 -386,14 +500,41 @@@
pushq %r13
pushq %r14
pushq %r15
- subq $8, %rsp /* stack 16-aligned */
+ subq $8, %rsp /* stack 16-aligned */
/* Initial loading of arguments */
movq %rdi, %rbx /* closure */
movq %rsi, %rax /* argument */
+#endif
movq 0(%rbx), %r12 /* code pointer */
jmp .Lcaml_start_program
FUNCTION(G(caml_callback2_exn))
+#ifdef SYS_mingw64
+ /* Save callee-save registers */
+ pushq %rbx
+ pushq %rbp
+ pushq %rsi
+ pushq %rdi
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ subq $(8+10*16), %rsp /* stack 16-aligned + 10 saved xmm regs */
+ movapd %xmm6, 0*16(%rsp)
+ movapd %xmm7, 1*16(%rsp)
+ movapd %xmm8, 2*16(%rsp)
+ movapd %xmm9, 3*16(%rsp)
+ movapd %xmm10, 4*16(%rsp)
+ movapd %xmm11, 5*16(%rsp)
+ movapd %xmm12, 6*16(%rsp)
+ movapd %xmm13, 7*16(%rsp)
+ movapd %xmm14, 8*16(%rsp)
+ movapd %xmm15, 9*16(%rsp)
+ /* Initial loading of arguments */
+ movq %rcx, %rdi /* closure */
+ movq %rdx, %rax /* first argument */
+ movq %r8, %rbx /* second argument */
+#else
/* Save callee-save registers */
pushq %rbx
pushq %rbp
@@@ -542,43 -401,15 +542,43 @@@
pushq %r13
pushq %r14
pushq %r15
- subq $8, %rsp /* stack 16-aligned */
+ subq $8, %rsp /* stack 16-aligned */
/* Initial loading of arguments */
/* closure stays in %rdi */
movq %rsi, %rax /* first argument */
movq %rdx, %rbx /* second argument */
+#endif
leaq GCALL(caml_apply2)(%rip), %r12 /* code pointer */
jmp .Lcaml_start_program
FUNCTION(G(caml_callback3_exn))
+#ifdef SYS_mingw64
+ /* Save callee-save registers */
+ pushq %rbx
+ pushq %rbp
+ pushq %rsi
+ pushq %rdi
+ pushq %r12
+ pushq %r13
+ pushq %r14
+ pushq %r15
+ subq $(8+10*16), %rsp /* stack 16-aligned + 10 saved xmm regs */
+ movapd %xmm6, 0*16(%rsp)
+ movapd %xmm7, 1*16(%rsp)
+ movapd %xmm8, 2*16(%rsp)
+ movapd %xmm9, 3*16(%rsp)
+ movapd %xmm10, 4*16(%rsp)
+ movapd %xmm11, 5*16(%rsp)
+ movapd %xmm12, 6*16(%rsp)
+ movapd %xmm13, 7*16(%rsp)
+ movapd %xmm14, 8*16(%rsp)
+ movapd %xmm15, 9*16(%rsp)
+ /* Initial loading of arguments */
+ movq %rcx, %rsi /* closure */
+ movq %rdx, %rax /* first argument */
+ movq %r8, %rbx /* second argument */
+ movq %r9, %rdi /* third argument */
+#else
/* Save callee-save registers */
pushq %rbx
pushq %rbp
@@@ -586,13 -417,12 +586,13 @@@
pushq %r13
pushq %r14
pushq %r15
- subq $8, %rsp /* stack 16-aligned */
+ subq $8, %rsp /* stack 16-aligned */
/* Initial loading of arguments */
movq %rsi, %rax /* first argument */
movq %rdx, %rbx /* second argument */
movq %rdi, %rsi /* closure */
movq %rcx, %rdi /* third argument */
+#endif
leaq GCALL(caml_apply3)(%rip), %r12 /* code pointer */
jmp .Lcaml_start_program
@@@ -612,7 -442,7 +612,7 @@@ G(caml_system__frametable)
#ifdef SYS_macosx
.literal16
-#else
+#elif defined(SYS_linux)
.section .rodata.cst8,"a",@progbits
#endif
.globl G(caml_negf_mask)
diff --git a/ocaml/3.12/asmcomp/amd64/emit_mingw64.mlp b/ocaml/3.12/asmcomp/amd64/emit_mingw64.mlp
new file mode 100644
index 0000000..6bc0bdf
--- /dev/null
+++ b/ocaml/3.12/asmcomp/amd64/emit_mingw64.mlp
@@ -0,0 +1,791 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 1996 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id: emit.mlp 10488 2010-06-02 08:55:35Z xleroy $ *)
+
+(* Emission of x86-64 (AMD 64) assembly code *)
+
+open Misc
+open Cmm
+open Arch
+open Proc
+open Reg
+open Mach
+open Linearize
+open Emitaux
+
+let macosx =
+ match Config.system with
+ | "macosx" -> true
+ | _ -> false
+
+
+(* Tradeoff between code size and code speed *)
+
+let fastcode_flag = ref true
+
+let stack_offset = ref 0
+
+(* Layout of the stack frame *)
+
+let frame_required () =
+ !contains_calls || num_stack_slots.(0) > 0 || num_stack_slots.(1) > 0
+
+let frame_size () = (* includes return address *)
+ if frame_required() then begin
+ let sz =
+ (!stack_offset + 8 * (num_stack_slots.(0) + num_stack_slots.(1)) + 8)
+ in Misc.align sz 16
+ end else
+ !stack_offset + 8
+
+let slot_offset loc cl =
+ match loc with
+ Incoming n -> frame_size() + n
+ | Local n ->
+ if cl = 0
+ then !stack_offset + n * 8
+ else !stack_offset + (num_stack_slots.(0) + n) * 8
+ | Outgoing n -> n
+
+(* Symbols *)
+
+let emit_symbol s =
+ if macosx then emit_string "_";
+ Emitaux.emit_symbol '$' s
+
+let emit_call s =
+ `call {emit_symbol s}`
+
+let emit_jump s =
+ `jmp {emit_symbol s}`
+
+let load_symbol_addr s =
+ if !pic_code
+ then `leaq {emit_symbol s}(%rip)`
+ else `movq ${emit_symbol s}`
+
+(* Output a label *)
+
+let emit_label lbl =
+ emit_string ".L"; emit_int lbl
+
+(* Output a .align directive. *)
+
+let emit_align n =
+ let n = if macosx then Misc.log2 n else n in
+ ` .align {emit_int n}\n`
+
+let emit_Llabel fallthrough lbl =
+ if not fallthrough && !fastcode_flag then emit_align 4;
+ emit_label lbl
+
+(* Output a pseudo-register *)
+
+let emit_reg = function
+ { loc = Reg r } ->
+ emit_string (register_name r)
+ | { loc = Stack s } as r ->
+ let ofs = slot_offset s (register_class r) in
+ `{emit_int ofs}(%rsp)`
+ | { loc = Unknown } ->
+ assert false
+
+(* Output a reference to the lower 8, 16 or 32 bits of a register *)
+
+let reg_low_8_name =
+ [| "%al"; "%bl"; "%dil"; "%sil"; "%dl"; "%cl"; "%r8b"; "%r9b";
+ "%r10b"; "%r11b"; "%bpl"; "%r12b"; "%r13b" |]
+let reg_low_16_name =
+ [| "%ax"; "%bx"; "%di"; "%si"; "%dx"; "%cx"; "%r8w"; "%r9w";
+ "%r10w"; "%r11w"; "%bp"; "%r12w"; "%r13w" |]
+let reg_low_32_name =
+ [| "%eax"; "%ebx"; "%edi"; "%esi"; "%edx"; "%ecx"; "%r8d"; "%r9d";
+ "%r10d"; "%r11d"; "%ebp"; "%r12d"; "%r13d" |]
+
+let emit_subreg tbl r =
+ match r.loc with
+ Reg r when r < 13 ->
+ emit_string tbl.(r)
+ | Stack s ->
+ let ofs = slot_offset s (register_class r) in
+ `{emit_int ofs}(%rsp)`
+ | _ ->
+ assert false
+
+let emit_reg8 r = emit_subreg reg_low_8_name r
+let emit_reg16 r = emit_subreg reg_low_16_name r
+let emit_reg32 r = emit_subreg reg_low_32_name r
+
+(* Output an addressing mode *)
+
+let emit_addressing addr r n =
+ match addr with
+ | Ibased _ when !Clflags.dlcode -> assert false
+ | Ibased(s, d) ->
+ `{emit_symbol s}`;
+ if d <> 0 then ` + {emit_int d}`;
+ `(%rip)`
+ | Iindexed d ->
+ if d <> 0 then emit_int d;
+ `({emit_reg r.(n)})`
+ | Iindexed2 d ->
+ if d <> 0 then emit_int d;
+ `({emit_reg r.(n)}, {emit_reg r.(n+1)})`
+ | Iscaled(2, d) ->
+ if d <> 0 then emit_int d;
+ `({emit_reg r.(n)}, {emit_reg r.(n)})`
+ | Iscaled(scale, d) ->
+ if d <> 0 then emit_int d;
+ `(, {emit_reg r.(n)}, {emit_int scale})`
+ | Iindexed2scaled(scale, d) ->
+ if d <> 0 then emit_int d;
+ `({emit_reg r.(n)}, {emit_reg r.(n+1)}, {emit_int scale})`
+
+(* Record live pointers at call points -- see Emitaux *)
+
+let record_frame_label live dbg =
+ let lbl = new_label() in
+ let live_offset = ref [] in
+ Reg.Set.iter
+ (function
+ {typ = Addr; loc = Reg r} ->
+ live_offset := ((r lsl 1) + 1) :: !live_offset
+ | {typ = Addr; loc = Stack s} as reg ->
+ live_offset := slot_offset s (register_class reg) :: !live_offset
+ | _ -> ())
+ live;
+ frame_descriptors :=
+ { fd_lbl = lbl;
+ fd_frame_size = frame_size();
+ fd_live_offset = !live_offset;
+ fd_debuginfo = dbg } :: !frame_descriptors;
+ lbl
+
+let record_frame live dbg =
+ let lbl = record_frame_label live dbg in `{emit_label lbl}:\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: label } (* Label of frame descriptor *)
+
+let call_gc_sites = ref ([] : gc_call list)
+
+let emit_call_gc gc =
+ `{emit_label gc.gc_lbl}: {emit_call "caml_call_gc"}\n`;
+ `{emit_label gc.gc_frame}: jmp {emit_label gc.gc_return_lbl}\n`
+
+(* Record calls to caml_ml_array_bound_error.
+ In -g mode, we maintain one call to caml_ml_array_bound_error
+ per bound check site. Without -g, we can share a single call. *)
+
+type bound_error_call =
+ { bd_lbl: label; (* Entry label *)
+ bd_frame: label } (* Label of frame descriptor *)
+
+let bound_error_sites = ref ([] : bound_error_call list)
+let bound_error_call = ref 0
+
+let bound_error_label dbg =
+ if !Clflags.debug then begin
+ let lbl_bound_error = new_label() in
+ let lbl_frame = record_frame_label Reg.Set.empty dbg in
+ bound_error_sites :=
+ { bd_lbl = lbl_bound_error; bd_frame = lbl_frame } :: !bound_error_sites;
+ lbl_bound_error
+ end else begin
+ if !bound_error_call = 0 then bound_error_call := new_label();
+ !bound_error_call
+ end
+
+let emit_call_bound_error bd =
+ `{emit_label bd.bd_lbl}: {emit_call "caml_ml_array_bound_error"}\n`;
+ `{emit_label bd.bd_frame}:\n`
+
+let emit_call_bound_errors () =
+ List.iter emit_call_bound_error !bound_error_sites;
+ if !bound_error_call > 0 then
+ `{emit_label !bound_error_call}: {emit_call "caml_ml_array_bound_error"}\n`
+
+(* Names for instructions *)
+
+let instr_for_intop = function
+ Iadd -> "addq"
+ | Isub -> "subq"
+ | Imul -> "imulq"
+ | Iand -> "andq"
+ | Ior -> "orq"
+ | Ixor -> "xorq"
+ | Ilsl -> "salq"
+ | Ilsr -> "shrq"
+ | Iasr -> "sarq"
+ | _ -> assert false
+
+let instr_for_floatop = function
+ Iaddf -> "addsd"
+ | Isubf -> "subsd"
+ | Imulf -> "mulsd"
+ | Idivf -> "divsd"
+ | _ -> assert false
+
+let instr_for_floatarithmem = function
+ Ifloatadd -> "addsd"
+ | Ifloatsub -> "subsd"
+ | Ifloatmul -> "mulsd"
+ | Ifloatdiv -> "divsd"
+
+let name_for_cond_branch = function
+ Isigned Ceq -> "e" | Isigned Cne -> "ne"
+ | Isigned Cle -> "le" | Isigned Cgt -> "g"
+ | Isigned Clt -> "l" | Isigned Cge -> "ge"
+ | Iunsigned Ceq -> "e" | Iunsigned Cne -> "ne"
+ | Iunsigned Cle -> "be" | Iunsigned Cgt -> "a"
+ | Iunsigned Clt -> "b" | Iunsigned Cge -> "ae"
+
+(* Output an = 0 or <> 0 test. *)
+
+let output_test_zero arg =
+ match arg.loc with
+ Reg r -> ` testq {emit_reg arg}, {emit_reg arg}\n`
+ | _ -> ` cmpq $0, {emit_reg arg}\n`
+
+(* Output a floating-point compare and branch *)
+
+let emit_float_test cmp neg arg lbl =
+ (* Effect of comisd on flags and conditional branches:
+ ZF PF CF cond. branches taken
+ unordered 1 1 1 je, jb, jbe, jp
+ > 0 0 0 jne, jae, ja
+ < 0 0 1 jne, jbe, jb
+ = 1 0 0 je, jae, jbe.
+ If FP traps are on (they are off by default),
+ comisd traps on QNaN and SNaN but ucomisd traps on SNaN only.
+ *)
+ match (cmp, neg) with
+ | (Ceq, false) | (Cne, true) ->
+ let next = new_label() in
+ ` ucomisd {emit_reg arg.(1)}, {emit_reg arg.(0)}\n`;
+ ` jp {emit_label next}\n`; (* skip if unordered *)
+ ` je {emit_label lbl}\n`; (* branch taken if x=y *)
+ `{emit_label next}:\n`
+ | (Cne, false) | (Ceq, true) ->
+ ` ucomisd {emit_reg arg.(1)}, {emit_reg arg.(0)}\n`;
+ ` jp {emit_label lbl}\n`; (* branch taken if unordered *)
+ ` jne {emit_label lbl}\n` (* branch taken if x<y or x>y *)
+ | (Clt, _) ->
+ ` comisd {emit_reg arg.(0)}, {emit_reg arg.(1)}\n`; (* swap compare *)
+ if not neg then
+ ` ja {emit_label lbl}\n` (* branch taken if y>x i.e. x<y *)
+ else
+ ` jbe {emit_label lbl}\n` (* taken if unordered or y<=x i.e. !(x<y) *)
+ | (Cle, _) ->
+ ` comisd {emit_reg arg.(0)}, {emit_reg arg.(1)}\n`; (* swap compare *)
+ if not neg then
+ ` jae {emit_label lbl}\n` (* branch taken if y>=x i.e. x<=y *)
+ else
+ ` jb {emit_label lbl}\n` (* taken if unordered or y<x i.e. !(x<=y) *)
+ | (Cgt, _) ->
+ ` comisd {emit_reg arg.(1)}, {emit_reg arg.(0)}\n`;
+ if not neg then
+ ` ja {emit_label lbl}\n` (* branch taken if x>y *)
+ else
+ ` jbe {emit_label lbl}\n` (* taken if unordered or x<=y i.e. !(x>y) *)
+ | (Cge, _) ->
+ ` comisd {emit_reg arg.(1)}, {emit_reg arg.(0)}\n`; (* swap compare *)
+ if not neg then
+ ` jae {emit_label lbl}\n` (* branch taken if x>=y *)
+ else
+ ` jb {emit_label lbl}\n` (* taken if unordered or x<y i.e. !(x>=y) *)
+
+(* Deallocate the stack frame before a return or tail call *)
+
+let output_epilogue () =
+ if frame_required() then begin
+ let n = frame_size() - 8 in
+ ` addq ${emit_int n}, %rsp\n`
+ end
+
+(* Output the assembly code for an instruction *)
+
+(* Name of current function *)
+let function_name = ref ""
+(* Entry point for tail recursive calls *)
+let tailrec_entry_point = ref 0
+
+let float_constants = ref ([] : (int * string) list)
+
+let emit_instr fallthrough 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
+ if src.typ = Float then
+ ` movsd {emit_reg src}, {emit_reg dst}\n`
+ else
+ ` movq {emit_reg src}, {emit_reg dst}\n`
+ end
+ | Lop(Iconst_int n) ->
+ if n = 0n then begin
+ match i.res.(0).loc with
+ Reg n -> ` xorq {emit_reg i.res.(0)}, {emit_reg i.res.(0)}\n`
+ | _ -> ` movq $0, {emit_reg i.res.(0)}\n`
+ end else if n <= 0x7FFFFFFFn && n >= -0x80000000n then
+ ` movq ${emit_nativeint n}, {emit_reg i.res.(0)}\n`
+ else
+ ` movabsq ${emit_nativeint n}, {emit_reg i.res.(0)}\n`
+ | Lop(Iconst_float s) ->
+ begin match Int64.bits_of_float (float_of_string s) with
+ | 0x0000_0000_0000_0000L -> (* +0.0 *)
+ ` xorpd {emit_reg i.res.(0)}, {emit_reg i.res.(0)}\n`
+ | _ ->
+ let lbl = new_label() in
+ float_constants := (lbl, s) :: !float_constants;
+ ` movlpd {emit_label lbl}(%rip), {emit_reg i.res.(0)}\n`
+ end
+ | Lop(Iconst_symbol s) ->
+ ` {load_symbol_addr s}, {emit_reg i.res.(0)}\n`
+ | Lop(Icall_ind) ->
+ ` call *{emit_reg i.arg.(0)}\n`;
+ record_frame i.live i.dbg
+ | Lop(Icall_imm(s)) ->
+ ` {emit_call s}\n`;
+ record_frame i.live i.dbg
+ | Lop(Itailcall_ind) ->
+ output_epilogue();
+ ` jmp *{emit_reg i.arg.(0)}\n`
+ | Lop(Itailcall_imm s) ->
+ if s = !function_name then
+ ` jmp {emit_label !tailrec_entry_point}\n`
+ else begin
+ output_epilogue();
+ ` {emit_jump s}\n`
+ end
+ | Lop(Iextcall(s, alloc)) ->
+ if alloc then begin
+ ` {load_symbol_addr s}, %rax\n`;
+ ` {emit_call "caml_c_call"}\n`;
+ record_frame i.live i.dbg
+ end else begin
+ ` {emit_call s}\n`
+ end
+ | Lop(Istackoffset n) ->
+ if n < 0
+ then ` addq ${emit_int(-n)}, %rsp\n`
+ else ` subq ${emit_int(n)}, %rsp\n`;
+ stack_offset := !stack_offset + n
+ | Lop(Iload(chunk, addr)) ->
+ let dest = i.res.(0) in
+ begin match chunk with
+ | Word ->
+ ` movq {emit_addressing addr i.arg 0}, {emit_reg dest}\n`
+ | Byte_unsigned ->
+ ` movzbq {emit_addressing addr i.arg 0}, {emit_reg dest}\n`
+ | Byte_signed ->
+ ` movsbq {emit_addressing addr i.arg 0}, {emit_reg dest}\n`
+ | Sixteen_unsigned ->
+ ` movzwq {emit_addressing addr i.arg 0}, {emit_reg dest}\n`
+ | Sixteen_signed ->
+ ` movswq {emit_addressing addr i.arg 0}, {emit_reg dest}\n`
+ | Thirtytwo_unsigned ->
+ ` movl {emit_addressing addr i.arg 0}, {emit_reg32 dest}\n`
+ | Thirtytwo_signed ->
+ ` movslq {emit_addressing addr i.arg 0}, {emit_reg dest}\n`
+ | Single ->
+ ` cvtss2sd {emit_addressing addr i.arg 0}, {emit_reg dest}\n`
+ | Double | Double_u ->
+ ` movlpd {emit_addressing addr i.arg 0}, {emit_reg dest}\n`
+ end
+ | Lop(Istore(chunk, addr)) ->
+ begin match chunk with
+ | Word ->
+ ` movq {emit_reg i.arg.(0)}, {emit_addressing addr i.arg 1}\n`
+ | Byte_unsigned | Byte_signed ->
+ ` movb {emit_reg8 i.arg.(0)}, {emit_addressing addr i.arg 1}\n`
+ | Sixteen_unsigned | Sixteen_signed ->
+ ` movw {emit_reg16 i.arg.(0)}, {emit_addressing addr i.arg 1}\n`
+ | Thirtytwo_signed | Thirtytwo_unsigned ->
+ ` movl {emit_reg32 i.arg.(0)}, {emit_addressing addr i.arg 1}\n`
+ | Single ->
+ ` cvtsd2ss {emit_reg i.arg.(0)}, %xmm15\n`;
+ ` movss %xmm15, {emit_addressing addr i.arg 1}\n`
+ | Double | Double_u ->
+ ` movlpd {emit_reg i.arg.(0)}, {emit_addressing addr i.arg 1}\n`
+ end
+ | Lop(Ialloc n) ->
+ if !fastcode_flag then begin
+ let lbl_redo = new_label() in
+ `{emit_label lbl_redo}: subq ${emit_int n}, %r15\n`;
+ if !Clflags.dlcode then begin
+ ` {load_symbol_addr "caml_young_limit"}, %rax\n`;
+ ` cmpq (%rax), %r15\n`;
+ end else
+ ` cmpq {emit_symbol "caml_young_limit"}(%rip), %r15\n`;
+ let lbl_call_gc = new_label() in
+ let lbl_frame = record_frame_label i.live Debuginfo.none in
+ ` jb {emit_label lbl_call_gc}\n`;
+ ` leaq 8(%r15), {emit_reg i.res.(0)}\n`;
+ call_gc_sites :=
+ { gc_lbl = lbl_call_gc;
+ gc_return_lbl = lbl_redo;
+ gc_frame = lbl_frame } :: !call_gc_sites
+ end else begin
+ begin match n with
+ 16 -> ` {emit_call "caml_alloc1"}\n`
+ | 24 -> ` {emit_call "caml_alloc2"}\n`
+ | 32 -> ` {emit_call "caml_alloc3"}\n`
+ | _ -> ` movq ${emit_int n}, %rax\n`;
+ ` {emit_call "caml_allocN"}\n`
+ end;
+ `{record_frame i.live Debuginfo.none} leaq 8(%r15), {emit_reg i.res.(0)}\n`
+ end
+ | Lop(Iintop(Icomp cmp)) ->
+ ` cmpq {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n`;
+ let b = name_for_cond_branch cmp in
+ ` set{emit_string b} %al\n`;
+ ` movzbq %al, {emit_reg i.res.(0)}\n`
+ | Lop(Iintop_imm(Icomp cmp, n)) ->
+ ` cmpq ${emit_int n}, {emit_reg i.arg.(0)}\n`;
+ let b = name_for_cond_branch cmp in
+ ` set{emit_string b} %al\n`;
+ ` movzbq %al, {emit_reg i.res.(0)}\n`
+ | Lop(Iintop Icheckbound) ->
+ let lbl = bound_error_label i.dbg in
+ ` cmpq {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n`;
+ ` jbe {emit_label lbl}\n`
+ | Lop(Iintop_imm(Icheckbound, n)) ->
+ let lbl = bound_error_label i.dbg in
+ ` cmpq ${emit_int n}, {emit_reg i.arg.(0)}\n`;
+ ` jbe {emit_label lbl}\n`
+ | Lop(Iintop(Idiv | Imod)) ->
+ ` cqto\n`;
+ ` idivq {emit_reg i.arg.(1)}\n`
+ | Lop(Iintop(Ilsl | Ilsr | Iasr as op)) ->
+ (* We have i.arg.(0) = i.res.(0) and i.arg.(1) = %rcx *)
+ ` {emit_string(instr_for_intop op)} %cl, {emit_reg i.res.(0)}\n`
+ | Lop(Iintop op) ->
+ (* We have i.arg.(0) = i.res.(0) *)
+ ` {emit_string(instr_for_intop op)} {emit_reg i.arg.(1)}, {emit_reg i.res.(0)}\n`
+ | Lop(Iintop_imm(Iadd, n)) when i.arg.(0).loc <> i.res.(0).loc ->
+ ` leaq {emit_int n}({emit_reg i.arg.(0)}), {emit_reg i.res.(0)}\n`
+ | Lop(Iintop_imm(Iadd, 1) | Iintop_imm(Isub, -1)) ->
+ ` incq {emit_reg i.res.(0)}\n`
+ | Lop(Iintop_imm(Iadd, -1) | Iintop_imm(Isub, 1)) ->
+ ` decq {emit_reg i.res.(0)}\n`
+ | Lop(Iintop_imm(Idiv, n)) ->
+ (* Note: i.arg.(0) = i.res.(0) = rdx (cf. selection.ml) *)
+ let l = Misc.log2 n in
+ ` movq {emit_reg i.arg.(0)}, %rax\n`;
+ ` addq ${emit_int(n-1)}, {emit_reg i.arg.(0)}\n`;
+ ` testq %rax, %rax\n`;
+ ` cmovns %rax, {emit_reg i.arg.(0)}\n`;
+ ` sarq ${emit_int l}, {emit_reg i.res.(0)}\n`
+ | Lop(Iintop_imm(Imod, n)) ->
+ (* Note: i.arg.(0) = i.res.(0) = rdx (cf. selection.ml) *)
+ ` movq {emit_reg i.arg.(0)}, %rax\n`;
+ ` testq %rax, %rax\n`;
+ ` leaq {emit_int(n-1)}(%rax), %rax\n`;
+ ` cmovns {emit_reg i.arg.(0)}, %rax\n`;
+ ` andq ${emit_int (-n)}, %rax\n`;
+ ` subq %rax, {emit_reg i.res.(0)}\n`
+ | Lop(Iintop_imm(op, n)) ->
+ (* We have i.arg.(0) = i.res.(0) *)
+ ` {emit_string(instr_for_intop op)} ${emit_int n}, {emit_reg i.res.(0)}\n`
+ | Lop(Inegf) ->
+ ` xorpd {emit_symbol "caml_negf_mask"}(%rip), {emit_reg i.res.(0)}\n`
+ | Lop(Iabsf) ->
+ ` andpd {emit_symbol "caml_absf_mask"}(%rip), {emit_reg i.res.(0)}\n`
+ | Lop(Iaddf | Isubf | Imulf | Idivf as floatop) ->
+ ` {emit_string(instr_for_floatop floatop)} {emit_reg i.arg.(1)}, {emit_reg i.res.(0)}\n`
+ | Lop(Ifloatofint) ->
+ ` cvtsi2sdq {emit_reg i.arg.(0)}, {emit_reg i.res.(0)}\n`
+ | Lop(Iintoffloat) ->
+ ` cvttsd2siq {emit_reg i.arg.(0)}, {emit_reg i.res.(0)}\n`
+ | Lop(Ispecific(Ilea addr)) ->
+ ` leaq {emit_addressing addr i.arg 0}, {emit_reg i.res.(0)}\n`
+ | Lop(Ispecific(Istore_int(n, addr))) ->
+ ` movq ${emit_nativeint n}, {emit_addressing addr i.arg 0}\n`
+ | Lop(Ispecific(Istore_symbol(s, addr))) ->
+ assert (not !pic_code && not !Clflags.dlcode);
+ ` movq ${emit_symbol s}, {emit_addressing addr i.arg 0}\n`
+ | Lop(Ispecific(Ioffset_loc(n, addr))) ->
+ ` addq ${emit_int n}, {emit_addressing addr i.arg 0}\n`
+ | Lop(Ispecific(Ifloatarithmem(op, addr))) ->
+ ` {emit_string(instr_for_floatarithmem op)} {emit_addressing addr i.arg 1}, {emit_reg i.res.(0)}\n`
+ | Lreloadretaddr ->
+ ()
+ | Lreturn ->
+ output_epilogue();
+ ` ret\n`
+ | Llabel lbl ->
+ `{emit_Llabel fallthrough lbl}:\n`
+ | Lbranch lbl ->
+ ` jmp {emit_label lbl}\n`
+ | Lcondbranch(tst, lbl) ->
+ begin match tst with
+ Itruetest ->
+ output_test_zero i.arg.(0);
+ ` jne {emit_label lbl}\n`
+ | Ifalsetest ->
+ output_test_zero i.arg.(0);
+ ` je {emit_label lbl}\n`
+ | Iinttest cmp ->
+ ` cmpq {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n`;
+ let b = name_for_cond_branch cmp in
+ ` j{emit_string b} {emit_label lbl}\n`
+ | Iinttest_imm((Isigned Ceq | Isigned Cne |
+ Iunsigned Ceq | Iunsigned Cne) as cmp, 0) ->
+ output_test_zero i.arg.(0);
+ let b = name_for_cond_branch cmp in
+ ` j{emit_string b} {emit_label lbl}\n`
+ | Iinttest_imm(cmp, n) ->
+ ` cmpq ${emit_int n}, {emit_reg i.arg.(0)}\n`;
+ let b = name_for_cond_branch cmp in
+ ` j{emit_string b} {emit_label lbl}\n`
+ | Ifloattest(cmp, neg) ->
+ emit_float_test cmp neg i.arg lbl
+ | Ioddtest ->
+ ` testb $1, {emit_reg8 i.arg.(0)}\n`;
+ ` jne {emit_label lbl}\n`
+ | Ieventest ->
+ ` testb $1, {emit_reg8 i.arg.(0)}\n`;
+ ` je {emit_label lbl}\n`
+ end
+ | Lcondbranch3(lbl0, lbl1, lbl2) ->
+ ` cmpq $1, {emit_reg i.arg.(0)}\n`;
+ begin match lbl0 with
+ None -> ()
+ | Some lbl -> ` jb {emit_label lbl}\n`
+ end;
+ begin match lbl1 with
+ None -> ()
+ | Some lbl -> ` je {emit_label lbl}\n`
+ end;
+ begin match lbl2 with
+ None -> ()
+ | Some lbl -> ` jg {emit_label lbl}\n`
+ end
+ | Lswitch jumptbl ->
+ let lbl = new_label() in
+ (* rax and rdx are clobbered by the Lswitch,
+ meaning that no variable that is live across the Lswitch
+ is assigned to rax or rdx. However, the argument to Lswitch
+ can still be assigned to one of these two registers, so
+ we must be careful not to clobber it before use. *)
+ let (tmp1, tmp2) =
+ if i.arg.(0).loc = Reg 0 (* rax *)
+ then (phys_reg 4 (*rdx*), phys_reg 0 (*rax*))
+ else (phys_reg 0 (*rax*), phys_reg 4 (*rdx*)) in
+ ` leaq {emit_label lbl}(%rip), {emit_reg tmp1}\n`;
+ ` movslq ({emit_reg tmp1}, {emit_reg i.arg.(0)}, 4), {emit_reg tmp2}\n`;
+ ` addq {emit_reg tmp2}, {emit_reg tmp1}\n`;
+ ` jmp *{emit_reg tmp1}\n`;
+ if macosx
+ then ` .const\n`
+ else ` .section .rodata\n`;
+ emit_align 4;
+ `{emit_label lbl}:`;
+ for i = 0 to Array.length jumptbl - 1 do
+ ` .long {emit_label jumptbl.(i)} - {emit_label lbl}\n`
+ done;
+ ` .text\n`
+ | Lsetuptrap lbl ->
+ ` call {emit_label lbl}\n`
+ | Lpushtrap ->
+ ` pushq %r14\n`;
+ ` movq %rsp, %r14\n`;
+ stack_offset := !stack_offset + 16
+ | Lpoptrap ->
+ ` popq %r14\n`;
+ ` addq $8, %rsp\n`;
+ stack_offset := !stack_offset - 16
+ | Lraise ->
+ if !Clflags.debug then begin
+ ` {emit_call "caml_raise_exn"}\n`;
+ record_frame Reg.Set.empty i.dbg
+ end else begin
+ ` movq %r14, %rsp\n`;
+ ` popq %r14\n`;
+ ` ret\n`
+ end
+
+let rec emit_all fallthrough i =
+ match i.desc with
+ | Lend -> ()
+ | _ ->
+ emit_instr fallthrough i;
+ emit_all (Linearize.has_fallthrough i.desc) i.next
+
+(* Emission of the floating-point constants *)
+
+let emit_float_constant (lbl, cst) =
+ `{emit_label lbl}:`;
+ emit_float64_directive ".quad" cst
+
+(* Emission of the profiling prelude *)
+
+let emit_profile () =
+ match Config.system with
+ | "linux" | "gnu" ->
+ (* mcount preserves rax, rcx, rdx, rsi, rdi, r8, r9 explicitly
+ and rbx, rbp, r12-r15 like all C functions.
+ We need to preserve r10 and r11 ourselves, since Caml can
+ use them for argument passing. *)
+ ` pushq %r10\n`;
+ ` movq %rsp, %rbp\n`;
+ ` pushq %r11\n`;
+ ` {emit_call "mcount"}\n`;
+ ` popq %r11\n`;
+ ` popq %r10\n`
+ | _ ->
+ () (*unsupported yet*)
+
+(* Emission of a function declaration *)
+
+let fundecl fundecl =
+ function_name := fundecl.fun_name;
+ fastcode_flag := fundecl.fun_fast;
+ tailrec_entry_point := new_label();
+ stack_offset := 0;
+ float_constants := [];
+ call_gc_sites := [];
+ bound_error_sites := [];
+ bound_error_call := 0;
+ ` .text\n`;
+ emit_align 16;
+ if macosx
+ && not !Clflags.output_c_object
+ && is_generic_function fundecl.fun_name
+ then (* PR#4690 *)
+ ` .private_extern {emit_symbol fundecl.fun_name}\n`
+ else
+ ` .globl {emit_symbol fundecl.fun_name}\n`;
+ `{emit_symbol fundecl.fun_name}:\n`;
+ if !Clflags.gprofile then emit_profile();
+ if frame_required() then begin
+ let n = frame_size() - 8 in
+ ` subq ${emit_int n}, %rsp\n`
+ end;
+ `{emit_label !tailrec_entry_point}:\n`;
+ emit_all true fundecl.fun_body;
+ List.iter emit_call_gc !call_gc_sites;
+ emit_call_bound_errors ();
+ if !float_constants <> [] then begin
+ if macosx
+ then ` .literal8\n`
+ else ` .section .rodata.cst8,\"a\"\n`;
+ List.iter emit_float_constant !float_constants
+ end;
+ match Config.system with
+ "linux" | "gnu" ->
+ ` .size {emit_symbol fundecl.fun_name},.-{emit_symbol fundecl.fun_name}\n`
+ | _ -> ()
+
+(* Emission of data *)
+
+let emit_item = function
+ Cglobal_symbol s ->
+ ` .globl {emit_symbol s}\n`;
+ | Cdefine_symbol s ->
+ `{emit_symbol s}:\n`
+ | Cdefine_label lbl ->
+ `{emit_label (100000 + lbl)}:\n`
+ | Cint8 n ->
+ ` .byte {emit_int n}\n`
+ | Cint16 n ->
+ ` .word {emit_int n}\n`
+ | Cint32 n ->
+ ` .long {emit_nativeint n}\n`
+ | Cint n ->
+ ` .quad {emit_nativeint n}\n`
+ | Csingle f ->
+ emit_float32_directive ".long" f
+ | Cdouble f ->
+ emit_float64_directive ".quad" f
+ | Csymbol_address s ->
+ ` .quad {emit_symbol s}\n`
+ | Clabel_address lbl ->
+ ` .quad {emit_label (100000 + lbl)}\n`
+ | Cstring s ->
+ emit_string_directive " .ascii " s
+ | Cskip n ->
+ if n > 0 then ` .space {emit_int n}\n`
+ | Calign n ->
+ emit_align n
+
+let data l =
+ ` .data\n`;
+ List.iter emit_item l
+
+(* Beginning / end of an assembly file *)
+
+let begin_assembly() =
+ if !Clflags.dlcode then begin
+ (* from amd64.S; could emit these constants on demand *)
+ if macosx then
+ ` .literal16\n`
+ else
+ ` .section .rodata.cst8,\"a\"\n`;
+ emit_align 16;
+ `{emit_symbol "caml_negf_mask"}: .quad 0x8000000000000000, 0\n`;
+ emit_align 16;
+ `{emit_symbol "caml_absf_mask"}: .quad 0x7FFFFFFFFFFFFFFF, 0xFFFFFFFFFFFFFFFF\n`
+ end;
+ let lbl_begin = Compilenv.make_symbol (Some "data_begin") in
+ ` .data\n`;
+ ` .globl {emit_symbol lbl_begin}\n`;
+ `{emit_symbol lbl_begin}:\n`;
+ let lbl_begin = Compilenv.make_symbol (Some "code_begin") in
+ ` .text\n`;
+ ` .globl {emit_symbol lbl_begin}\n`;
+ `{emit_symbol lbl_begin}:\n`;
+ if macosx then ` nop\n` (* PR#4690 *)
+
+let end_assembly() =
+ let lbl_end = Compilenv.make_symbol (Some "code_end") in
+ ` .text\n`;
+ if macosx then ` nop\n`; (* suppress "ld warning: atom sorting error" *)
+ ` .globl {emit_symbol lbl_end}\n`;
+ `{emit_symbol lbl_end}:\n`;
+ ` .data\n`;
+ let lbl_end = Compilenv.make_symbol (Some "data_end") in
+ ` .globl {emit_symbol lbl_end}\n`;
+ `{emit_symbol lbl_end}:\n`;
+ ` .long 0\n`;
+ let lbl = Compilenv.make_symbol (Some "frametable") in
+ ` .globl {emit_symbol lbl}\n`;
+ `{emit_symbol lbl}:\n`;
+ emit_frames
+ { efa_label = (fun l -> ` .quad {emit_label l}\n`);
+ efa_16 = (fun n -> ` .word {emit_int n}\n`);
+ efa_32 = (fun n -> ` .long {emit_int32 n}\n`);
+ efa_word = (fun n -> ` .quad {emit_int n}\n`);
+ efa_align = emit_align;
+ efa_label_rel =
+ if macosx then begin
+ let setcnt = ref 0 in
+ fun lbl ofs ->
+ incr setcnt;
+ ` .set L$set${emit_int !setcnt}, ({emit_label lbl} - .) + {emit_int32 ofs}\n`;
+ ` .long L$set${emit_int !setcnt}\n`
+ end else begin
+ fun lbl ofs ->
+ ` .long ({emit_label lbl} - .) + {emit_int32 ofs}\n`
+ end;
+ efa_def_label = (fun l -> `{emit_label l}:\n`);
+ efa_string = (fun s -> emit_string_directive " .asciz " s) };
+ if Config.system = "linux" then
+ (* Mark stack as non-executable, PR#4564 *)
+ ` .section .note.GNU-stack,\"\"\n`
diff --git a/ocaml/3.12/asmcomp/amd64/proc_mingw64.ml b/ocaml/3.12/asmcomp/amd64/proc_mingw64.ml
new file mode 100644
index 0000000..338e169
--- /dev/null
+++ b/ocaml/3.12/asmcomp/amd64/proc_mingw64.ml
@@ -0,0 +1,233 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 2000 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id: proc.ml 9547 2010-01-22 12:48:24Z doligez $ *)
+
+(* Description of the AMD64 processor with Win64 conventions *)
+
+open Misc
+open Arch
+open Cmm
+open Reg
+open Mach
+
+(* Registers available for register allocation *)
+
+(* Register map:
+ rax 0 rax - r11: Caml function arguments
+ rbx 1 rcx - r9: C function arguments
+ rdi 2 rax: Caml and C function results
+ rsi 3 rbx, rbp, rsi, rdi r12-r15 are preserved by C
+ rdx 4
+ rcx 5
+ r8 6
+ r9 7
+ r10 8
+ r11 9
+ rbp 10
+ r12 11
+ r13 12
+ r14 trap pointer
+ r15 allocation pointer
+
+ xmm0 - xmm15 100 - 115 xmm0 - xmm9: Caml function arguments
+ xmm0 - xmm3: C function arguments
+ xmm0: Caml and C function results
+ xmm6-xmm15 are preserved by C *)
+
+let int_reg_name =
+ [| "%rax"; "%rbx"; "%rdi"; "%rsi"; "%rdx"; "%rcx"; "%r8"; "%r9";
+ "%r10"; "%r11"; "%rbp"; "%r12"; "%r13" |]
+
+let float_reg_name =
+ [| "%xmm0"; "%xmm1"; "%xmm2"; "%xmm3"; "%xmm4"; "%xmm5"; "%xmm6"; "%xmm7";
+ "%xmm8"; "%xmm9"; "%xmm10"; "%xmm11";
+ "%xmm12"; "%xmm13"; "%xmm14"; "%xmm15" |]
+
+let num_register_classes = 2
+
+let register_class r =
+ match r.typ with
+ Int -> 0
+ | Addr -> 0
+ | Float -> 1
+
+let num_available_registers = [| 13; 16 |]
+
+let first_available_register = [| 0; 100 |]
+
+let register_name r =
+ if r < 100 then int_reg_name.(r) else float_reg_name.(r - 100)
+
+(* Pack registers starting at %rax so as to reduce the number of REX
+ prefixes and thus improve code density *)
+let rotate_registers = false
+
+(* Representation of hard registers by pseudo-registers *)
+
+let hard_int_reg =
+ let v = Array.create 13 Reg.dummy in
+ for i = 0 to 12 do v.(i) <- Reg.at_location Int (Reg i) done;
+ v
+
+let hard_float_reg =
+ let v = Array.create 16 Reg.dummy in
+ for i = 0 to 15 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 rax = phys_reg 0
+let rcx = phys_reg 5
+let rdx = phys_reg 4
+let r11 = phys_reg 9
+let rxmm15 = phys_reg 115
+
+let stack_slot slot ty =
+ Reg.at_location ty (Stack slot)
+
+(* Instruction selection *)
+
+let word_addressed = false
+
+(* Calling conventions *)
+
+let calling_conventions first_int last_int first_float last_float make_stack
+ arg =
+ let loc = Array.create (Array.length arg) Reg.dummy in
+ let int = ref first_int in
+ let float = ref first_float in
+ let ofs = ref 0 in
+ for i = 0 to Array.length arg - 1 do
+ match arg.(i).typ with
+ Int | Addr as ty ->
+ if !int <= last_int then begin
+ loc.(i) <- phys_reg !int;
+ incr int
+ end else begin
+ loc.(i) <- stack_slot (make_stack !ofs) ty;
+ ofs := !ofs + size_int
+ end
+ | Float ->
+ if !float <= last_float then begin
+ loc.(i) <- phys_reg !float;
+ incr float
+ end else begin
+ loc.(i) <- stack_slot (make_stack !ofs) Float;
+ ofs := !ofs + size_float
+ end
+ done;
+ (loc, Misc.align !ofs 16) (* keep stack 16-aligned *)
+
+let incoming ofs = Incoming ofs
+let outgoing ofs = Outgoing ofs
+let not_supported ofs = fatal_error "Proc.loc_results: cannot call"
+
+let loc_arguments arg =
+ calling_conventions 0 9 100 109 outgoing arg
+let loc_parameters arg =
+ let (loc, ofs) = calling_conventions 0 9 100 109 incoming arg in loc
+let loc_results res =
+ let (loc, ofs) = calling_conventions 0 0 100 100 not_supported res in loc
+
+(* C calling conventions (Win64):
+ first integer args in rcx, rdx, r8, r9 (4 - 7)
+ first float args in xmm0 ... xmm3 (100 - 103)
+ each integer arg consumes a float reg, and conversely
+ remaining args on stack
+ always 32 bytes reserved at bottom of stack.
+ Return value in rax or xmm0
+*)
+
+let loc_external_results res =
+ let (loc, ofs) = calling_conventions 0 0 100 100 not_supported res in loc
+
+let int_external_arguments =
+ [| 5 (*rcx*); 4 (*rdx*); 6 (*r8*); 7 (*r9*) |]
+let float_external_arguments =
+ [| 100 (*xmm0*); 101 (*xmm1*); 102 (*xmm2*); 103 (*xmm3*) |]
+
+let loc_external_arguments arg =
+ let loc = Array.create (Array.length arg) Reg.dummy in
+ let reg = ref 0
+ and ofs = ref 32 in
+ for i = 0 to Array.length arg - 1 do
+ match arg.(i).typ with
+ Int | Addr as ty ->
+ if !reg < 4 then begin
+ loc.(i) <- phys_reg int_external_arguments.(!reg);
+ incr reg
+ end else begin
+ loc.(i) <- stack_slot (Outgoing !ofs) ty;
+ ofs := !ofs + size_int
+ end
+ | Float ->
+ if !reg < 4 then begin
+ loc.(i) <- phys_reg float_external_arguments.(!reg);
+ incr reg
+ end else begin
+ loc.(i) <- stack_slot (Outgoing !ofs) Float;
+ ofs := !ofs + size_float
+ end
+ done;
+ (loc, Misc.align !ofs 16) (* keep stack 16-aligned *)
+
+let loc_exn_bucket = rax
+
+(* Registers destroyed by operations *)
+
+let destroyed_at_c_call =
+ (* Win64: rbx, rbp, rsi, rdi, r12-r15, xmm6-xmm15 preserved *)
+ Array.of_list(List.map phys_reg
+ [0;4;5;6;7;8;9;
+ 100;101;102;103;104;105])
+
+let destroyed_at_oper = function
+ Iop(Icall_ind | Icall_imm _ | Iextcall(_, true)) -> all_phys_regs
+ | Iop(Iextcall(_, false)) -> destroyed_at_c_call
+ | Iop(Iintop(Idiv | Imod)) -> [| rax; rdx |]
+ | Iop(Istore(Single, _)) -> [| rxmm15 |]
+ | Iop(Ialloc _ | Iintop(Icomp _) | Iintop_imm((Idiv|Imod|Icomp _), _))
+ -> [| rax |]
+ | Iswitch(_, _) when !pic_code -> [| r11 |]
+ | _ -> [||]
+
+let destroyed_at_raise = all_phys_regs
+
+(* Maximal register pressure *)
+
+let safe_register_pressure = function
+ Iextcall(_,_) -> 8
+ | _ -> 11
+
+let max_register_pressure = function
+ Iextcall(_, _) -> [| 8; 10 |]
+ | Iintop(Idiv | Imod) -> [| 11; 16 |]
+ | Ialloc _ | Iintop(Icomp _) | Iintop_imm((Idiv|Imod|Icomp _), _)
+ -> [| 12; 16 |]
+ | Istore(Single, _) -> [| 13; 15 |]
+ | _ -> [| 13; 16 |]
+
+(* Layout of the stack frame *)
+
+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)
diff --git a/ocaml/3.12/build.sh b/ocaml/3.12/build.sh
new file mode 100755
index 0000000..a26083e
--- /dev/null
+++ b/ocaml/3.12/build.sh
@@ -0,0 +1,15 @@
+# fix settings
+cp config/m-nt.h config/m.h || exit 1
+cp config/s-nt.h config/s.h || exit 1
+cp config/Makefile.mingw64 config/Makefile || exit 1
+
+# fix asmcomp
+cp asmcomp/amd64/emit_mingw64.mlp asmcomp/amd64/emit.mlp || exit 1
+cp asmcomp/amd64/proc_mingw64.ml asmcomp/amd64/proc.ml || exit 1
+
+# run make
+gmake -f Makefile.nt world || exit 1
+gmake -f Makefile.nt bootstrap || exit 1
+gmake -f Makefile.nt opt || exit 1
+gmake -f Makefile.nt opt.opt || exit 1
+gmake -f Makefile.nt install || exit 1
\ No newline at end of file
diff --git a/ocaml/3.12/config/Makefile.mingw64 b/ocaml/3.12/config/Makefile.mingw64
new file mode 100644
index 0000000..cf17d41
--- /dev/null
+++ b/ocaml/3.12/config/Makefile.mingw64
@@ -0,0 +1,158 @@
+#########################################################################
+# #
+# Objective Caml #
+# #
+# Xavier Leroy, projet Cristal, INRIA Rocquencourt #
+# #
+# Copyright 1999 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: Makefile.mingw 10461 2010-05-25 10:00:39Z frisch $
+
+# Configuration for Windows, Mingw compiler
+
+######### General configuration
+
+PREFIX=C:/ocamlmgw
+
+### Where to install the binaries
+BINDIR=$(PREFIX)/bin
+
+### Where to install the standard library
+LIBDIR=$(PREFIX)/lib
+
+### Where to install the stub DLLs
+STUBLIBDIR=$(LIBDIR)/stublibs
+
+### Where to install the info files
+DISTRIB=$(PREFIX)
+
+### Where to install the man pages
+MANDIR=$(PREFIX)/man
+
+########## Toolchain and OS dependencies
+
+TOOLCHAIN=mingw
+CCOMPTYPE=cc
+O=o
+A=a
+S=s
+SO=s.o
+DO=d.o
+EXE=.exe
+EXT_DLL=.dll
+EXT_OBJ=.$(O)
+EXT_LIB=.$(A)
+EXT_ASM=.$(S)
+MANEXT=1
+SHARPBANGSCRIPTS=false
+PTHREAD_LINK=
+X11_INCLUDES=
+X11_LINK=
+DBM_INCLUDES=
+DBM_LINK=
+BYTECCRPATH=
+SUPPORTS_SHARED_LIBRARIES=true
+SHAREDCCCOMPOPTS=
+MKSHAREDLIBRPATH=
+NATIVECCPROFOPTS=
+NATIVECCRPATH=
+ASM=as
+ASPP=gcc
+ASPPPROFFLAGS=
+PROFILING=noprof
+DYNLINKOPTS=
+DEBUGGER=ocamldebugger
+CC_PROFILE=
+SYSTHREAD_SUPPORT=true
+EXTRALIBS=
+NATDYNLINK=true
+CMXS=cmxs
+
+########## Configuration for the bytecode compiler
+
+### Which C compiler to use for the bytecode interpreter.
+BYTECC=gcc -mno-cygwin
+
+### Additional compile-time options for $(BYTECC). (For static linking.)
+BYTECCCOMPOPTS=-O -mms-bitfields -Wall -Wno-unused
+
+### Additional link-time options for $(BYTECC). (For static linking.)
+BYTECCLINKOPTS=
+
+### Additional compile-time options for $(BYTECC). (For building a DLL.)
+DLLCCCOMPOPTS=-O -mms-bitfields -Wall -Wno-unused -DCAML_DLL
+
+### Libraries needed
+BYTECCLIBS=-lws2_32
+NATIVECCLIBS=-lws2_32
+
+### How to invoke the C preprocessor
+CPP=$(BYTECC) -E
+
+### Flexlink
+FLEXLINK=flexlink -chain mingw64 -LC:/mingw64/x86_64-w64-mingw32/lib
+FLEXDIR=$(shell $(FLEXLINK) -where)
+IFLEXDIR=-I"$(FLEXDIR)"
+MKDLL=$(FLEXLINK)
+MKEXE=$(FLEXLINK) -exe
+MKMAINDLL=$(FLEXLINK) -maindll
+
+### How to build a static library
+MKLIB=rm -f $(1); ar rcs $(1) $(2)
+#ml let mklib out files opts = Printf.sprintf "rm -f %s && ar rcs %s %s %s" out opts out files;;
+
+### Canonicalize the name of a system library
+SYSLIB=-l$(1)
+#ml let syslib x = "-l"^x;;
+
+### The ranlib command
+RANLIB=ranlib
+RANLIBCMD=ranlib
+
+############# Configuration for the native-code compiler
+
+### Name of architecture for the native-code compiler
+ARCH=amd64
+
+### Name of architecture model for the native-code compiler.
+MODEL=default
+
+### Name of operating system family for the native-code compiler.
+SYSTEM=mingw64
+
+### Which C compiler to use for the native-code compiler.
+NATIVECC=$(BYTECC)
+
+### Additional compile-time options for $(NATIVECC).
+NATIVECCCOMPOPTS=-O -mms-bitfields -Wall -Wno-unused
+
+### Additional link-time options for $(NATIVECC)
+NATIVECCLINKOPTS=
+
+### Build partially-linked object file
+PACKLD=ld -r $(NATIVECCLINKOPTS) -o #there must be a space after this '-o'
+
+############# Configuration for the contributed libraries
+
+OTHERLIBRARIES=win32unix str num win32graph dynlink bigarray systhreads
+
+### Name of the target architecture for the "num" library
+BNG_ARCH=generic
+BNG_ASM_LEVEL=0
+
+### Configuration for LablTk
+# Set TK_ROOT to the directory where you installed TCL/TK 8.5
+# There must be no spaces or special characters in $(TK_ROOT)
+TK_ROOT=c:/tcl
+TK_DEFS=-I$(TK_ROOT)/include
+TK_LINK=$(TK_ROOT)/bin/tk85.dll $(TK_ROOT)/bin/tcl85.dll -lws2_32
+
+############# Aliases for common commands
+
+MAKEREC=$(MAKE) -f Makefile.nt
+MAKECMD=$(MAKE)
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [Caml-list] OCaml + mingw-w64
@ 2010-11-24 8:16 Christoph Cullmann
0 siblings, 0 replies; 4+ messages in thread
From: Christoph Cullmann @ 2010-11-24 8:16 UTC (permalink / raw)
To: caml-list
On Tuesday, November 23, 2010 05:31:12 pm Christoph Cullmann wrote:
> On Monday, November 22, 2010 04:33:08 pm Damien Doligez wrote:
> > On 2010-11-22, at 13:04, Christoph Cullmann wrote:
> > > In ocaml 3.12, in byterun/major_gc.h, there is:
> > >
> > >
> > > intnat caml_major_collection_slice (long howmuch)
> > >
> > >
> > >
> > > whereas in the .c file that is:
> > >
> > >
> > > intnat caml_major_collection_slice (intnat howmuch)
> > >
> > >
> > >
> > > As intnat is with mingw-w64 long long, this doesn't match.
> > > Should not the header use intnat, too?
> >
> > You're right. This will be fixed in 3.12.1.
>
> Thanks.
>
> We just started here to port ocaml to mingw-w64, question arises:
>
> Which files need adoption?
>
> I have seen that in asmrun the amd64.S needs patches and in asmcomp the
> emit and proc mls.
>
> Do I miss files?
We started to have some version that at least links (with patched flexdll) but
runs in a nice segfault already ;)
Have uploaded the current changes to:
http://caml.inria.fr/mantis/view.php?id=5179
Greetings
Christoph
--
-------------------------------------- Christoph Cullmann ---------
AbsInt Angewandte Informatik GmbH Email: cullmann@AbsInt.com
Science Park 1 Tel: +49-681-38360-22
66123 Saarbrücken Fax: +49-681-38360-20
GERMANY WWW: http://www.AbsInt.com
--------------------------------------------------------------------
Geschäftsführung: Dr.-Ing. Christian Ferdinand
Eingetragen im Handelsregister des Amtsgerichts Saarbrücken, HRB 11234
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2010-11-24 8:16 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <2017975850.988226.1290427453930.JavaMail.root@zmbs1.inria.fr>
2010-11-22 15:33 ` [Caml-list] OCaml + mingw-w64 Damien Doligez
2010-11-23 16:31 ` Christoph Cullmann
2010-11-24 7:14 ` Christoph Cullmann
2010-11-24 8:16 Christoph Cullmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox