/* assembly to compute the key powers */

#include "crypto_asm_hidden.h"
// linker define poly1305_maa44_g4_key
// linker define poly1305_maa44_g4_keypowers
// linker use mask44
// linker use mask42
// linker use pmask1
// linker use pmask2
// linker use pmask3
// linker use pmask4

#define mask44  CRYPTO_SHARED_NAMESPACE(mask44)
#define mask42  CRYPTO_SHARED_NAMESPACE(mask42)
#define pmask1  CRYPTO_SHARED_NAMESPACE(pmask1)
#define pmask2  CRYPTO_SHARED_NAMESPACE(pmask2)
#define pmask3  CRYPTO_SHARED_NAMESPACE(pmask3)
#define pmask4  CRYPTO_SHARED_NAMESPACE(pmask4)

#include "poly1305_keypowers_asm.h"

	.p2align 5
	
ASM_HIDDEN _CRYPTO_SHARED_NAMESPACE(poly1305_maa44_g4_key)
ASM_HIDDEN CRYPTO_SHARED_NAMESPACE(poly1305_maa44_g4_key)
.global _CRYPTO_SHARED_NAMESPACE(poly1305_maa44_g4_key)
.global CRYPTO_SHARED_NAMESPACE(poly1305_maa44_g4_key)
_CRYPTO_SHARED_NAMESPACE(poly1305_maa44_g4_key):
CRYPTO_SHARED_NAMESPACE(poly1305_maa44_g4_key):

	/* key */
	movq    0(%rdi),%r8
	movq    8(%rdi),%r9
	
	/* tau */
	movq    %r8,%r10
	andq    pmask1(%rip),%r8
	movq    %r9,%rax
	andq    pmask2(%rip),%r10
	shrq    $44,%r10
	andq    pmask3(%rip),%r9
	shlq    $20,%r9
	orq     %r10,%r9
	andq    pmask4(%rip),%rax
	shrq    $24,%rax

	movq    %r8,0(%rdi)
	movq    %r9,8(%rdi)
	movq    %rax,16(%rdi)

	ret

		
	.p2align 5
	
ASM_HIDDEN _CRYPTO_SHARED_NAMESPACE(poly1305_maa44_g4_keypowers)
ASM_HIDDEN CRYPTO_SHARED_NAMESPACE(poly1305_maa44_g4_keypowers)
.global _CRYPTO_SHARED_NAMESPACE(poly1305_maa44_g4_keypowers)
.global CRYPTO_SHARED_NAMESPACE(poly1305_maa44_g4_keypowers)
_CRYPTO_SHARED_NAMESPACE(poly1305_maa44_g4_keypowers):
CRYPTO_SHARED_NAMESPACE(poly1305_maa44_g4_keypowers):
	
	movq 	%rsp,%r11
	andq    $-32,%rsp
	subq 	$64,%rsp

	movq 	%r11,0(%rsp)
	movq 	%r12,8(%rsp)
	movq 	%r13,16(%rsp)
	movq 	%r14,24(%rsp)
	movq 	%r15,32(%rsp)
	movq 	%rbx,40(%rsp)
	movq 	%rbp,48(%rsp)

	/* tau = key */
	movq    0(%rdi),%r14
	movq    8(%rdi),%r15
	movq    16(%rdi),%rbx	
		
	cmp	$3,%rsi
	jl	.L2	
	
	/* tau^2 */	
	fe1305_tau_squaren(1)
	
	cmp	$3,%rsi
	je	.L2
	
	cmp	$4,%rsi
	je	.L1

	/* tau^4 */	
	fe1305_tau_squaren(3)
	
.L1:	
	/* tau^3 */
	fe1305_mul_tau_taun(1,2)

.L2:
	movq 	0(%rsp),%r11
	movq 	8(%rsp),%r12
	movq 	16(%rsp),%r13
	movq 	24(%rsp),%r14
	movq 	32(%rsp),%r15
	movq 	40(%rsp),%rbx
	movq 	48(%rsp),%rbp

	movq 	%r11,%rsp

	ret
