;
; Реализация среды исполнения языка программирования
; Объектно-ориентированный продвинутый векторный транслятор
;
; Copyright © 2021, 2024 Малик Разработчик
;
; Это свободная программа: вы можете перераспространять ее и/или изменять
; ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
; в каком она была опубликована Фондом свободного программного обеспечения;
; либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
;
; Эта программа распространяется в надежде, что она будет полезной,
; но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
; или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
; общественной лицензии GNU.
;
; Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
; вместе с этой программой. Если это не так, см.
; <https://www.gnu.org/licenses/>.
;
; <fold скалярное умножение>
if(used inst$smuld2) ; <fold returns double2>
proc inst$smuld2
vshufpd xmm2, xmm1, xmm1, $02
vshufpd xmm3, xmm2, xmm2, $01
vmulpd xmm2, xmm2, [cons$smuld2.c0]
vmulpd xmm1, xmm0, xmm3
vmulpd xmm0, xmm0, xmm2
vhaddpd xmm0, xmm0, xmm1
ret
end_proc
end if ; </fold>
if(used inst$smuld4) ; <fold returns double4>
proc inst$smuld4
vshuff64x2 ymm4, ymm1, ymm1, $02
vshuff64x2 ymm6, ymm4, ymm4, $01
vshufpd ymm5, ymm4, ymm4, $05
vshufpd ymm7, ymm6, ymm6, $05
vmulpd ymm4, ymm4, [cons$smuld4.q0]
vmulpd ymm5, ymm5, [cons$smuld4.q1]
vmulpd ymm6, ymm6, [cons$smuld4.q2]
vmulpd ymm7, ymm7, [cons$smuld4.q3]
vmulpd ymm3, ymm0, ymm7
vmulpd ymm2, ymm0, ymm6
vmulpd ymm1, ymm0, ymm5
vmulpd ymm0, ymm0, ymm4
vextractf128 xmm4, ymm0, $01
vextractf128 xmm5, ymm1, $01
vextractf128 xmm6, ymm2, $01
vextractf128 xmm7, ymm3, $01
vinsertf128 ymm0, ymm0, xmm2, $01
vinsertf128 ymm2, ymm1, xmm3, $01
vinsertf128 ymm1, ymm4, xmm6, $01
vinsertf128 ymm3, ymm5, xmm7, $01
vaddpd ymm0, ymm0, ymm1
vaddpd ymm1, ymm2, ymm3
vshufpd ymm2, ymm0, ymm1, $00
vshufpd ymm3, ymm0, ymm1, $0f
vaddpd ymm0, ymm2, ymm3
ret
end_proc
end if ; </fold>
if(used inst$smuld8) ; <fold returns double8>
proc inst$smuld8
vshuff64x2 zmm08, zmm01, zmm01, $e4
vshuff64x2 zmm10, zmm08, zmm08, $b1
vshuff64x2 zmm12, zmm08, zmm08, $4e
vshuff64x2 zmm14, zmm08, zmm08, $1b
vshufpd zmm09, zmm08, zmm08, $55
vshufpd zmm11, zmm10, zmm10, $55
vshufpd zmm13, zmm12, zmm12, $55
vshufpd zmm15, zmm14, zmm14, $55
vmulpd zmm08, zmm08, [cons$smuld8.o0]
vmulpd zmm09, zmm09, [cons$smuld8.o1]
vmulpd zmm10, zmm10, [cons$smuld8.o2]
vmulpd zmm11, zmm11, [cons$smuld8.o3]
vmulpd zmm12, zmm12, [cons$smuld8.o4]
vmulpd zmm13, zmm13, [cons$smuld8.o5]
vmulpd zmm14, zmm14, [cons$smuld8.o6]
vmulpd zmm15, zmm15, [cons$smuld8.o7]
vmulpd zmm07, zmm00, zmm15, {rn-sae}
vmulpd zmm06, zmm00, zmm14, {rn-sae}
vmulpd zmm05, zmm00, zmm13, {rn-sae}
vmulpd zmm04, zmm00, zmm12, {rn-sae}
vmulpd zmm03, zmm00, zmm11, {rn-sae}
vmulpd zmm02, zmm00, zmm10, {rn-sae}
vmulpd zmm01, zmm00, zmm09, {rn-sae}
vmulpd zmm00, zmm00, zmm08, {rn-sae}
vextractf64x4 ymm08, zmm00, $01
vextractf64x4 ymm09, zmm01, $01
vextractf64x4 ymm10, zmm02, $01
vextractf64x4 ymm11, zmm03, $01
vextractf64x4 ymm12, zmm04, $01
vextractf64x4 ymm13, zmm05, $01
vextractf64x4 ymm14, zmm06, $01
vextractf64x4 ymm15, zmm07, $01
vinsertf64x4 zmm00, zmm00, ymm02, $01
vinsertf64x4 zmm02, zmm04, ymm06, $01
vinsertf64x4 zmm04, zmm01, ymm03, $01
vinsertf64x4 zmm06, zmm05, ymm07, $01
vinsertf64x4 zmm01, zmm08, ymm10, $01
vinsertf64x4 zmm03, zmm12, ymm14, $01
vinsertf64x4 zmm05, zmm09, ymm11, $01
vinsertf64x4 zmm07, zmm13, ymm15, $01
vaddpd zmm00, zmm00, zmm01
vaddpd zmm01, zmm02, zmm03
vaddpd zmm02, zmm04, zmm05
vaddpd zmm03, zmm06, zmm07
vshuff64x2 zmm04, zmm00, zmm01, $88
vshuff64x2 zmm05, zmm00, zmm01, $dd
vshuff64x2 zmm06, zmm02, zmm03, $88
vshuff64x2 zmm07, zmm02, zmm03, $dd
vaddpd zmm00, zmm04, zmm05
vaddpd zmm01, zmm06, zmm07
vshufpd zmm02, zmm00, zmm01, $00
vshufpd zmm03, zmm00, zmm01, $ff
vaddpd zmm00, zmm02, zmm03
ret
end_proc
end if ; </fold>
if(used inst$smulf2) ; <fold returns float2>
proc inst$smulf2
vshufps xmm2, xmm1, xmm1, $e4
vshufps xmm3, xmm2, xmm2, $e1
vmulps xmm2, xmm2, [cons$smulf2.c0]
vmulps xmm1, xmm0, xmm3
vmulps xmm0, xmm0, xmm2
vhaddps xmm0, xmm0, xmm1
vshufps xmm0, xmm0, xmm0, $d8
ret
end_proc
end if ; </fold>
if(used inst$smulf4) ; <fold returns float4>
proc inst$smulf4
vshufps xmm4, xmm1, xmm1, $e4
vshufps xmm5, xmm4, xmm4, $b1
vshufps xmm6, xmm4, xmm4, $4e
vshufps xmm7, xmm4, xmm4, $1b
vmulps xmm4, xmm4, [cons$smulf4.q0]
vmulps xmm5, xmm5, [cons$smulf4.q1]
vmulps xmm6, xmm6, [cons$smulf4.q2]
vmulps xmm7, xmm7, [cons$smulf4.q3]
vmulps xmm3, xmm0, xmm7
vmulps xmm2, xmm0, xmm6
vmulps xmm1, xmm0, xmm5
vmulps xmm0, xmm0, xmm4
vhaddps xmm0, xmm0, xmm1
vhaddps xmm1, xmm2, xmm3
vhaddps xmm0, xmm0, xmm1
ret
end_proc
end if ; </fold>
if(used inst$smulf8) ; <fold returns float8>
proc inst$smulf8
vmovdqa ymm08, ymm01
vextractf128 xmm12, ymm08, $01
vinsertf128 ymm12, ymm12, xmm08, $01
vshufps ymm09, ymm08, ymm08, $b1
vshufps ymm10, ymm08, ymm08, $4e
vshufps ymm11, ymm08, ymm08, $1b
vshufps ymm13, ymm12, ymm12, $b1
vshufps ymm14, ymm12, ymm12, $4e
vshufps ymm15, ymm12, ymm12, $1b
vmulps ymm08, ymm08, [cons$smulf8.o0]
vmulps ymm09, ymm09, [cons$smulf8.o1]
vmulps ymm10, ymm10, [cons$smulf8.o2]
vmulps ymm11, ymm11, [cons$smulf8.o3]
vmulps ymm12, ymm12, [cons$smulf8.o4]
vmulps ymm13, ymm13, [cons$smulf8.o5]
vmulps ymm14, ymm14, [cons$smulf8.o6]
vmulps ymm15, ymm15, [cons$smulf8.o7]
vmulps ymm07, ymm00, ymm15
vmulps ymm06, ymm00, ymm14
vmulps ymm05, ymm00, ymm13
vmulps ymm04, ymm00, ymm12
vmulps ymm03, ymm00, ymm11
vmulps ymm02, ymm00, ymm10
vmulps ymm01, ymm00, ymm09
vmulps ymm00, ymm00, ymm08
vhaddps ymm00, ymm00, ymm01
vhaddps ymm01, ymm02, ymm03
vhaddps ymm02, ymm04, ymm05
vhaddps ymm03, ymm06, ymm07
vhaddps ymm00, ymm00, ymm01
vhaddps ymm01, ymm02, ymm03
vextractf128 xmm02, ymm00, $01
vextractf128 xmm03, ymm01, $01
vaddps xmm00, xmm00, xmm02
vaddps xmm01, xmm01, xmm03
vinsertf128 ymm00, ymm00, xmm01, $01
ret
end_proc
end if ; </fold>
if(used inst$smuli2) ; <fold returns int2>
proc inst$smuli2
vshufps xmm2, xmm1, xmm1, $e4
vshufps xmm3, xmm2, xmm2, $e1
vpmulld xmm2, xmm2, [cons$smuli2.c0]
vpmulld xmm1, xmm0, xmm3
vpmulld xmm0, xmm0, xmm2
vphaddd xmm0, xmm0, xmm1
vshufps xmm0, xmm0, xmm0, $d8
ret
end_proc
end if ; </fold>
if(used inst$smuli4) ; <fold returns int4>
proc inst$smuli4
vshufps xmm4, xmm1, xmm1, $e4
vshufps xmm5, xmm4, xmm4, $b1
vshufps xmm6, xmm4, xmm4, $4e
vshufps xmm7, xmm4, xmm4, $1b
vpmulld xmm4, xmm4, [cons$smuli4.q0]
vpmulld xmm5, xmm5, [cons$smuli4.q1]
vpmulld xmm6, xmm6, [cons$smuli4.q2]
vpmulld xmm7, xmm7, [cons$smuli4.q3]
vpmulld xmm3, xmm0, xmm7
vpmulld xmm2, xmm0, xmm6
vpmulld xmm1, xmm0, xmm5
vpmulld xmm0, xmm0, xmm4
vphaddd xmm0, xmm0, xmm1
vphaddd xmm1, xmm2, xmm3
vphaddd xmm0, xmm0, xmm1
ret
end_proc
end if ; </fold>
if(used inst$smuli8) ; <fold returns int8>
proc inst$smuli8
vmovdqa ymm08, ymm01
vextracti128 xmm12, ymm08, $01
vinserti128 ymm12, ymm12, xmm08, $01
vshufps ymm09, ymm08, ymm08, $b1
vshufps ymm10, ymm08, ymm08, $4e
vshufps ymm11, ymm08, ymm08, $1b
vshufps ymm13, ymm12, ymm12, $b1
vshufps ymm14, ymm12, ymm12, $4e
vshufps ymm15, ymm12, ymm12, $1b
vpmulld ymm08, ymm08, [cons$smuli8.o0]
vpmulld ymm09, ymm09, [cons$smuli8.o1]
vpmulld ymm10, ymm10, [cons$smuli8.o2]
vpmulld ymm11, ymm11, [cons$smuli8.o3]
vpmulld ymm12, ymm12, [cons$smuli8.o4]
vpmulld ymm13, ymm13, [cons$smuli8.o5]
vpmulld ymm14, ymm14, [cons$smuli8.o6]
vpmulld ymm15, ymm15, [cons$smuli8.o7]
vpmulld ymm07, ymm00, ymm15
vpmulld ymm06, ymm00, ymm14
vpmulld ymm05, ymm00, ymm13
vpmulld ymm04, ymm00, ymm12
vpmulld ymm03, ymm00, ymm11
vpmulld ymm02, ymm00, ymm10
vpmulld ymm01, ymm00, ymm09
vpmulld ymm00, ymm00, ymm08
vphaddd ymm00, ymm00, ymm01
vphaddd ymm01, ymm02, ymm03
vphaddd ymm02, ymm04, ymm05
vphaddd ymm03, ymm06, ymm07
vphaddd ymm00, ymm00, ymm01
vphaddd ymm01, ymm02, ymm03
vextracti128 xmm02, ymm00, $01
vextracti128 xmm03, ymm01, $01
vpaddd xmm00, xmm00, xmm02
vpaddd xmm01, xmm01, xmm03
vinserti128 ymm00, ymm00, xmm01, $01
ret
end_proc
end if ; </fold>
if(used inst$smull2) ; <fold returns long2>
proc inst$smull2
vshufpd xmm2, xmm1, xmm1, $02
vshufpd xmm3, xmm2, xmm2, $01
vpmullq xmm2, xmm2, [cons$smull2.c0]
vpmullq xmm1, xmm0, xmm3
vpmullq xmm0, xmm0, xmm2
vshufpd xmm2, xmm0, xmm1, $00
vshufpd xmm3, xmm0, xmm1, $03
vpaddq xmm0, xmm2, xmm3
ret
end_proc
end if ; </fold>
if(used inst$smull4) ; <fold returns long4>
proc inst$smull4
vshufi64x2 ymm4, ymm1, ymm1, $02
vshufi64x2 ymm6, ymm4, ymm4, $01
vshufpd ymm5, ymm4, ymm4, $05
vshufpd ymm7, ymm6, ymm6, $05
vpmullq ymm4, ymm4, [cons$smull4.q0]
vpmullq ymm5, ymm5, [cons$smull4.q1]
vpmullq ymm6, ymm6, [cons$smull4.q2]
vpmullq ymm7, ymm7, [cons$smull4.q3]
vpmullq ymm3, ymm0, ymm7
vpmullq ymm2, ymm0, ymm6
vpmullq ymm1, ymm0, ymm5
vpmullq ymm0, ymm0, ymm4
vextracti128 xmm4, ymm0, $01
vextracti128 xmm5, ymm1, $01
vextracti128 xmm6, ymm2, $01
vextracti128 xmm7, ymm3, $01
vinserti128 ymm0, ymm0, xmm2, $01
vinserti128 ymm2, ymm1, xmm3, $01
vinserti128 ymm1, ymm4, xmm6, $01
vinserti128 ymm3, ymm5, xmm7, $01
vpaddq ymm0, ymm0, ymm1
vpaddq ymm1, ymm2, ymm3
vshufpd ymm2, ymm0, ymm1, $00
vshufpd ymm3, ymm0, ymm1, $0f
vpaddq ymm0, ymm2, ymm3
ret
end_proc
end if ; </fold>
if(used inst$smull8) ; <fold returns long8>
proc inst$smull8
vshufi64x2 zmm08, zmm01, zmm01, $e4
vshufi64x2 zmm10, zmm08, zmm08, $b1
vshufi64x2 zmm12, zmm08, zmm08, $4e
vshufi64x2 zmm14, zmm08, zmm08, $1b
vshufpd zmm09, zmm08, zmm08, $55
vshufpd zmm11, zmm10, zmm10, $55
vshufpd zmm13, zmm12, zmm12, $55
vshufpd zmm15, zmm14, zmm14, $55
vpmullq zmm08, zmm08, [cons$smull8.o0]
vpmullq zmm09, zmm09, [cons$smull8.o1]
vpmullq zmm10, zmm10, [cons$smull8.o2]
vpmullq zmm11, zmm11, [cons$smull8.o3]
vpmullq zmm12, zmm12, [cons$smull8.o4]
vpmullq zmm13, zmm13, [cons$smull8.o5]
vpmullq zmm14, zmm14, [cons$smull8.o6]
vpmullq zmm15, zmm15, [cons$smull8.o7]
vpmullq zmm07, zmm00, zmm15
vpmullq zmm06, zmm00, zmm14
vpmullq zmm05, zmm00, zmm13
vpmullq zmm04, zmm00, zmm12
vpmullq zmm03, zmm00, zmm11
vpmullq zmm02, zmm00, zmm10
vpmullq zmm01, zmm00, zmm09
vpmullq zmm00, zmm00, zmm08
vextracti64x4 ymm08, zmm00, $01
vextracti64x4 ymm09, zmm01, $01
vextracti64x4 ymm10, zmm02, $01
vextracti64x4 ymm11, zmm03, $01
vextracti64x4 ymm12, zmm04, $01
vextracti64x4 ymm13, zmm05, $01
vextracti64x4 ymm14, zmm06, $01
vextracti64x4 ymm15, zmm07, $01
vinserti64x4 zmm00, zmm00, ymm02, $01
vinserti64x4 zmm02, zmm04, ymm06, $01
vinserti64x4 zmm04, zmm01, ymm03, $01
vinserti64x4 zmm06, zmm05, ymm07, $01
vinserti64x4 zmm01, zmm08, ymm10, $01
vinserti64x4 zmm03, zmm12, ymm14, $01
vinserti64x4 zmm05, zmm09, ymm11, $01
vinserti64x4 zmm07, zmm13, ymm15, $01
vpaddq zmm00, zmm00, zmm01
vpaddq zmm01, zmm02, zmm03
vpaddq zmm02, zmm04, zmm05
vpaddq zmm03, zmm06, zmm07
vshufi64x2 zmm04, zmm00, zmm01, $88
vshufi64x2 zmm05, zmm00, zmm01, $dd
vshufi64x2 zmm06, zmm02, zmm03, $88
vshufi64x2 zmm07, zmm02, zmm03, $dd
vpaddq zmm00, zmm04, zmm05
vpaddq zmm01, zmm06, zmm07
vshufpd zmm02, zmm00, zmm01, $00
vshufpd zmm03, zmm00, zmm01, $ff
vpaddq zmm00, zmm02, zmm03
ret
end_proc
end if ; </fold>
; </fold>