instruction.stack.inc

Переключить прокрутку окна
Загрузить этот исходный код

;
 ;  Исходный код среды исполнения ПВТ-ОО.
 ;
 ;  Этот исходный код является частью проекта ПВТ-ОО.
 ;
 ;  Copyright © 2021 Малик Разработчик
 ;
 ;  Это свободная программа: вы можете перераспространять её и/или
 ;  изменять её на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
 ;  в каком она была опубликована Фондом свободного программного обеспечения;
 ;  либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
 ;
 ;  Эта программа распространяется в надежде, что она может быть полезна,
 ;  но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
 ;  или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
 ;  общественной лицензии GNU.
 ;
 ;  Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
 ;  вместе с этой программой. Если это не так, см.
 ;  <http://www.gnu.org/licenses/>.
;

; <fold method enter>
    if(used inst$methodenter) ; <fold >
        inst methodenter ; (newEHP in rcx)
                    rdehp   rdx
                    rdtsp   rsi
                    rdtbp   rdi
                    lea     rsi, [rsi-$02]
                    lea     rsp, [rsp-$18]
                    mov     qword[rsp+$10], rdx
                    mov     qword[rsp+$08], rdi
                    mov     qword[rsp+$00], rbp
                    set     TAG_MLEAVE
                    wrehp   rcx
                    wrtsp   rsi
                    wrtbp   rsi
                    mov     rbp, rsp
        end_inst
    end if ; </fold>

    if(used inst$stackrealize) ; <fold >
        inst stackrealize ; (bytes in ecx)
                    neg     ecx
                    movsxd  rcx, ecx
                    lea     rdx, [rsp+rcx*1]
                    cmp     rdx, [rbx+context$guardEnd]
                    jl      .L.000
                    cmp     rdx, [rbx+context$tagsPointer]
                    jng     .L.001
            .L.000: throw   StackOverflowError
            .L.001: sar     rcx, $04
                    rdtsp
                    mov     rsp, rdx
                    lea     rsi, [rsi+rcx*1]
                    wrtsp
        end_inst
    end if ; </fold>
; </fold>

