;
; Реализация среды исполнения языка программирования
; Объектно-ориентированный продвинутый векторный транслятор
;
; Copyright © 2021, 2024 Малик Разработчик
;
; Это свободная программа: вы можете перераспространять ее и/или изменять
; ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
; в каком она была опубликована Фондом свободного программного обеспечения;
; либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
;
; Эта программа распространяется в надежде, что она будет полезной,
; но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
; или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
; общественной лицензии GNU.
;
; Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
; вместе с этой программой. Если это не так, см.
; <https://www.gnu.org/licenses/>.
;
; <fold все точки входа>
if(used ctxt$main) ; <fold точка входа в главный поток>
proc ctxt$main
label .prevr03q at rsp+$48
label .prevr06q at rsp+$40
label .prevr07q at rsp+$38
label .exitcode at rsp+$30
; вход
cld
lea rsp, [rsp-$58]
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$kernel.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$kernel.writeFile]
mov r01d, $fffffffe
call qword [impr$kernel.exitProcess]
@@: ; проверка поддержки XSAVE и XSAVEC
call ctxt$cpu.isSupportedXStorage
test r00d, r00d
jnz @F
mov r01d, $fffffff4
call qword [impr$kernel.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$kernel.writeFile]
mov r01d, $fffffffd
call qword [impr$kernel.exitProcess]
@@: ; проверка поддержки AVX-512 со стороны операционной системы
call ctxt$os.isSupportedAVX512
test r00d, r00d
jnz @F
mov r01d, $fffffff4
call qword [impr$kernel.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$kernel.writeFile]
mov r01d, $fffffffc
call qword [impr$kernel.exitProcess]
@@: ; определение размера в байтах области 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.runtime.Win32Runtime$TAGGED_STACK_CONTEXT_AREA_SIZE], r03q
mov qword [platform.dependent.mswindows.runtime.Win32Runtime$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$kernel.virtualAlloc]
; определение указателей на области тагированного стака
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 qword [.exitcode], r00q
xor r02q, r02q
mov r08d, platform.dependent.mswindows.kernel.Kernel$MEM_RELEASE
call qword [impr$kernel.virtualFree]
; восстановление кода выхода и возврат управления операционной системе
mov r00q, [.exitcode]
lea rsp, [rsp+$58]
ret
end_proc
end if ; </fold>
if(used ctxt$thread) ; <fold точка входа в дополнительный поток>
proc ctxt$thread
label .prevr03q at rsp+$38
label .prevr06q at rsp+$30
label .prevr07q at rsp+$28
label .argument at rsp+$20
; вход
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.runtime.Win32Runtime$TAGGED_STACK_CONTEXT_AREA_SIZE] ; размер области контекста
mov r06q, [platform.dependent.mswindows.runtime.Win32Runtime$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$kernel.virtualAlloc]
; определение указателей на области тагированного стака
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]
; переключение на тагированный стак
mov r01q, [.argument]
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], r01q
mov byte [rsi+$00], TAG_OBJECT
; вызов инстанционного метода avt.lang.Thread.execute()
call avt.lang.Thread$execute$
; восстановление значений регистров, переключение на стандартный стак
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$kernel.virtualFree]
; восстановление кода выхода и возврат управления операционной системе
xor r00q, r00q
lea rsp, [rsp+$48]
ret
end_proc
end if ; </fold>
; </fold>
; <fold функции проверки поддержки необходимых возможностей процессора и операционной системы>
include "cpu-check.inc"
; </fold>