instruction.inc

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

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

; <fold macroinstructions for the high-level instructions>
    ; <fold data verificators>
        macro overify tag0*, [tagi] {
            common
                        local   .L.000
                        local   .L.001
                        local   .offset
                        rdtsp
                        .offset = $00
            reverse
                if(~(tagi eq))
                    if(tagi in <TAG_LONG8, TAG_DOUBLE8>)
                                cmp     dword[rsi+.offset], tagi
                                .offset = .offset+$04
                    else if(tagi in <TAG_INT8, TAG_LONG4, TAG_FLOAT8, TAG_DOUBLE4>)
                                cmp     word[rsi+.offset], tagi
                                .offset = .offset+$02
                    else
                                cmp     byte[rsi+.offset], tagi
                                .offset = .offset+$01
                    end if
                            jne     .L.000
                end if
            common
                if(tag0 in <TAG_LONG8, TAG_DOUBLE8>)
                            cmp     dword[rsi+.offset], tag0
                else if(tag0 in <TAG_INT8, TAG_LONG4, TAG_FLOAT8, TAG_DOUBLE4>)
                            cmp     word[rsi+.offset], tag0
                else
                            cmp     byte[rsi+.offset], tag0
                end if
                        je      .L.001
                .L.000: throw   VerifyError
                .L.001:
        }

        macro averify elementType*, tag {
                    local   .L.000
                    local   .L.001
                    local   .L.002
                    overify TAG_OBJECT, TAG_INT, tag
            if(tag in <TAG_LONG8, TAG_DOUBLE8>)
                        mov     rdx, [rsp+$50]
            else if(tag in <TAG_INT8, TAG_LONG4, TAG_FLOAT8, TAG_DOUBLE4>)
                        mov     rdx, [rsp+$30]
            else if(~(tag eq))
                        mov     rdx, [rsp+$20]
            else
                        mov     rdx, [rsp+$10]
            end if
                    test    rdx, rdx
                    jnz     .L.000
                    throw   NullPointerException
            if(tag in <TAG_LONG8, TAG_DOUBLE8>)
                .L.000: movsxd  rdi, [rsp+$40]
            else if(tag in <TAG_INT8, TAG_LONG4, TAG_FLOAT8, TAG_DOUBLE4>)
                .L.000: movsxd  rdi, [rsp+$20]
            else if(~(tag eq))
                .L.000: movsxd  rdi, [rsp+$10]
            else
                .L.000: movsxd  rdi, [rsp+$00]
            end if
                    cmp     edi, $00
                    jl      .L.001
                    cmp     edi, [rdx+elementType#.01d$fldLength]
                    jl      .L.002
            .L.001: throw   ArrayIndexOutOfBoundsException
            .L.002: lea     rax, [rdx+elementType#.01d$fldOffset+$08]
                    add     rax, [rdx+elementType#.01d$fldOffset]
        }

        macro averifyz elementType* {
                    local   .L.000
                    local   .L.001
                    local   .L.002
                    overify TAG_OBJECT, TAG_INT
                    mov     rax, [rsp+$10]
                    test    rax, rax
                    jnz     .L.000
                    throw   NullPointerException
            .L.000: movsxd  rdi, [rsp+$00]
                    cmp     edi, $00
                    jl      .L.001
                    cmp     edi, [rdx+elementType#.01d$fldLength]
                    jl      .L.002
            .L.001: throw   ArrayIndexOutOfBoundsException
            .L.002: push2
                    mov     rdx, rax
                    lea     rax, [rdx+elementType#.01d$fldOffset+$08]
                    add     rax, [rdx+elementType#.01d$fldOffset]
        }

        macro vverify tag* {
                    local   .L.000
                    local   .L.001
                    overify tag, TAG_INT
                    movsxd  rdi, [rsp]
                    cmp     edi, $00
                    jl      .L.000
            if(tag in <TAG_BYTE2, TAG_SHORT2, TAG_INT2, TAG_LONG2, TAG_FLOAT2, TAG_DOUBLE2>)
                        cmp     edi, $02
            else if(tag in <TAG_BYTE4, TAG_SHORT4, TAG_INT4, TAG_LONG4, TAG_FLOAT4, TAG_DOUBLE4>)
                        cmp     edi, $04
            else
                        cmp     edi, $08
            end if
                    jl      .L.001
            .L.000: throw   VectorIndexOutOfBoundsException
            .L.001:
        }

        macro fverify tag {
                    local   .L.000
                    overify TAG_OBJECT, tag
            if(tag in <TAG_LONG8, TAG_DOUBLE8>)
                        mov     rax, [rsp+$40]
            else if(tag in <TAG_INT8, TAG_LONG4, TAG_FLOAT8, TAG_DOUBLE4>)
                        mov     rax, [rsp+$20]
            else if(~(tag eq))
                        mov     rax, [rsp+$10]
            else
                        mov     rax, [rsp+$00]
            end if
                    test    rax, rax
                    jnz     .L.000
                    throw   NullPointerException
            .L.000: movsxd  rdi, ecx
        }

        macro fverifyy {
                    fverify
                    push1
        }

        macro fverifyz {
                    fverify
                    push3
        }

        macro sverify tag {
                    local   .L.000
                    overify TAG_OBJECT, tag
            if(tag in <TAG_LONG8, TAG_DOUBLE8>)
                        mov     rdx, [rsp+$40]
            else if(tag in <TAG_INT8, TAG_LONG4, TAG_FLOAT8, TAG_DOUBLE4>)
                        mov     rdx, [rsp+$20]
            else if(~(tag eq))
                        mov     rdx, [rsp+$10]
            else
                        mov     rdx, [rsp+$00]
            end if
                    test    rdx, rdx
                    jnz     .L.000
                    throw   NullPointerException
            .L.000: movsxd  rdi, ecx
                    lea     rax, [rdx+avt.lang.Struct$fldOffset+$08]
                    add     rax, [rdx+avt.lang.Struct$fldOffset]
        }

        macro sverifyy {
                    fverifyy
                    mov     rdx, rax
                    lea     rax, [rdx+avt.lang.Struct$fldOffset+$08]
                    add     rax, [rdx+avt.lang.Struct$fldOffset]
        }

        macro sverifyz {
                    fverifyz
                    mov     rdx, rax
                    lea     rax, [rdx+avt.lang.Struct$fldOffset+$08]
                    add     rax, [rdx+avt.lang.Struct$fldOffset]
        }
    ; </fold>

    ; <fold stack manipulators>
        macro push1 {
                    mov     ecx, $10
                    call    subj$stackrealize
        }

        macro push2 {
                    mov     ecx, $20
                    call    subj$stackrealize
        }

        macro push3 {
                    mov     ecx, $30
                    call    subj$stackrealize
        }

        macro push4 {
                    mov     ecx, $40
                    call    subj$stackrealize
        }

        macro pop1set tag {
                    mov     byte[rsi], TAG_EMPTY
                    lea     rsp, [rsp+$10]
                    lea     rsi, [rsi+$01]
                    set     tag
                    wrtsp
        }

        macro pop2set tag {
                    mov     word[rsi], TAG_EMPTY
                    lea     rsp, [rsp+$20]
                    lea     rsi, [rsi+$02]
                    set     tag
                    wrtsp
        }

        macro pop3set tag {
            if(tag eq)
                        mov     word[rsi+$00], TAG_EMPTY
                        mov     byte[rsi+$02], TAG_EMPTY
            else
                        mov     dword[rsi], TAG_EMPTY
            end if
                    lea     rsp, [rsp+$30]
                    lea     rsi, [rsi+$03]
                    set     tag
                    wrtsp
        }

        macro pop4set tag {
                    mov     dword[rsi], TAG_EMPTY
                    lea     rsp, [rsp+$40]
                    lea     rsi, [rsi+$04]
                    set     tag
                    wrtsp
        }

        macro pop5set tag {
                    mov     dword[rsi+$00], TAG_EMPTY
                    mov     byte[rsi+$04], TAG_EMPTY
                    lea     rsp, [rsp+$50]
                    lea     rsi, [rsi+$05]
                    set     tag
                    wrtsp
        }

        macro pop6set tag {
            if((tag eq) | ~(tag in <TAG_LONG8, TAG_DOUBLE8, TAG_INT8, TAG_FLOAT8, TAG_LONG4, TAG_DOUBLE4>))
                        mov     dword[rsi+$00], TAG_EMPTY
                        mov     word[rsi+$04], TAG_EMPTY
            else
                        mov     qword[rsi], TAG_EMPTY
            end if
                    lea     rsp, [rsp+$60]
                    lea     rsi, [rsi+$06]
                    set     tag
                    wrtsp
        }

        macro pop7set tag {
            if(tag eq)
                        mov     dword[rsi+$00], TAG_EMPTY
                        mov     word[rsi+$04], TAG_EMPTY
                        mov     byte[rsi+$06], TAG_EMPTY
            else
                        mov     qword[rsi], TAG_EMPTY
            end if
                    lea     rsp, [rsp+$70]
                    lea     rsi, [rsi+$07]
                    set     tag
                    wrtsp
        }

        macro set tag {
            if(~(tag eq))
                if(tag in <TAG_LONG8, TAG_DOUBLE8, TAG_ILEAVE>)
                            mov     dword[rsi], tag
                else if(tag in <TAG_INT8, TAG_LONG4, TAG_FLOAT8, TAG_DOUBLE4, TAG_MLEAVE>)
                            mov     word[rsi], tag
                else
                            mov     byte[rsi], tag
                end if
            end if
        }
    ; </fold>

    ; <fold instruction temporary data manipulators>
        macro rdtemp0 gpr64* {
                    mov     gpr64, qword[rbx+context$temp0]
        }

        macro rdtemp1 gpr64* {
                    mov     gpr64, qword[rbx+context$temp1]
        }

        macro rdtemp2 gpr64* {
                    mov     gpr64, qword[rbx+context$temp2]
        }

        macro rdtemp3 gpr64* {
                    mov     gpr64, qword[rbx+context$temp3]
        }

        macro wrtemp0 gpr64* {
                    mov     qword[rbx+context$temp0], gpr64
        }

        macro wrtemp1 gpr64* {
                    mov     qword[rbx+context$temp1], gpr64
        }

        macro wrtemp2 gpr64* {
                    mov     qword[rbx+context$temp2], gpr64
        }

        macro wrtemp3 gpr64* {
                    mov     qword[rbx+context$temp3], gpr64
        }
    ; </fold>
; </fold>

; <fold includes with implementation of the high-level instructions>
            include "instruction.byte.inc"
            include "instruction.byte2.inc"
            include "instruction.byte4.inc"
            include "instruction.byte8.inc"
            include "instruction.short.inc"
            include "instruction.short2.inc"
            include "instruction.short4.inc"
            include "instruction.short8.inc"
            include "instruction.int.inc"
            include "instruction.int2.inc"
            include "instruction.int4.inc"
            include "instruction.int8.inc"
            include "instruction.long.inc"
            include "instruction.long2.inc"
            include "instruction.long4.inc"
            include "instruction.long8.inc"
            include "instruction.float.inc"
            include "instruction.float2.inc"
            include "instruction.float4.inc"
            include "instruction.float8.inc"
            include "instruction.double.inc"
            include "instruction.double2.inc"
            include "instruction.double4.inc"
            include "instruction.double8.inc"
            include "instruction.real.inc"
            include "instruction.reference.inc"
            include "instruction.stack.inc"
            include "instruction.exception.inc"
            include "instruction.newvector.inc"
            include "instruction.setfield.inc"
            include "instruction.setstructfield.inc"
            include "instruction.setarrayelement.inc"
            include "instruction.getfield.inc"
            include "instruction.getstructfield.inc"
            include "instruction.getarrayelement.inc"
            include "instruction.getvectorelement.inc"
; </fold>