; <fold method leave>
    if(used inst$methodleave) ; <fold >
        inst methodleave ; (newRSP in rcx)
                    rdtbp
                    cmp     word[rdi], TAG_MLEAVE
                    je      .L.000
                    throw   VerifyError
            .L.000: call    subj$stackdeallocate
                    lea     rcx, [rbp+$18]
                    mov     rdx, [rbp+$10] ; указатель на обработчик исключения
                    mov     rdi, [rbp+$08] ; tbp
                    mov     rbp, [rbp+$00] ; rbp
                    wrehp   rdx
                    wrtsp
                    wrtbp
                    mov     rsp, rcx
        end_inst
    end if ; </fold>

    if(used inst$methodleaved) ; <fold >
        inst methodleaved ; (newRSP in rcx)
                    rdtsp
                    cmp     byte[rsi], TAG_INT
                    jne     .L.000
                    rdtbp
                    cmp     word[rdi], TAG_MLEAVE
                    je      .L.001
            .L.000: throw   VerifyError
            .L.001: mov     eax, [rsp]
                    call    subj$stackdeallocate
                    lea     rcx, [rbp+$18]
                    mov     rdx, [rbp+$10] ; указатель на обработчик исключения
                    mov     rdi, [rbp+$08] ; tbp
                    mov     rbp, [rbp+$00] ; rbp
                    wrehp   rdx
                    wrtsp
                    wrtbp
                    mov     rsp, rcx
                    mov     ecx, TAG_INT
        end_inst
    end if ; </fold>

    if(used inst$methodleaveq) ; <fold >
        inst methodleaveq ; (newRSP in rcx)
                    rdtsp
                    cmp     byte[rsi], TAG_LONG
                    jne     .L.000
                    rdtbp
                    cmp     word[rdi], TAG_MLEAVE
                    je      .L.001
            .L.000: throw   VerifyError
            .L.001: mov     rax, [rsp]
                    call    subj$stackdeallocate
                    lea     rcx, [rbp+$18]
                    mov     rdx, [rbp+$10] ; указатель на обработчик исключения
                    mov     rdi, [rbp+$08] ; tbp
                    mov     rbp, [rbp+$00] ; rbp
                    wrehp   rdx
                    wrtsp
                    wrtbp
                    mov     rsp, rcx
                    mov     ecx, TAG_LONG
        end_inst
    end if ; </fold>

    if(used inst$methodleavet) ; <fold >
        inst methodleavet ; (newRSP in rcx)
                    rdtsp
                    cmp     byte[rsi], TAG_REAL
                    jne     .L.000
                    rdtbp
                    cmp     word[rdi], TAG_MLEAVE
                    je      .L.001
            .L.000: throw   VerifyError
            .L.001: fld     tbyte[rsp]
                    call    subj$stackdeallocate
                    lea     rcx, [rbp+$18]
                    mov     rdx, [rbp+$10] ; указатель на обработчик исключения
                    mov     rdi, [rbp+$08] ; tbp
                    mov     rbp, [rbp+$00] ; rbp
                    wrehp   rdx
                    wrtsp
                    wrtbp
                    mov     rsp, rcx
                    mov     ecx, TAG_REAL
        end_inst
    end if ; </fold>

    if(used inst$methodleavex) ; <fold >
        inst methodleavex ; (newRSP in rcx)
                    rdtsp
                    movzx   edx, byte[rsi]
                    cmp     dl, TAG_BYTE2
                    je      .L.000
                    cmp     dl, TAG_BYTE4
                    je      .L.000
                    cmp     dl, TAG_BYTE8
                    je      .L.000
                    cmp     dl, TAG_SHORT2
                    je      .L.000
                    cmp     dl, TAG_SHORT4
                    je      .L.000
                    cmp     dl, TAG_SHORT8
                    je      .L.000
                    cmp     dl, TAG_INT2
                    je      .L.000
                    cmp     dl, TAG_INT4
                    je      .L.000
                    cmp     dl, TAG_LONG2
                    je      .L.000
                    cmp     dl, TAG_FLOAT
                    je      .L.000
                    cmp     dl, TAG_FLOAT2
                    je      .L.000
                    cmp     dl, TAG_FLOAT4
                    je      .L.000
                    cmp     dl, TAG_DOUBLE
                    je      .L.000
                    cmp     dl, TAG_DOUBLE2
                    jne     .L.001
            .L.000: rdtbp
                    cmp     word[rdi], TAG_MLEAVE
                    je      .L.002
            .L.001: throw   VerifyError
            .L.002: wrtemp0 rdx
                    vmovdqa xmm0, [rsp]
                    call    subj$stackdeallocate
                    lea     rcx, [rbp+$18]
                    mov     rdx, [rbp+$10] ; указатель на обработчик исключения
                    mov     rdi, [rbp+$08] ; tbp
                    mov     rbp, [rbp+$00] ; rbp
                    wrehp   rdx
                    wrtsp
                    wrtbp
                    mov     rsp, rcx
                    rdtemp0 rcx
        end_inst
    end if ; </fold>

    if(used inst$methodleavey) ; <fold >
        inst methodleavey ; (newRSP in rcx)
                    rdtsp
                    movzx   edx, word[rsi]
                    cmp     dx, TAG_INT8
                    je      .L.000
                    cmp     dx, TAG_LONG4
                    je      .L.000
                    cmp     dx, TAG_FLOAT8
                    je      .L.000
                    cmp     dx, TAG_DOUBLE4
                    jne     .L.001
            .L.000: rdtbp
                    cmp     word[rdi], TAG_MLEAVE
                    je      .L.002
            .L.001: throw   VerifyError
            .L.002: wrtemp0 rdx
                    vmovdqu ymm0, [rsp]
                    call    subj$stackdeallocate
                    lea     rcx, [rbp+$18]
                    mov     rdx, [rbp+$10] ; указатель на обработчик исключения
                    mov     rdi, [rbp+$08] ; tbp
                    mov     rbp, [rbp+$00] ; rbp
                    wrehp   rdx
                    wrtsp
                    wrtbp
                    mov     rsp, rcx
                    rdtemp0 rcx
        end_inst
    end if ; </fold>

    if(used inst$methodleavez) ; <fold >
        inst methodleavez ; (newRSP in rcx)
                    rdtsp
                    mov     edx, [rsi]
                    cmp     edx, TAG_LONG8
                    je      .L.000
                    cmp     edx, TAG_DOUBLE8
                    jne     .L.001
            .L.000: rdtbp
                    cmp     word[rdi], TAG_MLEAVE
                    je      .L.002
            .L.001: throw   VerifyError
            .L.002: wrtemp0 rdx
                    vmovdqu64 zmm0, [rsp]
                    call    subj$stackdeallocate
                    lea     rcx, [rbp+$18]
                    mov     rdx, [rbp+$10] ; указатель на обработчик исключения
                    mov     rdi, [rbp+$08] ; tbp
                    mov     rbp, [rbp+$00] ; rbp
                    wrehp   rdx
                    wrtsp
                    wrtbp
                    mov     rsp, rcx
                    rdtemp0 rcx
        end_inst
    end if ; </fold>

    if(used inst$methodleaver) ; <fold >
        inst methodleaver ; (newRSP in rcx)
                    rdtsp
                    cmp     byte[rsi], TAG_OBJECT
                    jne     .L.000
                    rdtbp
                    cmp     word[rdi], TAG_MLEAVE
                    je      .L.001
            .L.000: throw   VerifyError
            .L.001: mov     byte[rsi], TAG_EMPTY
                    mov     rax, [rsp]
                    call    subj$stackdeallocate
                    lea     rcx, [rbp+$18]
                    mov     rdx, [rbp+$10] ; указатель на обработчик исключения
                    mov     rdi, [rbp+$08] ; tbp
                    mov     rbp, [rbp+$00] ; rbp
                    wrehp   rdx
                    wrtsp
                    wrtbp
                    mov     rsp, rcx
                    mov     ecx, TAG_OBJECT
        end_inst
    end if ; </fold>
