;
; Реализация среды исполнения языка программирования
; Объектно-ориентированный продвинутый векторный транслятор
;
; Copyright © 2021, 2024, 2026 Малик Разработчик
;
; Это свободная программа: вы можете перераспространять ее и/или изменять
; ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
; в каком она была опубликована Фондом свободного программного обеспечения;
; либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
;
; Эта программа распространяется в надежде, что она будет полезной,
; но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
; или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
; общественной лицензии GNU.
;
; Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
; вместе с этой программой. Если это не так, см.
; <https://www.gnu.org/licenses/>.
;
; <fold все точки входа>
if(used ctxt$main) ; <fold точка входа в главный поток>
proc ctxt$main
label .prevr03q at rsp+$30
label .prevr06q at rsp+$38
label .prevr07q at rsp+$40
label .hSnapshot at rsp+$48
label .exitСode at rsp+$50
label .counter at rsp+$54
label .processId at rsp+$58
label .threadInfo at rsp+$5c
; вход
cld
lea rsp, [rsp-$78]
mov qword [.prevr03q], r03q
mov qword [.prevr06q], r06q
mov qword [.prevr07q], r07q
; проверка поддержки AVX-512 со стороны процессора
call ctxt$cpu.isSupportedAVX512
test r00d, r00d
jnz @F
mov r01d, $fffffff4
call qword [impr$GetStdHandle]
lea r01q, [r00+$00]
lea r02q, [ctxt$noavxCPUMessage]
mov r08d, ctxt$noavxCPUMessage.end-ctxt$noavxCPUMessage
lea r09q, [rsp+$30]
mov qword [rsp+$20], $00
call qword [impr$WriteFile]
mov r00d, $fffffffe
jmp .L.0000
@@: ; проверка поддержки XSAVE и XSAVEC
call ctxt$cpu.isSupportedXStorage
test r00d, r00d
jnz @F
mov r01d, $fffffff4
call qword [impr$GetStdHandle]
lea r01q, [r00+$00]
lea r02q, [ctxt$noxstCPUMessage]
mov r08d, ctxt$noxstCPUMessage.end-ctxt$noxstCPUMessage
lea r09q, [rsp+$30]
mov qword [rsp+$20], $00
call qword [impr$WriteFile]
mov r00d, $fffffffd
jmp .L.0000
@@: ; проверка поддержки AVX-512 со стороны операционной системы
call ctxt$os.isSupportedAVX512
test r00d, r00d
jnz @F
mov r01d, $fffffff4
call qword [impr$GetStdHandle]
lea r01q, [r00+$00]
lea r02q, [ctxt$noavxOSMessage]
mov r08d, ctxt$noavxOSMessage.end-ctxt$noavxOSMessage
lea r09q, [rsp+$30]
mov qword [rsp+$20], $00
call qword [impr$WriteFile]
mov r00d, $fffffffc
jmp .L.0000
@@: ; определение размера в байтах области xstorage
call ctxt$cpu.getXStorageAreaSize
; определение размера областей тагированного стака
mov r06d, [ctxt$taggedStackSizeOfData] ; размер области данных
lea r03q, [r00+ctxt$xst]
lea r00q, [r03+$00]
neg r00q
and r00q, $00000fff
lea r03q, [r03+r00*1+$00] ; размер области контекста
lea r07q, [r06+$00]
shr r07q, $04
lea r07q, [r06+r07*1+$00] ; размер области данных + размер области тагов
mov qword [platform.dependent.mswindows.services.MSWindowsServices$TAGGED_STACK_CONTEXT_AREA_SIZE], r03q
mov qword [platform.dependent.mswindows.services.MSWindowsServices$TAGGED_STACK_DATA_AREA_SIZE], r06q
; определение размера тагированного стака и выделение памяти под него
xor r01q, r01q
lea r02q, [r07+r03*1+$00]
mov r08d, platform.dependent.mswindows.kernel.Kernel$MEM_COMMIT
mov r09d, platform.dependent.mswindows.kernel.Kernel$PAGE_READWRITE
call qword [impr$VirtualAlloc]
test r00q, r00q
jnz @F
mov r00d, $ffffffff
.L.0000: mov r03q, [.prevr03q]
mov r06q, [.prevr06q]
mov r07q, [.prevr07q]
jmp .L.EXIT
@@: ; определение указателей на области тагированного стака
lea r01q, [r00+$00001000]
lea r02q, [r03+$00000000]
lea r03q, [r00+r07*1+$00]
lea r06q, [r00+r06*1+$00]
lea r07q, [r03+r02*1+$00]
; заполнение области контекста
mov qword [r03+ctxt$zer], $00
mov qword [r03+ctxt$ehb], $00
mov qword [r03+ctxt$dat], r00q
mov qword [r03+ctxt$grd], r01q
mov qword [r03+ctxt$tag], r06q
mov qword [r03+ctxt$end], r07q
mov qword [r03+ctxt$sup], $00
mov r00q, [.prevr03q]
mov r01q, [.prevr06q]
mov r02q, [.prevr07q]
mov qword [r03+ctxt$r03], r00q
mov qword [r03+ctxt$r04], rsp
mov qword [r03+ctxt$r05], rbp
mov qword [r03+ctxt$r06], r01q
mov qword [r03+ctxt$r07], r02q
mov qword [r03+ctxt$r12], r12q
mov qword [r03+ctxt$r13], r13q
mov qword [r03+ctxt$r14], r14q
mov qword [r03+ctxt$r15], r15q
mov r00d, $000000e7
mov r02d, $00000000
xsavec64 [r03+ctxt$xst]
; переключение FPU и AVX на режим, необходимый коду на ПВТ-ОО
fldcw word [ctxt$fpuControlWord]
vldmxcsr dword [ctxt$avxControlStatusWord]
; переключение на тагированный стак
xor r02q, r02q
lea rsp, [r06+$00]
lea rbp, [r02+$00]
lea rsi, [r03+$00]
lea rdi, [r02+$00]
; вызов статичного метода platform.dependent.mswindows.EntryPoint.main()
call platform.dependent.mswindows.EntryPoint$main$
; восстановление значений регистров, переключение на стандартный стак
cld
mov r01d, r00d
mov r00d, $000000e7
mov r02d, $00000000
xrstor64 [r03+ctxt$xst]
mov r00d, r01d
mov r01q, [r03+ctxt$dat]
mov r15q, [r03+ctxt$r15]
mov r14q, [r03+ctxt$r14]
mov r13q, [r03+ctxt$r13]
mov r12q, [r03+ctxt$r12]
mov r07q, [r03+ctxt$r07]
mov r06q, [r03+ctxt$r06]
mov rbp, [r03+ctxt$r05]
mov rsp, [r03+ctxt$r04]
mov r03q, [r03+ctxt$r03]
mov dword [.exitСode], r00d
xor r02q, r02q
mov r08d, platform.dependent.mswindows.kernel.Kernel$MEM_RELEASE
call qword [impr$VirtualFree]
; если исполняется более одного потока исполнения, то выходим через функцию ExitProcess
call qword [impr$GetCurrentProcessId]
mov dword [.processId], r00d
mov dword [.counter], $00
mov r01d, platform.dependent.mswindows.kernel.Kernel$TH32CS_SNAPTHREAD
mov r02d, $00
call qword [impr$CreateToolhelp32Snapshot]
cmp r00q, [platform.dependent.mswindows.kernel.Kernel$INVALID_HANDLE_VALUE]
je .L.0004
mov qword [.hSnapshot], r00q
mov dword [.threadInfo+platform.dependent.mswindows.kernel.ThreadEntry32$dwSize.struct], $1c
mov r01q, r00q
lea r02q, [.threadInfo]
call qword [impr$Thread32First]
test r00d, r00d
jz .L.0003
.L.0001: mov r00d, [.threadInfo+platform.dependent.mswindows.kernel.ThreadEntry32$th32OwnerProcessID.struct]
cmp r00d, [.processId]
jne .L.0002
inc dword [.counter]
cmp dword [.counter], $01
jng .L.0002
mov r01q, [.hSnapshot]
call qword [impr$CloseHandle]
mov r01d, [.exitСode]
call qword [impr$ExitProcess]
.L.0002: mov r01q, [.hSnapshot]
lea r02q, [.threadInfo]
call qword [impr$Thread32Next]
test r00d, r00d
jnz .L.0001
.L.0003: mov r01q, [.hSnapshot]
call qword [impr$CloseHandle]
; восстановление кода выхода и возврат управления операционной системе
.L.0004: mov r00d, [.exitСode]
.L.EXIT: lea rsp, [rsp+$78]
ret
end_proc
end if ; </fold>
if(used ctxt$thread) ; <fold точка входа в дополнительный поток>
proc ctxt$thread
label .prevr03q at rsp+$20
label .prevr06q at rsp+$28
label .prevr07q at rsp+$30
label .argument at rsp+$38
; вход
cld
lea rsp, [rsp-$48]
mov qword [.prevr03q], r03q
mov qword [.prevr06q], r06q
mov qword [.prevr07q], r07q
mov qword [.argument], r01q
; определение размера областей тагированного стака
mov r03q, [platform.dependent.mswindows.services.MSWindowsServices$TAGGED_STACK_CONTEXT_AREA_SIZE] ; размер области контекста
mov r06q, [platform.dependent.mswindows.services.MSWindowsServices$TAGGED_STACK_DATA_AREA_SIZE] ; размер области данных
lea r07q, [r06+$00]
shr r07q, $04
lea r07q, [r06+r07*1+$00] ; размер области данных + размер области тагов
; определение размера тагированного стака и выделение памяти под него
xor r01q, r01q
lea r02q, [r07+r03*1+$00]
mov r08d, platform.dependent.mswindows.kernel.Kernel$MEM_COMMIT
mov r09d, platform.dependent.mswindows.kernel.Kernel$PAGE_READWRITE
call qword [impr$VirtualAlloc]
test r00q, r00q
jnz @F
mov dword [platform.dependent.mswindows.services.MSWindowsServices$startThreadResult], $a0727265
mov r03q, [.prevr03q]
mov r06q, [.prevr06q]
mov r07q, [.prevr07q]
jmp .L.EXIT
@@: mov r08q, [.argument]
incrcoth r08q
mov dword [platform.dependent.mswindows.services.MSWindowsServices$startThreadResult], $00004b4f
; определение указателей на области тагированного стака
lea r01q, [r00+$00001000]
lea r02q, [r03+$00000000]
lea r03q, [r00+r07*1+$00]
lea r06q, [r00+r06*1+$00]
lea r07q, [r03+r02*1+$00]
; заполнение области контекста
mov qword [r03+ctxt$zer], $00
mov qword [r03+ctxt$ehb], $00
mov qword [r03+ctxt$dat], r00q
mov qword [r03+ctxt$grd], r01q
mov qword [r03+ctxt$tag], r06q
mov qword [r03+ctxt$end], r07q
mov qword [r03+ctxt$sup], $00
mov r00q, [.prevr03q]
mov r01q, [.prevr06q]
mov r02q, [.prevr07q]
mov qword [r03+ctxt$r03], r00q
mov qword [r03+ctxt$r04], rsp
mov qword [r03+ctxt$r05], rbp
mov qword [r03+ctxt$r06], r01q
mov qword [r03+ctxt$r07], r02q
mov qword [r03+ctxt$r12], r12q
mov qword [r03+ctxt$r13], r13q
mov qword [r03+ctxt$r14], r14q
mov qword [r03+ctxt$r15], r15q
mov r00d, $000000e7
mov r02d, $00000000
xsavec64 [r03+ctxt$xst]
; переключение FPU и AVX на режим, необходимый коду на ПВТ-ОО
fldcw word [ctxt$fpuControlWord]
vldmxcsr dword [ctxt$avxControlStatusWord]
; переключение на тагированный стак
xor r02q, r02q
lea rsp, [r06-$10]
lea rbp, [r02+$00]
lea rsi, [r03-$01]
lea rdi, [r02+$00]
; запись аргумента this и тага
mov qword [rsp+$08], $00
mov qword [rsp+$00], r08q
mov byte [rsi+$00], TAG_OBJECT
; вызов инстанционного метода avt.lang.Runnable.run()
mov r00q, r08q
invservfast avt.lang.Runnable, run$
; восстановление значений регистров, переключение на стандартный стак
cld
mov r00d, $000000e7
mov r02d, $00000000
xrstor64 [r03+ctxt$xst]
mov r01q, [r03+ctxt$dat]
mov r15q, [r03+ctxt$r15]
mov r14q, [r03+ctxt$r14]
mov r13q, [r03+ctxt$r13]
mov r12q, [r03+ctxt$r12]
mov r07q, [r03+ctxt$r07]
mov r06q, [r03+ctxt$r06]
mov rbp, [r03+ctxt$r05]
mov rsp, [r03+ctxt$r04]
mov r03q, [r03+ctxt$r03]
xor r02q, r02q
mov r08d, platform.dependent.mswindows.kernel.Kernel$MEM_RELEASE
call qword [impr$VirtualFree]
; восстановление кода выхода и возврат управления операционной системе
.L.EXIT: xor r00q, r00q
lea rsp, [rsp+$48]
ret
end_proc
end if ; </fold>
; </fold>
; <fold функции проверки поддержки необходимых возможностей процессора и операционной системы>
include "cpu-check.inc"
; </fold>