; File: astartup.asm
; Author: John van Groningen
; Machine: amd64
_TEXT segment para 'CODE'
_TEXT ends
_DATA segment para 'DATA'
_DATA ends
d2 equ r10
d3 equ r11
d4 equ r12
d5 equ r13
d3d equ r11d
d4d equ r12d
d2b equ r10b
ifdef LINUX
.intel_syntax noprefix
endif
THREAD equ 1
ifndef LINUX
extrn convert_real_to_string:near
endif
ifndef LINUX
extrn write_heap:near
endif
extrn return_code:near
extrn execution_aborted:near
extrn e____system__kFinalizerGCTemp:near
extrn e____system__kFinalizer:near
ifdef LINUX
.globl times
.globl exit
else
extrn GetTickCount:near
extrn ExitProcess:near
endif
if THREAD
extrn TlsAlloc:near
endif
ifdef USE_LIBM
extrn cos:near
extrn sin:near
extrn tan:near
extrn atan:near
endif
NEW_DESCRIPTORS = 1
_DATA segment
align (1 shl 3)
ife THREAD
semi_space_size dq 0
heap_p1 dq 0
heap_p2 dq 0
heap_p3 dq 0
neg_heap_p3 dq 0
end_heap_p3 dq 0
neg_heap_vector_plus_4 dq 0
heap_size_64_65 dq 0
heap_vector dq 0
stack_top dq 0
end_vector dq 0
heap_size_257 dq 0
heap_copied_vector dq 0
heap_end_after_gc dq 0
extra_heap dq 0
extra_heap_size dq 0
stack_p dq 0
halt_sp dq 0
n_allocated_words dq 0
endif
if THREAD
public tlsp_tls_index
tlsp_tls_index dq 0
endif
last_time dq 0
execute_time dq 0
garbage_collect_time dq 0
IO_time dq 0
compact_garbage_collect_time dq 0
mark_compact_garbage_collect_time dq 0
total_gc_bytes dq 0
total_compact_gc_bytes dq 0
ife THREAD
public saved_heap_p
saved_heap_p label ptr
dq 0
dq 0
public saved_a_stack_p
saved_a_stack_p dq 0
public end_a_stack
end_a_stack dq 0
public int_to_real_scratch
int_to_real_scratch dq 0
endif
heap_end_write_heap dq 0
d3_flag_write_heap dq 0
ife THREAD
heap2_begin_and_end label ptr
dq 0
dq 0
endif
public a_stack_guard_page
a_stack_guard_page dq 0
public profile_stack_pointer
profile_stack_pointer dq 0
dll_initialised dq 0
ife THREAD
public end_b_stack
end_b_stack dq 0
endif
basic_only dq 0
ife THREAD
heap_size_65 dq 0
heap_copied_vector_size dq 0
heap_end_after_copy_gc dq 0
heap_mbp dq 0
heap_p dq 0
stack_mbp dq 0
bit_counter label ptr
dq 0
bit_vector_p label ptr
dq 0
zero_bits_before_mark label ptr
dq 1
n_free_words_after_mark label ptr
dq 1000
n_last_heap_free_bytes label ptr
dq 0
lazy_array_list label ptr
dq 0
n_marked_words label ptr
dq 0
end_stack label ptr
dq 0
bit_vector_size label ptr
dq 0
endif
if THREAD
comm main_thread_local_storage:512
heap_p1_offset = 0
heap_p2_offset = 8
heap_p3_offset = 16
saved_heap_p_offset = 24
saved_r15_offset = 32
saved_a_stack_p_offset = 40
heap_vector_offset = 48
end_vector_offset = 56 ; temp
neg_heap_vector_plus_4_offset = 64 ; temp
heap_size_64_65_offset = 72 ; temp
heap_size_257_offset = 80
heap_copied_vector_offset = 88
heap_end_after_gc_offset = 96
extra_heap_offset = 104
extra_heap_size_offset = 112
stack_top_offset = 120 ; temp
stack_p_offset = 128
halt_sp_offset = 136
n_allocated_words_offset = 144 ; temp
heap2_begin_and_end_offset = 152
heap_copied_vector_size_offset = 168
heap_end_after_copy_gc_offset = 176
heap_mbp_offset = 184
heap_p_offset = 192
stack_mbp_offset = 200
bit_counter_offset = 208
bit_vector_p_offset = 216
bit_vector_size_offset = 224
zero_bits_before_mark_offset = 232
n_free_words_after_mark_offset = 240
n_last_heap_free_bytes_offset = 248
n_marked_words_offset = 256 ; temp
end_stack_offset = 264 ; temp
lazy_array_list_offset = 272 ; temp
heap_size_offset = 280
heap_size_65_offset = 288
a_stack_size_offset = 296
garbage_collect_flag_offset = 304
semi_space_size_offset = 312 ; temp
neg_heap_p3_offset = 320 ; temp
end_heap_p3_offset = 328 ; temp
endif
caf_list label ptr
dq 0
public caf_listp
caf_listp label ptr
dq 0
zero_length_string label ptr
dq __STRING__+2
dq 0
true_string label ptr
dq __STRING__+2
dq 4
true_c_string label ptr
db "True"
db 0,0,0,0
false_string label ptr
dq __STRING__+2
dq 5
false_c_string label ptr
db "False"
db 0,0,0
file_c_string label ptr
db "File"
db 0,0,0,0
ife THREAD
garbage_collect_flag label ptr
db 0
db 0,0,0
align (1 shl 3)
endif
comm sprintf_buffer:32
out_of_memory_string_1 label ptr
db "Not enough memory to allocate heap and stack"
db 10,0
printf_int_string label ptr
db "%d"
db 0
printf_real_string label ptr
db "%.15g"
db 0
printf_string_string label ptr
db "%s"
db 0
printf_char_string label ptr
db "%c"
db 0
garbage_collect_string_1 label ptr
db "A stack: "
db 0
garbage_collect_string_2 label ptr
db " bytes. BC stack: "
db 0
garbage_collect_string_3 label ptr
db " bytes."
db 10,0
heap_use_after_gc_string_1 label ptr
db "Heap use after garbage collection: "
db 0
heap_use_after_compact_gc_string_1 label ptr
db "Heap use after compacting garbage collection: "
db 0
heap_use_after_gc_string_2 label ptr
db " Bytes."
db 10,0
stack_overflow_string label ptr
db "Stack overflow."
db 10,0
out_of_memory_string_4 label ptr
db "Heap full."
db 10,0
time_string_1 label ptr
db "Execution: "
db 0
time_string_2 label ptr
db " Garbage collection: "
db 0
time_string_3 label ptr
db " "
db 0
time_string_4 label ptr
db " Total: "
db 0
high_index_string label ptr
db "Index too high in UPDATE string."
db 10,0
low_index_string label ptr
db "Index negative in UPDATE string."
db 10,0
IO_error_string label ptr
db "IO error: "
db 0
new_line_string label ptr
db 10,0
sprintf_time_string label ptr
db "%d.%02d"
db 0
marked_gc_string_1 label ptr
db "Marked: "
db 0
if THREAD
tls_alloc_error_string label ptr
db "Could not allocate thread local storage index"
db 10,0
endif
ifdef PROFILE
align 8
m_system:
dd 6
db "System"
db 0
db 0
dd m_system
garbage_collector_name:
dq 0
db "garbage_collector"
db 0
align 8
endif
align 16
public sign_real_mask
sign_real_mask label ptr
dq 8000000000000000h,8000000000000000h
public abs_real_mask
abs_real_mask label ptr
dq 7fffffffffffffffh,7fffffffffffffffh
align (1 shl 3)
NAN_real label ptr
dd 0ffffffffh,7fffffffh
one_real label ptr
dd 00000000h,3ff00000h
zero_real label ptr
dd 00000000h,00000000h
align (1 shl 2)
bit_set_table label ptr
dd 00000001h,00000002h,00000004h,00000008h
dd 00000010h,00000020h,00000040h,00000080h
dd 00000100h,00000200h,00000400h,00000800h
dd 00001000h,00002000h,00004000h,00008000h
dd 00010000h,00020000h,00040000h,00080000h
dd 00100000h,00200000h,00400000h,00800000h
dd 01000000h,02000000h,04000000h,08000000h
dd 10000000h,20000000h,40000000h,80000000h
dd 0
bit_set_table2 label ptr
dd 00000001h,0,00000002h,0,00000004h,0,00000008h,0
dd 00000010h,0,00000020h,0,00000040h,0,00000080h,0
dd 00000100h,0,00000200h,0,00000400h,0,00000800h,0
dd 00001000h,0,00002000h,0,00004000h,0,00008000h,0
dd 00010000h,0,00020000h,0,00040000h,0,00080000h,0
dd 00100000h,0,00200000h,0,00400000h,0,00800000h,0
dd 01000000h,0,02000000h,0,04000000h,0,08000000h,0
dd 10000000h,0,20000000h,0,40000000h,0,80000000h,0
dd 0,0
bit_clear_table label ptr
dd 0fffffffeh,0fffffffdh,0fffffffbh,0fffffff7h
dd 0ffffffefh,0ffffffdfh,0ffffffbfh,0ffffff7fh
dd 0fffffeffh,0fffffdffh,0fffffbffh,0fffff7ffh
dd 0ffffefffh,0ffffdfffh,0ffffbfffh,0ffff7fffh
dd 0fffeffffh,0fffdffffh,0fffbffffh,0fff7ffffh
dd 0ffefffffh,0ffdfffffh,0ffbfffffh,0ff7fffffh
dd 0feffffffh,0fdffffffh,0fbffffffh,0f7ffffffh
dd 0efffffffh,0dfffffffh,0bfffffffh,7fffffffh
dd 0ffffffffh
bit_clear_table2 label ptr
dd 0fffffffeh,-1,0fffffffdh,-1,0fffffffbh,-1,0fffffff7h,-1
dd 0ffffffefh,-1,0ffffffdfh,-1,0ffffffbfh,-1,0ffffff7fh,-1
dd 0fffffeffh,-1,0fffffdffh,-1,0fffffbffh,-1,0fffff7ffh,-1
dd 0ffffefffh,-1,0ffffdfffh,-1,0ffffbfffh,-1,0ffff7fffh,-1
dd 0fffeffffh,-1,0fffdffffh,-1,0fffbffffh,-1,0fff7ffffh,-1
dd 0ffefffffh,-1,0ffdfffffh,-1,0ffbfffffh,-1,0ff7fffffh,-1
dd 0feffffffh,-1,0fdffffffh,-1,0fbffffffh,-1,0f7ffffffh,-1
dd 0efffffffh,-1,0dfffffffh,-1,0bfffffffh,-1,7fffffffh,-1
dd 0ffffffffh,-1
first_one_bit_table label ptr
db -1,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
db 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
db 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
db 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
db 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
db 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
db 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
db 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
db 7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
db 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
db 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
db 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
db 6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
db 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
db 5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
db 4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
align(1 shl 2)
comm sprintf_time_buffer:20
align(1 shl 3)
; public small_integers
comm small_integers:33*16
; public static_characters
comm static_characters:256*16
; extrn clean_exception_handler:near
; public clean_unwind_info
;clean_unwind_info:
; DD 000000009H
; DD imagerel(clean_exception_handler)
_DATA ends
_TEXT segment
public abc_main
public print
public print_char
public print_int
public print_real
public print__string__
public print__chars__sc
public print_sc
public print_symbol
public print_symbol_sc
public printD
public DtoAC
public push_t_r_args
public push_a_r_args
public halt
public dump
public catAC
public sliceAC
public updateAC
public eqAC
public cmpAC
public string_to_string_node
public int_array_to_node
public real_array_to_node
public _create_arrayB
public _create_arrayC
public _create_arrayI
public _create_arrayI32
public _create_arrayR
public _create_arrayR32
public _create_r_array
public create_array
public create_arrayB
public create_arrayC
public create_arrayI
public create_arrayI32
public create_arrayR
public create_arrayR32
public create_R_array
public BtoAC
public ItoAC
public RtoAC
public eqD
public collect_0
public collect_1
public collect_2
public collect_3
public yet_args_needed
public yet_args_needed_0
public yet_args_needed_1
public yet_args_needed_2
public yet_args_needed_3
public yet_args_needed_4
public _c3,_c4,_c5,_c6,_c7,_c8,_c9,_c10,_c11,_c12
public _c13,_c14,_c15,_c16,_c17,_c18,_c19,_c20,_c21,_c22
public _c23,_c24,_c25,_c26,_c27,_c28,_c29,_c30,_c31,_c32
public e__system__nind
public e__system__eaind
; old names of the previous two labels for compatibility, remove later
public __indirection,__eaind
extrn e__system__dind:near
public eval_fill
public eval_upd_0,eval_upd_1,eval_upd_2,eval_upd_3,eval_upd_4
public eval_upd_5,eval_upd_6,eval_upd_7,eval_upd_8,eval_upd_9
public eval_upd_10,eval_upd_11,eval_upd_12,eval_upd_13,eval_upd_14
public eval_upd_15,eval_upd_16,eval_upd_17,eval_upd_18,eval_upd_19
public eval_upd_20,eval_upd_21,eval_upd_22,eval_upd_23,eval_upd_24
public eval_upd_25,eval_upd_26,eval_upd_27,eval_upd_28,eval_upd_29
public eval_upd_30,eval_upd_31,eval_upd_32
public repl_args_b
public push_arg_b
public del_args
public add_IO_time
public add_execute_time
public IO_error
public stack_overflow
public out_of_memory_4
public print_error
ifdef LINUX
.globl __start
else
extrn _start:near
endif
ifdef PROFILE
; extrn init_profiler:near
; extrn profile_n:near
; extrn profile_s:near
; extrn profile_r:near
; extrn write_profile_information:near
; extrn write_profile_stack:near
endif
ifdef USE_LIBM
public cos_real
public sin_real
public tan_real
public asin_real
public acos_real
public atan_real
public ln_real
public log10_real
public exp_real
public pow_real
endif
public entier_real
public r_to_i_real
ifdef USE_LIBM
public _c_pow
public _c_log10
public _c_entier
endif
public __driver
; from system.abc:
extrn dINT:near
extrn INT32:near
extrn CHAR:near
extrn BOOL:near
extrn REAL:near
extrn REAL32:near
extrn FILE:near
extrn __STRING__:near
extrn __ARRAY__:near
extrn __cycle__in__spine:near
extrn __print__graph:near
extrn __eval__to__nf:near
; from wcon.c:
extrn w_print_char:near
extrn w_print_string:near
extrn w_print_text:near
extrn w_print_int:near
extrn w_print_real:near
extrn ew_print_char:near
extrn ew_print_text:near
extrn ew_print_string:near
extrn ew_print_int:near
extrn ew_print_real:near
extrn ab_stack_size:near
extrn heap_size:near
extrn flags:near
; from standard c library:
ifndef LINUX
extrn allocate_memory:near
ife THREAD
extrn allocate_memory_with_guard_page_at_end:near
endif
extrn free_memory:near
endif
extrn heap_size_multiple:near
extrn initial_heap_size:near
extrn min_write_heap_size:near
extrn __Nil:near
; public finalizer_list
comm finalizer_list:qword
; public free_finalizer_list
comm free_finalizer_list:qword
abc_main:
push rbx
push rcx
push rdx
push rbp
push rsi
push rdi
call init_clean
test rax,rax
jne init_error
call init_timer
if THREAD
mov halt_sp_offset[r9],rsp
else
mov halt_sp,rsp
endif
ifdef PROFILE
call init_profiler
endif
ifdef LINUX
call __start
exit_:
else
call _start
exit:
endif
call exit_clean
init_error:
pop rdi
pop rsi
pop rbp
pop rdx
pop rcx
pop rbx
ifdef LINUX
mov eax,dword ptr return_code
jne return_code_set_1
mov eax,-1
return_code_set_1:
endif
ret
public DllMain
DllMain:
cmp edx,1
je DLL_PROCESS_ATTACH
jb DLL_PROCESS_DETACH
ret
DLL_PROCESS_ATTACH:
push rbx
push rbp
push rsi
push rdi
ifndef LINUX
db 49h
push rsp
db 49h
push rbp
db 49h
push rsi
db 49h
push rdi
else
push r12
push r13
push r14
push r15
endif
mov qword ptr dll_initialised,1
call init_clean
test rax,rax
jne init_dll_error
call init_timer
if THREAD
mov halt_sp_offset[r9],rsp
else
mov halt_sp,rsp
endif
ifdef PROFILE
call init_profiler
endif
if THREAD
mov qword ptr saved_heap_p_offset[r9],rdi
mov qword ptr saved_r15_offset[r9],r15
mov qword ptr saved_a_stack_p_offset[r9],rsi
else
mov qword ptr saved_heap_p,rdi
mov qword ptr saved_heap_p+8,r15
mov saved_a_stack_p,rsi
endif
mov rax,1
jmp exit_dll_init
init_dll_error:
xor rax,rax
jmp exit_dll_init
DLL_PROCESS_DETACH:
push rbx
push rbp
push rsi
push rdi
ifndef LINUX
db 49h
push rsp
db 49h
push rbp
db 49h
push rsi
db 49h
push rdi
else
push r12
push r13
push r14
push r15
endif
if THREAD
mov rdi,qword ptr saved_heap_p_offset[r9]
mov r15,qword ptr saved_r15_offset[r9]
mov rsi,qword ptr saved_a_stack_p_offset[r9]
else
mov rdi,qword ptr saved_heap_p
mov r15,qword ptr saved_heap_p+8
mov rsi,saved_a_stack_p
endif
call exit_clean
exit_dll_init:
ifndef LINUX
db 49h
pop rdi
db 49h
pop rsi
db 49h
pop rbp
db 49h
pop rsp
else
pop r15
pop r14
pop r13
pop r12
endif
pop rdi
pop rsi
pop rbp
pop rbx
ret
init_clean:
if THREAD
ifdef LINUX
sub rsp,8
mov rdi,rsp
sub rsi,rsi
mov rbp,rsp
and rsp,-16
call pthread_key_create
mov rsp,rbp
lea r9,main_thread_local_storage
test eax,eax
jne tls_alloc_error
mov rdi,qword ptr [rsp]
mov rsi,r9
mov qword ptr tlsp_tls_index,rdi
mov rbp,rsp
and rsp,-16
call pthread_setspecific
mov rsp,rbp
lea r9,main_thread_local_storage
test eax,eax
jne tls_alloc_error
add rsp,8
lea r9,main_thread_local_storage
else
sub rsp,32
call TlsAlloc
add rsp,32
cmp rax,64
jae tls_alloc_error
mov qword ptr tlsp_tls_index,rax
lea r9,main_thread_local_storage
mov qword ptr gs:[1480h+rax*8],r9
endif
endif
lea rax,128[rsp]
sub rsp,32+8
ife THREAD
sub rax,qword ptr ab_stack_size
mov end_b_stack,rax
endif
mov rax,qword ptr flags
and rax,1
mov basic_only,rax
; call allow_prefetch_for_athlon
mov rax,qword ptr heap_size
if THREAD
mov heap_size_offset[r9],rax
endif
sub rax,7
xor rdx,rdx
mov rbx,65
div rbx
if THREAD
mov qword ptr heap_size_65_offset[r9],rax
mov rax,qword ptr heap_size_offset[r9]
else
mov qword ptr heap_size_65,rax
mov rax,qword ptr heap_size
endif
sub rax,7
xor rdx,rdx
mov rbx,257
div rbx
if THREAD
mov heap_size_257_offset[r9],rax
else
mov heap_size_257,rax
endif
add rax,7
and rax,-8
if THREAD
mov qword ptr heap_copied_vector_size_offset[r9],rax
mov qword ptr heap_end_after_copy_gc_offset[r9],0
mov rax,qword ptr heap_size_offset[r9]
else
mov qword ptr heap_copied_vector_size,rax
mov qword ptr heap_end_after_copy_gc,0
mov rax,qword ptr heap_size
endif
add rax,7
and rax,-8
if THREAD
mov qword ptr heap_size_offset[r9],rax
else
mov qword ptr heap_size,rax
endif
add rax,7
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov rdi,rax
call malloc
else
mov rcx,rax
call allocate_memory
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
test rax,rax
je no_memory_2
if THREAD
mov heap_mbp_offset[r9],rax
else
mov heap_mbp,rax
endif
lea rdi,7[rax]
and rdi,-8
if THREAD
mov heap_p_offset[r9],rdi
else
mov heap_p,rdi
endif
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r14,rdi
mov rdi,qword ptr ab_stack_size
if THREAD
mov qword ptr a_stack_size_offset[r9],rdi
endif
add rdi,7
call malloc
mov rdi,r14
else
mov rcx,qword ptr ab_stack_size
if THREAD
mov qword ptr a_stack_size_offset[r9],rcx
endif
add rcx,7
if THREAD
call allocate_memory
else
call allocate_memory_with_guard_page_at_end
endif
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
test rax,rax
je no_memory_3
if THREAD
mov stack_mbp_offset[r9],rax
add rax,qword ptr a_stack_size_offset[r9]
else
mov stack_mbp,rax
add rax,qword ptr ab_stack_size
endif
add rax,7+4095
and rax,-4096
mov qword ptr a_stack_guard_page,rax
if THREAD
sub rax,qword ptr a_stack_size_offset[r9]
else
sub rax,qword ptr ab_stack_size
endif
add rax,7
and rax,-8
mov rsi,rax
if THREAD
mov stack_p_offset[r9],rax
else
mov stack_p,rax
endif
ife THREAD
add rax,qword ptr ab_stack_size
sub rax,64
mov qword ptr end_a_stack,rax
endif
lea rcx,small_integers
xor rax,rax
lea rbx,(dINT+2)
make_small_integers_lp:
mov [rcx],rbx
mov 8[rcx],rax
inc rax
add rcx,16
cmp rax,33
jne make_small_integers_lp
lea rcx,static_characters
xor rax,rax
lea rbx,(CHAR+2)
make_static_characters_lp:
mov [rcx],rbx
mov 8[rcx],rax
inc rax
add rcx,16
cmp rax,256
jne make_static_characters_lp
lea rcx,(caf_list+8)
mov qword ptr caf_listp,rcx
lea rcx,__Nil-8
mov qword ptr finalizer_list,rcx
mov qword ptr free_finalizer_list,rcx
if THREAD
mov heap_p1_offset[r9],rdi
mov rbp,qword ptr heap_size_257_offset[r9]
else
mov heap_p1,rdi
mov rbp,qword ptr heap_size_257
endif
shl rbp,4
lea rax,[rdi+rbp*8]
if THREAD
mov heap_copied_vector_offset[r9],rax
add rax,heap_copied_vector_size_offset[r9]
mov heap_p2_offset[r9],rax
mov byte ptr garbage_collect_flag_offset[r9],0
else
mov heap_copied_vector,rax
add rax,heap_copied_vector_size
mov heap_p2,rax
mov byte ptr garbage_collect_flag,0
endif
test byte ptr flags,64
je no_mark1
if THREAD
mov rax,qword ptr heap_size_65_offset[r9]
mov qword ptr heap_vector_offset[r9],rdi
else
mov rax,qword ptr heap_size_65
mov qword ptr heap_vector,rdi
endif
add rdi,rax
add rdi,7
and rdi,-8
if THREAD
mov qword ptr heap_p3_offset[r9],rdi
else
mov qword ptr heap_p3,rdi
endif
lea rbp,[rax*8]
if THREAD
mov byte ptr garbage_collect_flag_offset [r9],-1
else
mov byte ptr garbage_collect_flag,-1
endif
no_mark1:
mov rax,qword ptr initial_heap_size
mov rbx,4000
test byte ptr flags,64
jne no_mark9
add rbx,rbx
no_mark9:
cmp rax,rbx
jle too_large_or_too_small
shr rax,3
cmp rax,rbp
jge too_large_or_too_small
mov rbp,rax
too_large_or_too_small:
lea rax,[rdi+rbp*8]
if THREAD
mov heap_end_after_gc_offset[r9],rax
else
mov heap_end_after_gc,rax
endif
test byte ptr flags,64
je no_mark2
if THREAD
mov qword ptr bit_vector_size_offset[r9],rbp
else
mov qword ptr bit_vector_size,rbp
endif
no_mark2:
mov r15,rbp
add rsp,32+8
xor rax,rax
ret
if THREAD
tls_alloc_error:
mov rbp,rsp
and rsp,-16
ifdef LINUX
lea rdi,tls_alloc_error_string
else
lea rcx,tls_alloc_error_string
endif
call ew_print_string
mov rsp,rbp
add rsp,8
mov rax,1
ret
endif
no_memory_2:
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
lea rdi,out_of_memory_string_1
else
lea rcx,out_of_memory_string_1
endif
call ew_print_string
mov rsp,rbp
mov qword ptr execution_aborted,1
add rsp,32
if THREAD
mov r9,rbx
endif
mov rax,1
ret
no_memory_3:
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
lea rdi,out_of_memory_string_1
else
lea ecx,out_of_memory_string_1
endif
call ew_print_string
mov qword ptr execution_aborted,1
if THREAD
mov r9,rbx
endif
ifdef LINUX
if THREAD
mov rdi,heap_mbp_offset[r9]
else
mov rdi,heap_mbp
endif
call free
else
if THREAD
mov rcx,heap_mbp_offset[r9]
else
mov rcx,heap_mbp
endif
call free_memory
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
add rsp,32
mov rax,1
ret
exit_clean:
call add_execute_time
mov rax,qword ptr flags
test al,8
je no_print_execution_time
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifndef LINUX
sub rsp,32
endif
ifdef LINUX
lea rdi,time_string_1
else
lea rcx,time_string_1
endif
call ew_print_string
mov rax,execute_time
call print_time
ifdef LINUX
lea rdi,time_string_2
else
lea rcx,time_string_2
endif
call ew_print_string
mov rax,garbage_collect_time
ifdef MEASURE_GC
else
add rax,mark_compact_garbage_collect_time
add rax,compact_garbage_collect_time
endif
call print_time
ifdef MEASURE_GC
ifdef LINUX
lea rdi,time_string_3
else
lea rcx,time_string_3
endif
call ew_print_string
mov rax,mark_compact_garbage_collect_time
call print_time
ifdef LINUX
lea rdi,time_string_3
else
lea rcx,time_string_3
endif
call ew_print_string
mov rax,compact_garbage_collect_time
call print_time
endif
ifdef LINUX
lea rdi,time_string_4
else
lea rcx,time_string_4
endif
call ew_print_string
mov rax,execute_time
add rax,garbage_collect_time
add rax,IO_time
add rax,mark_compact_garbage_collect_time
add rax,compact_garbage_collect_time
call print_time
ifdef LINUX
mov rdi,10
else
mov rcx,10
endif
call ew_print_char
ifdef MEASURE_GC
ifdef LINUX
mov rdi,total_gc_bytes
else
mov rcx,total_gc_bytes
endif
call ew_print_int
ifdef LINUX
mov rdi,32
else
mov rcx,32
endif
call ew_print_char
ifdef LINUX
mov rdi,total_compact_gc_bytes
else
mov rcx,total_compact_gc_bytes
endif
call ew_print_int
ifdef LINUX
mov rdi,32
else
mov rcx,32
endif
call ew_print_char
mov rax,1000
cvtsi2sd xmm1,rax
cvtsi2sd xmm0,qword ptr garbage_collect_time
divsd xmm0,xmm1
call ew_print_real
ifdef LINUX
mov rdi,32
else
mov rcx,32
endif
call ew_print_char
mov rax,1000
cvtsi2sd xmm1,rax
cvtsi2sd xmm0,qword ptr mark_compact_garbage_collect_time
divsd xmm0,xmm1
call ew_print_real
ifdef LINUX
mov rdi,32
else
mov rcx,32
endif
call ew_print_char
mov rax,1000
cvtsi2sd xmm1,rax
cvtsi2sd xmm0,qword ptr compact_garbage_collect_time
divsd xmm0,xmm1
call ew_print_real
ifdef LINUX
mov rdi,10
else
mov rcx,10
endif
call ew_print_char
mov rax,1000
cvtsi2sd xmm1,rax
cvtsi2sd xmm2,qword ptr garbage_collect_time
divsd xmm2,xmm1
mov rax,qword ptr total_gc_bytes
cvtsi2sd xmm0,rax
divsd xmm0,xmm2
call ew_print_real
ifdef LINUX
mov rdi,32
else
mov rcx,32
endif
call ew_print_char
mov rax,1000
cvtsi2sd xmm1,rax
cvtsi2sd xmm2,qword ptr mark_compact_garbage_collect_time
divsd xmm2,xmm1
mov rax,qword ptr total_compact_gc_bytes
cvtsi2sd xmm0,rax
divsd xmm0,xmm2
call ew_print_real
ifdef LINUX
mov rdi,32
else
mov rcx,32
endif
call ew_print_char
mov rax,1000
cvtsi2sd xmm1,rax
cvtsi2sd xmm2,qword ptr compact_garbage_collect_time
divsd xmm2,xmm1
mov rax,qword ptr total_compact_gc_bytes
cvtsi2sd xmm0,rax
divsd xmm0,xmm2
call ew_print_real
ifdef LINUX
mov rdi,32
else
mov rcx,32
endif
call ew_print_char
mov rax,1000
cvtsi2sd xmm1,rax
cvtsi2sd xmm2,qword ptr mark_compact_garbage_collect_time
cvtsi2sd xmm3,qword ptr compact_garbage_collect_time
addsd xmm2,xmm3
divsd xmm2,xmm1
mov rax,qword ptr total_compact_gc_bytes
cvtsi2sd xmm0,rax
divsd xmm0,xmm2
call ew_print_real
ifdef LINUX
mov rdi,10
else
mov rcx,10
endif
call ew_print_char
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
no_print_execution_time:
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
if THREAD
mov rdi,stack_mbp_offset[r9]
else
mov rdi,stack_mbp
endif
call free
if THREAD
mov r9,rbx
endif
if THREAD
mov rdi,heap_mbp_offset[r9]
else
mov rdi,heap_mbp
endif
call free
else
if THREAD
mov rcx,stack_mbp_offset[r9]
else
mov rcx,stack_mbp
endif
sub rsp,32
call free_memory
if THREAD
mov r9,rbx
endif
if THREAD
mov rcx,heap_mbp_offset[r9]
else
mov rcx,heap_mbp
endif
call free_memory
add rsp,32
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
ifdef PROFILE
ifndef TRACE
call write_profile_information
endif
endif
ret
__driver:
mov rbp,qword ptr flags
test rbp,16
je __print__graph
jmp __eval__to__nf
print_time:
push rbp
if THREAD
mov r14,r9
push rbx
endif
xor rdx,rdx
mov rbx,1000
div rbx
mov rcx,rax
mov rax,rdx
xor rdx,rdx
mov rbx,10
div rbx
push rax
mov rbp,rsp
and rsp,-16
ifdef LINUX
mov rdi,rcx
else
sub rsp,32
endif
call ew_print_int
mov rsp,rbp
lea rcx,sprintf_time_buffer
xor rdx,rdx
mov rbx,10
; movb $'.',(%rcx)
mov byte ptr [rcx],46
pop rax
div rbx
add rax,48
add rdx,48
mov byte ptr 1[rcx],al
mov byte ptr 2[rcx],dl
mov rbp,rsp
and rsp,-16
ifdef LINUX
mov rsi,3
mov rdi,rcx
else
mov rdx,3
sub rsp,32
endif
call ew_print_text
mov rsp,rbp
if THREAD
pop rbx
mov r9,r14
endif
pop rbp
ret
print_sc:
mov rbp,basic_only
test rbp,rbp
jne end_print
print:
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
mov rdi,rax
else
mov rcx,rax
sub rsp,32
endif
call w_print_string
ifdef LINUX
mov rsi,r13
mov rdi,r14
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
end_print:
ret
dump:
call print
jmp halt
printD: test al,2
jne printD_
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
lea rdi,4[rax]
mov esi,0[rax]
else
lea rcx,4[rax]
mov edx,dword ptr [rax]
sub rsp,32
endif
call w_print_text
ifdef LINUX
mov rsi,r13
mov rsi,r14
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
ret
DtoAC_record:
ifdef NEW_DESCRIPTORS
movsxd rbp,dword ptr (-6)[rax]
else
movsx rbp,dword ptr (-4)[rbp]
endif
jmp DtoAC_string_a2
DtoAC: test al,2
jne DtoAC_
mov rbp,rax
jmp DtoAC_string_a2
DtoAC_:
ifdef NEW_DESCRIPTORS
cmp word ptr (-2)[rax],256
jae DtoAC_record
movzx rbx,word ptr [rax]
lea rbp,10[rax+rbx]
else
lea rbp,(-2)[rax]
movsx rbx,word ptr [rbp]
cmp rbx,256
jae DtoAC_record
shl rbx,3
sub rbp,rbx
movzx rbx,word ptr (-2)[rbp]
lea rbp,4[rbp+rbx*8]
endif
DtoAC_string_a2:
mov eax,dword ptr [rbp]
lea rcx,4[rbp]
jmp build_string
print_symbol:
xor rbx,rbx
jmp print_symbol_2
print_symbol_sc:
mov rbx,basic_only
print_symbol_2:
mov rax,[rcx]
cmp rax,offset dINT+2
je print_int_node
cmp rax,offset CHAR+2
je print_char_denotation
cmp rax,offset BOOL+2
je print_bool
cmp rax,offset REAL+2
je print_real_node
test rbx,rbx
jne end_print_symbol
printD_:
ifdef NEW_DESCRIPTORS
cmp word ptr (-2)[rax],256
jae print_record
movzx rbx,word ptr [rax]
lea rbp,10[rax+rbx]
jmp print_string_a2
print_record:
movsxd rbp,dword ptr (-6)[rax]
jmp print_string_a2
else
lea rbp,(-2)[rax]
movsx rbx,word ptr [rbp]
cmp rbx,256
jae print_record
shl rbx,3
sub rbp,rbx
movzx rbx,word ptr (-2)[rbp]
lea rbp,4[rbp+rbx*8]
jmp print_string_a2
print_record:
mov ebp,(-4)[rbp]
jmp print_string_a2
endif
end_print_symbol:
ret
print_int_node:
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
mov rdi,8[rcx]
else
sub rsp,32
mov rcx,8[rcx]
endif
call w_print_int
ifdef LINUX
mov rsi,r13
mov rdi,r14
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
ret
print_int:
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
mov rdi,rax
else
mov rcx,rax
sub rsp,32
endif
call w_print_int
ifdef LINUX
mov rsi,r13
mov rdi,r14
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
ret
print_char_denotation:
test rbx,rbx
jne print_char_node
mov rbp,rsp
and rsp,-16
if THREAD
mov r14,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
else
sub rsp,32
endif
mov rbx,8[rcx]
ifdef LINUX
mov rdi,0x27
else
mov rcx,27h
endif
call w_print_char
ifdef LINUX
mov rdi,rbx
else
mov rcx,rbx
endif
call w_print_char
ifdef LINUX
mov rdi,0x27
else
mov rcx,27h
endif
call w_print_char
ifdef LINUX
mov rsi,r13
mov rdi,r14
endif
mov rsp,rbp
if THREAD
mov r9,r14
endif
ret
print_char_node:
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
mov rdi,8[rcx]
else
mov rcx,8[rcx]
sub rsp,32
endif
call w_print_char
ifdef LINUX
mov rsi,r13
mov rdi,r14
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
ret
print_char:
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
mov rdi,rax
else
mov rcx,rax
sub rsp,32
endif
call w_print_char
ifdef LINUX
mov rsi,r13
mov rdi,r14
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
ret
print_bool:
movsx rcx,byte ptr 8[rcx]
test rcx,rcx
je print_false
print_true:
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
lea rdi,true_c_string
else
lea rcx,true_c_string
sub rsp,32
endif
call w_print_string
ifdef LINUX
mov rsi,r13
mov rdi,r14
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
ret
print_false:
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
lea rdi,false_c_string
else
lea rcx,false_c_string
sub rsp,32
endif
call w_print_string
ifdef LINUX
mov rsi,r13
mov rdi,r14
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
ret
print_real_node:
movlpd xmm0,qword ptr 8[rcx]
print_real:
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
else
sub rsp,32
endif
call w_print_real
ifdef LINUX
mov rsi,r13
mov rdi,r14
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
ret
print_string_a2:
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
lea rdi,4[rbp]
mov esi,0[rbp]
mov rbp,rsp
and rsp,-16
else
lea rcx,4[rbp]
mov edx,0[rbp]
mov rbp,rsp
and rsp,-16
sub rsp,32
endif
call w_print_text
ifdef LINUX
mov rsi,r13
mov rdi,r14
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
ret
print__chars__sc:
mov rbp,basic_only
test rbp,rbp
jne no_print_chars
print__string__:
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
mov rsi,8[rcx]
lea rdi,16[rcx]
else
mov rdx,8[rcx]
lea rcx,16[rcx]
sub rsp,32
endif
call w_print_text
ifdef LINUX
mov rsi,r13
mov rdi,r14
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
no_print_chars:
ret
push_a_r_args:
push rdi
mov rdx,qword ptr 16[rcx]
sub rdx,2
movzx rdi,word ptr [rdx]
sub rdi,256
movzx rbx,word ptr 2[rdx]
add rdx,4
push rdx
mov rdx,rdi
sub rdx,rbx
shl rax,3
lea rcx,24[rcx+rbx*8]
dec rdi
mul_array_size_lp:
add rcx,rax
sub rdi,1
jnc mul_array_size_lp
lea rdi,[rcx+rdx*8]
jmp push_a_elements
push_a_elements_lp:
mov rax,qword ptr (-8)[rcx]
sub rcx,8
mov qword ptr [rsi],rax
add rsi,8
push_a_elements:
sub rbx,1
jnc push_a_elements_lp
mov rcx,rdi
pop rax
pop rdi
pop rbp
jmp push_b_elements
push_b_elements_lp:
push (-8)[rcx]
sub rcx,8
push_b_elements:
sub rdx,1
jnc push_b_elements_lp
jmp rbp
push_t_r_args:
pop rbp
mov rdx,qword ptr [rcx]
add rcx,8
sub rdx,2
movzx rax,word ptr [rdx]
sub rax,256
movzx rbx,word ptr 2[rdx]
add rdx,4
mov qword ptr [rsi],rdx
mov qword ptr 8[rsi],rbx
sub rbx,rax
neg rbx
lea rdx,[rcx+rax*8]
cmp rax,2
jbe small_record
mov rdx,qword ptr 8[rcx]
lea rdx,(-8)[rdx+rax*8]
small_record:
jmp push_r_b_elements
push_r_b_elements_lp:
dec rax
jne not_first_arg_b
push [rcx]
jmp push_r_b_elements
not_first_arg_b:
push (-8)[rdx]
sub rdx,8
push_r_b_elements:
sub rbx,1
jnc push_r_b_elements_lp
mov rbx,qword ptr 8[rsi]
push rbp
push [rsi]
jmp push_r_a_elements
push_r_a_elements_lp:
dec rax
jne not_first_arg_a
mov rbp,qword ptr [rcx]
mov qword ptr [rsi],rbp
add rsi,8
jmp push_r_a_elements
not_first_arg_a:
mov rbp,qword ptr (-8)[rdx]
sub rdx,8
mov qword ptr [rsi],rbp
add rsi,8
push_r_a_elements:
sub rbx,1
jnc push_r_a_elements_lp
pop rax
ret
BtoAC:
test al,al
je BtoAC_false
BtoAC_true:
mov rcx,offset true_string
ret
BtoAC_false:
mov rcx,offset false_string
ret
RtoAC:
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
lea rsi,printf_real_string
lea rdi,sprintf_buffer
mov rax,1
call sprintf
mov rsi,r13
mov rdi,r14
else
lea rdx,sprintf_buffer
sub rsp,32
call convert_real_to_string
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
jmp return_sprintf_buffer
ItoAC:
mov rcx,offset sprintf_buffer
call int_to_string
mov rax,rcx
sub rax,offset sprintf_buffer
jmp sprintf_buffer_to_string
public convert_int_to_string
convert_int_to_string:
push rbp
push rbx
mov rax,rdx
call int_to_string
mov rax,rcx
pop rbx
pop rbp
ret
int_to_string:
test rax,rax
jns no_minus
mov byte ptr [rcx],45
inc rcx
neg rax
no_minus:
mov rbp,rcx
je zero_digit
calculate_digits:
cmp rax,10
jb last_digit
mov rdx,0cccccccccccccccdh
mov rbx,rax
mul rdx
mov rax,rdx
and rdx,-8
add rbx,48
shr rax,3
sub rbx,rdx
shr rdx,2
sub rbx,rdx
mov byte ptr [rcx],bl
inc rcx
jmp calculate_digits
last_digit:
test rax,rax
je no_zero
zero_digit:
add rax,48
mov byte ptr [rcx],al
inc rcx
no_zero:
mov rdx,rcx
reverse_digits:
dec rdx
cmp rbp,rdx
jae end_reverse_digits
mov bl,byte ptr [rbp]
mov al,byte ptr [rdx]
mov byte ptr [rdx],bl
mov byte ptr [rbp],al
inc rbp
jmp reverse_digits
end_reverse_digits:
mov byte ptr [rcx],0
ret
return_sprintf_buffer:
mov rax,offset sprintf_buffer-1
skip_characters:
inc rax
cmp byte ptr [rax],0
jne skip_characters
sub rax,offset sprintf_buffer
sprintf_buffer_to_string:
mov rcx,offset sprintf_buffer
build_string:
lea rbx,16+7[rax]
shr rbx,3
sub r15,rbx
jge D_to_S_no_gc
push rcx
call collect_0
pop rcx
D_to_S_no_gc:
if THREAD
lea rbp,__STRING__+2
sub rbx,2
mov qword ptr [rdi],rbp
mov 8[rdi],rax
mov rbp,rdi
else
sub rbx,2
mov rbp,rdi
lea r9,__STRING__+2
mov qword ptr [rdi],r9
mov 8[rdi],rax
endif
add rdi,16
jmp D_to_S_cp_str_2
D_to_S_cp_str_1:
mov rax,[rcx]
add rcx,8
mov [rdi],rax
add rdi,8
D_to_S_cp_str_2:
sub rbx,1
jnc D_to_S_cp_str_1
mov rcx,rbp
ret
eqD: mov rax,[rcx]
cmp rax,[rdx]
jne eqD_false
cmp rax,offset dINT+2
je eqD_INT
cmp rax,offset CHAR+2
je eqD_CHAR
cmp rax ,offset BOOL+2
je eqD_BOOL
cmp rax ,offset REAL+2
je eqD_REAL
mov rax ,1
ret
eqD_CHAR:
eqD_INT:
mov rbx,8[rcx]
xor rax,rax
cmp rbx,8[rdx]
sete al
ret
eqD_BOOL:
mov bl,byte ptr 8[rcx]
xor rax,rax
cmp bl,byte ptr 8[rdx]
sete al
ret
eqD_REAL:
movlpd xmm0,qword ptr 8[rcx]
comisd xmm0,qword ptr 8[rdx]
fnstsw ax
and ah,68
xor ah,64
sete al
and rax,1
ret
eqD_false:
xor rax ,rax
ret
;
; the timer
;
init_timer:
mov rbp,rsp
and rsp,-16
sub rsp,32
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
mov rdi,rsp
call times
mov rsi,r13
mov rdi,r14
mov eax,[rsp]
imul eax,10
else
call GetTickCount
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
mov last_time,rax
xor rax,rax
mov execute_time,rax
mov garbage_collect_time,rax
mov IO_time,rax
mov mark_compact_garbage_collect_time,rax
mov compact_garbage_collect_time,rax
ret
get_time_diff:
mov rbp,rsp
and rsp,-16
sub rsp,32
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
mov rdi,rsp
call times
mov rsi,r13
mov rdi,r14
mov eax,[rsp]
imul eax,10
else
call GetTickCount
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
lea rcx,last_time
mov rdx,[rcx]
mov [rcx],rax
sub rax,rdx
ret
add_execute_time:
call get_time_diff
lea rcx,execute_time
add_time:
add rax,[rcx]
mov [rcx],rax
ret
add_garbage_collect_time:
call get_time_diff
mov rcx,offset garbage_collect_time
jmp add_time
add_IO_time:
call get_time_diff
mov rcx,offset IO_time
jmp add_time
add_mark_compact_garbage_collect_time:
call get_time_diff
mov rcx,offset mark_compact_garbage_collect_time
jmp add_time
add_compact_garbage_collect_time:
call get_time_diff
mov rcx,offset compact_garbage_collect_time
jmp add_time
;
; the garbage collector
;
collect_3:
ifdef PROFILE
lea rbp,garbage_collector_name
call profile_s
endif
mov [rsi],rcx
mov 8[rsi],rdx
mov 16[rsi],r8
add rsi,24
call collect_0_
mov r8,(-8)[rsi]
mov rdx,(-16)[rsi]
mov rcx,(-24)[rsi]
sub rsi,24
ifdef PROFILE
jmp profile_r
else
ret
endif
collect_2:
ifdef PROFILE
lea rbp,garbage_collector_name
call profile_s
endif
mov [rsi],rcx
mov 8[rsi],rdx
add rsi,16
call collect_0_
mov rdx,(-8)[rsi]
mov rcx,(-16)[rsi]
sub rsi,16
ifdef PROFILE
jmp profile_r
else
ret
endif
collect_1:
ifdef PROFILE
lea rbp,garbage_collector_name
call profile_s
endif
mov [rsi],rcx
add rsi,8
call collect_0_
mov rcx,(-8)[rsi]
sub rsi,8
ifdef PROFILE
jmp profile_r
else
ret
endif
collect_0:
ifdef PROFILE
lea rbp,garbage_collector_name
call profile_s
endif
call collect_0_
ifdef PROFILE
jmp profile_r
else
ret
endif
collect_0_:
mov rbp,rdi
push rax
push rbx
if THREAD
mov rbx,qword ptr heap_end_after_gc_offset[r9]
else
mov rbx,qword ptr heap_end_after_gc
endif
sub rbx,rdi
shr rbx,3
sub rbx,r15
if THREAD
mov qword ptr n_allocated_words_offset[r9],rbx
else
mov qword ptr n_allocated_words,rbx
endif
test byte ptr flags,64
je no_mark3
if THREAD
mov rbp,qword ptr bit_counter_offset[r9]
else
mov rbp,qword ptr bit_counter
endif
test rbp,rbp
je no_scan
push rsi
mov rsi,rbx
xor rbx,rbx
if THREAD
mov rcx,qword ptr bit_vector_p_offset[r9]
else
mov rcx,qword ptr bit_vector_p
endif
scan_bits:
cmp ebx,dword ptr[rcx]
je zero_bits
mov dword ptr [rcx],ebx
add rcx,4
sub rbp,1
jne scan_bits
jmp end_scan
zero_bits:
lea rdx,4[rcx]
add rcx,4
sub rbp,1
jne skip_zero_bits_lp1
jmp end_bits
skip_zero_bits_lp:
test rax,rax
jne end_zero_bits
skip_zero_bits_lp1:
mov eax,dword ptr [rcx]
add rcx,4
sub rbp,1
jne skip_zero_bits_lp
test rax,rax
je end_bits
mov dword ptr (-4)[rcx],ebx
mov rax,rcx
sub rax,rdx
jmp end_bits2
end_zero_bits:
mov rax,rcx
sub rax,rdx
shl rax,3
if THREAD
add qword ptr n_free_words_after_mark_offset[r9],rax
else
add qword ptr n_free_words_after_mark,rax
endif
mov dword ptr (-4)[rcx],ebx
cmp rax,rsi
jb scan_bits
found_free_memory:
if THREAD
mov qword ptr bit_counter_offset[r9],rbp
mov qword ptr bit_vector_p_offset[r9],rcx
else
mov qword ptr bit_counter,rbp
mov qword ptr bit_vector_p,rcx
endif
lea rbp,(-4)[rdx]
if THREAD
sub rbp,qword ptr heap_vector_offset[r9]
else
sub rbp,qword ptr heap_vector
endif
shl rbp,6
if THREAD
mov rdi,qword ptr heap_p3_offset[r9]
else
mov rdi,qword ptr heap_p3
endif
add rdi,rbp
lea rbp,[rdi+rax*8]
if THREAD
mov qword ptr heap_end_after_gc_offset[r9],rbp
else
mov qword ptr heap_end_after_gc,rbp
endif
mov r15,rax
sub r15,rsi
pop rsi
pop rbx
pop rax
ret
end_bits:
mov rax,rcx
sub rax,rdx
add rax,4
end_bits2:
shl rax,3
if THREAD
add qword ptr n_free_words_after_mark_offset[r9],rax
else
add qword ptr n_free_words_after_mark,rax
endif
cmp rax,rsi
jae found_free_memory
end_scan:
pop rsi
if THREAD
mov qword ptr bit_counter_offset[r9],rbp
else
mov qword ptr bit_counter,rbp
endif
no_scan:
no_mark3:
if THREAD
movsx rax,byte ptr garbage_collect_flag_offset[r9]
else
movsx rax,byte ptr garbage_collect_flag
endif
test rax,rax
jle collect
sub rax,2
if THREAD
mov byte ptr garbage_collect_flag_offset[r9],al
mov rbp,qword ptr extra_heap_size_offset[r9]
else
mov byte ptr garbage_collect_flag,al
mov rbp,qword ptr extra_heap_size
endif
cmp rbx,rbp
ja collect
if THREAD
mov rdi,qword ptr extra_heap_offset[r9]
else
mov rdi,qword ptr extra_heap
endif
mov r15,rbp
lea rbp,[rdi+rbp*8]
if THREAD
mov qword ptr heap_end_after_gc_offset[r9],rbp
else
mov qword ptr heap_end_after_gc,rbp
endif
sub r15,rbx
pop rbx
pop rax
ret
collect:
ifdef LINUX
sub rsp,104
else
sub rsp,88
endif
mov 32[rsp],r10
mov 24[rsp],r11
mov 16[rsp],r12
mov 8[rsp],r13
mov [rsp],r14
movsd 40[rsp],xmm0
movsd 48[rsp],xmm1
movsd 56[rsp],xmm2
movsd 64[rsp],xmm3
movsd 72[rsp],xmm4
movsd 80[rsp],xmm5
ifdef LINUX
movsd 88[rsp],xmm6
movsd 96[rsp],xmm7
endif
call add_execute_time
test qword ptr flags,4
je no_print_stack_sizes
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
else
sub rsp,32
endif
if 0
ifdef LINUX
mov rdi,qword ptr 64[rsp]
else
mov rcx,qword ptr 96[rsp]
endif
call ew_print_int
ifdef LINUX
mov rdi,32
else
mov rcx,32
endif
call ew_print_char
endif
ifdef LINUX
lea rdi,garbage_collect_string_1
else
lea rcx,garbage_collect_string_1
endif
call ew_print_string
ifdef LINUX
mov rdi,r13
if THREAD
mov r9,rbx
sub rdi,stack_p_offset[r9]
else
sub rdi,stack_p
endif
else
mov rcx,rsi
if THREAD
mov r9,rbx
sub rcx,stack_p_offset[r9]
else
sub rcx,stack_p
endif
endif
call ew_print_int
ifdef LINUX
lea rdi,garbage_collect_string_2
else
lea rcx,garbage_collect_string_2
endif
call ew_print_string
ifdef LINUX
if THREAD
mov r9,rbx
mov rdi,halt_sp_offset[r9]
else
mov rdi,halt_sp
endif
sub rdi,rsp
else
if THREAD
mov r9,rbx
mov rcx,halt_sp_offset[r9]
else
mov rcx,halt_sp
endif
sub rcx,rsp
endif
call ew_print_int
ifdef LINUX
lea rdi,garbage_collect_string_3
else
lea rcx,garbage_collect_string_3
endif
call ew_print_string
ifdef LINUX
mov rsi,r13
mov rdi,r14
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
no_print_stack_sizes:
if THREAD
mov rax,stack_p_offset[r9]
add rax,qword ptr a_stack_size_offset[r9]
else
mov rax,stack_p
add rax,qword ptr ab_stack_size
endif
cmp rsi,rax
ja stack_overflow
test byte ptr flags,64
jne compacting_collector
if THREAD
cmp byte ptr garbage_collect_flag_offset[r9],0
else
cmp byte ptr garbage_collect_flag,0
endif
jne compacting_collector
if THREAD
mov rbp,heap_copied_vector_offset[r9]
cmp qword ptr heap_end_after_copy_gc_offset[r9],0
else
mov rbp,heap_copied_vector
cmp qword ptr heap_end_after_copy_gc,0
endif
je zero_all
mov rax,rdi
if THREAD
sub rax,qword ptr heap_p1_offset[r9]
else
sub rax,qword ptr heap_p1
endif
add rax,127*8
shr rax,9
call zero_bit_vector
if THREAD
mov rdx,qword ptr heap_end_after_copy_gc_offset[r9]
sub rdx,qword ptr heap_p1_offset[r9]
else
mov rdx,qword ptr heap_end_after_copy_gc
sub rdx,qword ptr heap_p1
endif
shr rdx,7
and rdx,-4
if THREAD
mov rbp,qword ptr heap_copied_vector_offset[r9]
mov rax,qword ptr heap_copied_vector_size_offset[r9]
else
mov rbp,qword ptr heap_copied_vector
mov rax,qword ptr heap_copied_vector_size
endif
add rbp,rdx
sub rax,rdx
shr rax,2
if THREAD
mov qword ptr heap_end_after_copy_gc_offset[r9],0
else
mov qword ptr heap_end_after_copy_gc,0
endif
call zero_bit_vector
jmp end_zero_bit_vector
zero_all:
if THREAD
mov rax,heap_copied_vector_size_offset[r9]
else
mov rax,heap_copied_vector_size
endif
shr rax,2
call zero_bit_vector
end_zero_bit_vector:
include acopy.asm
if THREAD
mov qword ptr heap2_begin_and_end_offset[r9],rsi
else
mov qword ptr heap2_begin_and_end,rsi
endif
mov r15,rsi
sub r15,rdi
if THREAD
mov rax,heap_size_257_offset[r9]
else
mov rax,heap_size_257
endif
shl rax,7
sub rax,r15
add qword ptr total_gc_bytes,rax
shr r15,3
pop rsi
call add_garbage_collect_time
if THREAD
sub r15,qword ptr n_allocated_words_offset[r9]
else
sub r15,qword ptr n_allocated_words
endif
jc switch_to_mark_scan
lea rax,[r15+r15*4]
shl rax,6
if THREAD
mov rbx,qword ptr heap_size_offset[r9]
else
mov rbx,qword ptr heap_size
endif
mov rcx,rbx
shl rbx,2
add rbx,rcx
add rbx,rbx
add rbx,rcx
cmp rax,rbx
jnc no_mark_scan
switch_to_mark_scan:
if THREAD
mov rax,qword ptr heap_size_65_offset[r9]
else
mov rax,qword ptr heap_size_65
endif
shl rax,6
if THREAD
mov rbx,qword ptr heap_p_offset[r9]
mov rcx,qword ptr heap_p1_offset[r9]
cmp rcx,qword ptr heap_p2_offset[r9]
else
mov rbx,qword ptr heap_p
mov rcx,qword ptr heap_p1
cmp rcx,qword ptr heap_p2
endif
jc vector_at_begin
vector_at_end:
if THREAD
mov qword ptr heap_p3_offset[r9],rbx
else
mov qword ptr heap_p3,rbx
endif
add rbx,rax
if THREAD
mov qword ptr heap_vector_offset[r9],rbx
mov rax,qword ptr heap_p1_offset[r9]
mov qword ptr extra_heap_offset[r9],rax
else
mov qword ptr heap_vector,rbx
mov rax,qword ptr heap_p1
mov qword ptr extra_heap,rax
endif
sub rbx,rax
shr rbx,3
if THREAD
mov qword ptr extra_heap_size_offset[r9],rbx
else
mov qword ptr extra_heap_size,rbx
endif
jmp switch_to_mark_scan_2
vector_at_begin:
if THREAD
mov qword ptr heap_vector_offset[r9],rbx
add rbx,qword ptr heap_size_offset[r9]
else
mov qword ptr heap_vector,rbx
add rbx,qword ptr heap_size
endif
sub rbx,rax
if THREAD
mov qword ptr heap_p3_offset[r9],rbx
else
mov qword ptr heap_p3,rbx
endif
if THREAD
mov qword ptr extra_heap_offset[r9],rbx
mov rcx,qword ptr heap_p2_offset[r9]
else
mov qword ptr extra_heap,rbx
mov rcx,qword ptr heap_p2
endif
sub rcx,rbx
shr rcx,3
if THREAD
mov qword ptr extra_heap_size_offset[r9],rcx
else
mov qword ptr extra_heap_size,rcx
endif
switch_to_mark_scan_2:
if THREAD
mov rax,heap_size_257_offset[r9]
else
mov rax,heap_size_257
endif
shl rax,7-3
sub rax,r15
shl rax,3
if THREAD
mov byte ptr garbage_collect_flag_offset[r9],1
else
mov byte ptr garbage_collect_flag,1
endif
lea rcx,heap_use_after_gc_string_1
test r15,r15
jns end_garbage_collect
if THREAD
mov byte ptr garbage_collect_flag_offset[r9],-1
mov rbx,qword ptr extra_heap_size_offset[r9]
else
mov byte ptr garbage_collect_flag,-1
mov rbx,qword ptr extra_heap_size
endif
mov r15,rbx
if THREAD
sub r15,qword ptr n_allocated_words_offset[r9]
else
sub r15,qword ptr n_allocated_words
endif
js out_of_memory_4_3
if THREAD
mov rdi,qword ptr extra_heap_offset[r9]
else
mov rdi,qword ptr extra_heap
endif
shl rbx,3
add rbx,rdi
if THREAD
mov qword ptr heap_end_after_gc_offset[r9],rbx
else
mov qword ptr heap_end_after_gc,rbx
endif
mov qword ptr heap_end_write_heap,rdi
mov qword ptr d3_flag_write_heap,1
jmp end_garbage_collect_
no_mark_scan:
; exchange the semi_spaces
if THREAD
mov rax,heap_p1_offset[r9]
mov rbx,heap_p2_offset[r9]
mov heap_p2_offset[r9],rax
mov heap_p1_offset[r9],rbx
mov rax,heap_size_257_offset[r9]
else
mov rax,heap_p1
mov rbx,heap_p2
mov heap_p2,rax
mov heap_p1,rbx
mov rax,heap_size_257
endif
shl rax,7-3
mov rbx,rax
sub rax,r15
mov rcx,rax
imul qword ptr heap_size_multiple
shrd rax,rdx,9
shr rdx,9
jne no_small_heap1
cmp rax,4000
jge not_too_small1
mov rax,4000
not_too_small1:
sub rbx,rax
jb no_small_heap1
sub r15,rbx
shl rbx,3
if THREAD
mov rbp,qword ptr heap_end_after_gc_offset[r9]
mov qword ptr heap_end_after_copy_gc_offset[r9],rbp
else
mov rbp,qword ptr heap_end_after_gc
mov qword ptr heap_end_after_copy_gc,rbp
endif
sub rbp,rbx
if THREAD
mov qword ptr heap_end_after_gc_offset[r9],rbp
else
mov qword ptr heap_end_after_gc,rbp
endif
no_small_heap1:
mov rax,rcx
shl rax,3
lea rcx,heap_use_after_gc_string_1
end_garbage_collect:
mov qword ptr heap_end_write_heap,rdi
mov qword ptr d3_flag_write_heap,0
end_garbage_collect_:
test qword ptr flags,2
je no_heap_use_message
push rax
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov r13,rsi
mov r14,rdi
mov rdi,rcx
else
sub rsp,32
endif
call ew_print_string
ifdef LINUX
mov rdi,[rbp]
else
mov rcx,[rbp]
endif
call ew_print_int
ifdef LINUX
lea rdi,heap_use_after_gc_string_2
else
lea rcx,heap_use_after_gc_string_2
endif
call ew_print_string
ifdef LINUX
mov rsi,r13
mov rdi,r14
else
add rsp,32
endif
mov rsp,rbp
if THREAD
mov r9,rbx
endif
pop rax
no_heap_use_message:
call call_finalizers
test byte ptr flags,32
je no_write_heap
cmp rax,qword ptr min_write_heap_size
jb no_write_heap
push rcx
push rdx
push rbp
push rsi
push rdi
sub rsp,128
mov rax,qword ptr d3_flag_write_heap
test rax,rax
jne copy_to_compact_with_alloc_in_extra_heap
if THREAD
movsx rax,byte ptr garbage_collect_flag_offset[r9]
mov rcx,qword ptr heap2_begin_and_end_offset[r9]
mov rdx,qword ptr (heap2_begin_and_end_offset+8)[r9]
lea rbx,heap_p1_offset[r9]
else
movsx rax,byte ptr garbage_collect_flag
mov rcx,qword ptr heap2_begin_and_end
mov rdx,qword ptr (heap2_begin_and_end+8)
mov rbx,offset heap_p1
endif
test rax,rax
je gc0
if THREAD
lea rbx,heap_p2_offset[r9]
else
mov rbx,offset heap_p2
endif
jg gc1
if THREAD
lea rbx,heap_p3_offset[r9]
else
mov rbx,offset heap_p3
endif
xor rcx,rcx
xor rdx,rdx
gc0:
gc1:
mov rbx,qword ptr [rbx]
mov rax,rsp
mov qword ptr [rax],rbx
mov qword ptr 8[rax],rdi
mov qword ptr 16[rax],rcx
mov qword ptr 24[rax],rdx
if THREAD
mov rbx ,qword ptr stack_p_offset[r9]
else
mov rbx ,qword ptr stack_p
endif
mov qword ptr 32[rax],rbx
mov qword ptr 40[rax],rsi
mov qword ptr 48[rax],0
mov qword ptr 56[rax],0
mov qword ptr 64[rax],offset small_integers
mov qword ptr 72[rax],offset static_characters
mov qword ptr 80[rax],offset dINT+2
mov qword ptr 88[rax],offset CHAR+2
mov qword ptr 96[rax],offset REAL+2
mov qword ptr 104[rax],offset BOOL+2
mov qword ptr 112[rax],offset __STRING__+2
mov qword ptr 120[rax],offset __ARRAY__+2
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
ifdef LINUX
mov rdi,rax
else
mov rcx,rax
sub rsp,32
endif
ifndef LINUX
call write_heap
endif
mov rsp,rbp
add rsp,128
if THREAD
mov r9,rbx
endif
pop rdi
pop rsi
pop rbp
pop rdx
pop rcx
no_write_heap:
restore_registers_after_gc_and_return:
mov r10,32[rsp]
mov r11,24[rsp]
mov r12,16[rsp]
mov r13,8[rsp]
mov r14,[rsp]
movlpd xmm0,40[rsp]
movlpd xmm1,48[rsp]
movlpd xmm2,56[rsp]
movlpd xmm3,64[rsp]
movlpd xmm4,72[rsp]
movlpd xmm5,80[rsp]
ifdef LINUX
movlpd xmm6,88[rsp]
movlpd xmm7,96[rsp]
add rsp,104
else
add rsp,88
endif
pop rbx
pop rax
ret
call_finalizers:
mov rax,qword ptr free_finalizer_list
call_finalizers_lp:
if THREAD
lea rbx,__Nil-8
cmp rax,rbx
else
lea r9,__Nil-8
cmp rax,r9
endif
je end_call_finalizers
push 8[rax]
mov rbx,qword ptr 16[rax]
push 8[rbx]
call qword ptr [rbx]
add rsp,8
pop rax
jmp call_finalizers_lp
end_call_finalizers:
if THREAD
lea rbx,__Nil-8
mov qword ptr free_finalizer_list,rbx
else
lea r9,__Nil-8
mov qword ptr free_finalizer_list,r9
endif
ret
copy_to_compact_with_alloc_in_extra_heap:
if THREAD
mov rcx,qword ptr heap2_begin_and_end_offset[r9]
mov rdx,qword ptr (heap2_begin_and_end_offset+8)[r9]
lea rbx,heap_p2_offset[r9]
else
mov rcx,qword ptr heap2_begin_and_end
mov rdx,qword ptr (heap2_begin_and_end+8)
mov rbx,offset heap_p2
endif
jmp gc1
allow_prefetch_for_athlon:
test qword ptr flags,4096
jne no_prefetch_flag
xor rax,rax
cpuid
test rax,rax
jz disable_prefetch_flag
ifdef LINUX
cmp rbx,'A'+('u'*0x100)+('t'*0x10000)+('h'*0x1000000)
jne disable_prefetch_flag
cmp rdx,'e'+('n'*0x100)+('t'*0x10000)+('i'*0x1000000)
jne disable_prefetch_flag
cmp rcx,'c'+('A'*0x100)+('M'*0x10000)+('D'*0x1000000)
jne disable_prefetch_flag
else
cmp rbx,'A'+('u' shl 8)+('t' shl 16)+('h' shl 24)
jne disable_prefetch_flag
cmp rdx,'e'+('n' shl 8)+('t' shl 16)+('i' shl 24)
jne disable_prefetch_flag
cmp rcx,'c'+('A' shl 8)+('M' shl 16)+('D' shl 24)
jne disable_prefetch_flag
endif
; mov rax,1
; cpuid
; and rax,0f00h
; cmp rax,600h
; je keep_prefetch_flag
ret
disable_prefetch_flag:
and qword ptr flags,-4097
keep_prefetch_flag:
no_prefetch_flag:
ret
out_of_memory_4_3:
out_of_memory_4_2:
out_of_memory_4_1:
out_of_memory_4:
call add_garbage_collect_time
mov rbp,offset out_of_memory_string_4
jmp print_error
zero_bit_vector:
xor rdx,rdx
test al,1
je zero_bits1_1
mov dword ptr [rbp],edx
add rbp,4
zero_bits1_1:
shr rax,1
mov rbx,rax
shr rax,1
test bl,1
je zero_bits1_5
sub rbp,8
jmp zero_bits1_2
zero_bits1_4:
mov dword ptr [rbp],edx
mov dword ptr 4[rbp],edx
zero_bits1_2:
mov dword ptr 8[rbp],edx
mov dword ptr 12[rbp],edx
add rbp,16
zero_bits1_5:
sub rax,1
jae zero_bits1_4
ret
reorder:
push rsi
push rbp
mov rbp,rax
shl rbp,3
mov rsi,rbx
shl rsi,3
add rcx,rsi
sub rdx,rbp
push rsi
push rbp
push rbx
push rax
jmp st_reorder_lp
reorder_lp:
mov rbp,qword ptr [rcx]
mov rsi,qword ptr (-8)[rdx]
mov qword ptr (-8)[rdx],rbp
sub rdx,8
mov qword ptr [rcx],rsi
add rcx,8
dec rax
jne next_b_in_element
mov rax,qword ptr [rsp]
add rcx,qword ptr 24[rsp]
next_b_in_element:
dec rbx
jne next_a_in_element
mov rbx,qword ptr 8[rsp]
sub rdx,qword ptr 16[rsp]
next_a_in_element:
st_reorder_lp:
cmp rdx,rcx
ja reorder_lp
pop rax
pop rbx
add rsp,16
pop rbp
pop rsi
ret
;
; the sliding compacting garbage collector
;
compacting_collector:
; zero all mark bits
if THREAD
mov rax,qword ptr heap_p3_offset[r9]
else
mov rax,qword ptr heap_p3
endif
neg rax
if THREAD
mov qword ptr neg_heap_p3_offset[r9],rax
mov qword ptr stack_top_offset[r9],rsi
mov rdi,qword ptr heap_vector_offset[r9]
else
mov qword ptr neg_heap_p3,rax
mov qword ptr stack_top,rsi
mov rdi,qword ptr heap_vector
endif
test byte ptr flags,64
je no_mark4
if THREAD
cmp qword ptr zero_bits_before_mark_offset[r9],0
else
cmp qword ptr zero_bits_before_mark,0
endif
je no_zero_bits
if THREAD
mov qword ptr zero_bits_before_mark_offset[r9],0
else
mov qword ptr zero_bits_before_mark,0
endif
no_mark4:
mov rbp,rdi
if THREAD
mov rax,qword ptr heap_size_65_offset[r9]
else
mov rax,qword ptr heap_size_65
endif
add rax,3
shr rax,2
xor rbx,rbx
test al,1
je zero_bits_1
mov dword ptr [rbp],ebx
add rbp,4
zero_bits_1:
mov rcx,rax
shr rax,2
test cl,2
je zero_bits_5
sub rbp,8
jmp zero_bits_2
zero_bits_4:
mov dword ptr [rbp],ebx
mov dword ptr 4[rbp],ebx
zero_bits_2:
mov dword ptr 8[rbp],ebx
mov dword ptr 12[rbp],ebx
add rbp,16
zero_bits_5:
sub rax,1
jnc zero_bits_4
test byte ptr flags,64
je no_mark5
no_zero_bits:
if THREAD
mov rax,qword ptr n_last_heap_free_bytes_offset[r9]
mov rbx,qword ptr n_free_words_after_mark_offset[r9]
else
mov rax,qword ptr n_last_heap_free_bytes
mov rbx,qword ptr n_free_words_after_mark
endif
shl rbx,3
mov rbp,rbx
shl rbp,3
add rbp,rbx
shr rbp,2
cmp rax,rbp
jg compact_gc
if THREAD
mov rbx,qword ptr bit_vector_size_offset[r9]
else
mov rbx,qword ptr bit_vector_size
endif
shl rbx,3
sub rax,rbx
neg rax
imul qword ptr heap_size_multiple
shrd rax,rdx,7
shr rdx,7
jne no_smaller_heap
cmp rax,rbx
jae no_smaller_heap
cmp rbx,8000
jbe no_smaller_heap
jmp compact_gc
no_smaller_heap:
test qword ptr flags,4096
jne pmark
include amark.asm
include amark_prefetch.asm
compact_gc:
if THREAD
mov qword ptr zero_bits_before_mark_offset[r9],1
mov qword ptr n_last_heap_free_bytes_offset[r9],0
mov qword ptr n_free_words_after_mark_offset[r9],1000
else
mov qword ptr zero_bits_before_mark,1
mov qword ptr n_last_heap_free_bytes,0
mov qword ptr n_free_words_after_mark,1000
endif
no_mark5:
include acompact.asm
if THREAD
mov rsi,qword ptr stack_top_offset[r9]
else
mov rsi,qword ptr stack_top
endif
if THREAD
mov rbx,qword ptr heap_size_65_offset[r9]
else
mov rbx,qword ptr heap_size_65
endif
shl rbx,6
if THREAD
add rbx,qword ptr heap_p3_offset[r9]
else
add rbx,qword ptr heap_p3
endif
if THREAD
mov qword ptr heap_end_after_gc_offset[r9],rbx
else
mov qword ptr heap_end_after_gc,rbx
endif
sub rbx,rdi
shr rbx,3
if THREAD
sub rbx,qword ptr n_allocated_words_offset[r9]
else
sub rbx,qword ptr n_allocated_words
endif
mov r15,rbx
jc out_of_memory_4_1
mov rax,rbx
shl rax,2
add rax,rbx
shl rax,4
if THREAD
cmp rax,qword ptr heap_size_offset[r9]
else
cmp rax,qword ptr heap_size
endif
jc out_of_memory_4_2
test byte ptr flags,64
je no_mark_6
if THREAD
mov rax,qword ptr neg_heap_p3_offset[r9]
else
mov rax,qword ptr neg_heap_p3
endif
add rax,rdi
if THREAD
mov rbx,qword ptr n_allocated_words_offset[r9]
else
mov rbx,qword ptr n_allocated_words
endif
lea rax,[rax+rbx*8]
if THREAD
mov rbx,qword ptr heap_size_65_offset[r9]
else
mov rbx,qword ptr heap_size_65
endif
shl rbx,6
imul qword ptr heap_size_multiple
shrd rax,rdx,8
shr rdx,8
jne no_small_heap2
and rax,-4
cmp rax,8000
jae not_too_small2
mov rax,8000
not_too_small2:
mov rcx,rbx
sub rcx,rax
jb no_small_heap2
if THREAD
sub qword ptr heap_end_after_gc_offset[r9],rcx
else
sub qword ptr heap_end_after_gc,rcx
endif
shr rcx,3
sub r15,rcx
mov rbx,rax
no_small_heap2:
shr rbx,3
if THREAD
mov qword ptr bit_vector_size_offset[r9],rbx
else
mov qword ptr bit_vector_size,rbx
endif
no_mark_6:
jmp no_copy_garbage_collection
no_copy_garbage_collection:
call add_compact_garbage_collect_time
mov rax,rdi
if THREAD
sub rax,qword ptr heap_p3_offset[r9]
else
sub rax,qword ptr heap_p3
endif
add qword ptr total_compact_gc_bytes,rax
mov rax,rdi
if THREAD
sub rax,qword ptr heap_p3_offset[r9]
mov rbx,qword ptr n_allocated_words_offset[r9]
else
sub rax,qword ptr heap_p3
mov rbx,qword ptr n_allocated_words
endif
lea rax,[rax+rbx*8]
lea rcx,heap_use_after_compact_gc_string_1
jmp end_garbage_collect
if 0
public clean_exception_handler_
clean_exception_handler_:
jmp clean_exception_handler_
endif
if 0
mov rax,qword ptr [rcx]
cmp dword ptr [rax],0c00000fdh
je stack_overflow_exception
cmp dword ptr [rax],80000001h
je guard_page_or_access_violation_exception
cmp dword ptr [rax] ,0c0000005h
je guard_page_or_access_violation_exception
no_stack_overflow_exception:
mov rax,0
ret
guard_page_or_access_violation_exception:
mov rax,qword ptr 16[rax]
and rax,-4096
cmp qword ptr a_stack_guard_page,rax
jne no_stack_overflow_exception
cmp qword ptr a_stack_guard_page,0
je no_stack_overflow_exception
stack_overflow_exception:
mov rax,qword ptr 8[rcx]
mov qword ptr (0F8h)[rax],offset stack_overflow
mov rax,-1
ret
endif
stack_overflow:
call add_execute_time
mov rbp,offset stack_overflow_string
jmp print_error
IO_error:
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
mov rbx,rcx
ifdef LINUX
lea rdi,IO_error_string
else
sub rsp,32
lea rcx,IO_error_string
endif
call ew_print_string
ifdef LINUX
mov rdi,rbx
else
mov rcx,rbx
endif
call ew_print_string
ifdef LINUX
lea rdi,new_line_string
else
lea rcx,new_line_string
endif
call ew_print_string
mov rsp,rbp
if THREAD
mov r9,rbx
endif
jmp halt
print_error:
ifdef LINUX
mov rdi,rbp
else
mov rcx,rbp
endif
mov rbp,rsp
and rsp,-16
if THREAD
mov rbx,r9
endif
call ew_print_string
mov rsp,rbp
if THREAD
mov r9,rbx
endif
halt:
if THREAD
mov rsp,halt_sp_offset[r9]
else
mov rsp,halt_sp
endif
ifdef PROFILE
call write_profile_stack
endif
mov qword ptr execution_aborted,1
cmp qword ptr dll_initialised,0
ifdef LINUX
je exit_
else
je exit
endif
ifdef LINUX
cmp dword ptr return_code,0
else
cmp qword ptr return_code,0
endif
jne return_code_set
ifdef LINUX
mov dword ptr return_code,-1
else
mov qword ptr return_code,-1
endif
return_code_set:
ifdef LINUX
mov edi,dword ptr return_code
and rsp,-16
call exit
else
push qword ptr return_code
call (ExitProcess)
endif
jmp return_code_set
e__system__eaind:
__eaind:
eval_fill:
mov [rsi],rcx
add rsi,8
mov rcx,rdx
call qword ptr [rdx]
mov rdx,rcx
mov rcx,(-8)[rsi]
sub rsi,8
mov rbp,[rdx]
mov [rcx],rbp
mov rbp,8[rdx]
mov 8[rcx],rbp
mov rbp,16[rdx]
mov 16[rcx],rbp
ret
align (1 shl 2)
lea rax,e__system__eaind
jmp rax
ifdef LINUX
; pc relative lea instruction is one byte longer
db 0,0
else
db 0,0,0
endif
dd e__system__dind
dd -2
e__system__nind:
__indirection:
mov rdx,8[rcx]
mov rax,[rdx]
test al,2
je eval_fill2
mov [rcx],rax
mov rbp,8[rdx]
mov 8[rcx],rbp
mov rbp,16[rdx]
mov 16[rcx],rbp
ret
eval_fill2:
if THREAD
lea rbp,__cycle__in__spine
mov qword ptr [rcx],rbp
else
lea r9,__cycle__in__spine
mov qword ptr [rcx],r9
endif
mov qword ptr [rsi],rcx
test byte ptr flags,64
je __cycle__in__spine
add rsi,8
mov rcx,rdx
call rax
mov rdx,rcx
mov rcx,qword ptr (-8)[rsi]
sub rsi,8
mov rbp,[rdx]
mov [rcx],rbp
mov rbp,8[rdx]
mov 8[rcx],rbp
mov rbp,16[rdx]
mov 16[rcx],rbp
ret
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_0:
mov qword ptr [rdx],offset __indirection
mov 8[rdx],rcx
jmp rbp
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_1:
mov qword ptr [rdx],offset __indirection
mov rax,8[rdx]
mov 8[rdx],rcx
mov rdx,rax
jmp rbp
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_2:
mov qword ptr [rdx],offset __indirection
mov r8,8[rdx]
mov 8[rdx],rcx
mov rdx,16[rdx]
jmp rbp
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_3:
mov qword ptr [rdx],offset __indirection
mov r8,8[rdx]
mov 8[rdx],rcx
mov [rsi],rcx
mov rcx,24[rdx]
add rsi,8
mov rdx,16[rdx]
jmp rbp
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_4:
mov qword ptr [rdx],offset __indirection
mov r8,8[rdx]
mov 8[rdx],rcx
mov [rsi],rcx
mov rbx,32[rdx]
mov 8[rsi],rbx
mov rcx,24[rdx]
add rsi,16
mov rdx,16[rdx]
jmp rbp
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_5:
mov qword ptr [rdx],offset __indirection
mov r8,8[rdx]
mov [rsi],rcx
mov 8[rdx],rcx
mov rbx,40[rdx]
mov 8[rsi],rbx
mov rbx,32[rdx]
mov 16[rsi],rbx
mov rcx,24[rdx]
add rsi,24
mov rdx,16[rdx]
jmp rbp
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_6:
mov qword ptr [rdx],offset __indirection
mov r8,8[rdx]
mov [rsi],rcx
mov 8[rdx],rcx
mov rbx,48[rdx]
mov 8[rsi],rbx
mov rbx,40[rdx]
mov 16[rsi],rbx
mov rbx,32[rdx]
mov 24[rsi],rbx
mov rcx,24[rdx]
add rsi,32
mov rdx,16[rdx]
jmp rbp
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_7:
mov rax,0
mov rbx,40
eval_upd_n:
mov qword ptr [rdx],offset __indirection
mov r8,8[rdx]
mov [rsi],rcx
mov 8[rdx],rcx
add rdx,rbx
mov rbx,16[rdx ]
mov 8[rsi],rbx
mov rbx,8[rdx]
mov 16[rsi],rbx
mov rbx,[rdx]
mov 24[rsi],rbx
add rsi,32
eval_upd_n_lp:
mov rbx,(-8)[rdx]
sub rdx,8
mov [rsi],rbx
add rsi,8
sub rax,1
jnc eval_upd_n_lp
mov rcx,(-8)[rdx]
mov rdx,(-16)[rdx ]
jmp rbp
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_8:
mov rax,1
mov rbx,48
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_9:
mov rax,2
mov rbx,56
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_10:
mov rax,3
mov rbx,64
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_11:
mov rax,4
mov rbx,72
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_12:
mov rax,5
mov rbx,80
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_13:
mov rax,6
mov rbx,88
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_14:
mov rax,7
mov rbx,96
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_15:
mov rax,8
mov rbx,104
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_16:
mov rax,9
mov rbx,112
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_17:
mov rax,10
mov rbx,120
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_18:
mov rax,11
mov rbx,128
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_19:
mov rax,12
mov rbx,136
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_20:
mov rax,13
mov rbx,144
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_21:
mov rax,14
mov rbx,152
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_22:
mov rax,15
mov rbx,160
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_23:
mov rax,16
mov rbx,168
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_24:
mov rax,17
mov rbx,176
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_25:
mov rax,18
mov rbx,184
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_26:
mov rax,19
mov rbx,192
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_27:
mov rax,20
mov rbx,200
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_28:
mov rax,21
mov rbx,208
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_29:
mov rax,22
mov rbx,216
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_30:
mov rax,23
mov rbx,224
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_31:
mov rax,24
mov rbx,232
jmp eval_upd_n
ifdef PROFILE
call profile_n
mov rbp,rax
endif
eval_upd_32:
mov rax,25
mov rbx,240
jmp eval_upd_n
;
; STRINGS
;
catAC:
mov rax,8[rcx]
mov rbx,8[rdx]
lea rbp,16+7[rax+rbx]
shr rbp,3
sub r15,rbp
jl gc_3
gc_r_3:
add rcx,16
add rdx,16
; fill_node
mov r8,rdi
mov qword ptr [rdi],offset __STRING__+2
; store length
lea rbp,[rax+rbx]
mov 8[rdi],rbp
add rdi,16
; copy string 1
lea rbp,7[rbx]
shr rbp,3
add rbx,rdi
xchg rcx,rbp
xchg rsi,rdx
cld
rep movsq
mov rsi,rdx
mov rcx,rbp
mov rdi,rbx
; copy_string 2
cat_string_6:
mov rbp,rax
shr rbp,3
je cat_string_9
cat_string_7:
mov rbx,[rcx]
add rcx,8
mov [rdi],rbx
add rdi,8
dec rbp
jne cat_string_7
cat_string_9:
test al,4
je cat_string_10
mov ebx,dword ptr [rcx]
add rcx,4
mov dword ptr [rdi],ebx
add rdi,4
cat_string_10:
test al,2
je cat_string_11
mov bx,word ptr [rcx]
add rcx,2
mov word ptr [rdi],bx
add rdi,2
cat_string_11:
test al,1
je cat_string_12
mov bl,byte ptr [rcx]
mov byte ptr [rdi],bl
inc rdi
cat_string_12:
mov rcx,r8
; align heap pointer
add rdi,7
and rdi,-8
ret
gc_3: call collect_2
jmp gc_r_3
empty_string:
mov rcx,offset zero_length_string
ret
sliceAC:
mov rbp,8[rcx]
test rbx,rbx
jns slice_string_1
xor rbx,rbx
slice_string_1:
cmp rbx,rbp
jge empty_string
cmp rax,rbx
jl empty_string
inc rax
cmp rax,rbp
jle slice_string_2
mov rax,rbp
slice_string_2:
sub rax,rbx
lea rbp,(16+7)[rax]
shr rbp,3
sub r15,rbp
jl gc_4
r_gc_4:
sub rbp,2
lea rdx,16[rcx+rbx]
mov qword ptr [rdi],offset __STRING__+2
mov 8[rdi],rax
; copy part of string
mov rcx,rbp
mov rbp,rdi
add rdi,16
xchg rsi,rdx
cld
rep movsq
mov rsi,rdx
mov rcx,rbp
ret
gc_4:
mov rbp,rdx
call collect_1
lea rbp,(16+7)[rax]
shr rbp,3
jmp r_gc_4
updateAC:
mov rbp,8[rcx]
cmp rbx,rbp
jae update_string_error
add rbp,16+7
shr rbp,3
sub r15,rbp
jl gc_5
r_gc_5:
mov rbp,8[rcx]
add rbp,7
shr rbp,3
mov rdx,rcx
mov r8,rdi
mov qword ptr [rdi],offset __STRING__+2
mov rcx,8[rdx]
add rdx,16
mov 8[rdi],rcx
add rdi,16
add rbx,rdi
mov rcx,rbp
xchg rsi,rdx
cld
rep movsq
mov rsi,rdx
mov byte ptr [rbx],al
mov rcx,r8
ret
gc_5: call collect_1
jmp r_gc_5
update_string_error:
mov rbp,offset high_index_string
test rax,rax
jns update_string_error_2
mov rbp,offset low_index_string
update_string_error_2:
jmp print_error
eqAC:
mov rax,8[rcx]
cmp rax,8[rdx]
jne equal_string_ne
add rcx,16
add rdx,16
mov rbx,rax
and rbx,7
shr rax,3
je equal_string_d
equal_string_1:
mov rbp,[rcx]
cmp rbp,[rdx]
jne equal_string_ne
add rcx,8
add rdx,8
dec rax
jne equal_string_1
equal_string_d:
test bl,4
je equal_string_w
mov eax,dword ptr [rcx]
cmp eax,dword ptr [rdx]
jne equal_string_ne
add rcx,4
add rdx,4
equal_string_w:
test bl,2
je equal_string_b
mov ax,word ptr [rcx]
cmp ax,word ptr [rdx]
jne equal_string_ne
add rcx,2
add rdx,2
equal_string_b:
test bl,1
je equal_string_eq
mov bl,byte ptr [rcx]
cmp bl,byte ptr [rdx]
jne equal_string_ne
equal_string_eq:
mov rax,1
ret
equal_string_ne:
xor rax,rax
ret
cmpAC:
mov rbx,8[rcx]
mov rbp,8[rdx]
add rcx,16
add rdx,16
cmp rbp,rbx
jb cmp_string_less
ja cmp_string_more
xor rax,rax
jmp cmp_string_chars
cmp_string_more:
mov rax,1
jmp cmp_string_chars
cmp_string_less:
mov rax,-1
mov rbx,rbp
jmp cmp_string_chars
cmp_string_1:
mov rbp,[rdx]
cmp rbp,[rcx]
jne cmp_string_ne_q
add rdx,8
add rcx,8
cmp_string_chars:
sub rbx,8
jnc cmp_string_1
cmp_string_d:
test bl,4
je cmp_string_w
mov ebp,dword ptr [rdx]
cmp ebp,dword ptr [rcx]
jne cmp_string_ne_d
add rdx,4
add rcx,4
cmp_string_w:
test bl,2
je cmp_string_b
mov bpl,byte ptr [rdx]
cmp bpl,byte ptr [rcx]
jne cmp_string_ne
mov bpl,byte ptr 1[rdx]
cmp bpl,byte ptr 1[rcx]
jne cmp_string_ne
add rdx,2
add rcx,2
cmp_string_b:
test bl,1
je cmp_string_eq
mov bl,byte ptr [rdx]
cmp bl,byte ptr [rcx]
jne cmp_string_ne
cmp_string_eq:
ret
cmp_string_ne_d:
mov r10d,[rcx]
bswap ebp
bswap r10d
cmp ebp,r10d
jmp cmp_string_ne
cmp_string_ne_q:
mov r10,[rcx]
bswap rbp
bswap r10
cmp rbp,r10
cmp_string_ne:
ja cmp_string_r1
mov rax,-1
ret
cmp_string_r1:
mov rax,1
ret
string_to_string_node:
mov rax,qword ptr [rcx]
add rcx,8
lea rbx,16+7[rax]
shr rbx,3
sub r15,rbx
jl string_to_string_node_gc
string_to_string_node_r:
sub rbx,2
mov qword ptr [rdi],offset __STRING__+2
mov qword ptr 8[rdi],rax
mov rbp,rdi
add rdi,16
jmp string_to_string_node_4
string_to_string_node_2:
mov rax,qword ptr [rcx]
add rcx,8
mov qword ptr [rdi],rax
add rdi,8
string_to_string_node_4:
sub rbx,1
jge string_to_string_node_2
mov rcx,rbp
ret
string_to_string_node_gc:
push rcx
call collect_0
pop rcx
jmp string_to_string_node_r
int_array_to_node:
mov rax,qword ptr -16[rcx]
lea rbx,3[rax]
sub r15,rbx
jl int_array_to_node_gc
int_array_to_node_r:
mov qword ptr [rdi],offset __ARRAY__+2
mov rdx,rcx
mov qword ptr 8[rdi],rax
mov rcx,rdi
mov qword ptr 16[rdi],offset dINT+2
add rdi,24
jmp int_or_real_array_to_node_4
int_or_real_array_to_node_2:
mov rbx,qword ptr [rdx]
add rdx,8
mov qword ptr [rdi],rbx
add rdi,8
int_or_real_array_to_node_4:
sub rax,1
jge int_or_real_array_to_node_2
ret
int_array_to_node_gc:
push rcx
call collect_0
pop rcx
jmp int_array_to_node_r
real_array_to_node:
mov rax,qword ptr -16[rcx]
lea rbx,3[rax]
sub r15,rbx
jl real_array_to_node_gc
real_array_to_node_r:
mov qword ptr [rdi],offset __ARRAY__+2
mov rdx,rcx
mov qword ptr 8[rdi],rax
mov rcx,rdi
mov qword ptr 16[rdi],offset REAL+2
add rdi,24
jmp int_or_real_array_to_node_4
real_array_to_node_gc:
push rcx
call collect_0
pop rcx
jmp real_array_to_node_r
align (1 shl 2)
dd 3
_c3: jmp __cycle__in__spine
align (1 shl 2)
dd 4
_c4: jmp __cycle__in__spine
align (1 shl 2)
dd 5
_c5: jmp __cycle__in__spine
align (1 shl 2)
dd 6
_c6: jmp __cycle__in__spine
align (1 shl 2)
dd 7
_c7: jmp __cycle__in__spine
align (1 shl 2)
dd 8
_c8: jmp __cycle__in__spine
align (1 shl 2)
dd 9
_c9: jmp __cycle__in__spine
align (1 shl 2)
dd 10
_c10: jmp __cycle__in__spine
align (1 shl 2)
dd 11
_c11: jmp __cycle__in__spine
align (1 shl 2)
dd 12
_c12: jmp __cycle__in__spine
align (1 shl 2)
dd 13
_c13: jmp __cycle__in__spine
align (1 shl 2)
dd 14
_c14: jmp __cycle__in__spine
align (1 shl 2)
dd 15
_c15: jmp __cycle__in__spine
align (1 shl 2)
dd 16
_c16: jmp __cycle__in__spine
align (1 shl 2)
dd 17
_c17: jmp __cycle__in__spine
align (1 shl 2)
dd 18
_c18: jmp __cycle__in__spine
align (1 shl 2)
dd 19
_c19: jmp __cycle__in__spine
align (1 shl 2)
dd 20
_c20: jmp __cycle__in__spine
align (1 shl 2)
dd 21
_c21: jmp __cycle__in__spine
align (1 shl 2)
dd 22
_c22: jmp __cycle__in__spine
align (1 shl 2)
dd 23
_c23: jmp __cycle__in__spine
align (1 shl 2)
dd 24
_c24: jmp __cycle__in__spine
align (1 shl 2)
dd 25
_c25: jmp __cycle__in__spine
align (1 shl 2)
dd 26
_c26: jmp __cycle__in__spine
align (1 shl 2)
dd 27
_c27: jmp __cycle__in__spine
align (1 shl 2)
dd 28
_c28: jmp __cycle__in__spine
align (1 shl 2)
dd 29
_c29: jmp __cycle__in__spine
align (1 shl 2)
dd 30
_c30: jmp __cycle__in__spine
align (1 shl 2)
dd 31
_c31: jmp __cycle__in__spine
align (1 shl 2)
dd 32
_c32: jmp __cycle__in__spine
;
; ARRAYS
;
_create_arrayB:
mov rbx,rax
add rax,24+7
shr rax,3
sub r15,rax
jge no_collect_4574
call collect_0
no_collect_4574:
mov rcx,rdi
mov qword ptr [rdi],offset __ARRAY__+2
mov qword ptr 8[rdi],rbx
mov qword ptr 16[rdi],offset BOOL+2
lea rdi,[rdi+rax*8]
ret
_create_arrayC:
mov rbx,rax
add rax,16+7
shr rax,3
sub r15,rax
jge no_collect_4573
call collect_0
no_collect_4573:
mov rcx,rdi
mov qword ptr [rdi],offset __STRING__+2
mov qword ptr 8[rdi],rbx
lea rdi,[rdi+rax*8]
ret
_create_arrayI:
lea rbp,3[rax]
sub r15,rbp
jge no_collect_4572
call collect_0
no_collect_4572:
mov rcx,rdi
mov qword ptr [rdi],offset __ARRAY__+2
mov qword ptr 8[rdi],rax
lea rbp,dINT+2
mov qword ptr 16[rdi],rbp
lea rdi,24[rdi+rax*8]
ret
_create_arrayI32:
mov rbx,rax
add rax,6+1
shr rax,1
sub r15,rax
jge no_collect_3572
call collect_0
no_collect_3572:
mov rcx,rdi
mov qword ptr [rdi],offset __ARRAY__+2
mov qword ptr 8[rdi],rbx
mov qword ptr 16[rdi],offset INT32+2
lea rdi,[rdi+rax*8]
ret
_create_arrayR:
lea rbp,3[rax]
sub r15,rbp
jge no_collect_4580
call collect_0
no_collect_4580:
mov rcx,rdi
mov qword ptr [rdi],offset __ARRAY__+2
mov qword ptr 8[rdi],rax
mov qword ptr 16[rdi],offset REAL+2
lea rdi,24[rdi+rax*8]
ret
_create_arrayR32:
mov rbx,rax
add rax,6+1
shr rax,1
sub r15,rax
jge no_collect_3580
call collect_0
no_collect_3580:
mov rcx,rdi
mov qword ptr [rdi],offset __ARRAY__+2
mov qword ptr 8[rdi],rax
mov qword ptr 16[rdi],offset REAL32+2
lea rdi,[rdi+rax*8]
ret
; rax : number of elements, rbx: element descriptor
; r10 : element size, r11 : element a size, rcx :a_element-> rcx : array
_create_r_array:
mov rbp,rax
imul rbp,r10
add rbp,3
sub r15,rbp
jge no_collect_4586
call collect_1
no_collect_4586:
mov qword ptr [rdi],offset __ARRAY__+2
mov rdx,rcx
mov qword ptr 8[rdi],rax
mov rcx,rdi
mov qword ptr 16[rdi],rbx
add rdi,24
test r11,r11
je _create_r_array_0
sub r11,2
jc _create_r_array_1
je _create_r_array_2
sub r11,2
jc _create_r_array_3
je _create_r_array_4
jmp _create_r_array_5
_create_r_array_0:
imul r10,rax
lea rdi,[rdi+r10*8]
ret
_create_r_array_1:
shl r10,3
jmp _st_fillr1_array
_fillr1_array:
mov qword ptr [rdi],rdx
add rdi,r10
_st_fillr1_array:
sub rax,1
jnc _fillr1_array
ret
_create_r_array_2:
shl r10,3
jmp _st_fillr2_array
_fillr2_array:
mov qword ptr [rdi],rdx
mov qword ptr 8[rdi],rdx
add rdi,r10
_st_fillr2_array:
sub rax,1
jnc _fillr2_array
ret
_create_r_array_3:
shl r10,3
jmp _st_fillr3_array
_fillr3_array:
mov qword ptr [rdi],rdx
mov qword ptr 8[rdi],rdx
mov qword ptr 16[rdi],rdx
add rdi,r10
_st_fillr3_array:
sub rax,1
jnc _fillr3_array
ret
_create_r_array_4:
shl r10,3
jmp _st_fillr4_array
_fillr4_array:
mov qword ptr [rdi],rdx
mov qword ptr 8[rdi],rdx
mov qword ptr 16[rdi],rdx
mov qword ptr 24[rdi],rdx
add rdi,r10
_st_fillr4_array:
sub rax,1
jnc _fillr4_array
ret
_create_r_array_5:
sub r10,4
sub r10,r11
sub r11,1
shl r10,3
jmp _st_fillr5_array
_fillr5_array:
mov qword ptr [rdi],rdx
mov qword ptr 8[rdi],rdx
mov qword ptr 16[rdi],rdx
mov qword ptr 24[rdi],rdx
add rdi,32
mov rbx,r11
_copy_elem_5_lp:
mov qword ptr [rdi],rdx
add rdi,8
sub rbx,1
jnc _copy_elem_5_lp
add rdi,r10
_st_fillr5_array:
sub rax,1
jnc _fillr5_array
ret
create_arrayB:
mov r10,rbx
add rbx,24+7
shr rbx,3
sub r15,rbx
jge no_collect_4575
call collect_0
no_collect_4575:
mov rbp,rax
sub rbx,3
shl rbp,8
or rax,rbp
mov rbp,rax
shl rbp,16
or rax,rbp
mov rbp,rax
shl rbp,32
or rax,rbp
mov rcx,rdi
mov qword ptr [rdi],offset __ARRAY__+2
mov qword ptr 8[rdi],r10
mov qword ptr 16[rdi],offset BOOL+2
add rdi,24
jmp create_arrayBCI
create_arrayC:
mov r10,rbx
add rbx,16+7
shr rbx,3
sub r15,rbx
jge no_collect_4578
call collect_0
no_collect_4578:
mov rbp,rax
sub rbx,2
shl rbp,8
or rax,rbp
mov rbp,rax
shl rbp,16
or rax,rbp
mov rbp,rax
shl rbp,32
or rax,rbp
mov rcx,rdi
mov qword ptr [rdi],offset __STRING__+2
mov qword ptr 8[rdi],r10
add rdi,16
jmp create_arrayBCI
create_arrayI32:
mov r10,rbx
add rbx,6+1
shr rbx,1
sub r15,rbx
jge no_collect_3577
call collect_0
no_collect_3577:
mov rcx,rdi
mov qword ptr [rdi],offset __ARRAY__+2
mov qword ptr 8[rdi],r10
mov qword ptr 16[rdi],offset INT32+2
add rdi,24
sub rbx,3
mov ebp,eax
shl rax,32
or rax,rbp
jmp create_arrayBCI
create_arrayI:
lea rbp,3[rbx]
sub r15,rbp
jge no_collect_4577
call collect_0
no_collect_4577:
mov rcx,rdi
lea rbp,__ARRAY__+2
mov qword ptr [rdi],rbp
mov qword ptr 8[rdi],rbx
lea rbp,dINT+2
mov qword ptr 16[rdi],rbp
add rdi,24
create_arrayBCI:
mov rdx,rbx
shr rbx,1
test dl,1
je st_filli_array
mov qword ptr [rdi],rax
add rdi,8
jmp st_filli_array
filli_array:
mov qword ptr [rdi],rax
mov qword ptr 8[rdi],rax
add rdi,16
st_filli_array:
sub rbx,1
jnc filli_array
ret
create_arrayR32:
cvtsd2ss xmm0,xmm0
movss dword ptr (-8)[rsp],xmm0
mov r10,rax
add rax,6+1
shr rax,1
mov ebx,dword ptr (-8)[rsp]
sub r15,rax
jge no_collect_3579
call collect_0
no_collect_3579:
mov rcx,rdi
mov qword ptr [rdi],offset __ARRAY__+2
mov qword ptr 8[rdi],r10
mov qword ptr 16[rdi],offset REAL32+2
add rdi,24
sub rax,3
mov edx,ebx
shl rbx,32
or rbx,rdx
jmp st_fillr_array
create_arrayR:
movsd qword ptr (-8)[rsp],xmm0
lea rbp,3[rax]
mov rbx,qword ptr (-8)[rsp]
sub r15,rbp
jge no_collect_4579
call collect_0
no_collect_4579:
mov rcx,rdi
mov qword ptr [rdi],offset __ARRAY__+2
mov qword ptr 8[rdi],rax
mov qword ptr 16[rdi],offset REAL+2
add rdi,24
jmp st_fillr_array
fillr_array:
mov qword ptr [rdi],rbx
add rdi,8
st_fillr_array:
sub rax,1
jnc fillr_array
ret
create_array:
lea rbp,3[rax]
sub r15,rbp
jge no_collect_4576
call collect_1
no_collect_4576:
mov rbx,rcx
mov rcx,rdi
mov qword ptr [rdi],offset __ARRAY__+2
mov qword ptr 8[rdi],rax
mov qword ptr 16[rdi],0
add rdi,24
jmp fillr1_array
; in rax: number of elements, rbx: element descriptor
; r10 : element size, r11 : element a size -> rcx : array
create_R_array:
sub r10,2
jc create_R_array_1
je create_R_array_2
sub r10,2
jc create_R_array_3
je create_R_array_4
jmp create_R_array_5
create_R_array_1:
lea rbp,3[rax]
sub r15,rbp
jge no_collect_4581
call collect_0
no_collect_4581:
mov rcx,rdi
mov qword ptr [rdi],offset __ARRAY__+2
mov qword ptr 8[rdi],rax
mov qword ptr 16[rdi],rbx
add rdi,24
test r11,r11
je r_array_1_b
mov rbx,qword ptr (-8)[rsi]
jmp fillr1_array
r_array_1_b:
mov rbx,qword ptr 8[rsp]
fillr1_array:
mov rdx,rax
shr rax,1
test dl,1
je st_fillr1_array_1
mov qword ptr [rdi],rbx
add rdi,8
jmp st_fillr1_array_1
fillr1_array_lp:
mov qword ptr [rdi],rbx
mov qword ptr 8[rdi],rbx
add rdi,16
st_fillr1_array_1:
sub rax,1
jnc fillr1_array_lp
ret
create_R_array_2:
lea rbp,3[rax*2]
sub r15,rbp
jge no_collect_4582
call collect_0
no_collect_4582:
mov rcx,rdi
mov qword ptr [rdi],offset __ARRAY__+2
mov qword ptr 8[rdi],rax
mov qword ptr 16[rdi],rbx
add rdi,24
sub r11,1
jc r_array_2_bb
je r_array_2_ab
r_array_2_aa:
mov rbx,qword ptr (-8)[rsi]
mov rbp,qword ptr (-16)[rsi]
jmp st_fillr2_array
r_array_2_ab:
mov rbx,qword ptr (-8)[rsi]
mov rbp,qword ptr 8[rsp]
jmp st_fillr2_array
r_array_2_bb:
mov rbx,qword ptr 8[rsp]
mov rbp,qword ptr 16[rsp]
jmp st_fillr2_array
fillr2_array_1:
mov qword ptr [rdi],rbx
mov qword ptr 8[rdi],rbp
add rdi,16
st_fillr2_array:
sub rax,1
jnc fillr2_array_1
ret
create_R_array_3:
lea rbp,3[rax+rax*2]
sub r15,rbp
jge no_collect_4583
call collect_0
no_collect_4583:
mov rcx,rdi
mov qword ptr [rdi],offset __ARRAY__+2
mov qword ptr 8[rdi],rax
mov qword ptr 16[rdi],rbx
add rdi,24
pop rdx
mov r12,rsp
test r11,r11
je r_array_3
lea r13,0[r11*8]
mov rbp,rsi
sub rbp,r13
sub r11,1
copy_a_to_b_lp3:
push [rbp]
add rbp,8
sub r11,1
jnc copy_a_to_b_lp3
r_array_3:
mov rbx,qword ptr [rsp]
mov r13,qword ptr 8[rsp]
mov rbp,qword ptr 16[rsp]
mov rsp,r12
push rdx
jmp st_fillr3_array
fillr3_array_1:
mov qword ptr [rdi],rbx
mov qword ptr 8[rdi],r13
mov qword ptr 16[rdi],rbp
add rdi,24
st_fillr3_array:
sub rax,1
jnc fillr3_array_1
ret
create_R_array_4:
lea rbp,3[rax+4]
sub r15,rbp
jge no_collect_4584
call collect_0
no_collect_4584:
mov rcx,rdi
mov qword ptr [rdi],offset __ARRAY__+2
mov qword ptr 8[rdi],rax
mov qword ptr 16[rdi],rbx
add rdi,24
pop rdx
mov r12,rsp
test r11,r11
je r_array_4
lea r13,0[r11*8]
mov rbp,rsi
sub rbp,r13
sub r11,1
copy_a_to_b_lp4:
push [rbp]
add rbp,8
sub r11,1
jnc copy_a_to_b_lp4
r_array_4:
mov rbx,qword ptr [rsp]
mov r13,qword ptr 8[rsp]
mov r14,qword ptr 16[rsp]
mov rbp,qword ptr 24[rsp]
mov rsp,r12
push rdx
jmp st_fillr4_array
fillr4_array:
mov qword ptr [rdi],rbx
mov qword ptr 8[rdi],r13
mov qword ptr 16[rdi],r14
mov qword ptr 24[rdi],rbp
add rdi,32
st_fillr4_array:
sub rax,1
jnc fillr4_array
ret
create_R_array_5:
lea r12,4[r10]
mov rbp,rax
imul rbp,r12
add rbp,3
sub r15,rbp
jge no_collect_4585
call collect_0
no_collect_4585:
mov qword ptr [rdi],offset __ARRAY__+2
mov qword ptr 8[rdi],rax
mov qword ptr 16[rdi],rbx
mov rcx,rdi
add rdi,24
pop rdx
mov r12,rsp
test r11,r11
je r_array_5
lea r13,0[r11*8]
mov rbp,rsi
sub rbp,r13
sub r11,1
copy_a_to_b_lp5:
push [rbp]
add rbp,8
sub r11,1
jnc copy_a_to_b_lp5
r_array_5:
mov r13,qword ptr [rsp]
mov r14,qword ptr 8[rsp]
if THREAD
lea rbx,32[rsp+r10*8]
endif
mov r8,qword ptr 16[rsp]
if THREAD
mov r10,qword ptr 24[rsp]
else
mov r9,qword ptr 24[rsp]
endif
add rsp,32
ife THREAD
sub r10,1
endif
jmp st_fillr5_array
fillr5_array_1:
mov qword ptr [rdi],r13
mov qword ptr 8[rdi],r14
mov r11,rsp
ife THREAD
mov rbx,r10
endif
mov qword ptr 16[rdi],r8
if THREAD
mov qword ptr 24[rdi],r10
else
mov qword ptr 24[rdi],r9
endif
add rdi,32
copy_elem_lp5:
mov rbp,qword ptr [r11]
add r11,8
mov qword ptr [rdi],rbp
add rdi,8
if THREAD
cmp r11,rbx
jne copy_elem_lp5
else
sub rbx,1
jnc copy_elem_lp5
endif
st_fillr5_array:
sub rax,1
jnc fillr5_array_1
mov rsp,r12
jmp rdx
ifndef NEW_DESCRIPTORS
yet_args_needed:
; for more than 4 arguments
mov r10,[rdx]
movzx rax,word ptr (-2)[r10]
add rax,3
sub r15,rax
jl gc_1
gc_r_1: sub rax,3+1+4
mov rbx,8[rdx]
add r10,8
mov rdx,16[rdx]
mov rbp,rdi
mov r8,[rdx]
mov [rdi],r8
mov r8,8[rdx]
mov 8[rdi],r8
mov r8,16[rdx]
mov 16[rdi],r8
add rdx,24
add rdi,24
cp_a: mov r8,[rdx]
add rdx,8
mov [rdi],r8
add rdi,8
sub rax,1
jge cp_a
mov [rdi],rcx
mov 8[rdi],r10
lea rcx,8[rdi]
mov 16[rdi],rbx
mov 24[rdi],rbp
add rdi,32
ret
gc_1:
call collect_2
jmp gc_r_1
yet_args_needed_0:
sub r15,2
jl gc_20
gc_r_20:
mov 8[rdi],rcx
mov rax,[rdx]
mov rcx,rdi
add rax,8
mov [rdi],rax
add rdi,16
ret
gc_20:
call collect_2
jmp gc_r_20
yet_args_needed_1:
sub r15,3
jl gc_21
gc_r_21:
mov 16[rdi],rcx
mov rax,[rdx]
mov rcx,rdi
add rax,8
mov [rdi],rax
mov rbx,8[rdx]
mov 8[rdi],rbx
add rdi,24
ret
gc_21:
call collect_2
jmp gc_r_21
yet_args_needed_2:
sub r15,5
jl gc_22
gc_r_22:
mov rax,[rdx]
mov 8[rdi],rcx
add rax,8
mov rbp,8[rdx]
mov 16[rdi],rax
lea rcx,16[rdi]
mov 24[rdi],rbp
mov rbp,16[rdx]
mov [rdi],rbp
mov 32[rdi],rdi
add rdi,40
ret
gc_22:
call collect_2
jmp gc_r_22
yet_args_needed_3:
sub r15,6
jl gc_23
gc_r_23:
mov rax,[rdx]
mov 16[rdi],rcx
add rax,8
mov rbp,8[rdx]
mov 24[rdi],rax
mov rdx,16[rdx]
mov 32[rdi],rbp
mov rbp,[rdx]
mov 40[rdi],rdi
mov [rdi],rbp
mov rbp,8[rdx]
lea rcx,24[rdi]
mov 8[rdi],rbp
add rdi,48
ret
gc_23:
call collect_2
jmp gc_r_23
yet_args_needed_4:
sub r15,7
jl gc_24
gc_r_24:
mov rax,[rdx]
mov 24[rdi],rcx
add rax,8
mov rbp,8[rdx]
mov 32[rdi],rax
mov rdx,16[rdx]
mov 40[rdi],rbp
mov rbp,[rdx]
mov 48[rdi],rdi
mov [rdi],rbp
mov rbp,8[rdx]
lea rcx,32[rdi]
mov 8[rdi],rbp
mov rbp,16[rdx ]
mov 16[rdi],rbp
add rdi,56
ret
gc_24:
call collect_2
jmp gc_r_24
endif
repl_args_b:
test rax,rax
jle repl_args_b_1
dec rax
je repl_args_b_4
mov rdx,16[rcx]
sub rbx,2
jne repl_args_b_2
mov [rsi],rdx
add rsi,8
jmp repl_args_b_4
repl_args_b_2:
lea rdx,[rdx+rax*8]
repl_args_b_3:
mov rbp,(-8)[rdx]
sub rdx,8
mov [rsi],rbp
add rsi,8
dec rax
jne repl_args_b_3
repl_args_b_4:
mov rbp,8[rcx]
mov [rsi],rbp
add rsi,8
repl_args_b_1:
ret
push_arg_b:
cmp rbx,2
jb push_arg_b_1
jne push_arg_b_2
cmp rbx,rax
je push_arg_b_1
push_arg_b_2:
mov rcx,16[rcx]
sub rbx,2
push_arg_b_1:
mov rcx,[rcx+rbx*8]
ret
del_args:
mov rbx,[rcx]
sub rbx,rax
movsx rax,word ptr (-2)[rbx]
sub rax,2
jge del_args_2
mov [rdx],rbx
mov rbp,8[rcx]
mov 8[rdx],rbp
mov rbp,16[rcx]
mov 16[rdx],rbp
ret
del_args_2:
jne del_args_3
mov [rdx],rbx
mov rbp,8[rcx]
mov 8[rdx],rbp
mov rbp,16[rcx]
mov rbp,[rbp]
mov 16[rdx],rbp
ret
del_args_3:
sub r15,rax
jl del_args_gc
del_args_r_gc:
mov [rdx],rbx
mov 16[rdx],rdi
mov rbp,8[rcx]
mov rcx,16[rcx]
mov 8[rdx],rbp
del_args_copy_args:
mov rbp,[rcx]
add rcx,8
mov [rdi],rbp
add rdi,8
sub rax,1
jg del_args_copy_args
ret
del_args_gc:
call collect_2
jmp del_args_r_gc
ifdef USE_LIBM
cos_real:
mov rbp,rsp
and rsp,-16
mov r13,rsi
mov r14,rdi
call cos
mov rsp,rbp
mov rsi,r13
mov rdi,r14
ret
sin_real:
mov rbp,rsp
and rsp,-16
mov r13,rsi
mov r14,rdi
call sin
mov rsp,rbp
mov rsi,r13
mov rdi,r14
ret
tan_real:
mov rbp,rsp
and rsp,-16
mov r13,rsi
mov r14,rdi
call tan
mov rsp,rbp
mov rsi,r13
mov rdi,r14
ret
atan_real:
mov rbp,rsp
and rsp,-16
mov r13,rsi
mov r14,rdi
call atan
mov rsp,rbp
mov rsi,r13
mov rdi,r14
ret
asin_real:
acos_real:
ln_real:
log10_real:
exp_real:
pow_real:
exp2_real_:
_c_log10:
_c_pow:
_c_entier:
int 3
ret
endif
entier_real:
cvttsd2si rax,xmm0
ucomisd xmm0,qword ptr real_0_0
jb entier_real_m
ret
entier_real_m:
movsd qword ptr (-8)[rsp],xmm0
mov rcx,qword ptr (-8)[rsp]
mov rbx,rcx
shr rcx,52
cmp rcx,0bffh
jb entier_real_m_small
cmp rcx,0bffh+52
jae entier_real_m_large
sub rcx,0bffh-12
shl rbx,cl
je entier_m_exact
entier_real_m_small:
sub rax,1
entier_real_m_large:
entier_m_exact:
ret
r_to_i_real:
cvtsd2si rax,xmm0
ret
public getheapend
getheapend:
lea rbx,[rdi+r15*8]
if THREAD
mov rax,heap_end_after_gc_offset[r9]
else
mov rax,heap_end_after_gc
endif
ret
_TEXT ends
include ..\areals.asm
ifdef PROFILE
ifdef TRACE
include ..\atrace.asm
else
include ..\aprofile.asm
endif
endif
ifdef NEW_DESCRIPTORS
include aap.asm
endif
ifdef THREAD
include athread.asm
endif
end