; </fold>

; <fold method invocation checks>
    if(used inst$stackcheck) ; <fold >
        inst stackcheck ; (bytes in ecx)
                    neg     ecx
                    movsxd  rcx, ecx
                    lea     rdx, [rsp+rcx*1]
                    cmp     rdx, [rbx+context$guardEnd]
                    jl      .L.000
                    cmp     rdx, [rbx+context$tagsPointer]
                    jng     .L.001
            .L.000: throw   StackOverflowError
            .L.001:
        end_inst
    end if ; </fold>

    if(used inst$nullcheck) ; <fold >
        inst nullcheck ; (ofsTSP in ecx): reference in rax
                    movsxd  rcx, ecx
                    rdtsp
                    cmp     byte[rsi+rcx*1], TAG_OBJECT
                    je      @F
                    throw   VerifyError
            @@:     lea     rcx, [rcx+rcx*1]
                    mov     rax, [rsp+rcx*8]
                    test    rax, rax
                    jnz     @F
                    throw   NullPointerException
            @@:
        end_inst
    end if ; </fold>
; </fold>

; <fold result push>
    if(used inst$resultpushd | used inst$resultpushq | used inst$resultpushr) ; <fold >
        inst resultpushd, resultpushq, resultpushr ; (result in rax, tag in ecx)
                    rdtsp
                    lea     rsi, [rsi-$01]
                    lea     rsp, [rsp-$10]
                    mov     qword[rsp+$08], $00
                    mov     qword[rsp+$00], rax
                    mov     byte[rsi], cl
                    wrtsp
        end_inst
    end if ; </fold>

    if(used inst$resultpusht) ; <fold >
        inst resultpusht ; (result in st0, tag in ecx)
                    rdtsp
                    lea     rsi, [rsi-$01]
                    lea     rsp, [rsp-$10]
                    mov     dword[rsp+$0c], $00
                    mov     word[rsp+$0a], $00
                    fstp    tbyte[rsp+$00]
                    mov     byte[rsi], cl
                    wrtsp
        end_inst
    end if ; </fold>

    if(used inst$resultpushx) ; <fold >
        inst resultpushx ; (result in xmm0, tag in ecx)
                    rdtsp
                    lea     rsi, [rsi-$01]
                    lea     rsp, [rsp-$10]
                    vmovdqa xword[rsp+$00], xmm0
                    mov     byte[rsi], cl
                    wrtsp
        end_inst
    end if ; </fold>

    if(used inst$resultpushy) ; <fold >
        inst resultpushy ; (result in ymm0, tag in ecx)
                    rdtsp
                    lea     rsi, [rsi-$02]
                    lea     rsp, [rsp-$20]
                    vmovdqu yword[rsp+$00], ymm0
                    mov     word[rsi], cx
                    wrtsp
        end_inst
    end if ; </fold>

    if(used inst$resultpushz) ; <fold >
        inst resultpushz ; (result in zmm0, tag in ecx)
                    rdtsp
                    lea     rsi, [rsi-$04]
                    lea     rsp, [rsp-$40]
                    vmovdqu64 zword[rsp+$00], zmm0
                    mov     dword[rsi], ecx
                    wrtsp
        end_inst
    end if ; </fold>
