;
; Исходный код среды исполнения ПВТ-ОО.
;
; Этот исходный код является частью проекта ПВТ-ОО.
;
; Copyright © 2021 Малик Разработчик
;
; Это свободная программа: вы можете перераспространять её и/или
; изменять её на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
; в каком она была опубликована Фондом свободного программного обеспечения;
; либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
;
; Эта программа распространяется в надежде, что она может быть полезна,
; но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
; или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
; общественной лицензии GNU.
;
; Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
; вместе с этой программой. Если это не так, см.
; <http://www.gnu.org/licenses/>.
;
; <fold push/pop/peek>
if(used inst$dpush) ; <fold >
inst dpush ; (value in xmm0)
push1
vmovdqa xword[rsp], xmm0
set TAG_DOUBLE
end_inst
end if ; </fold>
if(used inst$dpop) ; <fold >
inst dpop ; (): value in xmm0
overify TAG_DOUBLE
vmovq xmm0, [rsp]
pop1set
end_inst
end if ; </fold>
; </fold>
; <fold conversion>
if(used inst$dtoi) ; <fold >
inst dtoi
overify TAG_DOUBLE
vmovq xmm0, [rsp]
vcvttsd2si eax, xmm0
vmovd xmm1, eax
vmovq xmm2, [d8.00]
vcmpsd xmm2, xmm2, xmm0, $02
vcmpsd xmm3, xmm0, xmm0, $07
vpsrldq xmm2, xmm2, $04
vpsrldq xmm3, xmm3, $04
vpaddd xmm0, xmm1, xmm2
vpand xmm0, xmm0, xmm3
vmovdqa xword[rsp], xmm0
set TAG_INT
end_inst
end if ; </fold>
if(used inst$dtol) ; <fold >
inst dtol
overify TAG_DOUBLE
vmovq xmm0, [rsp]
vcvttsd2si rax, xmm0
vmovq xmm1, rax
vmovq xmm2, [d8.01]
vcmpsd xmm2, xmm2, xmm0, $02
vcmpsd xmm3, xmm0, xmm0, $07
vpaddq xmm0, xmm1, xmm2
vpand xmm0, xmm0, xmm3
vmovdqa xword[rsp], xmm0
set TAG_LONG
end_inst
end if ; </fold>
if(used inst$dtof) ; <fold >
inst dtof
overify TAG_DOUBLE
vpxor xmm0, xmm0, xmm0
vcvtsd2ss xmm0, xmm0, [rsp]
vmovdqa xword[rsp], xmm0
set TAG_FLOAT
end_inst
end if ; </fold>
if(used inst$dtod2) ; <fold >
inst dtod2
overify TAG_DOUBLE
vmovq xmm0, [rsp]
vmovdqa xword[rsp], xmm0
set TAG_DOUBLE2
end_inst
end if ; </fold>
if(used inst$dtod4) ; <fold >
inst dtod4
overify TAG_DOUBLE
push1
vmovq xmm0, [rsp+$10]
vmovdqu yword[rsp], ymm0
set TAG_DOUBLE4
end_inst
end if ; </fold>
if(used inst$dtod8) ; <fold >
inst dtod8
overify TAG_DOUBLE
push3
vmovq xmm0, [rsp+$30]
vmovdqu64 zword[rsp], zmm0
set TAG_DOUBLE8
end_inst
end if ; </fold>
if(used inst$dtox) ; <fold >
inst dtox
overify TAG_DOUBLE
fld qword[rsp]
mov qword[rsp+$08], $00
fstp tbyte[rsp]
set TAG_REAL
end_inst
end if ; </fold>
; </fold>
; <fold relation>
if(used inst$dcmpg) ; <fold >
inst dcmpg
overify TAG_DOUBLE, TAG_DOUBLE
vmovq xmm0, [rsp+$10]
vcomisd xmm0, [rsp+$00]
jp .G
jc .L
jz .E
.G: mov eax, $01
jmp @F
.L: mov eax, -$01
jmp @F
.E: xor eax, eax
@@: mov qword[rsp+$10], rax
pop1set TAG_INT
end_inst
end if ; </fold>
if(used inst$dcmpl) ; <fold >
inst dcmpl
overify TAG_DOUBLE, TAG_DOUBLE
vmovq xmm0, [rsp+$10]
vcomisd xmm0, [rsp+$00]
jp .L
jc .L
jz .E
mov eax, $01
jmp @F
.L: mov eax, -$01
jmp @F
.E: xor eax, eax
@@: mov qword[rsp+$10], rax
pop1set TAG_INT
end_inst
end if ; </fold>
; </fold>
; <fold scalar>
if(used inst$dsneg | used inst$dvneg) ; <fold >
inst dsneg, dvneg
overify TAG_DOUBLE
vpxor xmm0, xmm0, xmm0
vsubsd xmm0, xmm0, [rsp]
vmovdqa xword[rsp], xmm0
end_inst
end if ; </fold>
if(used inst$dsmul | used inst$dvmul) ; <fold >
inst dsmul, dvmul
overify TAG_DOUBLE, TAG_DOUBLE
vmovq xmm0, [rsp+$10]
vmulsd xmm0, xmm0, [rsp]
vmovdqa xword[rsp+$10], xmm0
pop1set
end_inst
end if ; </fold>
if(used inst$dsdiv | used inst$dsdivu | used inst$dvdiv) ; <fold >
inst dsdiv, dsdivu, dvdiv
overify TAG_DOUBLE, TAG_DOUBLE
vmovq xmm0, [rsp+$10]
vdivsd xmm0, xmm0, [rsp]
vmovdqa xword[rsp+$10], xmm0
pop1set
end_inst
end if ; </fold>
if(used inst$dsrem | used inst$dsremu) ; <fold >
inst dsrem, dsremu
overify TAG_DOUBLE, TAG_DOUBLE
fld qword[rsp+$00]
fld qword[rsp+$10]
@@: fprem
fnstsw ax
test ax, $0400
jnz @B
fstp st1
fstp qword[rsp+$10]
pop1set
end_inst
end if ; </fold>
if(used inst$dsadd | used inst$dvadd) ; <fold >
inst dsadd, dvadd
overify TAG_DOUBLE, TAG_DOUBLE
vmovq xmm0, [rsp+$10]
vaddsd xmm0, xmm0, [rsp]
vmovdqa xword[rsp+$10], xmm0
pop1set
end_inst
end if ; </fold>
if(used inst$dssub | used inst$dvsub) ; <fold >
inst dssub, dvsub
overify TAG_DOUBLE, TAG_DOUBLE
vmovq xmm0, [rsp+$10]
vsubsd xmm0, xmm0, [rsp]
vmovdqa xword[rsp+$10], xmm0
pop1set
end_inst
end if ; </fold>
; </fold>
; <fold vector>
if(used inst$dvg) ; <fold >
inst dvg
overify TAG_DOUBLE, TAG_DOUBLE
vmovq xmm0, [rsp+$10]
vmovq xmm1, [rsp+$00]
vcmpsd xmm0, xmm1, xmm0, $01
vmovdqa xword[rsp+$10], xmm0
pop1set TAG_LONG
end_inst
end if ; </fold>
if(used inst$dvge) ; <fold >
inst dvge
overify TAG_DOUBLE, TAG_DOUBLE
vmovq xmm0, [rsp+$10]
vmovq xmm1, [rsp+$00]
vcmpsd xmm0, xmm1, xmm0, $02
vmovdqa xword[rsp+$10], xmm0
pop1set TAG_LONG
end_inst
end if ; </fold>
if(used inst$dvl) ; <fold >
inst dvl
overify TAG_DOUBLE, TAG_DOUBLE
vmovq xmm0, [rsp+$10]
vmovq xmm1, [rsp+$00]
vcmpsd xmm0, xmm0, xmm1, $01
vmovdqa xword[rsp+$10], xmm0
pop1set TAG_LONG
end_inst
end if ; </fold>
if(used inst$dvle) ; <fold >
inst dvle
overify TAG_DOUBLE, TAG_DOUBLE
vmovq xmm0, [rsp+$10]
vmovq xmm1, [rsp+$00]
vcmpsd xmm0, xmm0, xmm1, $02
vmovdqa xword[rsp+$10], xmm0
pop1set TAG_LONG
end_inst
end if ; </fold>
if(used inst$dve) ; <fold >
inst dve
overify TAG_DOUBLE, TAG_DOUBLE
vmovq xmm0, [rsp+$10]
vmovq xmm1, [rsp+$00]
vcmpsd xmm0, xmm0, xmm1, $00
vmovdqa xword[rsp+$10], xmm0
pop1set TAG_LONG
end_inst
end if ; </fold>
if(used inst$dvne) ; <fold >
inst dvne
overify TAG_DOUBLE, TAG_DOUBLE
vmovq xmm0, [rsp+$10]
vmovq xmm1, [rsp+$00]
vcmpsd xmm0, xmm0, xmm1, $04
vmovdqa xword[rsp+$10], xmm0
pop1set TAG_LONG
end_inst
end if ; </fold>
; </fold>