diff options
-rw-r--r-- | asmcomp/amd64/emit.mlp | 37 | ||||
-rw-r--r-- | asmrun/Makefile.nt | 3 | ||||
-rw-r--r-- | asmrun/amd64.S | 202 | ||||
-rw-r--r-- | bytecomp/bytelink.ml | 4 | ||||
-rw-r--r-- | byterun/parsing.c | 2 | ||||
-rw-r--r-- | byterun/printexc.c | 2 | ||||
-rw-r--r-- | config/Makefile.mingw64 | 161 | ||||
-rw-r--r-- | otherlibs/num/Makefile.nt | 2 | ||||
-rw-r--r-- | otherlibs/win32unix/channels.c | 6 |
9 files changed, 340 insertions, 79 deletions
diff --git a/asmcomp/amd64/emit.mlp b/asmcomp/amd64/emit.mlp index 1c4a59ce1..097c6cd2e 100644 --- a/asmcomp/amd64/emit.mlp +++ b/asmcomp/amd64/emit.mlp @@ -23,11 +23,8 @@ open Mach open Linearize open Emitaux -let macosx = - match Config.system with - | "macosx" -> true - | _ -> false - +let macosx = (Config.system = "macosx") +let mingw64 = (Config.system = "mingw64") (* Tradeoff between code size and code speed *) @@ -64,17 +61,17 @@ let emit_symbol s = Emitaux.emit_symbol '$' s let emit_call s = - if !Clflags.dlcode && not macosx + if !Clflags.dlcode && not macosx && not mingw64 then `call {emit_symbol s}@PLT` else `call {emit_symbol s}` let emit_jump s = - if !Clflags.dlcode && not macosx + if !Clflags.dlcode && not macosx && not mingw64 then `jmp {emit_symbol s}@PLT` else `jmp {emit_symbol s}` let load_symbol_addr s = - if !Clflags.dlcode + if !Clflags.dlcode && not mingw64 then `movq {emit_symbol s}@GOTPCREL(%rip)` else if !pic_code then `leaq {emit_symbol s}(%rip)` @@ -604,9 +601,12 @@ let emit_instr fallthrough i = ` 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`; + if macosx then + ` .const\n` + else if mingw64 then + ` .section .rdata,\"dr\"\n` + else + ` .section .rodata\n`; emit_align 4; `{emit_label lbl}:`; for i = 0 to Array.length jumptbl - 1 do @@ -701,9 +701,12 @@ let fundecl fundecl = | _ -> () end; if !float_constants <> [] then begin - if macosx - then ` .literal8\n` - else ` .section .rodata.cst8,\"a\",@progbits\n`; + if macosx then + ` .literal8\n` + else if mingw64 then + ` .section .rdata,\"dr\"\n` + else + ` .section .rodata.cst8,\"a\",@progbits\n`; List.iter emit_float_constant !float_constants end @@ -749,9 +752,11 @@ let begin_assembly() = if !Clflags.dlcode then begin (* from amd64.S; could emit these constants on demand *) if macosx then - ` .literal16\n` + ` .literal16\n` + else if mingw64 then + ` .section .rdata,\"dr\"\n` else - ` .section .rodata.cst8,\"a\",@progbits\n`; + ` .section .rodata.cst8,\"a\",@progbits\n`; emit_align 16; `{emit_symbol "caml_negf_mask"}: .quad 0x8000000000000000, 0\n`; emit_align 16; diff --git a/asmrun/Makefile.nt b/asmrun/Makefile.nt index 67f94d658..81e289014 100644 --- a/asmrun/Makefile.nt +++ b/asmrun/Makefile.nt @@ -54,6 +54,9 @@ amd64nt.obj: amd64nt.asm 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 --git a/asmrun/amd64.S b/asmrun/amd64.S index ff031dd5f..7dbafd441 100644 --- a/asmrun/amd64.S +++ b/asmrun/amd64.S @@ -18,7 +18,7 @@ /* PIC mode support based on contribution by Paul Stravers (see PR#4795) */ -#ifdef SYS_macosx +#if defined(SYS_macosx) #define LBL(x) L##x #define G(r) _##r @@ -32,6 +32,20 @@ .align FUNCTION_ALIGN; \ name: +#elif defined(SYS_mingw64) + +#define LBL(x) .L##x +#define G(r) r +#undef GREL +#define GCALL(r) r +#define FUNCTION_ALIGN 4 +#define EIGHT_ALIGN 8 +#define SIXTEEN_ALIGN 16 +#define FUNCTION(name) \ + .globl name; \ + .align FUNCTION_ALIGN; \ + name: + #else #define LBL(x) .L##x @@ -49,7 +63,7 @@ #endif -#ifdef __PIC__ +#if defined(__PIC__) && !defined(SYS_mingw64) /* Position-independent operations on global variables. */ @@ -122,6 +136,88 @@ #endif +/* Save and restore all callee-save registers on stack. + Keep the stack 16-aligned. */ + +#if defined(SYS_mingw64) + +/* Win64 API: callee-save regs are rbx, rbp, rsi, rdi, r12-r15, xmm6-xmm15 */ + +#define PUSH_CALLEE_SAVE_REGS \ + pushq %rbx; \ + pushq %rbp; \ + pushq %rsi; \ + pushq %rdi; \ + pushq %r12; \ + pushq %r13; \ + pushq %r14; \ + pushq %r15; \ + subq $(8+10*16), %rsp; \ + movupd %xmm6, 0*16(%rsp); \ + movupd %xmm7, 1*16(%rsp); \ + movupd %xmm8, 2*16(%rsp); \ + movupd %xmm9, 3*16(%rsp); \ + movupd %xmm10, 4*16(%rsp); \ + movupd %xmm11, 5*16(%rsp); \ + movupd %xmm12, 6*16(%rsp); \ + movupd %xmm13, 7*16(%rsp); \ + movupd %xmm14, 8*16(%rsp); \ + movupd %xmm15, 9*16(%rsp) + +#define POP_CALLEE_SAVE_REGS \ + movupd 0*16(%rsp), %xmm6; \ + movupd 1*16(%rsp), %xmm7; \ + movupd 2*16(%rsp), %xmm8; \ + movupd 3*16(%rsp), %xmm9; \ + movupd 4*16(%rsp), %xmm10; \ + movupd 5*16(%rsp), %xmm11; \ + movupd 6*16(%rsp), %xmm12; \ + movupd 7*16(%rsp), %xmm13; \ + movupd 8*16(%rsp), %xmm14; \ + movupd 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 + +/* Unix API: callee-save regs are rbx, rbp, r12-r15 */ + +#define PUSH_CALLEE_SAVE_REGS \ + pushq %rbx; \ + pushq %rbp; \ + pushq %r12; \ + pushq %r13; \ + pushq %r14; \ + pushq %r15; \ + subq $8, %rsp + +#define POP_CALLEE_SAVE_REGS \ + addq $8, %rsp; \ + popq %r15; \ + popq %r14; \ + popq %r13; \ + popq %r12; \ + popq %rbp; \ + popq %rbx + +#endif + +#ifdef SYS_mingw64 + /* Calls from Caml to C must reserve 32 bytes of extra stack space */ +# define PREPARE_FOR_C_CALL subq $32, %rsp +# define CLEANUP_AFTER_C_CALL addq $32, %rsp +#else +# define PREPARE_FOR_C_CALL +# define CLEANUP_AFTER_C_CALL +#endif + .text /* Allocation */ @@ -166,7 +262,9 @@ LBL(caml_call_gc): movsd %xmm14, 14*8(%rsp) movsd %xmm15, 15*8(%rsp) /* Call the garbage collector */ + PREPARE_FOR_C_CALL call GCALL(caml_garbage_collection) + CLEANUP_AFTER_C_CALL /* Restore caml_young_ptr, caml_exception_pointer */ LOAD_VAR(caml_young_ptr, %r15) LOAD_VAR(caml_exception_pointer, %r14) @@ -269,7 +367,9 @@ LBL(caml_c_call): STORE_VAR(%r15, caml_young_ptr) STORE_VAR(%r14, caml_exception_pointer) /* Call the function (address in %rax) */ + PREPARE_FOR_C_CALL call *%rax + CLEANUP_AFTER_C_CALL /* Reload alloc ptr */ LOAD_VAR(caml_young_ptr, %r15) /* Return to caller */ @@ -280,13 +380,7 @@ LBL(caml_c_call): FUNCTION(G(caml_start_program)) /* Save callee-save registers */ - pushq %rbx - pushq %rbp - pushq %r12 - pushq %r13 - pushq %r14 - pushq %r15 - subq $8, %rsp /* stack 16-aligned */ + PUSH_CALLEE_SAVE_REGS /* Initial entry point is G(caml_program) */ leaq GCALL(caml_program)(%rip), %r12 /* Common code for caml_start_program and caml_callback* */ @@ -320,13 +414,7 @@ LBL(109): POP_VAR(caml_gc_regs) addq $8, %rsp /* Restore callee-save registers. */ - addq $8, %rsp - popq %r15 - popq %r14 - popq %r13 - popq %r12 - popq %rbp - popq %rbx + POP_CALLEE_SAVE_REGS /* Return to caller. */ ret LBL(108): @@ -335,6 +423,20 @@ LBL(108): orq $2, %rax jmp LBL(109) +/* Registers holding arguments of C functions. */ + +#ifdef SYS_mingw64 +#define C_ARG_1 %rcx +#define C_ARG_2 %rdx +#define C_ARG_3 %r8 +#define C_ARG_4 %r9 +#else +#define C_ARG_1 %rdi +#define C_ARG_2 %rsi +#define C_ARG_3 %rdx +#define C_ARG_4 %rcx +#endif + /* Raise an exception from Caml */ FUNCTION(G(caml_raise_exn)) @@ -345,10 +447,11 @@ FUNCTION(G(caml_raise_exn)) ret LBL(110): 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 */ + movq %rax, C_ARG_1 /* arg 1: exception bucket */ + movq 0(%rsp), C_ARG_2 /* arg 2: pc of raise */ + leaq 8(%rsp), C_ARG_3 /* arg 3: sp of raise */ + movq %r14, C_ARG_4 /* arg 4: sp of handler */ + PREPARE_FOR_C_CALL /* no need to cleanup after */ call GCALL(caml_stash_backtrace) movq %r12, %rax /* Recover exception bucket */ movq %r14, %rsp @@ -360,17 +463,18 @@ LBL(110): FUNCTION(G(caml_raise_exception)) TESTL_VAR($1, caml_backtrace_active) jne LBL(111) - movq %rdi, %rax + movq C_ARG_1, %rax LOAD_VAR(caml_exception_pointer, %rsp) /* Cut stack */ popq %r14 /* Recover previous exception handler */ LOAD_VAR(caml_young_ptr, %r15) /* Reload alloc ptr */ ret LBL(111): - movq %rdi, %r12 /* Save exception bucket */ + movq C_ARG_1, %r12 /* Save exception bucket */ /* arg 1: exception bucket */ - 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 */ + LOAD_VAR(caml_last_return_address,C_ARG_2) /* arg 2: pc of raise */ + LOAD_VAR(caml_bottom_of_stack,C_ARG_3) /* arg 3: sp of raise */ + LOAD_VAR(caml_exception_pointer,C_ARG_4) /* arg 4: sp of handler */ + PREPARE_FOR_C_CALL /* no need to cleanup after */ call GCALL(caml_stash_backtrace) movq %r12, %rax /* Recover exception bucket */ LOAD_VAR(caml_exception_pointer,%rsp) @@ -382,49 +486,31 @@ LBL(111): FUNCTION(G(caml_callback_exn)) /* Save callee-save registers */ - pushq %rbx - pushq %rbp - pushq %r12 - pushq %r13 - pushq %r14 - pushq %r15 - subq $8, %rsp /* stack 16-aligned */ + PUSH_CALLEE_SAVE_REGS /* Initial loading of arguments */ - movq %rdi, %rbx /* closure */ - movq %rsi, %rax /* argument */ - movq 0(%rbx), %r12 /* code pointer */ + movq C_ARG_1, %rbx /* closure */ + movq C_ARG_2, %rax /* argument */ + movq 0(%rbx), %r12 /* code pointer */ jmp LBL(caml_start_program) FUNCTION(G(caml_callback2_exn)) /* Save callee-save registers */ - pushq %rbx - pushq %rbp - pushq %r12 - pushq %r13 - pushq %r14 - pushq %r15 - subq $8, %rsp /* stack 16-aligned */ + PUSH_CALLEE_SAVE_REGS /* Initial loading of arguments */ - /* closure stays in %rdi */ - movq %rsi, %rax /* first argument */ - movq %rdx, %rbx /* second argument */ + movq C_ARG_1, %rdi /* closure -- no op with Unix conventions */ + movq C_ARG_2, %rax /* first argument */ + movq C_ARG_3, %rbx /* second argument */ leaq GCALL(caml_apply2)(%rip), %r12 /* code pointer */ jmp LBL(caml_start_program) FUNCTION(G(caml_callback3_exn)) /* Save callee-save registers */ - pushq %rbx - pushq %rbp - pushq %r12 - pushq %r13 - pushq %r14 - pushq %r15 - subq $8, %rsp /* stack 16-aligned */ + PUSH_CALLEE_SAVE_REGS /* Initial loading of arguments */ - movq %rsi, %rax /* first argument */ - movq %rdx, %rbx /* second argument */ - movq %rdi, %rsi /* closure */ - movq %rcx, %rdi /* third argument */ + movq C_ARG_2, %rax /* first argument */ + movq C_ARG_3, %rbx /* second argument */ + movq C_ARG_1, %rsi /* closure */ + movq C_ARG_4, %rdi /* third argument */ leaq GCALL(caml_apply3)(%rip), %r12 /* code pointer */ jmp LBL(caml_start_program) @@ -442,8 +528,10 @@ G(caml_system__frametable): .value 0 /* no roots here */ .align EIGHT_ALIGN -#ifdef SYS_macosx +#if defined(SYS_macosx) .literal16 +#elif defined(SYS_mingw64) + .section .rdata,"dr" #else .section .rodata.cst8,"a",@progbits #endif diff --git a/bytecomp/bytelink.ml b/bytecomp/bytelink.ml index 794a0acb4..d458e72a4 100644 --- a/bytecomp/bytelink.ml +++ b/bytecomp/bytelink.ml @@ -513,7 +513,11 @@ let link objfiles output_name = extern \"C\" {\n\ #endif\n\ #ifdef _WIN64\n\ + #ifdef __MINGW32__\n\ + typedef long long value;\n\ + #else\n\ typedef __int64 value;\n\ + #endif\n\ #else\n\ typedef long value;\n\ #endif\n"; diff --git a/byterun/parsing.c b/byterun/parsing.c index aeba38d62..3d5ea8332 100644 --- a/byterun/parsing.c +++ b/byterun/parsing.c @@ -125,7 +125,7 @@ static void print_token(struct parser_tables *tables, int state, value tok) state, token_name(tables->names_block, Tag_val(tok))); v = Field(tok, 0); if (Is_long(v)) - fprintf(stderr, "%ld", Long_val(v)); + fprintf(stderr, "%" ARCH_INTNAT_PRINTF_FORMAT "d", Long_val(v)); else if (Tag_val(v) == String_tag) fprintf(stderr, "%s", String_val(v)); else if (Tag_val(v) == Double_tag) diff --git a/byterun/printexc.c b/byterun/printexc.c index f50853d90..e891d9c67 100644 --- a/byterun/printexc.c +++ b/byterun/printexc.c @@ -73,7 +73,7 @@ CAMLexport char * caml_format_exception(value exn) if (i > start) add_string(&buf, ", "); v = Field(bucket, i); if (Is_long(v)) { - sprintf(intbuf, "%ld", Long_val(v)); + sprintf(intbuf, "%" ARCH_INTNAT_PRINTF_FORMAT "d", Long_val(v)); add_string(&buf, intbuf); } else if (Tag_val(v) == String_tag) { add_char(&buf, '"'); diff --git a/config/Makefile.mingw64 b/config/Makefile.mingw64 new file mode 100644 index 000000000..d88a03e15 --- /dev/null +++ b/config/Makefile.mingw64 @@ -0,0 +1,161 @@ +######################################################################### +# # +# OCaml # +# # +# 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 11319 2011-12-16 17:02:48Z xleroy $ + +# Configuration for Windows, Mingw compiler + +######### General configuration + +PREFIX=C:/ocamlmgw64 + +### 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 + +### Toolchain prefix +TOOLPREF=x86_64-w64-mingw32- + +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=$(TOOLPREF)as +ASPP=gcc +ASPPPROFFLAGS= +PROFILING=noprof +RUNTIMED=noruntimed +DYNLINKOPTS= +DEBUGGER=ocamldebugger +CC_PROFILE= +SYSTHREAD_SUPPORT=true +EXTRALIBS= +NATDYNLINK=true +CMXS=cmxs +RUNTIMED=noruntimed + +########## Configuration for the bytecode compiler + +### Which C compiler to use for the bytecode interpreter. +BYTECC=$(TOOLPREF)gcc + +### 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 +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); $(TOOLPREF)ar rc $(1) $(2); $(RANLIB) $(1) +#ml let mklib out files opts = Printf.sprintf "rm -f %s && %sar rcs %s %s %s" out toolpref opts out files;; + +### Canonicalize the name of a system library +SYSLIB=-l$(1) +#ml let syslib x = "-l"^x;; + +### The ranlib command +RANLIB=$(TOOLPREF)ranlib +RANLIBCMD=$(TOOLPREF)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=$(TOOLPREF)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=amd64 +BNG_ASM_LEVEL=1 + +### Configuration for LablTk (not supported) +TK_DEFS= +TK_LINK= + +############# Aliases for common commands + +MAKEREC=$(MAKE) -f Makefile.nt +MAKECMD=$(MAKE) diff --git a/otherlibs/num/Makefile.nt b/otherlibs/num/Makefile.nt index 9d831657a..4ac69c7ca 100644 --- a/otherlibs/num/Makefile.nt +++ b/otherlibs/num/Makefile.nt @@ -28,7 +28,7 @@ clean:: rm -f *~ bng.$(O): bng.h bng_digit.c \ - bng_alpha.c bng_amd64.c bng_ia32.c bng_mips.c bng_ppc.c bng_sparc.c + bng_amd64.c bng_ia32.c bng_ppc.c bng_sparc.c depend: sed -e 's/\.o/.$(O)/g' .depend > .depend.nt diff --git a/otherlibs/win32unix/channels.c b/otherlibs/win32unix/channels.c index 2a3774d90..ea3912720 100644 --- a/otherlibs/win32unix/channels.c +++ b/otherlibs/win32unix/channels.c @@ -20,15 +20,15 @@ #include "unixsupport.h" #include <fcntl.h> -extern long _get_osfhandle(int); -extern int _open_osfhandle(long, int); +extern intptr_t _get_osfhandle(int); +extern int _open_osfhandle(intptr_t, int); int win_CRT_fd_of_filedescr(value handle) { if (CRT_fd_val(handle) != NO_CRT_FD) { return CRT_fd_val(handle); } else { - int fd = _open_osfhandle((long) Handle_val(handle), O_BINARY); + int fd = _open_osfhandle((intptr_t) Handle_val(handle), O_BINARY); if (fd == -1) uerror("channel_of_descr", Nothing); CRT_fd_val(handle) = fd; return fd; |