Files
avo/examples/md5x16/md5x16.s

715 lines
17 KiB
ArmAsm
Raw Normal View History

all: AVX-512 (#217) Extends avo to support most AVX-512 instruction sets. The instruction type is extended to support suffixes. The K family of opmask registers is added to the register package, and the operand package is updated to support the new operand types. Move instruction deduction in `Load` and `Store` is extended to support KMOV* and VMOV* forms. Internal code generation packages were overhauled. Instruction database loading required various messy changes to account for the additional complexities of the AVX-512 instruction sets. The internal/api package was added to introduce a separation between instruction forms in the database, and the functions avo provides to create them. This was required since with instruction suffixes there is no longer a one-to-one mapping between instruction constructors and opcodes. AVX-512 bloated generated source code size substantially, initially increasing compilation and CI test times to an unacceptable level. Two changes were made to address this: 1. Instruction constructors in the `x86` package moved to an optab-based approach. This compiles substantially faster than the verbose code generation we had before. 2. The most verbose code-generated tests are moved under build tags and limited to a stress test mode. Stress test builds are run on schedule but not in regular CI. An example of AVX-512 accelerated 16-lane MD5 is provided to demonstrate and test the new functionality. Updates #20 #163 #229 Co-authored-by: Vaughn Iverson <vsivsi@yahoo.com>
2021-11-12 18:35:36 -08:00
// Code generated by command: go run asm.go -out md5x16.s -stubs stub.go. DO NOT EDIT.
#include "textflag.h"
DATA consts<>+0(SB)/4, $0xd76aa478
DATA consts<>+4(SB)/4, $0xe8c7b756
DATA consts<>+8(SB)/4, $0x242070db
DATA consts<>+12(SB)/4, $0xc1bdceee
DATA consts<>+16(SB)/4, $0xf57c0faf
DATA consts<>+20(SB)/4, $0x4787c62a
DATA consts<>+24(SB)/4, $0xa8304613
DATA consts<>+28(SB)/4, $0xfd469501
DATA consts<>+32(SB)/4, $0x698098d8
DATA consts<>+36(SB)/4, $0x8b44f7af
DATA consts<>+40(SB)/4, $0xffff5bb1
DATA consts<>+44(SB)/4, $0x895cd7be
DATA consts<>+48(SB)/4, $0x6b901122
DATA consts<>+52(SB)/4, $0xfd987193
DATA consts<>+56(SB)/4, $0xa679438e
DATA consts<>+60(SB)/4, $0x49b40821
DATA consts<>+64(SB)/4, $0xf61e2562
DATA consts<>+68(SB)/4, $0xc040b340
DATA consts<>+72(SB)/4, $0x265e5a51
DATA consts<>+76(SB)/4, $0xe9b6c7aa
DATA consts<>+80(SB)/4, $0xd62f105d
DATA consts<>+84(SB)/4, $0x02441453
DATA consts<>+88(SB)/4, $0xd8a1e681
DATA consts<>+92(SB)/4, $0xe7d3fbc8
DATA consts<>+96(SB)/4, $0x21e1cde6
DATA consts<>+100(SB)/4, $0xc33707d6
DATA consts<>+104(SB)/4, $0xf4d50d87
DATA consts<>+108(SB)/4, $0x455a14ed
DATA consts<>+112(SB)/4, $0xa9e3e905
DATA consts<>+116(SB)/4, $0xfcefa3f8
DATA consts<>+120(SB)/4, $0x676f02d9
DATA consts<>+124(SB)/4, $0x8d2a4c8a
DATA consts<>+128(SB)/4, $0xfffa3942
DATA consts<>+132(SB)/4, $0x8771f681
DATA consts<>+136(SB)/4, $0x6d9d6122
DATA consts<>+140(SB)/4, $0xfde5380c
DATA consts<>+144(SB)/4, $0xa4beea44
DATA consts<>+148(SB)/4, $0x4bdecfa9
DATA consts<>+152(SB)/4, $0xf6bb4b60
DATA consts<>+156(SB)/4, $0xbebfbc70
DATA consts<>+160(SB)/4, $0x289b7ec6
DATA consts<>+164(SB)/4, $0xeaa127fa
DATA consts<>+168(SB)/4, $0xd4ef3085
DATA consts<>+172(SB)/4, $0x04881d05
DATA consts<>+176(SB)/4, $0xd9d4d039
DATA consts<>+180(SB)/4, $0xe6db99e5
DATA consts<>+184(SB)/4, $0x1fa27cf8
DATA consts<>+188(SB)/4, $0xc4ac5665
DATA consts<>+192(SB)/4, $0xf4292244
DATA consts<>+196(SB)/4, $0x432aff97
DATA consts<>+200(SB)/4, $0xab9423a7
DATA consts<>+204(SB)/4, $0xfc93a039
DATA consts<>+208(SB)/4, $0x655b59c3
DATA consts<>+212(SB)/4, $0x8f0ccc92
DATA consts<>+216(SB)/4, $0xffeff47d
DATA consts<>+220(SB)/4, $0x85845dd1
DATA consts<>+224(SB)/4, $0x6fa87e4f
DATA consts<>+228(SB)/4, $0xfe2ce6e0
DATA consts<>+232(SB)/4, $0xa3014314
DATA consts<>+236(SB)/4, $0x4e0811a1
DATA consts<>+240(SB)/4, $0xf7537e82
DATA consts<>+244(SB)/4, $0xbd3af235
DATA consts<>+248(SB)/4, $0x2ad7d2bb
DATA consts<>+252(SB)/4, $0xeb86d391
GLOBL consts<>(SB), RODATA|NOPTR, $256
// func block(h *[4][16]uint32, base uintptr, offsets *[16]uint32, mask uint16)
// Requires: AVX, AVX512F
TEXT ·block(SB), $0-26
MOVQ h+0(FP), AX
MOVQ base+8(FP), CX
MOVQ offsets+16(FP), DX
KMOVW mask+24(FP), K1
// Load offsets.
VMOVUPD (DX), Z0
// Load initial hash.
VMOVUPD (AX), Z1
VMOVUPD 64(AX), Z2
VMOVUPD 128(AX), Z3
VMOVUPD 192(AX), Z4
// Initialize registers.
VMOVUPD Z1, Z5
VMOVUPD Z2, Z6
VMOVUPD Z3, Z7
VMOVUPD Z4, Z8
// Round 0.
KMOVW K1, K2
VPGATHERDD (CX)(Z0*1), K2, Z9
VPADDD Z9, Z5, Z5
VPADDD.BCST consts<>+0(SB), Z5, Z5
VMOVUPD Z8, Z25
VPTERNLOGD $0xd8, Z6, Z7, Z25
VPADDD Z25, Z5, Z5
VPROLD $0x07, Z5, Z5
VPADDD Z6, Z5, Z5
// Round 1.
KMOVW K1, K2
VPGATHERDD 4(CX)(Z0*1), K2, Z10
VPADDD Z10, Z8, Z8
VPADDD.BCST consts<>+4(SB), Z8, Z8
VMOVUPD Z7, Z25
VPTERNLOGD $0xd8, Z5, Z6, Z25
VPADDD Z25, Z8, Z8
VPROLD $0x0c, Z8, Z8
VPADDD Z5, Z8, Z8
// Round 2.
KMOVW K1, K2
VPGATHERDD 8(CX)(Z0*1), K2, Z11
VPADDD Z11, Z7, Z7
VPADDD.BCST consts<>+8(SB), Z7, Z7
VMOVUPD Z6, Z25
VPTERNLOGD $0xd8, Z8, Z5, Z25
VPADDD Z25, Z7, Z7
VPROLD $0x11, Z7, Z7
VPADDD Z8, Z7, Z7
// Round 3.
KMOVW K1, K2
VPGATHERDD 12(CX)(Z0*1), K2, Z12
VPADDD Z12, Z6, Z6
VPADDD.BCST consts<>+12(SB), Z6, Z6
VMOVUPD Z5, Z25
VPTERNLOGD $0xd8, Z7, Z8, Z25
VPADDD Z25, Z6, Z6
VPROLD $0x16, Z6, Z6
VPADDD Z7, Z6, Z6
// Round 4.
KMOVW K1, K2
VPGATHERDD 16(CX)(Z0*1), K2, Z13
VPADDD Z13, Z5, Z5
VPADDD.BCST consts<>+16(SB), Z5, Z5
VMOVUPD Z8, Z25
VPTERNLOGD $0xd8, Z6, Z7, Z25
VPADDD Z25, Z5, Z5
VPROLD $0x07, Z5, Z5
VPADDD Z6, Z5, Z5
// Round 5.
KMOVW K1, K2
VPGATHERDD 20(CX)(Z0*1), K2, Z14
VPADDD Z14, Z8, Z8
VPADDD.BCST consts<>+20(SB), Z8, Z8
VMOVUPD Z7, Z25
VPTERNLOGD $0xd8, Z5, Z6, Z25
VPADDD Z25, Z8, Z8
VPROLD $0x0c, Z8, Z8
VPADDD Z5, Z8, Z8
// Round 6.
KMOVW K1, K2
VPGATHERDD 24(CX)(Z0*1), K2, Z15
VPADDD Z15, Z7, Z7
VPADDD.BCST consts<>+24(SB), Z7, Z7
VMOVUPD Z6, Z25
VPTERNLOGD $0xd8, Z8, Z5, Z25
VPADDD Z25, Z7, Z7
VPROLD $0x11, Z7, Z7
VPADDD Z8, Z7, Z7
// Round 7.
KMOVW K1, K2
VPGATHERDD 28(CX)(Z0*1), K2, Z16
VPADDD Z16, Z6, Z6
VPADDD.BCST consts<>+28(SB), Z6, Z6
VMOVUPD Z5, Z25
VPTERNLOGD $0xd8, Z7, Z8, Z25
VPADDD Z25, Z6, Z6
VPROLD $0x16, Z6, Z6
VPADDD Z7, Z6, Z6
// Round 8.
KMOVW K1, K2
VPGATHERDD 32(CX)(Z0*1), K2, Z17
VPADDD Z17, Z5, Z5
VPADDD.BCST consts<>+32(SB), Z5, Z5
VMOVUPD Z8, Z25
VPTERNLOGD $0xd8, Z6, Z7, Z25
VPADDD Z25, Z5, Z5
VPROLD $0x07, Z5, Z5
VPADDD Z6, Z5, Z5
// Round 9.
KMOVW K1, K2
VPGATHERDD 36(CX)(Z0*1), K2, Z18
VPADDD Z18, Z8, Z8
VPADDD.BCST consts<>+36(SB), Z8, Z8
VMOVUPD Z7, Z25
VPTERNLOGD $0xd8, Z5, Z6, Z25
VPADDD Z25, Z8, Z8
VPROLD $0x0c, Z8, Z8
VPADDD Z5, Z8, Z8
// Round 10.
KMOVW K1, K2
VPGATHERDD 40(CX)(Z0*1), K2, Z19
VPADDD Z19, Z7, Z7
VPADDD.BCST consts<>+40(SB), Z7, Z7
VMOVUPD Z6, Z25
VPTERNLOGD $0xd8, Z8, Z5, Z25
VPADDD Z25, Z7, Z7
VPROLD $0x11, Z7, Z7
VPADDD Z8, Z7, Z7
// Round 11.
KMOVW K1, K2
VPGATHERDD 44(CX)(Z0*1), K2, Z20
VPADDD Z20, Z6, Z6
VPADDD.BCST consts<>+44(SB), Z6, Z6
VMOVUPD Z5, Z25
VPTERNLOGD $0xd8, Z7, Z8, Z25
VPADDD Z25, Z6, Z6
VPROLD $0x16, Z6, Z6
VPADDD Z7, Z6, Z6
// Round 12.
KMOVW K1, K2
VPGATHERDD 48(CX)(Z0*1), K2, Z21
VPADDD Z21, Z5, Z5
VPADDD.BCST consts<>+48(SB), Z5, Z5
VMOVUPD Z8, Z25
VPTERNLOGD $0xd8, Z6, Z7, Z25
VPADDD Z25, Z5, Z5
VPROLD $0x07, Z5, Z5
VPADDD Z6, Z5, Z5
// Round 13.
KMOVW K1, K2
VPGATHERDD 52(CX)(Z0*1), K2, Z22
VPADDD Z22, Z8, Z8
VPADDD.BCST consts<>+52(SB), Z8, Z8
VMOVUPD Z7, Z25
VPTERNLOGD $0xd8, Z5, Z6, Z25
VPADDD Z25, Z8, Z8
VPROLD $0x0c, Z8, Z8
VPADDD Z5, Z8, Z8
// Round 14.
KMOVW K1, K2
VPGATHERDD 56(CX)(Z0*1), K2, Z23
VPADDD Z23, Z7, Z7
VPADDD.BCST consts<>+56(SB), Z7, Z7
VMOVUPD Z6, Z25
VPTERNLOGD $0xd8, Z8, Z5, Z25
VPADDD Z25, Z7, Z7
VPROLD $0x11, Z7, Z7
VPADDD Z8, Z7, Z7
// Round 15.
KMOVW K1, K1
VPGATHERDD 60(CX)(Z0*1), K1, Z24
VPADDD Z24, Z6, Z6
VPADDD.BCST consts<>+60(SB), Z6, Z6
VMOVUPD Z5, Z0
VPTERNLOGD $0xd8, Z7, Z8, Z0
VPADDD Z0, Z6, Z6
VPROLD $0x16, Z6, Z6
VPADDD Z7, Z6, Z6
// Round 16.
VPADDD Z10, Z5, Z5
VPADDD.BCST consts<>+64(SB), Z5, Z5
VMOVUPD Z8, Z0
VPTERNLOGD $0xac, Z6, Z7, Z0
VPADDD Z0, Z5, Z5
VPROLD $0x05, Z5, Z5
VPADDD Z6, Z5, Z5
// Round 17.
VPADDD Z15, Z8, Z8
VPADDD.BCST consts<>+68(SB), Z8, Z8
VMOVUPD Z7, Z0
VPTERNLOGD $0xac, Z5, Z6, Z0
VPADDD Z0, Z8, Z8
VPROLD $0x09, Z8, Z8
VPADDD Z5, Z8, Z8
// Round 18.
VPADDD Z20, Z7, Z7
VPADDD.BCST consts<>+72(SB), Z7, Z7
VMOVUPD Z6, Z0
VPTERNLOGD $0xac, Z8, Z5, Z0
VPADDD Z0, Z7, Z7
VPROLD $0x0e, Z7, Z7
VPADDD Z8, Z7, Z7
// Round 19.
VPADDD Z9, Z6, Z6
VPADDD.BCST consts<>+76(SB), Z6, Z6
VMOVUPD Z5, Z0
VPTERNLOGD $0xac, Z7, Z8, Z0
VPADDD Z0, Z6, Z6
VPROLD $0x14, Z6, Z6
VPADDD Z7, Z6, Z6
// Round 20.
VPADDD Z14, Z5, Z5
VPADDD.BCST consts<>+80(SB), Z5, Z5
VMOVUPD Z8, Z0
VPTERNLOGD $0xac, Z6, Z7, Z0
VPADDD Z0, Z5, Z5
VPROLD $0x05, Z5, Z5
VPADDD Z6, Z5, Z5
// Round 21.
VPADDD Z19, Z8, Z8
VPADDD.BCST consts<>+84(SB), Z8, Z8
VMOVUPD Z7, Z0
VPTERNLOGD $0xac, Z5, Z6, Z0
VPADDD Z0, Z8, Z8
VPROLD $0x09, Z8, Z8
VPADDD Z5, Z8, Z8
// Round 22.
VPADDD Z24, Z7, Z7
VPADDD.BCST consts<>+88(SB), Z7, Z7
VMOVUPD Z6, Z0
VPTERNLOGD $0xac, Z8, Z5, Z0
VPADDD Z0, Z7, Z7
VPROLD $0x0e, Z7, Z7
VPADDD Z8, Z7, Z7
// Round 23.
VPADDD Z13, Z6, Z6
VPADDD.BCST consts<>+92(SB), Z6, Z6
VMOVUPD Z5, Z0
VPTERNLOGD $0xac, Z7, Z8, Z0
VPADDD Z0, Z6, Z6
VPROLD $0x14, Z6, Z6
VPADDD Z7, Z6, Z6
// Round 24.
VPADDD Z18, Z5, Z5
VPADDD.BCST consts<>+96(SB), Z5, Z5
VMOVUPD Z8, Z0
VPTERNLOGD $0xac, Z6, Z7, Z0
VPADDD Z0, Z5, Z5
VPROLD $0x05, Z5, Z5
VPADDD Z6, Z5, Z5
// Round 25.
VPADDD Z23, Z8, Z8
VPADDD.BCST consts<>+100(SB), Z8, Z8
VMOVUPD Z7, Z0
VPTERNLOGD $0xac, Z5, Z6, Z0
VPADDD Z0, Z8, Z8
VPROLD $0x09, Z8, Z8
VPADDD Z5, Z8, Z8
// Round 26.
VPADDD Z12, Z7, Z7
VPADDD.BCST consts<>+104(SB), Z7, Z7
VMOVUPD Z6, Z0
VPTERNLOGD $0xac, Z8, Z5, Z0
VPADDD Z0, Z7, Z7
VPROLD $0x0e, Z7, Z7
VPADDD Z8, Z7, Z7
// Round 27.
VPADDD Z17, Z6, Z6
VPADDD.BCST consts<>+108(SB), Z6, Z6
VMOVUPD Z5, Z0
VPTERNLOGD $0xac, Z7, Z8, Z0
VPADDD Z0, Z6, Z6
VPROLD $0x14, Z6, Z6
VPADDD Z7, Z6, Z6
// Round 28.
VPADDD Z22, Z5, Z5
VPADDD.BCST consts<>+112(SB), Z5, Z5
VMOVUPD Z8, Z0
VPTERNLOGD $0xac, Z6, Z7, Z0
VPADDD Z0, Z5, Z5
VPROLD $0x05, Z5, Z5
VPADDD Z6, Z5, Z5
// Round 29.
VPADDD Z11, Z8, Z8
VPADDD.BCST consts<>+116(SB), Z8, Z8
VMOVUPD Z7, Z0
VPTERNLOGD $0xac, Z5, Z6, Z0
VPADDD Z0, Z8, Z8
VPROLD $0x09, Z8, Z8
VPADDD Z5, Z8, Z8
// Round 30.
VPADDD Z16, Z7, Z7
VPADDD.BCST consts<>+120(SB), Z7, Z7
VMOVUPD Z6, Z0
VPTERNLOGD $0xac, Z8, Z5, Z0
VPADDD Z0, Z7, Z7
VPROLD $0x0e, Z7, Z7
VPADDD Z8, Z7, Z7
// Round 31.
VPADDD Z21, Z6, Z6
VPADDD.BCST consts<>+124(SB), Z6, Z6
VMOVUPD Z5, Z0
VPTERNLOGD $0xac, Z7, Z8, Z0
VPADDD Z0, Z6, Z6
VPROLD $0x14, Z6, Z6
VPADDD Z7, Z6, Z6
// Round 32.
VPADDD Z14, Z5, Z5
VPADDD.BCST consts<>+128(SB), Z5, Z5
VMOVUPD Z8, Z0
VPTERNLOGD $0x96, Z6, Z7, Z0
VPADDD Z0, Z5, Z5
VPROLD $0x04, Z5, Z5
VPADDD Z6, Z5, Z5
// Round 33.
VPADDD Z17, Z8, Z8
VPADDD.BCST consts<>+132(SB), Z8, Z8
VMOVUPD Z7, Z0
VPTERNLOGD $0x96, Z5, Z6, Z0
VPADDD Z0, Z8, Z8
VPROLD $0x0b, Z8, Z8
VPADDD Z5, Z8, Z8
// Round 34.
VPADDD Z20, Z7, Z7
VPADDD.BCST consts<>+136(SB), Z7, Z7
VMOVUPD Z6, Z0
VPTERNLOGD $0x96, Z8, Z5, Z0
VPADDD Z0, Z7, Z7
VPROLD $0x10, Z7, Z7
VPADDD Z8, Z7, Z7
// Round 35.
VPADDD Z23, Z6, Z6
VPADDD.BCST consts<>+140(SB), Z6, Z6
VMOVUPD Z5, Z0
VPTERNLOGD $0x96, Z7, Z8, Z0
VPADDD Z0, Z6, Z6
VPROLD $0x17, Z6, Z6
VPADDD Z7, Z6, Z6
// Round 36.
VPADDD Z10, Z5, Z5
VPADDD.BCST consts<>+144(SB), Z5, Z5
VMOVUPD Z8, Z0
VPTERNLOGD $0x96, Z6, Z7, Z0
VPADDD Z0, Z5, Z5
VPROLD $0x04, Z5, Z5
VPADDD Z6, Z5, Z5
// Round 37.
VPADDD Z13, Z8, Z8
VPADDD.BCST consts<>+148(SB), Z8, Z8
VMOVUPD Z7, Z0
VPTERNLOGD $0x96, Z5, Z6, Z0
VPADDD Z0, Z8, Z8
VPROLD $0x0b, Z8, Z8
VPADDD Z5, Z8, Z8
// Round 38.
VPADDD Z16, Z7, Z7
VPADDD.BCST consts<>+152(SB), Z7, Z7
VMOVUPD Z6, Z0
VPTERNLOGD $0x96, Z8, Z5, Z0
VPADDD Z0, Z7, Z7
VPROLD $0x10, Z7, Z7
VPADDD Z8, Z7, Z7
// Round 39.
VPADDD Z19, Z6, Z6
VPADDD.BCST consts<>+156(SB), Z6, Z6
VMOVUPD Z5, Z0
VPTERNLOGD $0x96, Z7, Z8, Z0
VPADDD Z0, Z6, Z6
VPROLD $0x17, Z6, Z6
VPADDD Z7, Z6, Z6
// Round 40.
VPADDD Z22, Z5, Z5
VPADDD.BCST consts<>+160(SB), Z5, Z5
VMOVUPD Z8, Z0
VPTERNLOGD $0x96, Z6, Z7, Z0
VPADDD Z0, Z5, Z5
VPROLD $0x04, Z5, Z5
VPADDD Z6, Z5, Z5
// Round 41.
VPADDD Z9, Z8, Z8
VPADDD.BCST consts<>+164(SB), Z8, Z8
VMOVUPD Z7, Z0
VPTERNLOGD $0x96, Z5, Z6, Z0
VPADDD Z0, Z8, Z8
VPROLD $0x0b, Z8, Z8
VPADDD Z5, Z8, Z8
// Round 42.
VPADDD Z12, Z7, Z7
VPADDD.BCST consts<>+168(SB), Z7, Z7
VMOVUPD Z6, Z0
VPTERNLOGD $0x96, Z8, Z5, Z0
VPADDD Z0, Z7, Z7
VPROLD $0x10, Z7, Z7
VPADDD Z8, Z7, Z7
// Round 43.
VPADDD Z15, Z6, Z6
VPADDD.BCST consts<>+172(SB), Z6, Z6
VMOVUPD Z5, Z0
VPTERNLOGD $0x96, Z7, Z8, Z0
VPADDD Z0, Z6, Z6
VPROLD $0x17, Z6, Z6
VPADDD Z7, Z6, Z6
// Round 44.
VPADDD Z18, Z5, Z5
VPADDD.BCST consts<>+176(SB), Z5, Z5
VMOVUPD Z8, Z0
VPTERNLOGD $0x96, Z6, Z7, Z0
VPADDD Z0, Z5, Z5
VPROLD $0x04, Z5, Z5
VPADDD Z6, Z5, Z5
// Round 45.
VPADDD Z21, Z8, Z8
VPADDD.BCST consts<>+180(SB), Z8, Z8
VMOVUPD Z7, Z0
VPTERNLOGD $0x96, Z5, Z6, Z0
VPADDD Z0, Z8, Z8
VPROLD $0x0b, Z8, Z8
VPADDD Z5, Z8, Z8
// Round 46.
VPADDD Z24, Z7, Z7
VPADDD.BCST consts<>+184(SB), Z7, Z7
VMOVUPD Z6, Z0
VPTERNLOGD $0x96, Z8, Z5, Z0
VPADDD Z0, Z7, Z7
VPROLD $0x10, Z7, Z7
VPADDD Z8, Z7, Z7
// Round 47.
VPADDD Z11, Z6, Z6
VPADDD.BCST consts<>+188(SB), Z6, Z6
VMOVUPD Z5, Z0
VPTERNLOGD $0x96, Z7, Z8, Z0
VPADDD Z0, Z6, Z6
VPROLD $0x17, Z6, Z6
VPADDD Z7, Z6, Z6
// Round 48.
VPADDD Z9, Z5, Z5
VPADDD.BCST consts<>+192(SB), Z5, Z5
VMOVUPD Z8, Z0
VPTERNLOGD $0x63, Z6, Z7, Z0
VPADDD Z0, Z5, Z5
VPROLD $0x06, Z5, Z5
VPADDD Z6, Z5, Z5
// Round 49.
VPADDD Z16, Z8, Z8
VPADDD.BCST consts<>+196(SB), Z8, Z8
VMOVUPD Z7, Z0
VPTERNLOGD $0x63, Z5, Z6, Z0
VPADDD Z0, Z8, Z8
VPROLD $0x0a, Z8, Z8
VPADDD Z5, Z8, Z8
// Round 50.
VPADDD Z23, Z7, Z7
VPADDD.BCST consts<>+200(SB), Z7, Z7
VMOVUPD Z6, Z0
VPTERNLOGD $0x63, Z8, Z5, Z0
VPADDD Z0, Z7, Z7
VPROLD $0x0f, Z7, Z7
VPADDD Z8, Z7, Z7
// Round 51.
VPADDD Z14, Z6, Z6
VPADDD.BCST consts<>+204(SB), Z6, Z6
VMOVUPD Z5, Z0
VPTERNLOGD $0x63, Z7, Z8, Z0
VPADDD Z0, Z6, Z6
VPROLD $0x15, Z6, Z6
VPADDD Z7, Z6, Z6
// Round 52.
VPADDD Z21, Z5, Z5
VPADDD.BCST consts<>+208(SB), Z5, Z5
VMOVUPD Z8, Z0
VPTERNLOGD $0x63, Z6, Z7, Z0
VPADDD Z0, Z5, Z5
VPROLD $0x06, Z5, Z5
VPADDD Z6, Z5, Z5
// Round 53.
VPADDD Z12, Z8, Z8
VPADDD.BCST consts<>+212(SB), Z8, Z8
VMOVUPD Z7, Z0
VPTERNLOGD $0x63, Z5, Z6, Z0
VPADDD Z0, Z8, Z8
VPROLD $0x0a, Z8, Z8
VPADDD Z5, Z8, Z8
// Round 54.
VPADDD Z19, Z7, Z7
VPADDD.BCST consts<>+216(SB), Z7, Z7
VMOVUPD Z6, Z0
VPTERNLOGD $0x63, Z8, Z5, Z0
VPADDD Z0, Z7, Z7
VPROLD $0x0f, Z7, Z7
VPADDD Z8, Z7, Z7
// Round 55.
VPADDD Z10, Z6, Z6
VPADDD.BCST consts<>+220(SB), Z6, Z6
VMOVUPD Z5, Z0
VPTERNLOGD $0x63, Z7, Z8, Z0
VPADDD Z0, Z6, Z6
VPROLD $0x15, Z6, Z6
VPADDD Z7, Z6, Z6
// Round 56.
VPADDD Z17, Z5, Z5
VPADDD.BCST consts<>+224(SB), Z5, Z5
VMOVUPD Z8, Z0
VPTERNLOGD $0x63, Z6, Z7, Z0
VPADDD Z0, Z5, Z5
VPROLD $0x06, Z5, Z5
VPADDD Z6, Z5, Z5
// Round 57.
VPADDD Z24, Z8, Z8
VPADDD.BCST consts<>+228(SB), Z8, Z8
VMOVUPD Z7, Z0
VPTERNLOGD $0x63, Z5, Z6, Z0
VPADDD Z0, Z8, Z8
VPROLD $0x0a, Z8, Z8
VPADDD Z5, Z8, Z8
// Round 58.
VPADDD Z15, Z7, Z7
VPADDD.BCST consts<>+232(SB), Z7, Z7
VMOVUPD Z6, Z0
VPTERNLOGD $0x63, Z8, Z5, Z0
VPADDD Z0, Z7, Z7
VPROLD $0x0f, Z7, Z7
VPADDD Z8, Z7, Z7
// Round 59.
VPADDD Z22, Z6, Z6
VPADDD.BCST consts<>+236(SB), Z6, Z6
VMOVUPD Z5, Z0
VPTERNLOGD $0x63, Z7, Z8, Z0
VPADDD Z0, Z6, Z6
VPROLD $0x15, Z6, Z6
VPADDD Z7, Z6, Z6
// Round 60.
VPADDD Z13, Z5, Z5
VPADDD.BCST consts<>+240(SB), Z5, Z5
VMOVUPD Z8, Z0
VPTERNLOGD $0x63, Z6, Z7, Z0
VPADDD Z0, Z5, Z5
VPROLD $0x06, Z5, Z5
VPADDD Z6, Z5, Z5
// Round 61.
VPADDD Z20, Z8, Z8
VPADDD.BCST consts<>+244(SB), Z8, Z8
VMOVUPD Z7, Z0
VPTERNLOGD $0x63, Z5, Z6, Z0
VPADDD Z0, Z8, Z8
VPROLD $0x0a, Z8, Z8
VPADDD Z5, Z8, Z8
// Round 62.
VPADDD Z11, Z7, Z7
VPADDD.BCST consts<>+248(SB), Z7, Z7
VMOVUPD Z6, Z0
VPTERNLOGD $0x63, Z8, Z5, Z0
VPADDD Z0, Z7, Z7
VPROLD $0x0f, Z7, Z7
VPADDD Z8, Z7, Z7
// Round 63.
VPADDD Z18, Z6, Z6
VPADDD.BCST consts<>+252(SB), Z6, Z6
VMOVUPD Z5, Z0
VPTERNLOGD $0x63, Z7, Z8, Z0
VPADDD Z0, Z6, Z6
VPROLD $0x15, Z6, Z6
VPADDD Z7, Z6, Z6
// Final add.
VPADDD Z5, Z1, Z1
VPADDD Z6, Z2, Z2
VPADDD Z7, Z3, Z3
VPADDD Z8, Z4, Z4
// Store results back.
VMOVUPD Z1, (AX)
VMOVUPD Z2, 64(AX)
VMOVUPD Z3, 128(AX)
VMOVUPD Z4, 192(AX)
VZEROUPPER
RET