; </fold>

; <fold element duplicate>
    if(used inst$dup1) ; <fold >
        inst dup1
                    rdtsp
                    mov     eax, [rsi]
                    cmp     eax, TAG_LONG8
                    je      .L.004
                    cmp     eax, TAG_DOUBLE8
                    je      .L.004
                    cmp     ax, TAG_INT8
                    je      .L.002
                    cmp     ax, TAG_FLOAT8
                    je      .L.002
                    cmp     ax, TAG_LONG4
                    je      .L.002
                    cmp     ax, TAG_DOUBLE4
                    je      .L.002
                    cmp     al, TAG_OBJECT
                    jne     .L.001
                    push1
                    mov     rax, [rsp+$10]
                    test    rax, rax
                    jz      @F
                    lock inc qword[rax+avt.lang.Object$fldRefCountFromOthers]
            @@:     mov     qword[rsp+$08], $00
                    mov     qword[rsp+$00], rax
                    mov     byte[rsi], TAG_OBJECT
                    jmp     .L.RET
            .L.001: push1
                    vmovdqa xmm0, [rsp+$10]
                    vmovdqa xword[rsp], xmm0
                    mov     byte[rsi], al
                    jmp     .L.RET
            .L.002: push2
                    vmovdqu ymm0, [rsp+$20]
                    vmovdqu yword[rsp], ymm0
                    mov     word[rsi], ax
                    jmp     .L.RET
            .L.004: push4
                    vmovdqu64 zmm0, [rsp+$40]
                    vmovdqu64 zword[rsp], zmm0
                    mov     dword[rsi], eax
            .L.RET:
        end_inst
    end if ; </fold>

    if(used inst$dup1x1) ; <fold >
        inst dup1x1
                    rdtsp
                    call    subj$stackelements
                    mov     rcx, rax
                    mov     rdi, rax
                    lea     rsi, [rsi+rax*1]
                    call    subj$stackelements
                    lea     rax, [rcx+rax*1]
                    shl     rcx, $04
                    call    subj$stackrealize
                    mov     rdx, rdi
                    ; rax = размер 1-го + размер 2-го
                    ; rdx = размер 1-го
                    cld
                    lea     rcx, [rax+rax*1]
                    lea     rsi, [rdx+rdx*1]
                    lea     rsi, [rsp+rsi*8]
                    lea     rdi, [rsp]
                    rep movsq
                    lea     rcx, [rdx+rdx*1]
                    lea     rsi, [rsp]
                    rep movsq
                    rdtsp   rdi
                    lea     rsi, [rdi+rdx*1]
                    cmp     byte[rsi], TAG_OBJECT
                    jne     @F
                    mov     rcx, [rsp]
                    test    rcx, rcx
                    jz      @F
                    lock inc qword[rcx+avt.lang.Object$fldRefCountFromOthers]
            @@:     mov     rcx, rax
                    rep movsb
                    rdtsp
                    mov     rcx, rdx
                    rep movsb
        end_inst
    end if ; </fold>

    if(used inst$dup1x2) ; <fold >
        inst dup1x2
                    rdtsp
                    call    subj$stackelements
                    mov     rcx, rax
                    mov     rdi, rax
                    lea     rsi, [rsi+rax*1]
                    call    subj$stackelements
                    lea     rdx, [rcx+rax*1]
                    lea     rsi, [rsi+rax*1]
                    call    subj$stackelements
                    lea     rax, [rdx+rax*1]
                    shl     rcx, $04
                    call    subj$stackrealize
                    mov     rdx, rdi
                    ; rax = размер 1-го + размер 2-го + размер 3-го
                    ; rdx = размер 1-го
                    cld
                    lea     rcx, [rax+rax*1]
                    lea     rsi, [rdx+rdx*1]
                    lea     rsi, [rsp+rsi*8]
                    lea     rdi, [rsp]
                    rep movsq
                    lea     rcx, [rdx+rdx*1]
                    lea     rsi, [rsp]
                    rep movsq
                    rdtsp   rdi
                    lea     rsi, [rdi+rdx*1]
                    cmp     byte[rsi], TAG_OBJECT
                    jne     @F
                    mov     rcx, [rsp]
                    test    rcx, rcx
                    jz      @F
                    lock inc qword[rcx+avt.lang.Object$fldRefCountFromOthers]
            @@:     mov     rcx, rax
                    rep movsb
                    rdtsp
                    mov     rcx, rdx
                    rep movsb
        end_inst
    end if ; </fold>

    if(used inst$dup2) ; <fold >
        inst dup2
                    rdtsp
                    call    subj$stackelements
                    mov     rdi, rax
                    lea     rsi, [rsi+rax*1]
                    call    subj$stackelements
                    lea     rax, [rdi+rax*1]
                    mov     rcx, rax
                    shl     rcx, $04
                    call    subj$stackrealize
                    mov     rdx, rdi
                    ; rax = размер 1-го + размер 2-го
                    ; rdx = размер 1-го
                    cld
                    lea     rcx, [rax+rax*1]
                    lea     rsi, [rsp+rcx*8]
                    lea     rdi, [rsp]
                    rep movsq
                    rdtsp   rdi
                    lea     rsi, [rdi+rax*1]
                    cmp     byte[rsi], TAG_OBJECT
                    jne     @F
                    mov     rcx, [rsp]
                    test    rcx, rcx
                    jz      @F
                    lock inc qword[rcx+avt.lang.Object$fldRefCountFromOthers]
            @@:     cmp     byte[rsi+rdx*1], TAG_OBJECT
                    jne     @F
                    lea     rcx, [rdx+rdx*1]
                    mov     rcx, [rsp+rcx*8]
                    test    rcx, rcx
                    jz      @F
                    lock inc qword[rcx+avt.lang.Object$fldRefCountFromOthers]
            @@:     mov     rcx, rax
                    rep movsb
        end_inst
    end if ; </fold>
; </fold>

; <fold element pop>
    if(used inst$pop1) ; <fold >
        inst pop1
                    rdtsp
                    mov     eax, [rsi]
                    cmp     eax, TAG_LONG8
                    je      .L.004
                    cmp     eax, TAG_DOUBLE8
                    je      .L.004
                    cmp     ax, TAG_INT8
                    je      .L.002
                    cmp     ax, TAG_FLOAT8
                    je      .L.002
                    cmp     ax, TAG_LONG4
                    je      .L.002
                    cmp     ax, TAG_DOUBLE4
                    je      .L.002
                    cmp     al, TAG_OBJECT
                    jne     .L.001
                    mov     rax, [rsp]
                    test    rax, rax
                    jz      .L.001
                    lock dec qword[rax+avt.lang.Object$fldRefCountFromOthers]
            .L.001: pop1set
                    jmp     .L.RET
            .L.002: pop2set
                    jmp     .L.RET
            .L.004: pop4set
            .L.RET:
        end_inst
    end if ; </fold>
; </fold>