; 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