summaryrefslogtreecommitdiff
path: root/ocaml-binary-annot/asmrun/amd64nt.asm
diff options
context:
space:
mode:
Diffstat (limited to 'ocaml-binary-annot/asmrun/amd64nt.asm')
-rw-r--r--ocaml-binary-annot/asmrun/amd64nt.asm466
1 files changed, 466 insertions, 0 deletions
diff --git a/ocaml-binary-annot/asmrun/amd64nt.asm b/ocaml-binary-annot/asmrun/amd64nt.asm
new file mode 100644
index 0000000000..c1d97e05b1
--- /dev/null
+++ b/ocaml-binary-annot/asmrun/amd64nt.asm
@@ -0,0 +1,466 @@
+;*********************************************************************
+;
+; Objective Caml
+;
+; Xavier Leroy, projet Gallium, INRIA Rocquencourt
+;
+; Copyright 2006 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$
+
+; Asm part of the runtime system, AMD64 processor, Intel syntax
+
+; Notes on Win64 calling conventions:
+; function arguments in RCX, RDX, R8, R9 / XMM0 - XMM3
+; caller must reserve 32 bytes of stack space
+; callee must preserve RBX, RBP, RSI, RDI, R12-R15, XMM6-XMM15
+
+ EXTRN caml_garbage_collection: NEAR
+ EXTRN caml_apply2: NEAR
+ EXTRN caml_apply3: NEAR
+ EXTRN caml_program: NEAR
+ EXTRN caml_array_bound_error: NEAR
+ EXTRN caml_young_limit: QWORD
+ EXTRN caml_young_ptr: QWORD
+ EXTRN caml_bottom_of_stack: QWORD
+ EXTRN caml_last_return_address: QWORD
+ EXTRN caml_gc_regs: QWORD
+ EXTRN caml_exception_pointer: QWORD
+ EXTRN caml_backtrace_active: DWORD
+ EXTRN caml_stash_backtrace: NEAR
+
+ .CODE
+
+; Allocation
+
+ PUBLIC caml_call_gc
+ ALIGN 16
+caml_call_gc:
+ ; Record lowest stack address and return address
+ mov rax, [rsp]
+ mov caml_last_return_address, rax
+ lea rax, [rsp+8]
+ mov caml_bottom_of_stack, rax
+L105:
+ ; Save caml_young_ptr, caml_exception_pointer
+ mov caml_young_ptr, r15
+ mov caml_exception_pointer, r14
+ ; Build array of registers, save it into caml_gc_regs
+ push r13
+ push r12
+ push rbp
+ push r11
+ push r10
+ push r9
+ push r8
+ push rcx
+ push rdx
+ push rsi
+ push rdi
+ push rbx
+ push rax
+ mov caml_gc_regs, rsp
+ ; Save floating-point registers
+ sub rsp, 16*8
+ movlpd QWORD PTR [rsp + 0*8], xmm0
+ movlpd QWORD PTR [rsp + 1*8], xmm1
+ movlpd QWORD PTR [rsp + 2*8], xmm2
+ movlpd QWORD PTR [rsp + 3*8], xmm3
+ movlpd QWORD PTR [rsp + 4*8], xmm4
+ movlpd QWORD PTR [rsp + 5*8], xmm5
+ movlpd QWORD PTR [rsp + 6*8], xmm6
+ movlpd QWORD PTR [rsp + 7*8], xmm7
+ movlpd QWORD PTR [rsp + 8*8], xmm8
+ movlpd QWORD PTR [rsp + 9*8], xmm9
+ movlpd QWORD PTR [rsp + 10*8], xmm10
+ movlpd QWORD PTR [rsp + 11*8], xmm11
+ movlpd QWORD PTR [rsp + 12*8], xmm12
+ movlpd QWORD PTR [rsp + 13*8], xmm13
+ movlpd QWORD PTR [rsp + 14*8], xmm14
+ movlpd QWORD PTR [rsp + 15*8], xmm15
+ ; Call the garbage collector
+ sub rsp, 32 ; PR#5008: bottom 32 bytes are reserved for callee
+ call caml_garbage_collection
+ add rsp, 32 ; PR#5008
+ ; Restore all regs used by the code generator
+ movlpd xmm0, QWORD PTR [rsp + 0*8]
+ movlpd xmm1, QWORD PTR [rsp + 1*8]
+ movlpd xmm2, QWORD PTR [rsp + 2*8]
+ movlpd xmm3, QWORD PTR [rsp + 3*8]
+ movlpd xmm4, QWORD PTR [rsp + 4*8]
+ movlpd xmm5, QWORD PTR [rsp + 5*8]
+ movlpd xmm6, QWORD PTR [rsp + 6*8]
+ movlpd xmm7, QWORD PTR [rsp + 7*8]
+ movlpd xmm8, QWORD PTR [rsp + 8*8]
+ movlpd xmm9, QWORD PTR [rsp + 9*8]
+ movlpd xmm10, QWORD PTR [rsp + 10*8]
+ movlpd xmm11, QWORD PTR [rsp + 11*8]
+ movlpd xmm12, QWORD PTR [rsp + 12*8]
+ movlpd xmm13, QWORD PTR [rsp + 13*8]
+ movlpd xmm14, QWORD PTR [rsp + 14*8]
+ movlpd xmm15, QWORD PTR [rsp + 15*8]
+ add rsp, 16*8
+ pop rax
+ pop rbx
+ pop rdi
+ pop rsi
+ pop rdx
+ pop rcx
+ pop r8
+ pop r9
+ pop r10
+ pop r11
+ pop rbp
+ pop r12
+ pop r13
+ ; Restore caml_young_ptr, caml_exception_pointer
+ mov r15, caml_young_ptr
+ mov r14, caml_exception_pointer
+ ; Return to caller
+ ret
+
+ PUBLIC caml_alloc1
+ ALIGN 16
+caml_alloc1:
+ sub r15, 16
+ cmp r15, caml_young_limit
+ jb L100
+ ret
+L100:
+ mov rax, [rsp + 0]
+ mov caml_last_return_address, rax
+ lea rax, [rsp + 8]
+ mov caml_bottom_of_stack, rax
+ sub rsp, 8
+ call L105
+ add rsp, 8
+ jmp caml_alloc1
+
+ PUBLIC caml_alloc2
+ ALIGN 16
+caml_alloc2:
+ sub r15, 24
+ cmp r15, caml_young_limit
+ jb L101
+ ret
+L101:
+ mov rax, [rsp + 0]
+ mov caml_last_return_address, rax
+ lea rax, [rsp + 8]
+ mov caml_bottom_of_stack, rax
+ sub rsp, 8
+ call L105
+ add rsp, 8
+ jmp caml_alloc2
+
+ PUBLIC caml_alloc3
+ ALIGN 16
+caml_alloc3:
+ sub r15, 32
+ cmp r15, caml_young_limit
+ jb L102
+ ret
+L102:
+ mov rax, [rsp + 0]
+ mov caml_last_return_address, rax
+ lea rax, [rsp + 8]
+ mov caml_bottom_of_stack, rax
+ sub rsp, 8
+ call L105
+ add rsp, 8
+ jmp caml_alloc3
+
+ PUBLIC caml_allocN
+ ALIGN 16
+caml_allocN:
+ sub r15, rax
+ cmp r15, caml_young_limit
+ jb L103
+ ret
+L103:
+ push rax ; save desired size
+ mov rax, [rsp + 8]
+ mov caml_last_return_address, rax
+ lea rax, [rsp + 16]
+ mov caml_bottom_of_stack, rax
+ call L105
+ pop rax ; recover desired size
+ jmp caml_allocN
+
+; Call a C function from Caml
+
+ PUBLIC caml_c_call
+ ALIGN 16
+caml_c_call:
+ ; Record lowest stack address and return address
+ pop r12
+ mov caml_last_return_address, r12
+ mov caml_bottom_of_stack, rsp
+ ; Make the exception handler and alloc ptr available to the C code
+ mov caml_young_ptr, r15
+ mov caml_exception_pointer, r14
+ ; Call the function (address in rax)
+ call rax
+ ; Reload alloc ptr
+ mov r15, caml_young_ptr
+ ; Return to caller
+ push r12
+ ret
+
+; Start the Caml program
+
+ PUBLIC caml_start_program
+ ALIGN 16
+caml_start_program:
+ ; Save callee-save registers
+ push rbx
+ push rbp
+ push rsi
+ push rdi
+ push r12
+ push r13
+ push r14
+ push r15
+ sub rsp, 8+10*16 ; stack 16-aligned + 10 saved xmm regs
+ movapd OWORD PTR [rsp + 0*16], xmm6
+ movapd OWORD PTR [rsp + 1*16], xmm7
+ movapd OWORD PTR [rsp + 2*16], xmm8
+ movapd OWORD PTR [rsp + 3*16], xmm9
+ movapd OWORD PTR [rsp + 4*16], xmm10
+ movapd OWORD PTR [rsp + 5*16], xmm11
+ movapd OWORD PTR [rsp + 6*16], xmm12
+ movapd OWORD PTR [rsp + 7*16], xmm13
+ movapd OWORD PTR [rsp + 8*16], xmm14
+ movapd OWORD PTR [rsp + 9*16], xmm15
+ ; Initial entry point is caml_program
+ lea r12, caml_program
+ ; Common code for caml_start_program and caml_callback*
+L106:
+ ; Build a callback link
+ sub rsp, 8 ; stack 16-aligned
+ push caml_gc_regs
+ push caml_last_return_address
+ push caml_bottom_of_stack
+ ; Setup alloc ptr and exception ptr
+ mov r15, caml_young_ptr
+ mov r14, caml_exception_pointer
+ ; Build an exception handler
+ lea r13, L108
+ push r13
+ push r14
+ mov r14, rsp
+ ; Call the Caml code
+ call r12
+L107:
+ ; Pop the exception handler
+ pop r14
+ pop r12 ; dummy register
+L109:
+ ; Update alloc ptr and exception ptr
+ mov caml_young_ptr, r15
+ mov caml_exception_pointer, r14
+ ; Pop the callback restoring, link the global variables
+ pop caml_bottom_of_stack
+ pop caml_last_return_address
+ pop caml_gc_regs
+ add rsp, 8
+ ; Restore callee-save registers.
+ movapd xmm6, OWORD PTR [rsp + 0*16]
+ movapd xmm7, OWORD PTR [rsp + 1*16]
+ movapd xmm8, OWORD PTR [rsp + 2*16]
+ movapd xmm9, OWORD PTR [rsp + 3*16]
+ movapd xmm10, OWORD PTR [rsp + 4*16]
+ movapd xmm11, OWORD PTR [rsp + 5*16]
+ movapd xmm12, OWORD PTR [rsp + 6*16]
+ movapd xmm13, OWORD PTR [rsp + 7*16]
+ movapd xmm14, OWORD PTR [rsp + 8*16]
+ movapd xmm15, OWORD PTR [rsp + 9*16]
+ add rsp, 8+10*16
+ pop r15
+ pop r14
+ pop r13
+ pop r12
+ pop rdi
+ pop rsi
+ pop rbp
+ pop rbx
+ ; Return to caller
+ ret
+L108:
+ ; Exception handler
+ ; Mark the bucket as an exception result and return it
+ or rax, 2
+ jmp L109
+
+; Raise an exception from Caml
+
+ PUBLIC caml_raise_exn
+ ALIGN 16
+caml_raise_exn:
+ test caml_backtrace_active, 1
+ jne L110
+ mov rsp, r14 ; Cut stack
+ pop r14 ; Recover previous exception handler
+ ret ; Branch to handler
+L110:
+ mov r12, rax ; Save exception bucket in r12
+ mov rcx, rax ; Arg 1: exception bucket
+ mov rdx, [rsp] ; Arg 2: PC of raise
+ lea r8, [rsp+8] ; Arg 3: SP of raise
+ mov r9, r14 ; Arg 4: SP of handler
+ sub rsp, 32 ; Reserve 32 bytes on stack
+ call caml_stash_backtrace
+ mov rax, r12 ; Recover exception bucket
+ mov rsp, r14 ; Cut stack
+ pop r14 ; Recover previous exception handler
+ ret ; Branch to handler
+
+; Raise an exception from C
+
+ PUBLIC caml_raise_exception
+ ALIGN 16
+caml_raise_exception:
+ test caml_backtrace_active, 1
+ jne L111
+ mov rax, rcx ; First argument is exn bucket
+ mov rsp, caml_exception_pointer
+ pop r14 ; Recover previous exception handler
+ mov r15, caml_young_ptr ; Reload alloc ptr
+ ret
+L111:
+ mov r12, rcx ; Save exception bucket in r12
+ ; Arg 1: exception bucket
+ mov rdx, caml_last_return_address ; Arg 2: PC of raise
+ mov r8, caml_bottom_of_stack ; Arg 3: SP of raise
+ mov r9, caml_exception_pointer ; Arg 4: SP of handler
+ sub rsp, 32 ; Reserve 32 bytes on stack
+ call caml_stash_backtrace
+ mov rax, r12 ; Recover exception bucket
+ mov rsp, caml_exception_pointer
+ pop r14 ; Recover previous exception handler
+ mov r15, caml_young_ptr ; Reload alloc ptr
+ ret
+
+; Callback from C to Caml
+
+ PUBLIC caml_callback_exn
+ ALIGN 16
+caml_callback_exn:
+ ; Save callee-save registers
+ push rbx
+ push rbp
+ push rsi
+ push rdi
+ push r12
+ push r13
+ push r14
+ push r15
+ sub rsp, 8+10*16 ; stack 16-aligned + 10 saved xmm regs
+ movapd OWORD PTR [rsp + 0*16], xmm6
+ movapd OWORD PTR [rsp + 1*16], xmm7
+ movapd OWORD PTR [rsp + 2*16], xmm8
+ movapd OWORD PTR [rsp + 3*16], xmm9
+ movapd OWORD PTR [rsp + 4*16], xmm10
+ movapd OWORD PTR [rsp + 5*16], xmm11
+ movapd OWORD PTR [rsp + 6*16], xmm12
+ movapd OWORD PTR [rsp + 7*16], xmm13
+ movapd OWORD PTR [rsp + 8*16], xmm14
+ movapd OWORD PTR [rsp + 9*16], xmm15
+ ; Initial loading of arguments
+ mov rbx, rcx ; closure
+ mov rax, rdx ; argument
+ mov r12, [rbx] ; code pointer
+ jmp L106
+
+ PUBLIC caml_callback2_exn
+ ALIGN 16
+caml_callback2_exn:
+ ; Save callee-save registers
+ push rbx
+ push rbp
+ push rsi
+ push rdi
+ push r12
+ push r13
+ push r14
+ push r15
+ sub rsp, 8+10*16 ; stack 16-aligned + 10 saved xmm regs
+ movapd OWORD PTR [rsp + 0*16], xmm6
+ movapd OWORD PTR [rsp + 1*16], xmm7
+ movapd OWORD PTR [rsp + 2*16], xmm8
+ movapd OWORD PTR [rsp + 3*16], xmm9
+ movapd OWORD PTR [rsp + 4*16], xmm10
+ movapd OWORD PTR [rsp + 5*16], xmm11
+ movapd OWORD PTR [rsp + 6*16], xmm12
+ movapd OWORD PTR [rsp + 7*16], xmm13
+ movapd OWORD PTR [rsp + 8*16], xmm14
+ movapd OWORD PTR [rsp + 9*16], xmm15
+ ; Initial loading of arguments
+ mov rdi, rcx ; closure
+ mov rax, rdx ; first argument
+ mov rbx, r8 ; second argument
+ lea r12, caml_apply2 ; code pointer
+ jmp L106
+
+ PUBLIC caml_callback3_exn
+ ALIGN 16
+caml_callback3_exn:
+ ; Save callee-save registers
+ push rbx
+ push rbp
+ push rsi
+ push rdi
+ push r12
+ push r13
+ push r14
+ push r15
+ sub rsp, 8+10*16 ; stack 16-aligned + 10 saved xmm regs
+ movapd OWORD PTR [rsp + 0*16], xmm6
+ movapd OWORD PTR [rsp + 1*16], xmm7
+ movapd OWORD PTR [rsp + 2*16], xmm8
+ movapd OWORD PTR [rsp + 3*16], xmm9
+ movapd OWORD PTR [rsp + 4*16], xmm10
+ movapd OWORD PTR [rsp + 5*16], xmm11
+ movapd OWORD PTR [rsp + 6*16], xmm12
+ movapd OWORD PTR [rsp + 7*16], xmm13
+ movapd OWORD PTR [rsp + 8*16], xmm14
+ movapd OWORD PTR [rsp + 9*16], xmm15
+ ; Initial loading of arguments
+ mov rsi, rcx ; closure
+ mov rax, rdx ; first argument
+ mov rbx, r8 ; second argument
+ mov rdi, r9 ; third argument
+ lea r12, caml_apply3 ; code pointer
+ jmp L106
+
+ PUBLIC caml_ml_array_bound_error
+ ALIGN 16
+caml_ml_array_bound_error:
+ lea rax, caml_array_bound_error
+ jmp caml_c_call
+
+ .DATA
+ PUBLIC caml_system__frametable
+caml_system__frametable LABEL QWORD
+ QWORD 1 ; one descriptor
+ QWORD L107 ; return address into callback
+ WORD -1 ; negative frame size => use callback link
+ WORD 0 ; no roots here
+ ALIGN 8
+
+ PUBLIC caml_negf_mask
+ ALIGN 16
+caml_negf_mask LABEL QWORD
+ QWORD 8000000000000000H, 0
+
+ PUBLIC caml_absf_mask
+ ALIGN 16
+caml_absf_mask LABEL QWORD
+ QWORD 7FFFFFFFFFFFFFFFH, 0FFFFFFFFFFFFFFFFH
+
+ END