162306a36Sopenharmony_ci########################################################################
262306a36Sopenharmony_ci# Implement fast SHA-512 with AVX2 instructions. (x86_64)
362306a36Sopenharmony_ci#
462306a36Sopenharmony_ci# Copyright (C) 2013 Intel Corporation.
562306a36Sopenharmony_ci#
662306a36Sopenharmony_ci# Authors:
762306a36Sopenharmony_ci#     James Guilford <james.guilford@intel.com>
862306a36Sopenharmony_ci#     Kirk Yap <kirk.s.yap@intel.com>
962306a36Sopenharmony_ci#     David Cote <david.m.cote@intel.com>
1062306a36Sopenharmony_ci#     Tim Chen <tim.c.chen@linux.intel.com>
1162306a36Sopenharmony_ci#
1262306a36Sopenharmony_ci# This software is available to you under a choice of one of two
1362306a36Sopenharmony_ci# licenses.  You may choose to be licensed under the terms of the GNU
1462306a36Sopenharmony_ci# General Public License (GPL) Version 2, available from the file
1562306a36Sopenharmony_ci# COPYING in the main directory of this source tree, or the
1662306a36Sopenharmony_ci# OpenIB.org BSD license below:
1762306a36Sopenharmony_ci#
1862306a36Sopenharmony_ci#     Redistribution and use in source and binary forms, with or
1962306a36Sopenharmony_ci#     without modification, are permitted provided that the following
2062306a36Sopenharmony_ci#     conditions are met:
2162306a36Sopenharmony_ci#
2262306a36Sopenharmony_ci#      - Redistributions of source code must retain the above
2362306a36Sopenharmony_ci#        copyright notice, this list of conditions and the following
2462306a36Sopenharmony_ci#        disclaimer.
2562306a36Sopenharmony_ci#
2662306a36Sopenharmony_ci#      - Redistributions in binary form must reproduce the above
2762306a36Sopenharmony_ci#        copyright notice, this list of conditions and the following
2862306a36Sopenharmony_ci#        disclaimer in the documentation and/or other materials
2962306a36Sopenharmony_ci#        provided with the distribution.
3062306a36Sopenharmony_ci#
3162306a36Sopenharmony_ci# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3262306a36Sopenharmony_ci# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3362306a36Sopenharmony_ci# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
3462306a36Sopenharmony_ci# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
3562306a36Sopenharmony_ci# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
3662306a36Sopenharmony_ci# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
3762306a36Sopenharmony_ci# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
3862306a36Sopenharmony_ci# SOFTWARE.
3962306a36Sopenharmony_ci#
4062306a36Sopenharmony_ci########################################################################
4162306a36Sopenharmony_ci#
4262306a36Sopenharmony_ci# This code is described in an Intel White-Paper:
4362306a36Sopenharmony_ci# "Fast SHA-512 Implementations on Intel Architecture Processors"
4462306a36Sopenharmony_ci#
4562306a36Sopenharmony_ci# To find it, surf to http://www.intel.com/p/en_US/embedded
4662306a36Sopenharmony_ci# and search for that title.
4762306a36Sopenharmony_ci#
4862306a36Sopenharmony_ci########################################################################
4962306a36Sopenharmony_ci# This code schedules 1 blocks at a time, with 4 lanes per block
5062306a36Sopenharmony_ci########################################################################
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci#include <linux/linkage.h>
5362306a36Sopenharmony_ci#include <linux/cfi_types.h>
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci.text
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci# Virtual Registers
5862306a36Sopenharmony_ciY_0 = %ymm4
5962306a36Sopenharmony_ciY_1 = %ymm5
6062306a36Sopenharmony_ciY_2 = %ymm6
6162306a36Sopenharmony_ciY_3 = %ymm7
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ciYTMP0 = %ymm0
6462306a36Sopenharmony_ciYTMP1 = %ymm1
6562306a36Sopenharmony_ciYTMP2 = %ymm2
6662306a36Sopenharmony_ciYTMP3 = %ymm3
6762306a36Sopenharmony_ciYTMP4 = %ymm8
6862306a36Sopenharmony_ciXFER  = YTMP0
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ciBYTE_FLIP_MASK  = %ymm9
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci# 1st arg is %rdi, which is saved to the stack and accessed later via %r12
7362306a36Sopenharmony_ciCTX1        = %rdi
7462306a36Sopenharmony_ciCTX2        = %r12
7562306a36Sopenharmony_ci# 2nd arg
7662306a36Sopenharmony_ciINP         = %rsi
7762306a36Sopenharmony_ci# 3rd arg
7862306a36Sopenharmony_ciNUM_BLKS    = %rdx
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_cic           = %rcx
8162306a36Sopenharmony_cid           = %r8
8262306a36Sopenharmony_cie           = %rdx
8362306a36Sopenharmony_ciy3          = %rsi
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ciTBL   = %rdi # clobbers CTX1
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_cia     = %rax
8862306a36Sopenharmony_cib     = %rbx
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_cif     = %r9
9162306a36Sopenharmony_cig     = %r10
9262306a36Sopenharmony_cih     = %r11
9362306a36Sopenharmony_ciold_h = %r11
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ciT1    = %r12 # clobbers CTX2
9662306a36Sopenharmony_ciy0    = %r13
9762306a36Sopenharmony_ciy1    = %r14
9862306a36Sopenharmony_ciy2    = %r15
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci# Local variables (stack frame)
10162306a36Sopenharmony_ciXFER_SIZE = 4*8
10262306a36Sopenharmony_ciSRND_SIZE = 1*8
10362306a36Sopenharmony_ciINP_SIZE = 1*8
10462306a36Sopenharmony_ciINPEND_SIZE = 1*8
10562306a36Sopenharmony_ciCTX_SIZE = 1*8
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ciframe_XFER = 0
10862306a36Sopenharmony_ciframe_SRND = frame_XFER + XFER_SIZE
10962306a36Sopenharmony_ciframe_INP = frame_SRND + SRND_SIZE
11062306a36Sopenharmony_ciframe_INPEND = frame_INP + INP_SIZE
11162306a36Sopenharmony_ciframe_CTX = frame_INPEND + INPEND_SIZE
11262306a36Sopenharmony_ciframe_size = frame_CTX + CTX_SIZE
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci## assume buffers not aligned
11562306a36Sopenharmony_ci#define	VMOVDQ vmovdqu
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci# addm [mem], reg
11862306a36Sopenharmony_ci# Add reg to mem using reg-mem add and store
11962306a36Sopenharmony_ci.macro addm p1 p2
12062306a36Sopenharmony_ci	add	\p1, \p2
12162306a36Sopenharmony_ci	mov	\p2, \p1
12262306a36Sopenharmony_ci.endm
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci# COPY_YMM_AND_BSWAP ymm, [mem], byte_flip_mask
12662306a36Sopenharmony_ci# Load ymm with mem and byte swap each dword
12762306a36Sopenharmony_ci.macro COPY_YMM_AND_BSWAP p1 p2 p3
12862306a36Sopenharmony_ci	VMOVDQ \p2, \p1
12962306a36Sopenharmony_ci	vpshufb \p3, \p1, \p1
13062306a36Sopenharmony_ci.endm
13162306a36Sopenharmony_ci# rotate_Ys
13262306a36Sopenharmony_ci# Rotate values of symbols Y0...Y3
13362306a36Sopenharmony_ci.macro rotate_Ys
13462306a36Sopenharmony_ci	Y_ = Y_0
13562306a36Sopenharmony_ci	Y_0 = Y_1
13662306a36Sopenharmony_ci	Y_1 = Y_2
13762306a36Sopenharmony_ci	Y_2 = Y_3
13862306a36Sopenharmony_ci	Y_3 = Y_
13962306a36Sopenharmony_ci.endm
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_ci# RotateState
14262306a36Sopenharmony_ci.macro RotateState
14362306a36Sopenharmony_ci	# Rotate symbols a..h right
14462306a36Sopenharmony_ci	old_h  = h
14562306a36Sopenharmony_ci	TMP_   = h
14662306a36Sopenharmony_ci	h      = g
14762306a36Sopenharmony_ci	g      = f
14862306a36Sopenharmony_ci	f      = e
14962306a36Sopenharmony_ci	e      = d
15062306a36Sopenharmony_ci	d      = c
15162306a36Sopenharmony_ci	c      = b
15262306a36Sopenharmony_ci	b      = a
15362306a36Sopenharmony_ci	a      = TMP_
15462306a36Sopenharmony_ci.endm
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci# macro MY_VPALIGNR	YDST, YSRC1, YSRC2, RVAL
15762306a36Sopenharmony_ci# YDST = {YSRC1, YSRC2} >> RVAL*8
15862306a36Sopenharmony_ci.macro MY_VPALIGNR YDST YSRC1 YSRC2 RVAL
15962306a36Sopenharmony_ci	vperm2f128      $0x3, \YSRC2, \YSRC1, \YDST     # YDST = {YS1_LO, YS2_HI}
16062306a36Sopenharmony_ci	vpalignr        $\RVAL, \YSRC2, \YDST, \YDST    # YDST = {YDS1, YS2} >> RVAL*8
16162306a36Sopenharmony_ci.endm
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci.macro FOUR_ROUNDS_AND_SCHED
16462306a36Sopenharmony_ci################################### RND N + 0 #########################################
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci	# Extract w[t-7]
16762306a36Sopenharmony_ci	MY_VPALIGNR	YTMP0, Y_3, Y_2, 8		# YTMP0 = W[-7]
16862306a36Sopenharmony_ci	# Calculate w[t-16] + w[t-7]
16962306a36Sopenharmony_ci	vpaddq		Y_0, YTMP0, YTMP0		# YTMP0 = W[-7] + W[-16]
17062306a36Sopenharmony_ci	# Extract w[t-15]
17162306a36Sopenharmony_ci	MY_VPALIGNR	YTMP1, Y_1, Y_0, 8		# YTMP1 = W[-15]
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	# Calculate sigma0
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci	# Calculate w[t-15] ror 1
17662306a36Sopenharmony_ci	vpsrlq		$1, YTMP1, YTMP2
17762306a36Sopenharmony_ci	vpsllq		$(64-1), YTMP1, YTMP3
17862306a36Sopenharmony_ci	vpor		YTMP2, YTMP3, YTMP3		# YTMP3 = W[-15] ror 1
17962306a36Sopenharmony_ci	# Calculate w[t-15] shr 7
18062306a36Sopenharmony_ci	vpsrlq		$7, YTMP1, YTMP4		# YTMP4 = W[-15] >> 7
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci	mov	a, y3		# y3 = a                                # MAJA
18362306a36Sopenharmony_ci	rorx	$41, e, y0	# y0 = e >> 41				# S1A
18462306a36Sopenharmony_ci	rorx	$18, e, y1	# y1 = e >> 18				# S1B
18562306a36Sopenharmony_ci	add	frame_XFER(%rsp),h		# h = k + w + h         # --
18662306a36Sopenharmony_ci	or	c, y3		# y3 = a|c                              # MAJA
18762306a36Sopenharmony_ci	mov	f, y2		# y2 = f                                # CH
18862306a36Sopenharmony_ci	rorx	$34, a, T1	# T1 = a >> 34				# S0B
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci	xor	y1, y0		# y0 = (e>>41) ^ (e>>18)		# S1
19162306a36Sopenharmony_ci	xor	g, y2		# y2 = f^g                              # CH
19262306a36Sopenharmony_ci	rorx	$14, e, y1	# y1 = (e >> 14)			# S1
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci	and	e, y2		# y2 = (f^g)&e                          # CH
19562306a36Sopenharmony_ci	xor	y1, y0		# y0 = (e>>41) ^ (e>>18) ^ (e>>14)	# S1
19662306a36Sopenharmony_ci	rorx	$39, a, y1	# y1 = a >> 39				# S0A
19762306a36Sopenharmony_ci	add	h, d		# d = k + w + h + d                     # --
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci	and	b, y3		# y3 = (a|c)&b                          # MAJA
20062306a36Sopenharmony_ci	xor	T1, y1		# y1 = (a>>39) ^ (a>>34)		# S0
20162306a36Sopenharmony_ci	rorx	$28, a, T1	# T1 = (a >> 28)			# S0
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci	xor	g, y2		# y2 = CH = ((f^g)&e)^g                 # CH
20462306a36Sopenharmony_ci	xor	T1, y1		# y1 = (a>>39) ^ (a>>34) ^ (a>>28)	# S0
20562306a36Sopenharmony_ci	mov	a, T1		# T1 = a                                # MAJB
20662306a36Sopenharmony_ci	and	c, T1		# T1 = a&c                              # MAJB
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci	add	y0, y2		# y2 = S1 + CH                          # --
20962306a36Sopenharmony_ci	or	T1, y3		# y3 = MAJ = (a|c)&b)|(a&c)             # MAJ
21062306a36Sopenharmony_ci	add	y1, h		# h = k + w + h + S0                    # --
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci	add	y2, d		# d = k + w + h + d + S1 + CH = d + t1  # --
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci	add	y2, h		# h = k + w + h + S0 + S1 + CH = t1 + S0# --
21562306a36Sopenharmony_ci	add	y3, h		# h = t1 + S0 + MAJ                     # --
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci	RotateState
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci################################### RND N + 1 #########################################
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	# Calculate w[t-15] ror 8
22262306a36Sopenharmony_ci	vpsrlq		$8, YTMP1, YTMP2
22362306a36Sopenharmony_ci	vpsllq		$(64-8), YTMP1, YTMP1
22462306a36Sopenharmony_ci	vpor		YTMP2, YTMP1, YTMP1		# YTMP1 = W[-15] ror 8
22562306a36Sopenharmony_ci	# XOR the three components
22662306a36Sopenharmony_ci	vpxor		YTMP4, YTMP3, YTMP3		# YTMP3 = W[-15] ror 1 ^ W[-15] >> 7
22762306a36Sopenharmony_ci	vpxor		YTMP1, YTMP3, YTMP1		# YTMP1 = s0
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	# Add three components, w[t-16], w[t-7] and sigma0
23162306a36Sopenharmony_ci	vpaddq		YTMP1, YTMP0, YTMP0		# YTMP0 = W[-16] + W[-7] + s0
23262306a36Sopenharmony_ci	# Move to appropriate lanes for calculating w[16] and w[17]
23362306a36Sopenharmony_ci	vperm2f128	$0x0, YTMP0, YTMP0, Y_0		# Y_0 = W[-16] + W[-7] + s0 {BABA}
23462306a36Sopenharmony_ci	# Move to appropriate lanes for calculating w[18] and w[19]
23562306a36Sopenharmony_ci	vpand		MASK_YMM_LO(%rip), YTMP0, YTMP0	# YTMP0 = W[-16] + W[-7] + s0 {DC00}
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci	# Calculate w[16] and w[17] in both 128 bit lanes
23862306a36Sopenharmony_ci
23962306a36Sopenharmony_ci	# Calculate sigma1 for w[16] and w[17] on both 128 bit lanes
24062306a36Sopenharmony_ci	vperm2f128	$0x11, Y_3, Y_3, YTMP2		# YTMP2 = W[-2] {BABA}
24162306a36Sopenharmony_ci	vpsrlq		$6, YTMP2, YTMP4		# YTMP4 = W[-2] >> 6 {BABA}
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci	mov	a, y3		# y3 = a                                # MAJA
24562306a36Sopenharmony_ci	rorx	$41, e, y0	# y0 = e >> 41				# S1A
24662306a36Sopenharmony_ci	rorx	$18, e, y1	# y1 = e >> 18				# S1B
24762306a36Sopenharmony_ci	add	1*8+frame_XFER(%rsp), h		# h = k + w + h         # --
24862306a36Sopenharmony_ci	or	c, y3		# y3 = a|c                              # MAJA
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci	mov	f, y2		# y2 = f                                # CH
25262306a36Sopenharmony_ci	rorx	$34, a, T1	# T1 = a >> 34				# S0B
25362306a36Sopenharmony_ci	xor	y1, y0		# y0 = (e>>41) ^ (e>>18)		# S1
25462306a36Sopenharmony_ci	xor	g, y2		# y2 = f^g                              # CH
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci
25762306a36Sopenharmony_ci	rorx	$14, e, y1	# y1 = (e >> 14)			# S1
25862306a36Sopenharmony_ci	xor	y1, y0		# y0 = (e>>41) ^ (e>>18) ^ (e>>14)	# S1
25962306a36Sopenharmony_ci	rorx	$39, a, y1	# y1 = a >> 39				# S0A
26062306a36Sopenharmony_ci	and	e, y2		# y2 = (f^g)&e                          # CH
26162306a36Sopenharmony_ci	add	h, d		# d = k + w + h + d                     # --
26262306a36Sopenharmony_ci
26362306a36Sopenharmony_ci	and	b, y3		# y3 = (a|c)&b                          # MAJA
26462306a36Sopenharmony_ci	xor	T1, y1		# y1 = (a>>39) ^ (a>>34)		# S0
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci	rorx	$28, a, T1	# T1 = (a >> 28)			# S0
26762306a36Sopenharmony_ci	xor	g, y2		# y2 = CH = ((f^g)&e)^g                 # CH
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci	xor	T1, y1		# y1 = (a>>39) ^ (a>>34) ^ (a>>28)	# S0
27062306a36Sopenharmony_ci	mov	a, T1		# T1 = a                                # MAJB
27162306a36Sopenharmony_ci	and	c, T1		# T1 = a&c                              # MAJB
27262306a36Sopenharmony_ci	add	y0, y2		# y2 = S1 + CH                          # --
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci	or	T1, y3		# y3 = MAJ = (a|c)&b)|(a&c)             # MAJ
27562306a36Sopenharmony_ci	add	y1, h		# h = k + w + h + S0                    # --
27662306a36Sopenharmony_ci
27762306a36Sopenharmony_ci	add	y2, d		# d = k + w + h + d + S1 + CH = d + t1  # --
27862306a36Sopenharmony_ci	add	y2, h		# h = k + w + h + S0 + S1 + CH = t1 + S0# --
27962306a36Sopenharmony_ci	add	y3, h		# h = t1 + S0 + MAJ                     # --
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci	RotateState
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci################################### RND N + 2 #########################################
28562306a36Sopenharmony_ci
28662306a36Sopenharmony_ci	vpsrlq		$19, YTMP2, YTMP3		# YTMP3 = W[-2] >> 19 {BABA}
28762306a36Sopenharmony_ci	vpsllq		$(64-19), YTMP2, YTMP1		# YTMP1 = W[-2] << 19 {BABA}
28862306a36Sopenharmony_ci	vpor		YTMP1, YTMP3, YTMP3		# YTMP3 = W[-2] ror 19 {BABA}
28962306a36Sopenharmony_ci	vpxor		YTMP3, YTMP4, YTMP4		# YTMP4 = W[-2] ror 19 ^ W[-2] >> 6 {BABA}
29062306a36Sopenharmony_ci	vpsrlq		$61, YTMP2, YTMP3		# YTMP3 = W[-2] >> 61 {BABA}
29162306a36Sopenharmony_ci	vpsllq		$(64-61), YTMP2, YTMP1		# YTMP1 = W[-2] << 61 {BABA}
29262306a36Sopenharmony_ci	vpor		YTMP1, YTMP3, YTMP3		# YTMP3 = W[-2] ror 61 {BABA}
29362306a36Sopenharmony_ci	vpxor		YTMP3, YTMP4, YTMP4		# YTMP4 = s1 = (W[-2] ror 19) ^
29462306a36Sopenharmony_ci							#  (W[-2] ror 61) ^ (W[-2] >> 6) {BABA}
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci	# Add sigma1 to the other compunents to get w[16] and w[17]
29762306a36Sopenharmony_ci	vpaddq		YTMP4, Y_0, Y_0			# Y_0 = {W[1], W[0], W[1], W[0]}
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci	# Calculate sigma1 for w[18] and w[19] for upper 128 bit lane
30062306a36Sopenharmony_ci	vpsrlq		$6, Y_0, YTMP4			# YTMP4 = W[-2] >> 6 {DC--}
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci	mov	a, y3		# y3 = a                                # MAJA
30362306a36Sopenharmony_ci	rorx	$41, e, y0	# y0 = e >> 41				# S1A
30462306a36Sopenharmony_ci	add	2*8+frame_XFER(%rsp), h		# h = k + w + h         # --
30562306a36Sopenharmony_ci
30662306a36Sopenharmony_ci	rorx	$18, e, y1	# y1 = e >> 18				# S1B
30762306a36Sopenharmony_ci	or	c, y3		# y3 = a|c                              # MAJA
30862306a36Sopenharmony_ci	mov	f, y2		# y2 = f                                # CH
30962306a36Sopenharmony_ci	xor	g, y2		# y2 = f^g                              # CH
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci	rorx	$34, a, T1	# T1 = a >> 34				# S0B
31262306a36Sopenharmony_ci	xor	y1, y0		# y0 = (e>>41) ^ (e>>18)		# S1
31362306a36Sopenharmony_ci	and	e, y2		# y2 = (f^g)&e                          # CH
31462306a36Sopenharmony_ci
31562306a36Sopenharmony_ci	rorx	$14, e, y1	# y1 = (e >> 14)			# S1
31662306a36Sopenharmony_ci	add	h, d		# d = k + w + h + d                     # --
31762306a36Sopenharmony_ci	and	b, y3		# y3 = (a|c)&b                          # MAJA
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci	xor	y1, y0		# y0 = (e>>41) ^ (e>>18) ^ (e>>14)	# S1
32062306a36Sopenharmony_ci	rorx	$39, a, y1	# y1 = a >> 39				# S0A
32162306a36Sopenharmony_ci	xor	g, y2		# y2 = CH = ((f^g)&e)^g                 # CH
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ci	xor	T1, y1		# y1 = (a>>39) ^ (a>>34)		# S0
32462306a36Sopenharmony_ci	rorx	$28, a, T1	# T1 = (a >> 28)			# S0
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci	xor	T1, y1		# y1 = (a>>39) ^ (a>>34) ^ (a>>28)	# S0
32762306a36Sopenharmony_ci	mov	a, T1		# T1 = a                                # MAJB
32862306a36Sopenharmony_ci	and	c, T1		# T1 = a&c                              # MAJB
32962306a36Sopenharmony_ci	add	y0, y2		# y2 = S1 + CH                          # --
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	or	T1, y3		# y3 = MAJ = (a|c)&b)|(a&c)             # MAJ
33262306a36Sopenharmony_ci	add	y1, h		# h = k + w + h + S0                    # --
33362306a36Sopenharmony_ci	add	y2, d		# d = k + w + h + d + S1 + CH = d + t1  # --
33462306a36Sopenharmony_ci	add	y2, h		# h = k + w + h + S0 + S1 + CH = t1 + S0# --
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci	add	y3, h		# h = t1 + S0 + MAJ                     # --
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci	RotateState
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci################################### RND N + 3 #########################################
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci	vpsrlq		$19, Y_0, YTMP3			# YTMP3 = W[-2] >> 19 {DC--}
34362306a36Sopenharmony_ci	vpsllq		$(64-19), Y_0, YTMP1		# YTMP1 = W[-2] << 19 {DC--}
34462306a36Sopenharmony_ci	vpor		YTMP1, YTMP3, YTMP3		# YTMP3 = W[-2] ror 19 {DC--}
34562306a36Sopenharmony_ci	vpxor		YTMP3, YTMP4, YTMP4		# YTMP4 = W[-2] ror 19 ^ W[-2] >> 6 {DC--}
34662306a36Sopenharmony_ci	vpsrlq		$61, Y_0, YTMP3			# YTMP3 = W[-2] >> 61 {DC--}
34762306a36Sopenharmony_ci	vpsllq		$(64-61), Y_0, YTMP1		# YTMP1 = W[-2] << 61 {DC--}
34862306a36Sopenharmony_ci	vpor		YTMP1, YTMP3, YTMP3		# YTMP3 = W[-2] ror 61 {DC--}
34962306a36Sopenharmony_ci	vpxor		YTMP3, YTMP4, YTMP4		# YTMP4 = s1 = (W[-2] ror 19) ^
35062306a36Sopenharmony_ci							#  (W[-2] ror 61) ^ (W[-2] >> 6) {DC--}
35162306a36Sopenharmony_ci
35262306a36Sopenharmony_ci	# Add the sigma0 + w[t-7] + w[t-16] for w[18] and w[19]
35362306a36Sopenharmony_ci	# to newly calculated sigma1 to get w[18] and w[19]
35462306a36Sopenharmony_ci	vpaddq		YTMP4, YTMP0, YTMP2		# YTMP2 = {W[3], W[2], --, --}
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci	# Form w[19, w[18], w17], w[16]
35762306a36Sopenharmony_ci	vpblendd		$0xF0, YTMP2, Y_0, Y_0		# Y_0 = {W[3], W[2], W[1], W[0]}
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci	mov	a, y3		# y3 = a                                # MAJA
36062306a36Sopenharmony_ci	rorx	$41, e, y0	# y0 = e >> 41				# S1A
36162306a36Sopenharmony_ci	rorx	$18, e, y1	# y1 = e >> 18				# S1B
36262306a36Sopenharmony_ci	add	3*8+frame_XFER(%rsp), h		# h = k + w + h         # --
36362306a36Sopenharmony_ci	or	c, y3		# y3 = a|c                              # MAJA
36462306a36Sopenharmony_ci
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci	mov	f, y2		# y2 = f                                # CH
36762306a36Sopenharmony_ci	rorx	$34, a, T1	# T1 = a >> 34				# S0B
36862306a36Sopenharmony_ci	xor	y1, y0		# y0 = (e>>41) ^ (e>>18)		# S1
36962306a36Sopenharmony_ci	xor	g, y2		# y2 = f^g                              # CH
37062306a36Sopenharmony_ci
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci	rorx	$14, e, y1	# y1 = (e >> 14)			# S1
37362306a36Sopenharmony_ci	and	e, y2		# y2 = (f^g)&e                          # CH
37462306a36Sopenharmony_ci	add	h, d		# d = k + w + h + d                     # --
37562306a36Sopenharmony_ci	and	b, y3		# y3 = (a|c)&b                          # MAJA
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci	xor	y1, y0		# y0 = (e>>41) ^ (e>>18) ^ (e>>14)	# S1
37862306a36Sopenharmony_ci	xor	g, y2		# y2 = CH = ((f^g)&e)^g                 # CH
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci	rorx	$39, a, y1	# y1 = a >> 39				# S0A
38162306a36Sopenharmony_ci	add	y0, y2		# y2 = S1 + CH                          # --
38262306a36Sopenharmony_ci
38362306a36Sopenharmony_ci	xor	T1, y1		# y1 = (a>>39) ^ (a>>34)		# S0
38462306a36Sopenharmony_ci	add	y2, d		# d = k + w + h + d + S1 + CH = d + t1  # --
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_ci	rorx	$28, a, T1	# T1 = (a >> 28)			# S0
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci	xor	T1, y1		# y1 = (a>>39) ^ (a>>34) ^ (a>>28)	# S0
38962306a36Sopenharmony_ci	mov	a, T1		# T1 = a                                # MAJB
39062306a36Sopenharmony_ci	and	c, T1		# T1 = a&c                              # MAJB
39162306a36Sopenharmony_ci	or	T1, y3		# y3 = MAJ = (a|c)&b)|(a&c)             # MAJ
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_ci	add	y1, h		# h = k + w + h + S0                    # --
39462306a36Sopenharmony_ci	add	y2, h		# h = k + w + h + S0 + S1 + CH = t1 + S0# --
39562306a36Sopenharmony_ci	add	y3, h		# h = t1 + S0 + MAJ                     # --
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci	RotateState
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci	rotate_Ys
40062306a36Sopenharmony_ci.endm
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci.macro DO_4ROUNDS
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci################################### RND N + 0 #########################################
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci	mov	f, y2		# y2 = f                                # CH
40762306a36Sopenharmony_ci	rorx	$41, e, y0	# y0 = e >> 41				# S1A
40862306a36Sopenharmony_ci	rorx	$18, e, y1	# y1 = e >> 18				# S1B
40962306a36Sopenharmony_ci	xor	g, y2		# y2 = f^g                              # CH
41062306a36Sopenharmony_ci
41162306a36Sopenharmony_ci	xor	y1, y0		# y0 = (e>>41) ^ (e>>18)		# S1
41262306a36Sopenharmony_ci	rorx	$14, e, y1	# y1 = (e >> 14)			# S1
41362306a36Sopenharmony_ci	and	e, y2		# y2 = (f^g)&e                          # CH
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	xor	y1, y0		# y0 = (e>>41) ^ (e>>18) ^ (e>>14)	# S1
41662306a36Sopenharmony_ci	rorx	$34, a, T1	# T1 = a >> 34				# S0B
41762306a36Sopenharmony_ci	xor	g, y2		# y2 = CH = ((f^g)&e)^g                 # CH
41862306a36Sopenharmony_ci	rorx	$39, a, y1	# y1 = a >> 39				# S0A
41962306a36Sopenharmony_ci	mov	a, y3		# y3 = a                                # MAJA
42062306a36Sopenharmony_ci
42162306a36Sopenharmony_ci	xor	T1, y1		# y1 = (a>>39) ^ (a>>34)		# S0
42262306a36Sopenharmony_ci	rorx	$28, a, T1	# T1 = (a >> 28)			# S0
42362306a36Sopenharmony_ci	add	frame_XFER(%rsp), h		# h = k + w + h         # --
42462306a36Sopenharmony_ci	or	c, y3		# y3 = a|c                              # MAJA
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci	xor	T1, y1		# y1 = (a>>39) ^ (a>>34) ^ (a>>28)	# S0
42762306a36Sopenharmony_ci	mov	a, T1		# T1 = a                                # MAJB
42862306a36Sopenharmony_ci	and	b, y3		# y3 = (a|c)&b                          # MAJA
42962306a36Sopenharmony_ci	and	c, T1		# T1 = a&c                              # MAJB
43062306a36Sopenharmony_ci	add	y0, y2		# y2 = S1 + CH                          # --
43162306a36Sopenharmony_ci
43262306a36Sopenharmony_ci	add	h, d		# d = k + w + h + d                     # --
43362306a36Sopenharmony_ci	or	T1, y3		# y3 = MAJ = (a|c)&b)|(a&c)             # MAJ
43462306a36Sopenharmony_ci	add	y1, h		# h = k + w + h + S0                    # --
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ci	add	y2, d		# d = k + w + h + d + S1 + CH = d + t1  # --
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci	RotateState
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci################################### RND N + 1 #########################################
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci	add	y2, old_h	# h = k + w + h + S0 + S1 + CH = t1 + S0# --
44362306a36Sopenharmony_ci	mov	f, y2		# y2 = f                                # CH
44462306a36Sopenharmony_ci	rorx	$41, e, y0	# y0 = e >> 41				# S1A
44562306a36Sopenharmony_ci	rorx	$18, e, y1	# y1 = e >> 18				# S1B
44662306a36Sopenharmony_ci	xor	g, y2		# y2 = f^g                              # CH
44762306a36Sopenharmony_ci
44862306a36Sopenharmony_ci	xor	y1, y0		# y0 = (e>>41) ^ (e>>18)		# S1
44962306a36Sopenharmony_ci	rorx	$14, e, y1	# y1 = (e >> 14)			# S1
45062306a36Sopenharmony_ci	and	e, y2		# y2 = (f^g)&e                          # CH
45162306a36Sopenharmony_ci	add	y3, old_h	# h = t1 + S0 + MAJ                     # --
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_ci	xor	y1, y0		# y0 = (e>>41) ^ (e>>18) ^ (e>>14)	# S1
45462306a36Sopenharmony_ci	rorx	$34, a, T1	# T1 = a >> 34				# S0B
45562306a36Sopenharmony_ci	xor	g, y2		# y2 = CH = ((f^g)&e)^g                 # CH
45662306a36Sopenharmony_ci	rorx	$39, a, y1	# y1 = a >> 39				# S0A
45762306a36Sopenharmony_ci	mov	a, y3		# y3 = a                                # MAJA
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_ci	xor	T1, y1		# y1 = (a>>39) ^ (a>>34)		# S0
46062306a36Sopenharmony_ci	rorx	$28, a, T1	# T1 = (a >> 28)			# S0
46162306a36Sopenharmony_ci	add	8*1+frame_XFER(%rsp), h		# h = k + w + h         # --
46262306a36Sopenharmony_ci	or	c, y3		# y3 = a|c                              # MAJA
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci	xor	T1, y1		# y1 = (a>>39) ^ (a>>34) ^ (a>>28)	# S0
46562306a36Sopenharmony_ci	mov	a, T1		# T1 = a                                # MAJB
46662306a36Sopenharmony_ci	and	b, y3		# y3 = (a|c)&b                          # MAJA
46762306a36Sopenharmony_ci	and	c, T1		# T1 = a&c                              # MAJB
46862306a36Sopenharmony_ci	add	y0, y2		# y2 = S1 + CH                          # --
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_ci	add	h, d		# d = k + w + h + d                     # --
47162306a36Sopenharmony_ci	or	T1, y3		# y3 = MAJ = (a|c)&b)|(a&c)             # MAJ
47262306a36Sopenharmony_ci	add	y1, h		# h = k + w + h + S0                    # --
47362306a36Sopenharmony_ci
47462306a36Sopenharmony_ci	add	y2, d		# d = k + w + h + d + S1 + CH = d + t1  # --
47562306a36Sopenharmony_ci
47662306a36Sopenharmony_ci	RotateState
47762306a36Sopenharmony_ci
47862306a36Sopenharmony_ci################################### RND N + 2 #########################################
47962306a36Sopenharmony_ci
48062306a36Sopenharmony_ci	add	y2, old_h	# h = k + w + h + S0 + S1 + CH = t1 + S0# --
48162306a36Sopenharmony_ci	mov	f, y2		# y2 = f                                # CH
48262306a36Sopenharmony_ci	rorx	$41, e, y0	# y0 = e >> 41				# S1A
48362306a36Sopenharmony_ci	rorx	$18, e, y1	# y1 = e >> 18				# S1B
48462306a36Sopenharmony_ci	xor	g, y2		# y2 = f^g                              # CH
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci	xor	y1, y0		# y0 = (e>>41) ^ (e>>18)		# S1
48762306a36Sopenharmony_ci	rorx	$14, e, y1	# y1 = (e >> 14)			# S1
48862306a36Sopenharmony_ci	and	e, y2		# y2 = (f^g)&e                          # CH
48962306a36Sopenharmony_ci	add	y3, old_h	# h = t1 + S0 + MAJ                     # --
49062306a36Sopenharmony_ci
49162306a36Sopenharmony_ci	xor	y1, y0		# y0 = (e>>41) ^ (e>>18) ^ (e>>14)	# S1
49262306a36Sopenharmony_ci	rorx	$34, a, T1	# T1 = a >> 34				# S0B
49362306a36Sopenharmony_ci	xor	g, y2		# y2 = CH = ((f^g)&e)^g                 # CH
49462306a36Sopenharmony_ci	rorx	$39, a, y1	# y1 = a >> 39				# S0A
49562306a36Sopenharmony_ci	mov	a, y3		# y3 = a                                # MAJA
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ci	xor	T1, y1		# y1 = (a>>39) ^ (a>>34)		# S0
49862306a36Sopenharmony_ci	rorx	$28, a, T1	# T1 = (a >> 28)			# S0
49962306a36Sopenharmony_ci	add	8*2+frame_XFER(%rsp), h		# h = k + w + h         # --
50062306a36Sopenharmony_ci	or	c, y3		# y3 = a|c                              # MAJA
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_ci	xor	T1, y1		# y1 = (a>>39) ^ (a>>34) ^ (a>>28)	# S0
50362306a36Sopenharmony_ci	mov	a, T1		# T1 = a                                # MAJB
50462306a36Sopenharmony_ci	and	b, y3		# y3 = (a|c)&b                          # MAJA
50562306a36Sopenharmony_ci	and	c, T1		# T1 = a&c                              # MAJB
50662306a36Sopenharmony_ci	add	y0, y2		# y2 = S1 + CH                          # --
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci	add	h, d		# d = k + w + h + d                     # --
50962306a36Sopenharmony_ci	or	T1, y3		# y3 = MAJ = (a|c)&b)|(a&c)             # MAJ
51062306a36Sopenharmony_ci	add	y1, h		# h = k + w + h + S0                    # --
51162306a36Sopenharmony_ci
51262306a36Sopenharmony_ci	add	y2, d		# d = k + w + h + d + S1 + CH = d + t1  # --
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci	RotateState
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci################################### RND N + 3 #########################################
51762306a36Sopenharmony_ci
51862306a36Sopenharmony_ci	add	y2, old_h	# h = k + w + h + S0 + S1 + CH = t1 + S0# --
51962306a36Sopenharmony_ci	mov	f, y2		# y2 = f                                # CH
52062306a36Sopenharmony_ci	rorx	$41, e, y0	# y0 = e >> 41				# S1A
52162306a36Sopenharmony_ci	rorx	$18, e, y1	# y1 = e >> 18				# S1B
52262306a36Sopenharmony_ci	xor	g, y2		# y2 = f^g                              # CH
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci	xor	y1, y0		# y0 = (e>>41) ^ (e>>18)		# S1
52562306a36Sopenharmony_ci	rorx	$14, e, y1	# y1 = (e >> 14)			# S1
52662306a36Sopenharmony_ci	and	e, y2		# y2 = (f^g)&e                          # CH
52762306a36Sopenharmony_ci	add	y3, old_h	# h = t1 + S0 + MAJ                     # --
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_ci	xor	y1, y0		# y0 = (e>>41) ^ (e>>18) ^ (e>>14)	# S1
53062306a36Sopenharmony_ci	rorx	$34, a, T1	# T1 = a >> 34				# S0B
53162306a36Sopenharmony_ci	xor	g, y2		# y2 = CH = ((f^g)&e)^g                 # CH
53262306a36Sopenharmony_ci	rorx	$39, a, y1	# y1 = a >> 39				# S0A
53362306a36Sopenharmony_ci	mov	a, y3		# y3 = a                                # MAJA
53462306a36Sopenharmony_ci
53562306a36Sopenharmony_ci	xor	T1, y1		# y1 = (a>>39) ^ (a>>34)		# S0
53662306a36Sopenharmony_ci	rorx	$28, a, T1	# T1 = (a >> 28)			# S0
53762306a36Sopenharmony_ci	add	8*3+frame_XFER(%rsp), h		# h = k + w + h         # --
53862306a36Sopenharmony_ci	or	c, y3		# y3 = a|c                              # MAJA
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	xor	T1, y1		# y1 = (a>>39) ^ (a>>34) ^ (a>>28)	# S0
54162306a36Sopenharmony_ci	mov	a, T1		# T1 = a                                # MAJB
54262306a36Sopenharmony_ci	and	b, y3		# y3 = (a|c)&b                          # MAJA
54362306a36Sopenharmony_ci	and	c, T1		# T1 = a&c                              # MAJB
54462306a36Sopenharmony_ci	add	y0, y2		# y2 = S1 + CH                          # --
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci
54762306a36Sopenharmony_ci	add	h, d		# d = k + w + h + d                     # --
54862306a36Sopenharmony_ci	or	T1, y3		# y3 = MAJ = (a|c)&b)|(a&c)             # MAJ
54962306a36Sopenharmony_ci	add	y1, h		# h = k + w + h + S0                    # --
55062306a36Sopenharmony_ci
55162306a36Sopenharmony_ci	add	y2, d		# d = k + w + h + d + S1 + CH = d + t1  # --
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci	add	y2, h		# h = k + w + h + S0 + S1 + CH = t1 + S0# --
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_ci	add	y3, h		# h = t1 + S0 + MAJ                     # --
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci	RotateState
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_ci.endm
56062306a36Sopenharmony_ci
56162306a36Sopenharmony_ci########################################################################
56262306a36Sopenharmony_ci# void sha512_transform_rorx(sha512_state *state, const u8 *data, int blocks)
56362306a36Sopenharmony_ci# Purpose: Updates the SHA512 digest stored at "state" with the message
56462306a36Sopenharmony_ci# stored in "data".
56562306a36Sopenharmony_ci# The size of the message pointed to by "data" must be an integer multiple
56662306a36Sopenharmony_ci# of SHA512 message blocks.
56762306a36Sopenharmony_ci# "blocks" is the message length in SHA512 blocks
56862306a36Sopenharmony_ci########################################################################
56962306a36Sopenharmony_ciSYM_TYPED_FUNC_START(sha512_transform_rorx)
57062306a36Sopenharmony_ci	# Save GPRs
57162306a36Sopenharmony_ci	push	%rbx
57262306a36Sopenharmony_ci	push	%r12
57362306a36Sopenharmony_ci	push	%r13
57462306a36Sopenharmony_ci	push	%r14
57562306a36Sopenharmony_ci	push	%r15
57662306a36Sopenharmony_ci
57762306a36Sopenharmony_ci	# Allocate Stack Space
57862306a36Sopenharmony_ci	push	%rbp
57962306a36Sopenharmony_ci	mov	%rsp, %rbp
58062306a36Sopenharmony_ci	sub	$frame_size, %rsp
58162306a36Sopenharmony_ci	and	$~(0x20 - 1), %rsp
58262306a36Sopenharmony_ci
58362306a36Sopenharmony_ci	shl	$7, NUM_BLKS	# convert to bytes
58462306a36Sopenharmony_ci	jz	.Ldone_hash
58562306a36Sopenharmony_ci	add	INP, NUM_BLKS	# pointer to end of data
58662306a36Sopenharmony_ci	mov	NUM_BLKS, frame_INPEND(%rsp)
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ci	## load initial digest
58962306a36Sopenharmony_ci	mov	8*0(CTX1), a
59062306a36Sopenharmony_ci	mov	8*1(CTX1), b
59162306a36Sopenharmony_ci	mov	8*2(CTX1), c
59262306a36Sopenharmony_ci	mov	8*3(CTX1), d
59362306a36Sopenharmony_ci	mov	8*4(CTX1), e
59462306a36Sopenharmony_ci	mov	8*5(CTX1), f
59562306a36Sopenharmony_ci	mov	8*6(CTX1), g
59662306a36Sopenharmony_ci	mov	8*7(CTX1), h
59762306a36Sopenharmony_ci
59862306a36Sopenharmony_ci	# save %rdi (CTX) before it gets clobbered
59962306a36Sopenharmony_ci	mov	%rdi, frame_CTX(%rsp)
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_ci	vmovdqa	PSHUFFLE_BYTE_FLIP_MASK(%rip), BYTE_FLIP_MASK
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ci.Lloop0:
60462306a36Sopenharmony_ci	lea	K512(%rip), TBL
60562306a36Sopenharmony_ci
60662306a36Sopenharmony_ci	## byte swap first 16 dwords
60762306a36Sopenharmony_ci	COPY_YMM_AND_BSWAP	Y_0, (INP), BYTE_FLIP_MASK
60862306a36Sopenharmony_ci	COPY_YMM_AND_BSWAP	Y_1, 1*32(INP), BYTE_FLIP_MASK
60962306a36Sopenharmony_ci	COPY_YMM_AND_BSWAP	Y_2, 2*32(INP), BYTE_FLIP_MASK
61062306a36Sopenharmony_ci	COPY_YMM_AND_BSWAP	Y_3, 3*32(INP), BYTE_FLIP_MASK
61162306a36Sopenharmony_ci
61262306a36Sopenharmony_ci	mov	INP, frame_INP(%rsp)
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_ci	## schedule 64 input dwords, by doing 12 rounds of 4 each
61562306a36Sopenharmony_ci	movq	$4, frame_SRND(%rsp)
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci.align 16
61862306a36Sopenharmony_ci.Lloop1:
61962306a36Sopenharmony_ci	vpaddq	(TBL), Y_0, XFER
62062306a36Sopenharmony_ci	vmovdqa XFER, frame_XFER(%rsp)
62162306a36Sopenharmony_ci	FOUR_ROUNDS_AND_SCHED
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci	vpaddq	1*32(TBL), Y_0, XFER
62462306a36Sopenharmony_ci	vmovdqa XFER, frame_XFER(%rsp)
62562306a36Sopenharmony_ci	FOUR_ROUNDS_AND_SCHED
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_ci	vpaddq	2*32(TBL), Y_0, XFER
62862306a36Sopenharmony_ci	vmovdqa XFER, frame_XFER(%rsp)
62962306a36Sopenharmony_ci	FOUR_ROUNDS_AND_SCHED
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_ci	vpaddq	3*32(TBL), Y_0, XFER
63262306a36Sopenharmony_ci	vmovdqa XFER, frame_XFER(%rsp)
63362306a36Sopenharmony_ci	add	$(4*32), TBL
63462306a36Sopenharmony_ci	FOUR_ROUNDS_AND_SCHED
63562306a36Sopenharmony_ci
63662306a36Sopenharmony_ci	subq	$1, frame_SRND(%rsp)
63762306a36Sopenharmony_ci	jne	.Lloop1
63862306a36Sopenharmony_ci
63962306a36Sopenharmony_ci	movq	$2, frame_SRND(%rsp)
64062306a36Sopenharmony_ci.Lloop2:
64162306a36Sopenharmony_ci	vpaddq	(TBL), Y_0, XFER
64262306a36Sopenharmony_ci	vmovdqa XFER, frame_XFER(%rsp)
64362306a36Sopenharmony_ci	DO_4ROUNDS
64462306a36Sopenharmony_ci	vpaddq	1*32(TBL), Y_1, XFER
64562306a36Sopenharmony_ci	vmovdqa XFER, frame_XFER(%rsp)
64662306a36Sopenharmony_ci	add	$(2*32), TBL
64762306a36Sopenharmony_ci	DO_4ROUNDS
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci	vmovdqa	Y_2, Y_0
65062306a36Sopenharmony_ci	vmovdqa	Y_3, Y_1
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_ci	subq	$1, frame_SRND(%rsp)
65362306a36Sopenharmony_ci	jne	.Lloop2
65462306a36Sopenharmony_ci
65562306a36Sopenharmony_ci	mov	frame_CTX(%rsp), CTX2
65662306a36Sopenharmony_ci	addm	8*0(CTX2), a
65762306a36Sopenharmony_ci	addm	8*1(CTX2), b
65862306a36Sopenharmony_ci	addm	8*2(CTX2), c
65962306a36Sopenharmony_ci	addm	8*3(CTX2), d
66062306a36Sopenharmony_ci	addm	8*4(CTX2), e
66162306a36Sopenharmony_ci	addm	8*5(CTX2), f
66262306a36Sopenharmony_ci	addm	8*6(CTX2), g
66362306a36Sopenharmony_ci	addm	8*7(CTX2), h
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci	mov	frame_INP(%rsp), INP
66662306a36Sopenharmony_ci	add	$128, INP
66762306a36Sopenharmony_ci	cmp	frame_INPEND(%rsp), INP
66862306a36Sopenharmony_ci	jne	.Lloop0
66962306a36Sopenharmony_ci
67062306a36Sopenharmony_ci.Ldone_hash:
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci	# Restore Stack Pointer
67362306a36Sopenharmony_ci	mov	%rbp, %rsp
67462306a36Sopenharmony_ci	pop	%rbp
67562306a36Sopenharmony_ci
67662306a36Sopenharmony_ci	# Restore GPRs
67762306a36Sopenharmony_ci	pop	%r15
67862306a36Sopenharmony_ci	pop	%r14
67962306a36Sopenharmony_ci	pop	%r13
68062306a36Sopenharmony_ci	pop	%r12
68162306a36Sopenharmony_ci	pop	%rbx
68262306a36Sopenharmony_ci
68362306a36Sopenharmony_ci	RET
68462306a36Sopenharmony_ciSYM_FUNC_END(sha512_transform_rorx)
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_ci########################################################################
68762306a36Sopenharmony_ci### Binary Data
68862306a36Sopenharmony_ci
68962306a36Sopenharmony_ci
69062306a36Sopenharmony_ci# Mergeable 640-byte rodata section. This allows linker to merge the table
69162306a36Sopenharmony_ci# with other, exactly the same 640-byte fragment of another rodata section
69262306a36Sopenharmony_ci# (if such section exists).
69362306a36Sopenharmony_ci.section	.rodata.cst640.K512, "aM", @progbits, 640
69462306a36Sopenharmony_ci.align 64
69562306a36Sopenharmony_ci# K[t] used in SHA512 hashing
69662306a36Sopenharmony_ciK512:
69762306a36Sopenharmony_ci	.quad	0x428a2f98d728ae22,0x7137449123ef65cd
69862306a36Sopenharmony_ci	.quad	0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
69962306a36Sopenharmony_ci	.quad	0x3956c25bf348b538,0x59f111f1b605d019
70062306a36Sopenharmony_ci	.quad	0x923f82a4af194f9b,0xab1c5ed5da6d8118
70162306a36Sopenharmony_ci	.quad	0xd807aa98a3030242,0x12835b0145706fbe
70262306a36Sopenharmony_ci	.quad	0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
70362306a36Sopenharmony_ci	.quad	0x72be5d74f27b896f,0x80deb1fe3b1696b1
70462306a36Sopenharmony_ci	.quad	0x9bdc06a725c71235,0xc19bf174cf692694
70562306a36Sopenharmony_ci	.quad	0xe49b69c19ef14ad2,0xefbe4786384f25e3
70662306a36Sopenharmony_ci	.quad	0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
70762306a36Sopenharmony_ci	.quad	0x2de92c6f592b0275,0x4a7484aa6ea6e483
70862306a36Sopenharmony_ci	.quad	0x5cb0a9dcbd41fbd4,0x76f988da831153b5
70962306a36Sopenharmony_ci	.quad	0x983e5152ee66dfab,0xa831c66d2db43210
71062306a36Sopenharmony_ci	.quad	0xb00327c898fb213f,0xbf597fc7beef0ee4
71162306a36Sopenharmony_ci	.quad	0xc6e00bf33da88fc2,0xd5a79147930aa725
71262306a36Sopenharmony_ci	.quad	0x06ca6351e003826f,0x142929670a0e6e70
71362306a36Sopenharmony_ci	.quad	0x27b70a8546d22ffc,0x2e1b21385c26c926
71462306a36Sopenharmony_ci	.quad	0x4d2c6dfc5ac42aed,0x53380d139d95b3df
71562306a36Sopenharmony_ci	.quad	0x650a73548baf63de,0x766a0abb3c77b2a8
71662306a36Sopenharmony_ci	.quad	0x81c2c92e47edaee6,0x92722c851482353b
71762306a36Sopenharmony_ci	.quad	0xa2bfe8a14cf10364,0xa81a664bbc423001
71862306a36Sopenharmony_ci	.quad	0xc24b8b70d0f89791,0xc76c51a30654be30
71962306a36Sopenharmony_ci	.quad	0xd192e819d6ef5218,0xd69906245565a910
72062306a36Sopenharmony_ci	.quad	0xf40e35855771202a,0x106aa07032bbd1b8
72162306a36Sopenharmony_ci	.quad	0x19a4c116b8d2d0c8,0x1e376c085141ab53
72262306a36Sopenharmony_ci	.quad	0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
72362306a36Sopenharmony_ci	.quad	0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
72462306a36Sopenharmony_ci	.quad	0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
72562306a36Sopenharmony_ci	.quad	0x748f82ee5defb2fc,0x78a5636f43172f60
72662306a36Sopenharmony_ci	.quad	0x84c87814a1f0ab72,0x8cc702081a6439ec
72762306a36Sopenharmony_ci	.quad	0x90befffa23631e28,0xa4506cebde82bde9
72862306a36Sopenharmony_ci	.quad	0xbef9a3f7b2c67915,0xc67178f2e372532b
72962306a36Sopenharmony_ci	.quad	0xca273eceea26619c,0xd186b8c721c0c207
73062306a36Sopenharmony_ci	.quad	0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
73162306a36Sopenharmony_ci	.quad	0x06f067aa72176fba,0x0a637dc5a2c898a6
73262306a36Sopenharmony_ci	.quad	0x113f9804bef90dae,0x1b710b35131c471b
73362306a36Sopenharmony_ci	.quad	0x28db77f523047d84,0x32caab7b40c72493
73462306a36Sopenharmony_ci	.quad	0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
73562306a36Sopenharmony_ci	.quad	0x4cc5d4becb3e42b6,0x597f299cfc657e2a
73662306a36Sopenharmony_ci	.quad	0x5fcb6fab3ad6faec,0x6c44198c4a475817
73762306a36Sopenharmony_ci
73862306a36Sopenharmony_ci.section	.rodata.cst32.PSHUFFLE_BYTE_FLIP_MASK, "aM", @progbits, 32
73962306a36Sopenharmony_ci.align 32
74062306a36Sopenharmony_ci# Mask for byte-swapping a couple of qwords in an XMM register using (v)pshufb.
74162306a36Sopenharmony_ciPSHUFFLE_BYTE_FLIP_MASK:
74262306a36Sopenharmony_ci	.octa 0x08090a0b0c0d0e0f0001020304050607
74362306a36Sopenharmony_ci	.octa 0x18191a1b1c1d1e1f1011121314151617
74462306a36Sopenharmony_ci
74562306a36Sopenharmony_ci.section	.rodata.cst32.MASK_YMM_LO, "aM", @progbits, 32
74662306a36Sopenharmony_ci.align 32
74762306a36Sopenharmony_ciMASK_YMM_LO:
74862306a36Sopenharmony_ci	.octa 0x00000000000000000000000000000000
74962306a36Sopenharmony_ci	.octa 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
750