diff --git a/Makefile.am b/Makefile.am index 93be72bf..ff58cb8d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,156 +1,133 @@ AUTOMAKE_OPTIONS=foreign ACLOCAL_AMFLAGS= -I m4 --install BOOTSTRAP_OPTIONS = if INTINFISINT POLYIMPORT_OPTIONS = --intIsIntInf else POLYIMPORT_OPTIONS = endif DIST_SUBDIRS = libpolyml libpolymain modules SUBDIRS = libpolyml libpolymain . modules bin_PROGRAMS = polyimport poly dist_bin_SCRIPTS = polyc man_MANS = poly.1 polyimport.1 polyc.1 -# Select the architecture-specific pre-built compiler +# Select the pre-built compiler if ARCHI386 -POLYIMPORT = $(srcdir)/imports/polymli386.txt +POLYIMPORT = $(srcdir)/bootstrap/bootstrap32.txt else if ARCHINTERPRET -POLYIMPORT = $(srcdir)/imports/polymlint.txt +POLYIMPORT = $(srcdir)/bootstrap/bootstrap32.txt else if ARCHINTERPRET64 -POLYIMPORT = $(srcdir)/imports/polymlint64.txt +POLYIMPORT = $(srcdir)/bootstrap/bootstrap64.txt else if ARCHX86_64 -if WINDOWSCALLCONV -POLYIMPORT = $(srcdir)/imports/polymlx86_64win.txt -else -POLYIMPORT = $(srcdir)/imports/polymlx86_64sysv.txt -endif +POLYIMPORT = $(srcdir)/bootstrap/bootstrap64.txt else if ARCHX8632IN64 -if WINDOWSCALLCONV -POLYIMPORT = $(srcdir)/imports/polymlx64_32win.txt -else -POLYIMPORT = $(srcdir)/imports/polymlx64_32sysv.txt -endif +POLYIMPORT = $(srcdir)/bootstrap/bootstrap32.txt else endif endif endif endif endif noinst_HEADERS = polyexports.h poly_LDFLAGS= polyimport_LDFLAGS= POLYRESOURCES= EXTRALDFLAGS= if NATIVE_WINDOWS if ARCHINTERPRET64 EXTRALDFLAGS += -Wl,-u,WinMain else if ARCHX86_64 EXTRALDFLAGS += -Wl,-u,WinMain else if ARCHX8632IN64 EXTRALDFLAGS += -Wl,-u,WinMain else EXTRALDFLAGS += -Wl,-u,_WinMain@16 -Wl,--large-address-aware endif endif endif if WINDOWSGUI EXTRALDFLAGS += -mwindows polyimport_LDFLAGS += -mwindows else EXTRALDFLAGS += -mconsole polyimport_LDFLAGS += -mconsole endif poly_LDFLAGS += $(EXTRALDFLAGS) POLYOBJECTFILE = polyexport.obj POLYRESOURCES += polyresource.o OBJECTSUFFIX=obj else POLYOBJECTFILE = polyexport.o OBJECTSUFFIX=o endif if MACOSLDOPTS poly_LDFLAGS += -Wl,-no_pie endif poly_SOURCES = poly_LDADD = $(POLYOBJECTFILE) $(POLYRESOURCES) libpolymain/libpolymain.la libpolyml/libpolyml.la polyimport_SOURCES = polyimport.c polyimport_LDADD = $(POLYRESOURCES) libpolyml/libpolyml.la EXTRA_DIST = \ - imports/polymli386.txt \ - imports/polymlint64.txt \ - imports/polymlint.txt \ - imports/polymlx86_64sysv.txt \ - imports/polymlx86_64win.txt \ - imports/polymlx64_32sysv.txt \ - imports/polymlx64_32win.txt \ - libpolyml/x86asm.asm \ - exportPoly.sml \ poly.1 \ polyimport.1 dist-hook: - find {basis,mlsource}/ -type d -exec mkdir $(distdir)/{} \; - find {basis,mlsource}/ -type f -not -name .svn \ + find {bootstrap,basis,mlsource}/ -type d -exec mkdir $(distdir)/{} \; + find {bootstrap,basis,mlsource}/ -type f -not -name .git \ -exec cp -pf {} $(distdir)/{} \; - - # Unix. -polyexport.o: polyimport exportPoly.sml polytemp.txt - ./polyimport $(POLYIMPORT_OPTIONS) polytemp.txt -I $(srcdir) < $(srcdir)/exportPoly.sml +polyexport.o: polyimport exportPoly.sml $(POLYIMPORT) + ./polyimport $(POLYIMPORT_OPTIONS) $(POLYIMPORT) -I $(srcdir) < $(srcdir)/bootstrap/Stage1.sml # Windows. When building on Windows make sure that we provide both stdin and stdout to suppress the GUI. -polyexport.obj: polyimport$(EXEEXT) exportPoly.sml polytemp.txt - ./polyimport $(POLYIMPORT_OPTIONS) polytemp.txt -I $(srcdir) < $(srcdir)/exportPoly.sml | cat +polyexport.obj: polyimport$(EXEEXT) exportPoly.sml $(POLYIMPORT) + ./polyimport $(POLYIMPORT_OPTIONS) $(POLYIMPORT) -I $(srcdir) < $(srcdir)/bootstrap/Stage1.sml | cat polyresource.o: PolyML.rc poly.ico $(WINDRES) -o polyresource.o $(srcdir)/PolyML.rc -polytemp.txt: $(POLYIMPORT) - cp $(POLYIMPORT) polytemp.txt - #polyc: buildpolyc # ./buildpolyc LINK=\"$(CC)\" BINDIR=\"$(bindir)\" LIBDIR=\"$(libdir)\" LIBS=\"$(LIBS)\" EXTRALDFLAGS=\"$(EXTRALDFLAGS)\" SUFFIX=\"$(OBJECTSUFFIX)\" -# This builds the compiler but does not update the files in the imports directory. -# It then builds a version of poly containing the new compiler. +# Recompiler the compiler using the last step of the bootstrap process. compiler: all - ./poly $(BOOTSTRAP_OPTIONS) --error-exit < mlsource/BuildExport.sml + ./poly $(BOOTSTRAP_OPTIONS) --error-exit < bootstrap/Stage6.sml $(MAKE) reboot: compiler - cp polytemp.txt $(POLYIMPORT) + cp $(POLYIMPORT) clean-local: - rm -f *.obj polytemp.txt polyc + rm -f *.obj polyc # Run tests check-local: all echo "val () = use \"$(srcdir)/Tests/RunTests\"; val () = OS.Process.exit(if runTests \"$(srcdir)/Tests\" then OS.Process.success else OS.Process.failure):unit;" | ./poly # Retain this target for backwards compatibility tests: check diff --git a/libpolyml/Makefile.am b/libpolyml/Makefile.am index 1ffe0450..9f4ab67d 100644 --- a/libpolyml/Makefile.am +++ b/libpolyml/Makefile.am @@ -1,160 +1,162 @@ AUTOMAKE_OPTIONS=foreign moduledir = @moduledir@ AM_CPPFLAGS = $(CFLAGS) $(OSFLAG) $(GIT_VERSION) -Wall -DMODULEDIR=\"$(moduledir)\" AM_CFLAGS = $(CFLAGS) $(OSFLAG) $(GIT_VERSION) -Wall -fno-strict-aliasing AM_ASFLAGS = $(OSFLAG) AM_CCASFLAGS = $(OSFLAG) lib_LTLIBRARIES = libpolyml.la libpolyml_la_LDFLAGS = -version-info 11:0:0 if NO_UNDEFINED # Force all references to be defined to build the DLL. libpolyml_la_LDFLAGS += -no-undefined endif # Select the architecture-specific modules if ARCHI386 ARCHSOURCE = x86_dep.cpp x86assembly_gas32.S else if ARCHINTERPRET -ARCHSOURCE = interpret.cpp +ARCHSOURCE = interpreter.cpp AM_CPPFLAGS += -DCODEISNOTEXECUTABLE else if ARCHINTERPRET64 -ARCHSOURCE = interpret.cpp +ARCHSOURCE = interpreter.cpp AM_CPPFLAGS += -DCODEISNOTEXECUTABLE else if ARCHX86_64 ARCHSOURCE = x86_dep.cpp x86assembly_gas64.S else if ARCHX8632IN64 ARCHSOURCE = x86_dep.cpp x86assembly_gas64.S else endif endif endif endif endif # Select the object-format-specific modules if EXPPECOFF EXPORTSOURCE = pecoffexport.cpp else if EXPELF EXPORTSOURCE = elfexport.cpp else if EXPMACHO EXPORTSOURCE = machoexport.cpp endif endif endif if NATIVE_WINDOWS OSSOURCE = winstartup.cpp winbasicio.cpp winguiconsole.cpp windows_specific.cpp osmemwin.cpp else OSSOURCE = basicio.cpp unix_specific.cpp osmemunix.cpp endif noinst_HEADERS = \ arb.h \ basicio.h \ bitmap.h \ + bytecode.h \ check_objects.h \ diagnostics.h \ elfexport.h \ errors.h \ exporter.h \ gc.h \ gctaskfarm.h \ gc_progress.h \ globals.h \ heapsizing.h \ int_opcodes.h \ io_internal.h \ locking.h \ machine_dep.h \ machoexport.h \ memmgr.h \ mpoly.h \ network.h \ noreturn.h \ objsize.h \ osmem.h \ os_specific.h \ pecoffexport.h \ pexport.h \ PolyControl.h \ poly_specific.h \ polyffi.h \ polystring.h \ process_env.h \ processes.h \ profiling.h \ realconv.h \ reals.h \ rts_module.h \ rtsentry.h \ run_time.h \ savestate.h \ save_vec.h \ scanaddrs.h \ sharedata.h \ sighandler.h \ statistics.h \ sys.h \ timing.h \ version.h \ winguiconsole.h \ winstartup.h \ xcall_numbers.h \ xwindows.h libpolyml_la_SOURCES = \ arb.cpp \ bitmap.cpp \ + bytecode.cpp \ check_objects.cpp \ diagnostics.cpp \ errors.cpp \ exporter.cpp \ gc.cpp \ gc_check_weak_ref.cpp \ gc_copy_phase.cpp \ gc_mark_phase.cpp \ gc_progress.cpp \ gc_share_phase.cpp \ gc_update_phase.cpp \ gctaskfarm.cpp \ heapsizing.cpp \ locking.cpp \ memmgr.cpp \ mpoly.cpp \ network.cpp \ objsize.cpp \ pexport.cpp \ poly_specific.cpp \ polyffi.cpp \ polystring.cpp \ process_env.cpp \ processes.cpp \ profiling.cpp \ quick_gc.cpp \ realconv.cpp \ reals.cpp \ rts_module.cpp \ rtsentry.cpp \ run_time.cpp \ save_vec.cpp \ savestate.cpp \ scanaddrs.cpp \ sharedata.cpp \ sighandler.cpp \ statistics.cpp \ timing.cpp \ xwindows.cpp \ $(ARCHSOURCE) $(EXPORTSOURCE) $(OSSOURCE) pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = polyml.pc diff --git a/libpolyml/x86assembly_gas32.S b/libpolyml/x86assembly_gas32.S index 599748e0..c72d9325 100644 --- a/libpolyml/x86assembly_gas32.S +++ b/libpolyml/x86assembly_gas32.S @@ -1,178 +1,182 @@ /* Title: Assembly code routines for the poly system. Author: David Matthews Copyright (c) David C. J. Matthews 2000-2020 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* This is the 32-bit Unix version of the assembly code file. There are separate versions of 32/64 and Windows (Intel syntax) and Unix (gas syntax). */ /* Registers used :- %%eax: First argument to function. Result of function call. %%ebx: Second argument to function. %%ecx: General register %%edx: Closure pointer in call. %%ebp: Points to memory used for extra registers %%esi: General register. %%edi: General register. %%esp: Stack pointer. */ #include "config.h" #ifdef SYMBOLS_REQUIRE_UNDERSCORE #define EXTNAME(x) _##x #else #define EXTNAME(x) x #endif # # Macro to begin the hand-coded functions # #ifdef MACOSX #define GLOBAL .globl #else #define GLOBAL .global #endif #define INLINE_ROUTINE(id) \ GLOBAL EXTNAME(id); \ EXTNAME(id): #define Fr_Size 16 /* This is the argument vector passed in to X86AsmSwitchToPoly It is used to initialise the frame. A few values are updated when ML returns. */ #define Arg_LocalMpointer 0x0 #define Arg_HandlerRegister 0x4 #define Arg_LocalMbottom 0x8 #define Arg_StackLimit 0xc #define Arg_ExceptionPacket 0x10 /* Address of packet to raise */ #define Arg_RequestCode 0x14 /* Byte: Io function to call. */ #define Arg_ReturnReason 0x16 /* Byte: Reason for returning from ML. */ #define Arg_FullRestore 0x17 /* Byte: Full/partial restore */ #define Arg_SaveCStack 0x18 /* Save C Stack pointer */ #define Arg_ThreadId 0x1c /* My thread id */ #define Arg_StackPtr 0x20 /* Stack Pointer */ #define Arg_SaveRAX 0x34 #define Arg_SaveRBX 0x38 #define Arg_SaveRCX 0x3c #define Arg_SaveRDX 0x40 #define Arg_SaveRSI 0x44 #define Arg_SaveRDI 0x48 #define Arg_SaveFP 0x4c #define RETURN_HEAP_OVERFLOW 1 #define RETURN_STACK_OVERFLOW 2 #define RETURN_STACK_OVERFLOWEX 3 +#define RETURN_ENTER_INTERPRETER 4 # Mark the stack as non-executable when supported #if (defined(__linux__) && defined(__ELF__)) .section .note.GNU-stack, "", @progbits #endif # # CODE STARTS HERE # .text #define CALL_EXTRA(index) \ movb $index,Arg_ReturnReason(%ebp); \ jmp CallTrapHandler; /* Enter ML code. This is now only ever used to start a new thread. It is probably unnecessary to save the callee-save regs or load the ML regs. */ INLINE_ROUTINE(X86AsmSwitchToPoly) pushl %ebp # Standard entry sequence movl 8(%esp),%ebp # Address of argument vector pushl %ebx pushl %edi pushl %esi # Push callee-save registers subl $(Fr_Size-12),%esp # Allocate frame movl %esp,Arg_SaveCStack(%ebp) movl Arg_StackPtr(%ebp),%esp FRSTOR Arg_SaveFP(%ebp) movl Arg_SaveRAX(%ebp),%eax # Load the registers movl Arg_SaveRBX(%ebp),%ebx # Load the registers movl Arg_SaveRCX(%ebp),%ecx movl Arg_SaveRDX(%ebp),%edx movl Arg_SaveRSI(%ebp),%esi movl Arg_SaveRDI(%ebp),%edi cld # Clear this just in case jmp *(%edx) /* Save all the registers and enter the trap handler. It is probably unnecessary to save the FP state now. */ CallTrapHandler: movl %eax,Arg_SaveRAX(%ebp) movl %ebx,Arg_SaveRBX(%ebp) movl %ecx,Arg_SaveRCX(%ebp) movl %edx,Arg_SaveRDX(%ebp) movl %esi,Arg_SaveRSI(%ebp) movl %edi,Arg_SaveRDI(%ebp) fnsave Arg_SaveFP(%ebp) # Save FP state. Also resets the state so... fldcw Arg_SaveFP(%ebp) # ...load because we need the same rounding mode in the RTS movl %esp,Arg_StackPtr(%ebp) # Save ML stack pointer movl Arg_SaveCStack(%ebp),%esp # Restore C stack pointer subl $12,%esp # Align stack ptr - GCC prefers this pushl Arg_ThreadId(%ebp) call X86TrapHandler addl $16,%esp movl Arg_StackPtr(%ebp),%esp movl Arg_ExceptionPacket(%ebp),%eax cmpl $1,%eax # Did we raise an exception? jnz raisexlocal FRSTOR Arg_SaveFP(%ebp) movl Arg_SaveRAX(%ebp),%eax # Load the registers movl Arg_SaveRBX(%ebp),%ebx # Load the registers movl Arg_SaveRCX(%ebp),%ecx movl Arg_SaveRDX(%ebp),%edx movl Arg_SaveRSI(%ebp),%esi movl Arg_SaveRDI(%ebp),%edi cld # Clear this just in case ret raisexlocal: movl Arg_HandlerRegister(%ebp),%ecx # Get next handler into %rcx jmp *(%ecx) INLINE_ROUTINE(X86AsmCallExtraRETURN_HEAP_OVERFLOW) CALL_EXTRA(RETURN_HEAP_OVERFLOW) INLINE_ROUTINE(X86AsmCallExtraRETURN_STACK_OVERFLOW) CALL_EXTRA(RETURN_STACK_OVERFLOW) INLINE_ROUTINE(X86AsmCallExtraRETURN_STACK_OVERFLOWEX) CALL_EXTRA(RETURN_STACK_OVERFLOWEX) + +INLINE_ROUTINE(X86AsmCallExtraRETURN_ENTER_INTERPRETER) + CALL_EXTRA(RETURN_ENTER_INTERPRETER) # Additional assembly code routines # Fallback exchange and add if we can't use inline. INLINE_ROUTINE(X86AsmAtomicExchangeAndAdd) # Use %ecx and %eax because they are volatile (unlike %ebx on X86/64/Unix) movl 4(%esp),%ecx movl 8(%esp),%eax lock; xaddl %eax,(%ecx) ret diff --git a/libpolyml/x86assembly_gas64.S b/libpolyml/x86assembly_gas64.S index 0237aeb0..9ed6ce8d 100644 --- a/libpolyml/x86assembly_gas64.S +++ b/libpolyml/x86assembly_gas64.S @@ -1,286 +1,289 @@ /* Title: Assembly code routines for the poly system. Author: David Matthews Copyright (c) David C. J. Matthews 2000-2020 This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* This is the 64-bit gas version of the assembly code file. There are separate versions of 32/64 and MAMS (Intel syntax) and and GCC (gas syntax). */ /* Registers used :- %rax: First argument to function. Result of function call. %rbx: Second argument to function. %rcx: General register %rdx: Closure pointer in call. %rbp: Points to memory used for extra registers %rsi: General register. %rdi: General register. %rsp: Stack pointer. %r8: Third argument to function %r9: Fourth argument to function %r10: Fifth argument to function %r11: General register %r12: General register %r13: General register %r14: General register %r15: Memory allocation pointer */ #include "config.h" #ifdef SYMBOLS_REQUIRE_UNDERSCORE #define EXTNAME(x) _##x #else #define EXTNAME(x) x #endif #ifdef __CYGWIN__ #define _WIN32 1 #endif /* Macro to begin the hand-coded functions */ #ifdef MACOSX #define GLOBAL .globl #else #define GLOBAL .global #endif #define INLINE_ROUTINE(id) \ GLOBAL EXTNAME(id); \ EXTNAME(id): /* Extra entries on the C stack */ #define Fr_Size 64 /* Must be multiple of 16 to get alignment correct */ /* This is the argument vector passed in to X86AsmSwitchToPoly It is used to initialise the frame. A few values are updated when ML returns. */ #define Arg_LocalMpointer 0x0 #define Arg_HandlerRegister 0x8 #define Arg_LocalMbottom 0x10 #define Arg_StackLimit 0x18 #define Arg_ExceptionPacket 0x20 /* Address of packet to raise */ #define Arg_RequestCode 0x28 /* Byte: Io function to call. */ #define Arg_ReturnReason 0x2a /* Byte: Reason for returning from ML. */ #define Arg_UnusedRestore 0x2b /* Byte: Full/partial restore */ #define Arg_SaveCStack 0x30 /* Current stack base */ #define Arg_ThreadId 0x38 /* My thread id */ #define Arg_StackPtr 0x40 /* Stack Pointer */ #define Arg_SaveRAX 0x68 #define Arg_SaveRBX 0x70 #define Arg_SaveRCX 0x78 #define Arg_SaveRDX 0x80 #define Arg_SaveRSI 0x88 #define Arg_SaveRDI 0x90 #define Arg_SaveR8 0x98 #define Arg_SaveR9 0xa0 #define Arg_SaveR10 0xa8 #define Arg_SaveR11 0xb0 #define Arg_SaveR12 0xb8 #define Arg_SaveR13 0xc0 #define Arg_SaveR14 0xc8 #define Arg_SaveXMM0 0xd0 #define Arg_SaveXMM1 0xd8 #define Arg_SaveXMM2 0xe0 #define Arg_SaveXMM3 0xe8 #define Arg_SaveXMM4 0xf0 #define Arg_SaveXMM5 0xf8 #define Arg_SaveXMM6 0x100 /* IO function numbers. These are functions that are called to handle special cases in this code */ #include "sys.h" #define RETURN_HEAP_OVERFLOW 1 #define RETURN_STACK_OVERFLOW 2 #define RETURN_STACK_OVERFLOWEX 3 -#define RETURN_RAISE_OVERFLOW 8 +#define RETURN_ENTER_INTERPRETER 4 # Mark the stack as non-executable when supported #if (defined(__linux__) && defined(__ELF__)) .section .note.GNU-stack, "", @progbits #endif # # CODE STARTS HERE # .text #define CALL_EXTRA(index) \ movb $index,Arg_ReturnReason(%rbp); \ jmp CallTrapHandler; /* Enter ML code. This is now only ever used to start a new thread. It is probably unnecessary to save the callee-save regs or load the ML regs. */ INLINE_ROUTINE(X86AsmSwitchToPoly) pushq %rbp # Standard entry sequence /* If we're compiling with Mingw we're using Windows calling conventions. */ #ifdef _WIN32 movq %rcx,%rbp # Argument is in %rcx #else movq %rdi,%rbp # Argument is in %rdi #endif pushq %rbx pushq %r12 pushq %r13 pushq %r14 pushq %r15 #ifdef _WIN32 pushq %rdi # Callee save in Windows pushq %rsi subq $(Fr_Size-56),%rsp # Argument is already in %rcx #else subq $(Fr_Size-40),%rsp #endif movq %rsp,Arg_SaveCStack(%rbp) movq Arg_LocalMpointer(%rbp),%r15 movq Arg_StackPtr(%rbp),%rsp # Set the new stack ptr movsd Arg_SaveXMM0(%rbp),%xmm0 # Load the registers movsd Arg_SaveXMM1(%rbp),%xmm1 movsd Arg_SaveXMM2(%rbp),%xmm2 movsd Arg_SaveXMM3(%rbp),%xmm3 movsd Arg_SaveXMM4(%rbp),%xmm4 movsd Arg_SaveXMM5(%rbp),%xmm5 movsd Arg_SaveXMM6(%rbp),%xmm6 movq Arg_SaveRBX(%rbp),%rbx movq Arg_SaveRCX(%rbp),%rcx movq Arg_SaveRDX(%rbp),%rdx movq Arg_SaveRSI(%rbp),%rsi movq Arg_SaveRDI(%rbp),%rdi movq Arg_SaveR8(%rbp),%r8 movq Arg_SaveR9(%rbp),%r9 movq Arg_SaveR10(%rbp),%r10 movq Arg_SaveR11(%rbp),%r11 movq Arg_SaveR12(%rbp),%r12 movq Arg_SaveR13(%rbp),%r13 movq Arg_SaveR14(%rbp),%r14 movq Arg_SaveRAX(%rbp),%rax cld # Clear this just in case #ifdef POLYML32IN64 jmp *(%rbx,%rdx,4) #else jmp *(%rdx) #endif /* This is exactly the same as raisex but seems to be needed to work round a PIC problem. */ raisexLocal: movq Arg_HandlerRegister(%rbp),%rcx # Get next handler into %rcx jmp *(%rcx) /* Save all the registers and enter the trap handler. It is probably unnecessary to save the FP state now. */ CallTrapHandler: movq %rax,Arg_SaveRAX(%rbp) movq %rbx,Arg_SaveRBX(%rbp) movq %rcx,Arg_SaveRCX(%rbp) movq %rdx,Arg_SaveRDX(%rbp) movq %rsi,Arg_SaveRSI(%rbp) movq %rdi,Arg_SaveRDI(%rbp) movsd %xmm0,Arg_SaveXMM0(%rbp) movsd %xmm1,Arg_SaveXMM1(%rbp) movsd %xmm2,Arg_SaveXMM2(%rbp) movsd %xmm3,Arg_SaveXMM3(%rbp) movsd %xmm4,Arg_SaveXMM4(%rbp) movsd %xmm5,Arg_SaveXMM5(%rbp) movsd %xmm6,Arg_SaveXMM6(%rbp) movq %r8,Arg_SaveR8(%rbp) movq %r9,Arg_SaveR9(%rbp) movq %r10,Arg_SaveR10(%rbp) movq %r11,Arg_SaveR11(%rbp) movq %r12,Arg_SaveR12(%rbp) movq %r13,Arg_SaveR13(%rbp) movq %r14,Arg_SaveR14(%rbp) movq %rsp,Arg_StackPtr(%rbp) movq %r15,Arg_LocalMpointer(%rbp) # Save back heap pointer movq Arg_SaveCStack(%rbp),%rsp # Restore C stack pointer #ifdef _WIN32 subq $32,%rsp # Windows save area movq Arg_ThreadId(%rbp),%rcx #else movq Arg_ThreadId(%rbp),%rdi #endif call X86TrapHandler@plt #ifdef _WIN32 addq $32,%rsp #endif movq Arg_LocalMpointer(%rbp),%r15 movq Arg_StackPtr(%rbp),%rsp # Set the new stack ptr movsd Arg_SaveXMM0(%rbp),%xmm0 # Load the registers movsd Arg_SaveXMM1(%rbp),%xmm1 movsd Arg_SaveXMM2(%rbp),%xmm2 movsd Arg_SaveXMM3(%rbp),%xmm3 movsd Arg_SaveXMM4(%rbp),%xmm4 movsd Arg_SaveXMM5(%rbp),%xmm5 movsd Arg_SaveXMM6(%rbp),%xmm6 movq Arg_SaveRBX(%rbp),%rbx movq Arg_SaveRCX(%rbp),%rcx movq Arg_SaveRDX(%rbp),%rdx movq Arg_SaveRSI(%rbp),%rsi movq Arg_SaveRDI(%rbp),%rdi movq Arg_SaveR8(%rbp),%r8 movq Arg_SaveR9(%rbp),%r9 movq Arg_SaveR10(%rbp),%r10 movq Arg_SaveR11(%rbp),%r11 movq Arg_SaveR12(%rbp),%r12 movq Arg_SaveR13(%rbp),%r13 movq Arg_SaveR14(%rbp),%r14 movq Arg_ExceptionPacket(%rbp),%rax cmpq $1,%rax # Did we raise an exception? jnz raisexLocal movq Arg_SaveRAX(%rbp),%rax cld # Clear this just in case ret # Additional assembly code routines INLINE_ROUTINE(X86AsmCallExtraRETURN_HEAP_OVERFLOW) CALL_EXTRA(RETURN_HEAP_OVERFLOW) INLINE_ROUTINE(X86AsmCallExtraRETURN_STACK_OVERFLOW) CALL_EXTRA(RETURN_STACK_OVERFLOW) INLINE_ROUTINE(X86AsmCallExtraRETURN_STACK_OVERFLOWEX) CALL_EXTRA(RETURN_STACK_OVERFLOWEX) +INLINE_ROUTINE(X86AsmCallExtraRETURN_ENTER_INTERPRETER) + CALL_EXTRA(RETURN_ENTER_INTERPRETER) + # Fallback exchange and add if we can't use inline. INLINE_ROUTINE(X86AsmAtomicExchangeAndAdd) #ifdef _WIN32 # Windows calling conventions rcx,rdx movq %rdx,%rax #ifdef POLYML32IN64 lock xaddl %eax,(%rcx) # rax is an absolute address but this is only a word #else lock xaddq %rax,(%rcx) #endif # Unix calling conventions rdi,rsi #else movq %rsi,%rax #ifdef POLYML32IN64 lock xaddl %eax,(%rdi) # rax is an absolute address but this is only a word #else lock xaddq %rax,(%rdi) #endif #endif ret