Blame crypto/chacha/asm/chacha-c64xplus.pl

Packit Service 084de1
#! /usr/bin/env perl
Packit Service 084de1
# Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
Packit Service 084de1
#
Packit Service 084de1
# Licensed under the OpenSSL license (the "License").  You may not use
Packit Service 084de1
# this file except in compliance with the License.  You can obtain a copy
Packit Service 084de1
# in the file LICENSE in the source distribution or at
Packit Service 084de1
# https://www.openssl.org/source/license.html
Packit Service 084de1
Packit Service 084de1
#
Packit Service 084de1
# ====================================================================
Packit Service 084de1
# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
Packit Service 084de1
# project. The module is, however, dual licensed under OpenSSL and
Packit Service 084de1
# CRYPTOGAMS licenses depending on where you obtain it. For further
Packit Service 084de1
# details see http://www.openssl.org/~appro/cryptogams/.
Packit Service 084de1
# ====================================================================
Packit Service 084de1
#
Packit Service 084de1
# ChaCha20 for C64x+.
Packit Service 084de1
#
Packit Service 084de1
# October 2015
Packit Service 084de1
#
Packit Service 084de1
# Performance is 3.54 cycles per processed byte, which is ~4.3 times
Packit Service 084de1
# faster than code generated by TI compiler. Compiler also disables
Packit Service 084de1
# interrupts for some reason, thus making interrupt response time
Packit Service 084de1
# dependent on input length. This module on the other hand is free
Packit Service 084de1
# from such limitation.
Packit Service 084de1
Packit Service 084de1
$output=pop;
Packit Service 084de1
open STDOUT,">$output";
Packit Service 084de1
Packit Service 084de1
($OUT,$INP,$LEN,$KEYB,$COUNTERA)=("A4","B4","A6","B6","A8");
Packit Service 084de1
($KEYA,$COUNTERB,$STEP)=("A7","B7","A3");
Packit Service 084de1
Packit Service 084de1
@X=  ("A16","B16","A17","B17","A18","B18","A19","B19",
Packit Service 084de1
      "A20","B20","A21","B21","A22","B22","A23","B23");
Packit Service 084de1
@Y=  ("A24","B24","A25","B25","A26","B26","A27","B27",
Packit Service 084de1
      "A28","B28","A29","B29","A30","B30","A31","B31");
Packit Service 084de1
@DAT=("A6", "A7", "B6", "B7", "A8", "A9", "B8", "B9",
Packit Service 084de1
      "A10","A11","B10","B11","A12","A13","B12","B13");
Packit Service 084de1
Packit Service 084de1
# yes, overlaps with @DAT, used only in 2x interleave code path...
Packit Service 084de1
@K2x=("A6", "B6", "A7", "B7", "A8", "B8", "A9", "B9",
Packit Service 084de1
      "A10","B10","A11","B11","A2", "B2", "A13","B13");
Packit Service 084de1
Packit Service 084de1
$code.=<<___;
Packit Service 084de1
	.text
Packit Service 084de1
Packit Service 084de1
	.if	.ASSEMBLER_VERSION<7000000
Packit Service 084de1
	.asg	0,__TI_EABI__
Packit Service 084de1
	.endif
Packit Service 084de1
	.if	__TI_EABI__
Packit Service 084de1
	.asg	ChaCha20_ctr32,_ChaCha20_ctr32
Packit Service 084de1
	.endif
Packit Service 084de1
Packit Service 084de1
	.asg	B3,RA
Packit Service 084de1
	.asg	A15,FP
Packit Service 084de1
	.asg	B15,SP
Packit Service 084de1
Packit Service 084de1
	.global	_ChaCha20_ctr32
Packit Service 084de1
	.align	32
Packit Service 084de1
_ChaCha20_ctr32:
Packit Service 084de1
	.asmfunc	stack_usage(40+64)
Packit Service 084de1
	MV	$LEN,A0			; reassign
Packit Service 084de1
  [!A0]	BNOP	RA			; no data
Packit Service 084de1
|| [A0]	STW	FP,*SP--(40+64)		; save frame pointer and alloca(40+64)
Packit Service 084de1
|| [A0]	MV	SP,FP
Packit Service 084de1
   [A0]	STDW	B13:B12,*SP[4+8]	; ABI says so
Packit Service 084de1
|| [A0]	MV	$KEYB,$KEYA
Packit Service 084de1
|| [A0]	MV	$COUNTERA,$COUNTERB
Packit Service 084de1
   [A0]	STDW	B11:B10,*SP[3+8]
Packit Service 084de1
|| [A0]	STDW	A13:A12,*FP[-3]
Packit Service 084de1
   [A0]	STDW	A11:A10,*FP[-4]
Packit Service 084de1
|| [A0]	MVK	128,$STEP		; 2 * input block size
Packit Service 084de1
Packit Service 084de1
   [A0]	LDW	*${KEYA}[0],@Y[4]	; load key
Packit Service 084de1
|| [A0]	LDW	*${KEYB}[1],@Y[5]
Packit Service 084de1
|| [A0]	MVK	0x00007865,@Y[0]	; synthesize sigma
Packit Service 084de1
|| [A0]	MVK	0x0000646e,@Y[1]
Packit Service 084de1
   [A0]	LDW	*${KEYA}[2],@Y[6]
Packit Service 084de1
|| [A0]	LDW	*${KEYB}[3],@Y[7]
Packit Service 084de1
|| [A0]	MVKH	0x61700000,@Y[0]
Packit Service 084de1
|| [A0]	MVKH	0x33200000,@Y[1]
Packit Service 084de1
	LDW	*${KEYA}[4],@Y[8]
Packit Service 084de1
||	LDW	*${KEYB}[5],@Y[9]
Packit Service 084de1
||	MVK	0x00002d32,@Y[2]
Packit Service 084de1
||	MVK	0x00006574,@Y[3]
Packit Service 084de1
	LDW	*${KEYA}[6],@Y[10]
Packit Service 084de1
||	LDW	*${KEYB}[7],@Y[11]
Packit Service 084de1
||	MVKH	0x79620000,@Y[2]
Packit Service 084de1
||	MVKH	0x6b200000,@Y[3]
Packit Service 084de1
	LDW	*${COUNTERA}[0],@Y[12]	; load counter||nonce
Packit Service 084de1
||	LDW	*${COUNTERB}[1],@Y[13]
Packit Service 084de1
||	CMPLTU	A0,$STEP,A1		; is length < 2*blocks?
Packit Service 084de1
	LDW	*${COUNTERA}[2],@Y[14]
Packit Service 084de1
||	LDW	*${COUNTERB}[3],@Y[15]
Packit Service 084de1
|| [A1]	BNOP	top1x?
Packit Service 084de1
   [A1]	MVK	64,$STEP		; input block size
Packit Service 084de1
||	MVK	10,B0			; inner loop counter
Packit Service 084de1
Packit Service 084de1
	DMV	@Y[2],@Y[0],@X[2]:@X[0]	; copy block
Packit Service 084de1
||	DMV	@Y[3],@Y[1],@X[3]:@X[1]
Packit Service 084de1
||[!A1]	STDW	@Y[2]:@Y[0],*FP[-12]	; offload key material to stack
Packit Service 084de1
||[!A1]	STDW	@Y[3]:@Y[1],*SP[2]
Packit Service 084de1
	DMV	@Y[6],@Y[4],@X[6]:@X[4]
Packit Service 084de1
||	DMV	@Y[7],@Y[5],@X[7]:@X[5]
Packit Service 084de1
||[!A1]	STDW	@Y[6]:@Y[4],*FP[-10]
Packit Service 084de1
||[!A1]	STDW	@Y[7]:@Y[5],*SP[4]
Packit Service 084de1
	DMV	@Y[10],@Y[8],@X[10]:@X[8]
Packit Service 084de1
||	DMV	@Y[11],@Y[9],@X[11]:@X[9]
Packit Service 084de1
||[!A1]	STDW	@Y[10]:@Y[8],*FP[-8]
Packit Service 084de1
||[!A1]	STDW	@Y[11]:@Y[9],*SP[6]
Packit Service 084de1
	DMV	@Y[14],@Y[12],@X[14]:@X[12]
Packit Service 084de1
||	DMV	@Y[15],@Y[13],@X[15]:@X[13]
Packit Service 084de1
||[!A1]	MV	@Y[12],@K2x[12]		; counter
Packit Service 084de1
||[!A1]	MV	@Y[13],@K2x[13]
Packit Service 084de1
||[!A1]	STW	@Y[14],*FP[-6*2]
Packit Service 084de1
||[!A1]	STW	@Y[15],*SP[8*2]
Packit Service 084de1
___
Packit Service 084de1
{	################################################################
Packit Service 084de1
	# 2x interleave gives 50% performance improvement
Packit Service 084de1
	#
Packit Service 084de1
my ($a0,$a1,$a2,$a3) = (0..3);
Packit Service 084de1
my ($b0,$b1,$b2,$b3) = (4..7);
Packit Service 084de1
my ($c0,$c1,$c2,$c3) = (8..11);
Packit Service 084de1
my ($d0,$d1,$d2,$d3) = (12..15);
Packit Service 084de1
Packit Service 084de1
$code.=<<___;
Packit Service 084de1
outer2x?:
Packit Service 084de1
	ADD	@X[$b1],@X[$a1],@X[$a1]
Packit Service 084de1
||	ADD	@X[$b2],@X[$a2],@X[$a2]
Packit Service 084de1
||	ADD	@X[$b0],@X[$a0],@X[$a0]
Packit Service 084de1
||	ADD	@X[$b3],@X[$a3],@X[$a3]
Packit Service 084de1
||	 DMV	@Y[2],@Y[0],@K2x[2]:@K2x[0]
Packit Service 084de1
||	 DMV	@Y[3],@Y[1],@K2x[3]:@K2x[1]
Packit Service 084de1
	XOR	@X[$a1],@X[$d1],@X[$d1]
Packit Service 084de1
||	XOR	@X[$a2],@X[$d2],@X[$d2]
Packit Service 084de1
||	XOR	@X[$a0],@X[$d0],@X[$d0]
Packit Service 084de1
||	XOR	@X[$a3],@X[$d3],@X[$d3]
Packit Service 084de1
||	 DMV	@Y[6],@Y[4],@K2x[6]:@K2x[4]
Packit Service 084de1
||	 DMV	@Y[7],@Y[5],@K2x[7]:@K2x[5]
Packit Service 084de1
	SWAP2	@X[$d1],@X[$d1]		; rotate by 16
Packit Service 084de1
||	SWAP2	@X[$d2],@X[$d2]
Packit Service 084de1
||	SWAP2	@X[$d0],@X[$d0]
Packit Service 084de1
||	SWAP2	@X[$d3],@X[$d3]
Packit Service 084de1
Packit Service 084de1
	ADD	@X[$d1],@X[$c1],@X[$c1]
Packit Service 084de1
||	ADD	@X[$d2],@X[$c2],@X[$c2]
Packit Service 084de1
||	ADD	@X[$d0],@X[$c0],@X[$c0]
Packit Service 084de1
||	ADD	@X[$d3],@X[$c3],@X[$c3]
Packit Service 084de1
||	 DMV	@Y[10],@Y[8],@K2x[10]:@K2x[8]
Packit Service 084de1
||	 DMV	@Y[11],@Y[9],@K2x[11]:@K2x[9]
Packit Service 084de1
	XOR	@X[$c1],@X[$b1],@X[$b1]
Packit Service 084de1
||	XOR	@X[$c2],@X[$b2],@X[$b2]
Packit Service 084de1
||	XOR	@X[$c0],@X[$b0],@X[$b0]
Packit Service 084de1
||	XOR	@X[$c3],@X[$b3],@X[$b3]
Packit Service 084de1
||	 ADD	1,@Y[12],@Y[12]		; adjust counter for 2nd block
Packit Service 084de1
	ROTL	@X[$b1],12,@X[$b1]
Packit Service 084de1
||	ROTL	@X[$b2],12,@X[$b2]
Packit Service 084de1
||	 MV	@Y[14],@K2x[14]
Packit Service 084de1
||	 MV	@Y[15],@K2x[15]
Packit Service 084de1
top2x?:
Packit Service 084de1
	ROTL	@X[$b0],12,@X[$b0]
Packit Service 084de1
||	ROTL	@X[$b3],12,@X[$b3]
Packit Service 084de1
||	 ADD	@Y[$b1],@Y[$a1],@Y[$a1]
Packit Service 084de1
||	 ADD	@Y[$b2],@Y[$a2],@Y[$a2]
Packit Service 084de1
	 ADD	@Y[$b0],@Y[$a0],@Y[$a0]
Packit Service 084de1
||	 ADD	@Y[$b3],@Y[$a3],@Y[$a3]
Packit Service 084de1
Packit Service 084de1
||	ADD	@X[$b1],@X[$a1],@X[$a1]
Packit Service 084de1
||	ADD	@X[$b2],@X[$a2],@X[$a2]
Packit Service 084de1
||	 XOR	@Y[$a1],@Y[$d1],@Y[$d1]
Packit Service 084de1
||	 XOR	@Y[$a2],@Y[$d2],@Y[$d2]
Packit Service 084de1
	 XOR	@Y[$a0],@Y[$d0],@Y[$d0]
Packit Service 084de1
||	 XOR	@Y[$a3],@Y[$d3],@Y[$d3]
Packit Service 084de1
||	ADD	@X[$b0],@X[$a0],@X[$a0]
Packit Service 084de1
||	ADD	@X[$b3],@X[$a3],@X[$a3]
Packit Service 084de1
||	XOR	@X[$a1],@X[$d1],@X[$d1]
Packit Service 084de1
||	XOR	@X[$a2],@X[$d2],@X[$d2]
Packit Service 084de1
	XOR	@X[$a0],@X[$d0],@X[$d0]
Packit Service 084de1
||	XOR	@X[$a3],@X[$d3],@X[$d3]
Packit Service 084de1
||	ROTL	@X[$d1],8,@X[$d1]
Packit Service 084de1
||	ROTL	@X[$d2],8,@X[$d2]
Packit Service 084de1
||	 SWAP2	@Y[$d1],@Y[$d1]		; rotate by 16
Packit Service 084de1
||	 SWAP2	@Y[$d2],@Y[$d2]
Packit Service 084de1
||	 SWAP2	@Y[$d0],@Y[$d0]
Packit Service 084de1
||	 SWAP2	@Y[$d3],@Y[$d3]
Packit Service 084de1
	ROTL	@X[$d0],8,@X[$d0]
Packit Service 084de1
||	ROTL	@X[$d3],8,@X[$d3]
Packit Service 084de1
||	 ADD	@Y[$d1],@Y[$c1],@Y[$c1]
Packit Service 084de1
||	 ADD	@Y[$d2],@Y[$c2],@Y[$c2]
Packit Service 084de1
||	 ADD	@Y[$d0],@Y[$c0],@Y[$c0]
Packit Service 084de1
||	 ADD	@Y[$d3],@Y[$c3],@Y[$c3]
Packit Service 084de1
||	BNOP	middle2x1?		; protect from interrupt
Packit Service 084de1
Packit Service 084de1
	ADD	@X[$d1],@X[$c1],@X[$c1]
Packit Service 084de1
||	ADD	@X[$d2],@X[$c2],@X[$c2]
Packit Service 084de1
||	 XOR	@Y[$c1],@Y[$b1],@Y[$b1]
Packit Service 084de1
||	 XOR	@Y[$c2],@Y[$b2],@Y[$b2]
Packit Service 084de1
||	 XOR	@Y[$c0],@Y[$b0],@Y[$b0]
Packit Service 084de1
||	 XOR	@Y[$c3],@Y[$b3],@Y[$b3]
Packit Service 084de1
	ADD	@X[$d0],@X[$c0],@X[$c0]
Packit Service 084de1
||	ADD	@X[$d3],@X[$c3],@X[$c3]
Packit Service 084de1
||	XOR	@X[$c1],@X[$b1],@X[$b1]
Packit Service 084de1
||	XOR	@X[$c2],@X[$b2],@X[$b2]
Packit Service 084de1
||	ROTL	@X[$d1],0,@X[$d2]	; moved to avoid cross-path stall
Packit Service 084de1
||	ROTL	@X[$d2],0,@X[$d3]
Packit Service 084de1
	XOR	@X[$c0],@X[$b0],@X[$b0]
Packit Service 084de1
||	XOR	@X[$c3],@X[$b3],@X[$b3]
Packit Service 084de1
||	MV	@X[$d0],@X[$d1]
Packit Service 084de1
||	MV	@X[$d3],@X[$d0]
Packit Service 084de1
||	 ROTL	@Y[$b1],12,@Y[$b1]
Packit Service 084de1
||	 ROTL	@Y[$b2],12,@Y[$b2]
Packit Service 084de1
	ROTL	@X[$b1],7,@X[$b0]	; avoided cross-path stall
Packit Service 084de1
||	ROTL	@X[$b2],7,@X[$b1]
Packit Service 084de1
	ROTL	@X[$b0],7,@X[$b3]
Packit Service 084de1
||	ROTL	@X[$b3],7,@X[$b2]
Packit Service 084de1
middle2x1?:
Packit Service 084de1
Packit Service 084de1
	 ROTL	@Y[$b0],12,@Y[$b0]
Packit Service 084de1
||	 ROTL	@Y[$b3],12,@Y[$b3]
Packit Service 084de1
||	ADD	@X[$b0],@X[$a0],@X[$a0]
Packit Service 084de1
||	ADD	@X[$b1],@X[$a1],@X[$a1]
Packit Service 084de1
	ADD	@X[$b2],@X[$a2],@X[$a2]
Packit Service 084de1
||	ADD	@X[$b3],@X[$a3],@X[$a3]
Packit Service 084de1
Packit Service 084de1
||	 ADD	@Y[$b1],@Y[$a1],@Y[$a1]
Packit Service 084de1
||	 ADD	@Y[$b2],@Y[$a2],@Y[$a2]
Packit Service 084de1
||	XOR	@X[$a0],@X[$d0],@X[$d0]
Packit Service 084de1
||	XOR	@X[$a1],@X[$d1],@X[$d1]
Packit Service 084de1
	XOR	@X[$a2],@X[$d2],@X[$d2]
Packit Service 084de1
||	XOR	@X[$a3],@X[$d3],@X[$d3]
Packit Service 084de1
||	 ADD	@Y[$b0],@Y[$a0],@Y[$a0]
Packit Service 084de1
||	 ADD	@Y[$b3],@Y[$a3],@Y[$a3]
Packit Service 084de1
||	 XOR	@Y[$a1],@Y[$d1],@Y[$d1]
Packit Service 084de1
||	 XOR	@Y[$a2],@Y[$d2],@Y[$d2]
Packit Service 084de1
	 XOR	@Y[$a0],@Y[$d0],@Y[$d0]
Packit Service 084de1
||	 XOR	@Y[$a3],@Y[$d3],@Y[$d3]
Packit Service 084de1
||	 ROTL	@Y[$d1],8,@Y[$d1]
Packit Service 084de1
||	 ROTL	@Y[$d2],8,@Y[$d2]
Packit Service 084de1
||	SWAP2	@X[$d0],@X[$d0]		; rotate by 16
Packit Service 084de1
||	SWAP2	@X[$d1],@X[$d1]
Packit Service 084de1
||	SWAP2	@X[$d2],@X[$d2]
Packit Service 084de1
||	SWAP2	@X[$d3],@X[$d3]
Packit Service 084de1
	 ROTL	@Y[$d0],8,@Y[$d0]
Packit Service 084de1
||	 ROTL	@Y[$d3],8,@Y[$d3]
Packit Service 084de1
||	ADD	@X[$d0],@X[$c2],@X[$c2]
Packit Service 084de1
||	ADD	@X[$d1],@X[$c3],@X[$c3]
Packit Service 084de1
||	ADD	@X[$d2],@X[$c0],@X[$c0]
Packit Service 084de1
||	ADD	@X[$d3],@X[$c1],@X[$c1]
Packit Service 084de1
||	BNOP	middle2x2?		; protect from interrupt
Packit Service 084de1
Packit Service 084de1
	 ADD	@Y[$d1],@Y[$c1],@Y[$c1]
Packit Service 084de1
||	 ADD	@Y[$d2],@Y[$c2],@Y[$c2]
Packit Service 084de1
||	XOR	@X[$c2],@X[$b0],@X[$b0]
Packit Service 084de1
||	XOR	@X[$c3],@X[$b1],@X[$b1]
Packit Service 084de1
||	XOR	@X[$c0],@X[$b2],@X[$b2]
Packit Service 084de1
||	XOR	@X[$c1],@X[$b3],@X[$b3]
Packit Service 084de1
	 ADD	@Y[$d0],@Y[$c0],@Y[$c0]
Packit Service 084de1
||	 ADD	@Y[$d3],@Y[$c3],@Y[$c3]
Packit Service 084de1
||	 XOR	@Y[$c1],@Y[$b1],@Y[$b1]
Packit Service 084de1
||	 XOR	@Y[$c2],@Y[$b2],@Y[$b2]
Packit Service 084de1
||	 ROTL	@Y[$d1],0,@Y[$d2]	; moved to avoid cross-path stall
Packit Service 084de1
||	 ROTL	@Y[$d2],0,@Y[$d3]
Packit Service 084de1
	 XOR	@Y[$c0],@Y[$b0],@Y[$b0]
Packit Service 084de1
||	 XOR	@Y[$c3],@Y[$b3],@Y[$b3]
Packit Service 084de1
||	 MV	@Y[$d0],@Y[$d1]
Packit Service 084de1
||	 MV	@Y[$d3],@Y[$d0]
Packit Service 084de1
||	ROTL	@X[$b0],12,@X[$b0]
Packit Service 084de1
||	ROTL	@X[$b1],12,@X[$b1]
Packit Service 084de1
	 ROTL	@Y[$b1],7,@Y[$b0]	; avoided cross-path stall
Packit Service 084de1
||	 ROTL	@Y[$b2],7,@Y[$b1]
Packit Service 084de1
	 ROTL	@Y[$b0],7,@Y[$b3]
Packit Service 084de1
||	 ROTL	@Y[$b3],7,@Y[$b2]
Packit Service 084de1
middle2x2?:
Packit Service 084de1
Packit Service 084de1
	ROTL	@X[$b2],12,@X[$b2]
Packit Service 084de1
||	ROTL	@X[$b3],12,@X[$b3]
Packit Service 084de1
||	 ADD	@Y[$b0],@Y[$a0],@Y[$a0]
Packit Service 084de1
||	 ADD	@Y[$b1],@Y[$a1],@Y[$a1]
Packit Service 084de1
	 ADD	@Y[$b2],@Y[$a2],@Y[$a2]
Packit Service 084de1
||	 ADD	@Y[$b3],@Y[$a3],@Y[$a3]
Packit Service 084de1
Packit Service 084de1
||	ADD	@X[$b0],@X[$a0],@X[$a0]
Packit Service 084de1
||	ADD	@X[$b1],@X[$a1],@X[$a1]
Packit Service 084de1
||	 XOR	@Y[$a0],@Y[$d0],@Y[$d0]
Packit Service 084de1
||	 XOR	@Y[$a1],@Y[$d1],@Y[$d1]
Packit Service 084de1
	 XOR	@Y[$a2],@Y[$d2],@Y[$d2]
Packit Service 084de1
||	 XOR	@Y[$a3],@Y[$d3],@Y[$d3]
Packit Service 084de1
||	ADD	@X[$b2],@X[$a2],@X[$a2]
Packit Service 084de1
||	ADD	@X[$b3],@X[$a3],@X[$a3]
Packit Service 084de1
||	XOR	@X[$a0],@X[$d0],@X[$d0]
Packit Service 084de1
||	XOR	@X[$a1],@X[$d1],@X[$d1]
Packit Service 084de1
	XOR	@X[$a2],@X[$d2],@X[$d2]
Packit Service 084de1
||	XOR	@X[$a3],@X[$d3],@X[$d3]
Packit Service 084de1
||	ROTL	@X[$d0],8,@X[$d0]
Packit Service 084de1
||	ROTL	@X[$d1],8,@X[$d1]
Packit Service 084de1
||	 SWAP2	@Y[$d0],@Y[$d0]		; rotate by 16
Packit Service 084de1
||	 SWAP2	@Y[$d1],@Y[$d1]
Packit Service 084de1
||	 SWAP2	@Y[$d2],@Y[$d2]
Packit Service 084de1
||	 SWAP2	@Y[$d3],@Y[$d3]
Packit Service 084de1
	ROTL	@X[$d2],8,@X[$d2]
Packit Service 084de1
||	ROTL	@X[$d3],8,@X[$d3]
Packit Service 084de1
||	 ADD	@Y[$d0],@Y[$c2],@Y[$c2]
Packit Service 084de1
||	 ADD	@Y[$d1],@Y[$c3],@Y[$c3]
Packit Service 084de1
||	 ADD	@Y[$d2],@Y[$c0],@Y[$c0]
Packit Service 084de1
||	 ADD	@Y[$d3],@Y[$c1],@Y[$c1]
Packit Service 084de1
||	BNOP	bottom2x1?		; protect from interrupt
Packit Service 084de1
Packit Service 084de1
	ADD	@X[$d0],@X[$c2],@X[$c2]
Packit Service 084de1
||	ADD	@X[$d1],@X[$c3],@X[$c3]
Packit Service 084de1
||	 XOR	@Y[$c2],@Y[$b0],@Y[$b0]
Packit Service 084de1
||	 XOR	@Y[$c3],@Y[$b1],@Y[$b1]
Packit Service 084de1
||	 XOR	@Y[$c0],@Y[$b2],@Y[$b2]
Packit Service 084de1
||	 XOR	@Y[$c1],@Y[$b3],@Y[$b3]
Packit Service 084de1
	ADD	@X[$d2],@X[$c0],@X[$c0]
Packit Service 084de1
||	ADD	@X[$d3],@X[$c1],@X[$c1]
Packit Service 084de1
||	XOR	@X[$c2],@X[$b0],@X[$b0]
Packit Service 084de1
||	XOR	@X[$c3],@X[$b1],@X[$b1]
Packit Service 084de1
||	ROTL	@X[$d0],0,@X[$d3]	; moved to avoid cross-path stall
Packit Service 084de1
||	ROTL	@X[$d1],0,@X[$d0]
Packit Service 084de1
	XOR	@X[$c0],@X[$b2],@X[$b2]
Packit Service 084de1
||	XOR	@X[$c1],@X[$b3],@X[$b3]
Packit Service 084de1
||	MV	@X[$d2],@X[$d1]
Packit Service 084de1
||	MV	@X[$d3],@X[$d2]
Packit Service 084de1
||	 ROTL	@Y[$b0],12,@Y[$b0]
Packit Service 084de1
||	 ROTL	@Y[$b1],12,@Y[$b1]
Packit Service 084de1
	ROTL	@X[$b0],7,@X[$b1]	; avoided cross-path stall
Packit Service 084de1
||	ROTL	@X[$b1],7,@X[$b2]
Packit Service 084de1
	ROTL	@X[$b2],7,@X[$b3]
Packit Service 084de1
||	ROTL	@X[$b3],7,@X[$b0]
Packit Service 084de1
|| [B0]	SUB	B0,1,B0			; decrement inner loop counter
Packit Service 084de1
bottom2x1?:
Packit Service 084de1
Packit Service 084de1
	 ROTL	@Y[$b2],12,@Y[$b2]
Packit Service 084de1
||	 ROTL	@Y[$b3],12,@Y[$b3]
Packit Service 084de1
|| [B0]	ADD	@X[$b1],@X[$a1],@X[$a1]	; modulo-scheduled
Packit Service 084de1
|| [B0]	ADD	@X[$b2],@X[$a2],@X[$a2]
Packit Service 084de1
   [B0]	ADD	@X[$b0],@X[$a0],@X[$a0]
Packit Service 084de1
|| [B0]	ADD	@X[$b3],@X[$a3],@X[$a3]
Packit Service 084de1
Packit Service 084de1
||	 ADD	@Y[$b0],@Y[$a0],@Y[$a0]
Packit Service 084de1
||	 ADD	@Y[$b1],@Y[$a1],@Y[$a1]
Packit Service 084de1
|| [B0]	XOR	@X[$a1],@X[$d1],@X[$d1]
Packit Service 084de1
|| [B0]	XOR	@X[$a2],@X[$d2],@X[$d2]
Packit Service 084de1
   [B0]	XOR	@X[$a0],@X[$d0],@X[$d0]
Packit Service 084de1
|| [B0]	XOR	@X[$a3],@X[$d3],@X[$d3]
Packit Service 084de1
||	 ADD	@Y[$b2],@Y[$a2],@Y[$a2]
Packit Service 084de1
||	 ADD	@Y[$b3],@Y[$a3],@Y[$a3]
Packit Service 084de1
||	 XOR	@Y[$a0],@Y[$d0],@Y[$d0]
Packit Service 084de1
||	 XOR	@Y[$a1],@Y[$d1],@Y[$d1]
Packit Service 084de1
	 XOR	@Y[$a2],@Y[$d2],@Y[$d2]
Packit Service 084de1
||	 XOR	@Y[$a3],@Y[$d3],@Y[$d3]
Packit Service 084de1
||	 ROTL	@Y[$d0],8,@Y[$d0]
Packit Service 084de1
||	 ROTL	@Y[$d1],8,@Y[$d1]
Packit Service 084de1
|| [B0]	SWAP2	@X[$d1],@X[$d1]		; rotate by 16
Packit Service 084de1
|| [B0]	SWAP2	@X[$d2],@X[$d2]
Packit Service 084de1
|| [B0]	SWAP2	@X[$d0],@X[$d0]
Packit Service 084de1
|| [B0]	SWAP2	@X[$d3],@X[$d3]
Packit Service 084de1
	 ROTL	@Y[$d2],8,@Y[$d2]
Packit Service 084de1
||	 ROTL	@Y[$d3],8,@Y[$d3]
Packit Service 084de1
|| [B0]	ADD	@X[$d1],@X[$c1],@X[$c1]
Packit Service 084de1
|| [B0]	ADD	@X[$d2],@X[$c2],@X[$c2]
Packit Service 084de1
|| [B0]	ADD	@X[$d0],@X[$c0],@X[$c0]
Packit Service 084de1
|| [B0]	ADD	@X[$d3],@X[$c3],@X[$c3]
Packit Service 084de1
|| [B0]	BNOP	top2x?			; even protects from interrupt
Packit Service 084de1
Packit Service 084de1
	 ADD	@Y[$d0],@Y[$c2],@Y[$c2]
Packit Service 084de1
||	 ADD	@Y[$d1],@Y[$c3],@Y[$c3]
Packit Service 084de1
|| [B0]	XOR	@X[$c1],@X[$b1],@X[$b1]
Packit Service 084de1
|| [B0]	XOR	@X[$c2],@X[$b2],@X[$b2]
Packit Service 084de1
|| [B0]	XOR	@X[$c0],@X[$b0],@X[$b0]
Packit Service 084de1
|| [B0]	XOR	@X[$c3],@X[$b3],@X[$b3]
Packit Service 084de1
	 ADD	@Y[$d2],@Y[$c0],@Y[$c0]
Packit Service 084de1
||	 ADD	@Y[$d3],@Y[$c1],@Y[$c1]
Packit Service 084de1
||	 XOR	@Y[$c2],@Y[$b0],@Y[$b0]
Packit Service 084de1
||	 XOR	@Y[$c3],@Y[$b1],@Y[$b1]
Packit Service 084de1
||	 ROTL	@Y[$d0],0,@Y[$d3]	; moved to avoid cross-path stall
Packit Service 084de1
||	 ROTL	@Y[$d1],0,@Y[$d0]
Packit Service 084de1
	 XOR	@Y[$c0],@Y[$b2],@Y[$b2]
Packit Service 084de1
||	 XOR	@Y[$c1],@Y[$b3],@Y[$b3]
Packit Service 084de1
||	 MV	@Y[$d2],@Y[$d1]
Packit Service 084de1
||	 MV	@Y[$d3],@Y[$d2]
Packit Service 084de1
|| [B0]	ROTL	@X[$b1],12,@X[$b1]
Packit Service 084de1
|| [B0]	ROTL	@X[$b2],12,@X[$b2]
Packit Service 084de1
	 ROTL	@Y[$b0],7,@Y[$b1]	; avoided cross-path stall
Packit Service 084de1
||	 ROTL	@Y[$b1],7,@Y[$b2]
Packit Service 084de1
	 ROTL	@Y[$b2],7,@Y[$b3]
Packit Service 084de1
||	 ROTL	@Y[$b3],7,@Y[$b0]
Packit Service 084de1
bottom2x2?:
Packit Service 084de1
___
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
$code.=<<___;
Packit Service 084de1
	ADD	@K2x[0],@X[0],@X[0]	; accumulate key material
Packit Service 084de1
||	ADD	@K2x[1],@X[1],@X[1]
Packit Service 084de1
||	ADD	@K2x[2],@X[2],@X[2]
Packit Service 084de1
||	ADD	@K2x[3],@X[3],@X[3]
Packit Service 084de1
	 ADD	@K2x[0],@Y[0],@Y[0]
Packit Service 084de1
||	 ADD	@K2x[1],@Y[1],@Y[1]
Packit Service 084de1
||	 ADD	@K2x[2],@Y[2],@Y[2]
Packit Service 084de1
||	 ADD	@K2x[3],@Y[3],@Y[3]
Packit Service 084de1
||	LDNDW	*${INP}++[8],@DAT[1]:@DAT[0]
Packit Service 084de1
	ADD	@K2x[4],@X[4],@X[4]
Packit Service 084de1
||	ADD	@K2x[5],@X[5],@X[5]
Packit Service 084de1
||	ADD	@K2x[6],@X[6],@X[6]
Packit Service 084de1
||	ADD	@K2x[7],@X[7],@X[7]
Packit Service 084de1
||	LDNDW	*${INP}[-7],@DAT[3]:@DAT[2]
Packit Service 084de1
	 ADD	@K2x[4],@Y[4],@Y[4]
Packit Service 084de1
||	 ADD	@K2x[5],@Y[5],@Y[5]
Packit Service 084de1
||	 ADD	@K2x[6],@Y[6],@Y[6]
Packit Service 084de1
||	 ADD	@K2x[7],@Y[7],@Y[7]
Packit Service 084de1
||	LDNDW	*${INP}[-6],@DAT[5]:@DAT[4]
Packit Service 084de1
	ADD	@K2x[8],@X[8],@X[8]
Packit Service 084de1
||	ADD	@K2x[9],@X[9],@X[9]
Packit Service 084de1
||	ADD	@K2x[10],@X[10],@X[10]
Packit Service 084de1
||	ADD	@K2x[11],@X[11],@X[11]
Packit Service 084de1
||	LDNDW	*${INP}[-5],@DAT[7]:@DAT[6]
Packit Service 084de1
	 ADD	@K2x[8],@Y[8],@Y[8]
Packit Service 084de1
||	 ADD	@K2x[9],@Y[9],@Y[9]
Packit Service 084de1
||	 ADD	@K2x[10],@Y[10],@Y[10]
Packit Service 084de1
||	 ADD	@K2x[11],@Y[11],@Y[11]
Packit Service 084de1
||	LDNDW	*${INP}[-4],@DAT[9]:@DAT[8]
Packit Service 084de1
	ADD	@K2x[12],@X[12],@X[12]
Packit Service 084de1
||	ADD	@K2x[13],@X[13],@X[13]
Packit Service 084de1
||	ADD	@K2x[14],@X[14],@X[14]
Packit Service 084de1
||	ADD	@K2x[15],@X[15],@X[15]
Packit Service 084de1
||	LDNDW	*${INP}[-3],@DAT[11]:@DAT[10]
Packit Service 084de1
	 ADD	@K2x[12],@Y[12],@Y[12]
Packit Service 084de1
||	 ADD	@K2x[13],@Y[13],@Y[13]
Packit Service 084de1
||	 ADD	@K2x[14],@Y[14],@Y[14]
Packit Service 084de1
||	 ADD	@K2x[15],@Y[15],@Y[15]
Packit Service 084de1
||	LDNDW	*${INP}[-2],@DAT[13]:@DAT[12]
Packit Service 084de1
	 ADD	1,@Y[12],@Y[12]		; adjust counter for 2nd block
Packit Service 084de1
||	ADD	2,@K2x[12],@K2x[12]	; increment counter
Packit Service 084de1
||	LDNDW	*${INP}[-1],@DAT[15]:@DAT[14]
Packit Service 084de1
Packit Service 084de1
	.if	.BIG_ENDIAN
Packit Service 084de1
	SWAP2	@X[0],@X[0]
Packit Service 084de1
||	SWAP2	@X[1],@X[1]
Packit Service 084de1
||	SWAP2	@X[2],@X[2]
Packit Service 084de1
||	SWAP2	@X[3],@X[3]
Packit Service 084de1
	SWAP2	@X[4],@X[4]
Packit Service 084de1
||	SWAP2	@X[5],@X[5]
Packit Service 084de1
||	SWAP2	@X[6],@X[6]
Packit Service 084de1
||	SWAP2	@X[7],@X[7]
Packit Service 084de1
	SWAP2	@X[8],@X[8]
Packit Service 084de1
||	SWAP2	@X[9],@X[9]
Packit Service 084de1
||	SWAP4	@X[0],@X[1]
Packit Service 084de1
||	SWAP4	@X[1],@X[0]
Packit Service 084de1
	SWAP2	@X[10],@X[10]
Packit Service 084de1
||	SWAP2	@X[11],@X[11]
Packit Service 084de1
||	SWAP4	@X[2],@X[3]
Packit Service 084de1
||	SWAP4	@X[3],@X[2]
Packit Service 084de1
	SWAP2	@X[12],@X[12]
Packit Service 084de1
||	SWAP2	@X[13],@X[13]
Packit Service 084de1
||	SWAP4	@X[4],@X[5]
Packit Service 084de1
||	SWAP4	@X[5],@X[4]
Packit Service 084de1
	SWAP2	@X[14],@X[14]
Packit Service 084de1
||	SWAP2	@X[15],@X[15]
Packit Service 084de1
||	SWAP4	@X[6],@X[7]
Packit Service 084de1
||	SWAP4	@X[7],@X[6]
Packit Service 084de1
	SWAP4	@X[8],@X[9]
Packit Service 084de1
||	SWAP4	@X[9],@X[8]
Packit Service 084de1
||	 SWAP2	@Y[0],@Y[0]
Packit Service 084de1
||	 SWAP2	@Y[1],@Y[1]
Packit Service 084de1
	SWAP4	@X[10],@X[11]
Packit Service 084de1
||	SWAP4	@X[11],@X[10]
Packit Service 084de1
||	 SWAP2	@Y[2],@Y[2]
Packit Service 084de1
||	 SWAP2	@Y[3],@Y[3]
Packit Service 084de1
	SWAP4	@X[12],@X[13]
Packit Service 084de1
||	SWAP4	@X[13],@X[12]
Packit Service 084de1
||	 SWAP2	@Y[4],@Y[4]
Packit Service 084de1
||	 SWAP2	@Y[5],@Y[5]
Packit Service 084de1
	SWAP4	@X[14],@X[15]
Packit Service 084de1
||	SWAP4	@X[15],@X[14]
Packit Service 084de1
||	 SWAP2	@Y[6],@Y[6]
Packit Service 084de1
||	 SWAP2	@Y[7],@Y[7]
Packit Service 084de1
	 SWAP2	@Y[8],@Y[8]
Packit Service 084de1
||	 SWAP2	@Y[9],@Y[9]
Packit Service 084de1
||	 SWAP4	@Y[0],@Y[1]
Packit Service 084de1
||	 SWAP4	@Y[1],@Y[0]
Packit Service 084de1
	 SWAP2	@Y[10],@Y[10]
Packit Service 084de1
||	 SWAP2	@Y[11],@Y[11]
Packit Service 084de1
||	 SWAP4	@Y[2],@Y[3]
Packit Service 084de1
||	 SWAP4	@Y[3],@Y[2]
Packit Service 084de1
	 SWAP2	@Y[12],@Y[12]
Packit Service 084de1
||	 SWAP2	@Y[13],@Y[13]
Packit Service 084de1
||	 SWAP4	@Y[4],@Y[5]
Packit Service 084de1
||	 SWAP4	@Y[5],@Y[4]
Packit Service 084de1
	 SWAP2	@Y[14],@Y[14]
Packit Service 084de1
||	 SWAP2	@Y[15],@Y[15]
Packit Service 084de1
||	 SWAP4	@Y[6],@Y[7]
Packit Service 084de1
||	 SWAP4	@Y[7],@Y[6]
Packit Service 084de1
	 SWAP4	@Y[8],@Y[9]
Packit Service 084de1
||	 SWAP4	@Y[9],@Y[8]
Packit Service 084de1
	 SWAP4	@Y[10],@Y[11]
Packit Service 084de1
||	 SWAP4	@Y[11],@Y[10]
Packit Service 084de1
	 SWAP4	@Y[12],@Y[13]
Packit Service 084de1
||	 SWAP4	@Y[13],@Y[12]
Packit Service 084de1
	 SWAP4	@Y[14],@Y[15]
Packit Service 084de1
||	 SWAP4	@Y[15],@Y[14]
Packit Service 084de1
	.endif
Packit Service 084de1
Packit Service 084de1
	XOR	@DAT[0],@X[0],@X[0]	; xor 1st block
Packit Service 084de1
||	XOR	@DAT[3],@X[3],@X[3]
Packit Service 084de1
||	XOR	@DAT[2],@X[2],@X[1]
Packit Service 084de1
||	XOR	@DAT[1],@X[1],@X[2]
Packit Service 084de1
||	LDNDW	*${INP}++[8],@DAT[1]:@DAT[0]
Packit Service 084de1
	XOR	@DAT[4],@X[4],@X[4]
Packit Service 084de1
||	XOR	@DAT[7],@X[7],@X[7]
Packit Service 084de1
||	LDNDW	*${INP}[-7],@DAT[3]:@DAT[2]
Packit Service 084de1
	XOR	@DAT[6],@X[6],@X[5]
Packit Service 084de1
||	XOR	@DAT[5],@X[5],@X[6]
Packit Service 084de1
||	LDNDW	*${INP}[-6],@DAT[5]:@DAT[4]
Packit Service 084de1
	XOR	@DAT[8],@X[8],@X[8]
Packit Service 084de1
||	XOR	@DAT[11],@X[11],@X[11]
Packit Service 084de1
||	LDNDW	*${INP}[-5],@DAT[7]:@DAT[6]
Packit Service 084de1
	XOR	@DAT[10],@X[10],@X[9]
Packit Service 084de1
||	XOR	@DAT[9],@X[9],@X[10]
Packit Service 084de1
||	LDNDW	*${INP}[-4],@DAT[9]:@DAT[8]
Packit Service 084de1
	XOR	@DAT[12],@X[12],@X[12]
Packit Service 084de1
||	XOR	@DAT[15],@X[15],@X[15]
Packit Service 084de1
||	LDNDW	*${INP}[-3],@DAT[11]:@DAT[10]
Packit Service 084de1
	XOR	@DAT[14],@X[14],@X[13]
Packit Service 084de1
||	XOR	@DAT[13],@X[13],@X[14]
Packit Service 084de1
||	LDNDW	*${INP}[-2],@DAT[13]:@DAT[12]
Packit Service 084de1
   [A0]	SUB	A0,$STEP,A0		; SUB	A0,128,A0
Packit Service 084de1
||	LDNDW	*${INP}[-1],@DAT[15]:@DAT[14]
Packit Service 084de1
Packit Service 084de1
	XOR	@Y[0],@DAT[0],@DAT[0]	; xor 2nd block
Packit Service 084de1
||	XOR	@Y[1],@DAT[1],@DAT[1]
Packit Service 084de1
||	STNDW	@X[2]:@X[0],*${OUT}++[8]
Packit Service 084de1
	XOR	@Y[2],@DAT[2],@DAT[2]
Packit Service 084de1
||	XOR	@Y[3],@DAT[3],@DAT[3]
Packit Service 084de1
||	STNDW	@X[3]:@X[1],*${OUT}[-7]
Packit Service 084de1
	XOR	@Y[4],@DAT[4],@DAT[4]
Packit Service 084de1
|| [A0]	LDDW	*FP[-12],@X[2]:@X[0]	; re-load key material from stack
Packit Service 084de1
|| [A0]	LDDW	*SP[2],  @X[3]:@X[1]
Packit Service 084de1
	XOR	@Y[5],@DAT[5],@DAT[5]
Packit Service 084de1
||	STNDW	@X[6]:@X[4],*${OUT}[-6]
Packit Service 084de1
	XOR	@Y[6],@DAT[6],@DAT[6]
Packit Service 084de1
||	XOR	@Y[7],@DAT[7],@DAT[7]
Packit Service 084de1
||	STNDW	@X[7]:@X[5],*${OUT}[-5]
Packit Service 084de1
	XOR	@Y[8],@DAT[8],@DAT[8]
Packit Service 084de1
|| [A0]	LDDW	*FP[-10],@X[6]:@X[4]
Packit Service 084de1
|| [A0]	LDDW	*SP[4],  @X[7]:@X[5]
Packit Service 084de1
	XOR	@Y[9],@DAT[9],@DAT[9]
Packit Service 084de1
||	STNDW	@X[10]:@X[8],*${OUT}[-4]
Packit Service 084de1
	XOR	@Y[10],@DAT[10],@DAT[10]
Packit Service 084de1
||	XOR	@Y[11],@DAT[11],@DAT[11]
Packit Service 084de1
||	STNDW	@X[11]:@X[9],*${OUT}[-3]
Packit Service 084de1
	XOR	@Y[12],@DAT[12],@DAT[12]
Packit Service 084de1
|| [A0]	LDDW	*FP[-8], @X[10]:@X[8]
Packit Service 084de1
|| [A0]	LDDW	*SP[6],  @X[11]:@X[9]
Packit Service 084de1
	XOR	@Y[13],@DAT[13],@DAT[13]
Packit Service 084de1
||	STNDW	@X[14]:@X[12],*${OUT}[-2]
Packit Service 084de1
	XOR	@Y[14],@DAT[14],@DAT[14]
Packit Service 084de1
||	XOR	@Y[15],@DAT[15],@DAT[15]
Packit Service 084de1
||	STNDW	@X[15]:@X[13],*${OUT}[-1]
Packit Service 084de1
Packit Service 084de1
   [A0]	MV	@K2x[12],@X[12]
Packit Service 084de1
|| [A0]	MV	@K2x[13],@X[13]
Packit Service 084de1
|| [A0]	LDW	*FP[-6*2], @X[14]
Packit Service 084de1
|| [A0]	LDW	*SP[8*2],  @X[15]
Packit Service 084de1
Packit Service 084de1
   [A0]	DMV	@X[2],@X[0],@Y[2]:@Y[0]	; duplicate key material
Packit Service 084de1
||	STNDW	@DAT[1]:@DAT[0],*${OUT}++[8]
Packit Service 084de1
   [A0]	DMV	@X[3],@X[1],@Y[3]:@Y[1]
Packit Service 084de1
||	STNDW	@DAT[3]:@DAT[2],*${OUT}[-7]
Packit Service 084de1
   [A0]	DMV	@X[6],@X[4],@Y[6]:@Y[4]
Packit Service 084de1
||	STNDW	@DAT[5]:@DAT[4],*${OUT}[-6]
Packit Service 084de1
||	CMPLTU	A0,$STEP,A1		; is remaining length < 2*blocks?
Packit Service 084de1
||[!A0]	BNOP	epilogue?
Packit Service 084de1
   [A0]	DMV	@X[7],@X[5],@Y[7]:@Y[5]
Packit Service 084de1
||	STNDW	@DAT[7]:@DAT[6],*${OUT}[-5]
Packit Service 084de1
||[!A1]	BNOP	outer2x?
Packit Service 084de1
   [A0]	DMV	@X[10],@X[8],@Y[10]:@Y[8]
Packit Service 084de1
||	STNDW	@DAT[9]:@DAT[8],*${OUT}[-4]
Packit Service 084de1
   [A0]	DMV	@X[11],@X[9],@Y[11]:@Y[9]
Packit Service 084de1
||	STNDW	@DAT[11]:@DAT[10],*${OUT}[-3]
Packit Service 084de1
   [A0]	DMV	@X[14],@X[12],@Y[14]:@Y[12]
Packit Service 084de1
||	STNDW	@DAT[13]:@DAT[12],*${OUT}[-2]
Packit Service 084de1
   [A0]	DMV	@X[15],@X[13],@Y[15]:@Y[13]
Packit Service 084de1
||	STNDW	@DAT[15]:@DAT[14],*${OUT}[-1]
Packit Service 084de1
;;===== branch to epilogue? is taken here
Packit Service 084de1
   [A1]	MVK	64,$STEP
Packit Service 084de1
|| [A0]	MVK	10,B0			; inner loop counter
Packit Service 084de1
;;===== branch to outer2x? is taken here
Packit Service 084de1
___
Packit Service 084de1
{
Packit Service 084de1
my ($a0,$a1,$a2,$a3) = (0..3);
Packit Service 084de1
my ($b0,$b1,$b2,$b3) = (4..7);
Packit Service 084de1
my ($c0,$c1,$c2,$c3) = (8..11);
Packit Service 084de1
my ($d0,$d1,$d2,$d3) = (12..15);
Packit Service 084de1
Packit Service 084de1
$code.=<<___;
Packit Service 084de1
top1x?:
Packit Service 084de1
	ADD	@X[$b1],@X[$a1],@X[$a1]
Packit Service 084de1
||	ADD	@X[$b2],@X[$a2],@X[$a2]
Packit Service 084de1
	ADD	@X[$b0],@X[$a0],@X[$a0]
Packit Service 084de1
||	ADD	@X[$b3],@X[$a3],@X[$a3]
Packit Service 084de1
||	XOR	@X[$a1],@X[$d1],@X[$d1]
Packit Service 084de1
||	XOR	@X[$a2],@X[$d2],@X[$d2]
Packit Service 084de1
	XOR	@X[$a0],@X[$d0],@X[$d0]
Packit Service 084de1
||	XOR	@X[$a3],@X[$d3],@X[$d3]
Packit Service 084de1
||	SWAP2	@X[$d1],@X[$d1]		; rotate by 16
Packit Service 084de1
||	SWAP2	@X[$d2],@X[$d2]
Packit Service 084de1
	SWAP2	@X[$d0],@X[$d0]
Packit Service 084de1
||	SWAP2	@X[$d3],@X[$d3]
Packit Service 084de1
Packit Service 084de1
||	ADD	@X[$d1],@X[$c1],@X[$c1]
Packit Service 084de1
||	ADD	@X[$d2],@X[$c2],@X[$c2]
Packit Service 084de1
	ADD	@X[$d0],@X[$c0],@X[$c0]
Packit Service 084de1
||	ADD	@X[$d3],@X[$c3],@X[$c3]
Packit Service 084de1
||	XOR	@X[$c1],@X[$b1],@X[$b1]
Packit Service 084de1
||	XOR	@X[$c2],@X[$b2],@X[$b2]
Packit Service 084de1
	XOR	@X[$c0],@X[$b0],@X[$b0]
Packit Service 084de1
||	XOR	@X[$c3],@X[$b3],@X[$b3]
Packit Service 084de1
||	ROTL	@X[$b1],12,@X[$b1]
Packit Service 084de1
||	ROTL	@X[$b2],12,@X[$b2]
Packit Service 084de1
	ROTL	@X[$b0],12,@X[$b0]
Packit Service 084de1
||	ROTL	@X[$b3],12,@X[$b3]
Packit Service 084de1
Packit Service 084de1
	ADD	@X[$b1],@X[$a1],@X[$a1]
Packit Service 084de1
||	ADD	@X[$b2],@X[$a2],@X[$a2]
Packit Service 084de1
	ADD	@X[$b0],@X[$a0],@X[$a0]
Packit Service 084de1
||	ADD	@X[$b3],@X[$a3],@X[$a3]
Packit Service 084de1
||	XOR	@X[$a1],@X[$d1],@X[$d1]
Packit Service 084de1
||	XOR	@X[$a2],@X[$d2],@X[$d2]
Packit Service 084de1
	XOR	@X[$a0],@X[$d0],@X[$d0]
Packit Service 084de1
||	XOR	@X[$a3],@X[$d3],@X[$d3]
Packit Service 084de1
||	ROTL	@X[$d1],8,@X[$d1]
Packit Service 084de1
||	ROTL	@X[$d2],8,@X[$d2]
Packit Service 084de1
	ROTL	@X[$d0],8,@X[$d0]
Packit Service 084de1
||	ROTL	@X[$d3],8,@X[$d3]
Packit Service 084de1
||	BNOP	middle1x?		; protect from interrupt
Packit Service 084de1
Packit Service 084de1
	ADD	@X[$d1],@X[$c1],@X[$c1]
Packit Service 084de1
||	ADD	@X[$d2],@X[$c2],@X[$c2]
Packit Service 084de1
	ADD	@X[$d0],@X[$c0],@X[$c0]
Packit Service 084de1
||	ADD	@X[$d3],@X[$c3],@X[$c3]
Packit Service 084de1
||	XOR	@X[$c1],@X[$b1],@X[$b1]
Packit Service 084de1
||	XOR	@X[$c2],@X[$b2],@X[$b2]
Packit Service 084de1
||	ROTL	@X[$d1],0,@X[$d2]	; moved to avoid cross-path stall
Packit Service 084de1
||	ROTL	@X[$d2],0,@X[$d3]
Packit Service 084de1
	XOR	@X[$c0],@X[$b0],@X[$b0]
Packit Service 084de1
||	XOR	@X[$c3],@X[$b3],@X[$b3]
Packit Service 084de1
||	ROTL	@X[$d0],0,@X[$d1]
Packit Service 084de1
||	ROTL	@X[$d3],0,@X[$d0]
Packit Service 084de1
	ROTL	@X[$b1],7,@X[$b0]	; avoided cross-path stall
Packit Service 084de1
||	ROTL	@X[$b2],7,@X[$b1]
Packit Service 084de1
	ROTL	@X[$b0],7,@X[$b3]
Packit Service 084de1
||	ROTL	@X[$b3],7,@X[$b2]
Packit Service 084de1
middle1x?:
Packit Service 084de1
Packit Service 084de1
	ADD	@X[$b0],@X[$a0],@X[$a0]
Packit Service 084de1
||	ADD	@X[$b1],@X[$a1],@X[$a1]
Packit Service 084de1
	ADD	@X[$b2],@X[$a2],@X[$a2]
Packit Service 084de1
||	ADD	@X[$b3],@X[$a3],@X[$a3]
Packit Service 084de1
||	XOR	@X[$a0],@X[$d0],@X[$d0]
Packit Service 084de1
||	XOR	@X[$a1],@X[$d1],@X[$d1]
Packit Service 084de1
	XOR	@X[$a2],@X[$d2],@X[$d2]
Packit Service 084de1
||	XOR	@X[$a3],@X[$d3],@X[$d3]
Packit Service 084de1
||	SWAP2	@X[$d0],@X[$d0]		; rotate by 16
Packit Service 084de1
||	SWAP2	@X[$d1],@X[$d1]
Packit Service 084de1
	SWAP2	@X[$d2],@X[$d2]
Packit Service 084de1
||	SWAP2	@X[$d3],@X[$d3]
Packit Service 084de1
Packit Service 084de1
||	ADD	@X[$d0],@X[$c2],@X[$c2]
Packit Service 084de1
||	ADD	@X[$d1],@X[$c3],@X[$c3]
Packit Service 084de1
	ADD	@X[$d2],@X[$c0],@X[$c0]
Packit Service 084de1
||	ADD	@X[$d3],@X[$c1],@X[$c1]
Packit Service 084de1
||	XOR	@X[$c2],@X[$b0],@X[$b0]
Packit Service 084de1
||	XOR	@X[$c3],@X[$b1],@X[$b1]
Packit Service 084de1
	XOR	@X[$c0],@X[$b2],@X[$b2]
Packit Service 084de1
||	XOR	@X[$c1],@X[$b3],@X[$b3]
Packit Service 084de1
||	ROTL	@X[$b0],12,@X[$b0]
Packit Service 084de1
||	ROTL	@X[$b1],12,@X[$b1]
Packit Service 084de1
	ROTL	@X[$b2],12,@X[$b2]
Packit Service 084de1
||	ROTL	@X[$b3],12,@X[$b3]
Packit Service 084de1
Packit Service 084de1
	ADD	@X[$b0],@X[$a0],@X[$a0]
Packit Service 084de1
||	ADD	@X[$b1],@X[$a1],@X[$a1]
Packit Service 084de1
|| [B0]	SUB	B0,1,B0			; decrement inner loop counter
Packit Service 084de1
	ADD	@X[$b2],@X[$a2],@X[$a2]
Packit Service 084de1
||	ADD	@X[$b3],@X[$a3],@X[$a3]
Packit Service 084de1
||	XOR	@X[$a0],@X[$d0],@X[$d0]
Packit Service 084de1
||	XOR	@X[$a1],@X[$d1],@X[$d1]
Packit Service 084de1
	XOR	@X[$a2],@X[$d2],@X[$d2]
Packit Service 084de1
||	XOR	@X[$a3],@X[$d3],@X[$d3]
Packit Service 084de1
||	ROTL	@X[$d0],8,@X[$d0]
Packit Service 084de1
||	ROTL	@X[$d1],8,@X[$d1]
Packit Service 084de1
	ROTL	@X[$d2],8,@X[$d2]
Packit Service 084de1
||	ROTL	@X[$d3],8,@X[$d3]
Packit Service 084de1
|| [B0]	BNOP	top1x?			; even protects from interrupt
Packit Service 084de1
Packit Service 084de1
	ADD	@X[$d0],@X[$c2],@X[$c2]
Packit Service 084de1
||	ADD	@X[$d1],@X[$c3],@X[$c3]
Packit Service 084de1
	ADD	@X[$d2],@X[$c0],@X[$c0]
Packit Service 084de1
||	ADD	@X[$d3],@X[$c1],@X[$c1]
Packit Service 084de1
||	XOR	@X[$c2],@X[$b0],@X[$b0]
Packit Service 084de1
||	XOR	@X[$c3],@X[$b1],@X[$b1]
Packit Service 084de1
||	ROTL	@X[$d0],0,@X[$d3]	; moved to avoid cross-path stall
Packit Service 084de1
||	ROTL	@X[$d1],0,@X[$d0]
Packit Service 084de1
	XOR	@X[$c0],@X[$b2],@X[$b2]
Packit Service 084de1
||	XOR	@X[$c1],@X[$b3],@X[$b3]
Packit Service 084de1
||	ROTL	@X[$d2],0,@X[$d1]
Packit Service 084de1
||	ROTL	@X[$d3],0,@X[$d2]
Packit Service 084de1
	ROTL	@X[$b0],7,@X[$b1]	; avoided cross-path stall
Packit Service 084de1
||	ROTL	@X[$b1],7,@X[$b2]
Packit Service 084de1
	ROTL	@X[$b2],7,@X[$b3]
Packit Service 084de1
||	ROTL	@X[$b3],7,@X[$b0]
Packit Service 084de1
||[!B0]	CMPLTU	A0,$STEP,A1		; less than 64 bytes left?
Packit Service 084de1
bottom1x?:
Packit Service 084de1
___
Packit Service 084de1
}
Packit Service 084de1
Packit Service 084de1
$code.=<<___;
Packit Service 084de1
	ADD	@Y[0],@X[0],@X[0]	; accumulate key material
Packit Service 084de1
||	ADD	@Y[1],@X[1],@X[1]
Packit Service 084de1
||	ADD	@Y[2],@X[2],@X[2]
Packit Service 084de1
||	ADD	@Y[3],@X[3],@X[3]
Packit Service 084de1
||[!A1]	LDNDW	*${INP}++[8],@DAT[1]:@DAT[0]
Packit Service 084de1
|| [A1]	BNOP	tail?
Packit Service 084de1
	ADD	@Y[4],@X[4],@X[4]
Packit Service 084de1
||	ADD	@Y[5],@X[5],@X[5]
Packit Service 084de1
||	ADD	@Y[6],@X[6],@X[6]
Packit Service 084de1
||	ADD	@Y[7],@X[7],@X[7]
Packit Service 084de1
||[!A1]	LDNDW	*${INP}[-7],@DAT[3]:@DAT[2]
Packit Service 084de1
	ADD	@Y[8],@X[8],@X[8]
Packit Service 084de1
||	ADD	@Y[9],@X[9],@X[9]
Packit Service 084de1
||	ADD	@Y[10],@X[10],@X[10]
Packit Service 084de1
||	ADD	@Y[11],@X[11],@X[11]
Packit Service 084de1
||[!A1]	LDNDW	*${INP}[-6],@DAT[5]:@DAT[4]
Packit Service 084de1
	ADD	@Y[12],@X[12],@X[12]
Packit Service 084de1
||	ADD	@Y[13],@X[13],@X[13]
Packit Service 084de1
||	ADD	@Y[14],@X[14],@X[14]
Packit Service 084de1
||	ADD	@Y[15],@X[15],@X[15]
Packit Service 084de1
||[!A1]	LDNDW	*${INP}[-5],@DAT[7]:@DAT[6]
Packit Service 084de1
  [!A1]	LDNDW	*${INP}[-4],@DAT[9]:@DAT[8]
Packit Service 084de1
  [!A1]	LDNDW	*${INP}[-3],@DAT[11]:@DAT[10]
Packit Service 084de1
	LDNDW	*${INP}[-2],@DAT[13]:@DAT[12]
Packit Service 084de1
	LDNDW	*${INP}[-1],@DAT[15]:@DAT[14]
Packit Service 084de1
Packit Service 084de1
	.if	.BIG_ENDIAN
Packit Service 084de1
	SWAP2	@X[0],@X[0]
Packit Service 084de1
||	SWAP2	@X[1],@X[1]
Packit Service 084de1
||	SWAP2	@X[2],@X[2]
Packit Service 084de1
||	SWAP2	@X[3],@X[3]
Packit Service 084de1
	SWAP2	@X[4],@X[4]
Packit Service 084de1
||	SWAP2	@X[5],@X[5]
Packit Service 084de1
||	SWAP2	@X[6],@X[6]
Packit Service 084de1
||	SWAP2	@X[7],@X[7]
Packit Service 084de1
	SWAP2	@X[8],@X[8]
Packit Service 084de1
||	SWAP2	@X[9],@X[9]
Packit Service 084de1
||	SWAP4	@X[0],@X[1]
Packit Service 084de1
||	SWAP4	@X[1],@X[0]
Packit Service 084de1
	SWAP2	@X[10],@X[10]
Packit Service 084de1
||	SWAP2	@X[11],@X[11]
Packit Service 084de1
||	SWAP4	@X[2],@X[3]
Packit Service 084de1
||	SWAP4	@X[3],@X[2]
Packit Service 084de1
	SWAP2	@X[12],@X[12]
Packit Service 084de1
||	SWAP2	@X[13],@X[13]
Packit Service 084de1
||	SWAP4	@X[4],@X[5]
Packit Service 084de1
||	SWAP4	@X[5],@X[4]
Packit Service 084de1
	SWAP2	@X[14],@X[14]
Packit Service 084de1
||	SWAP2	@X[15],@X[15]
Packit Service 084de1
||	SWAP4	@X[6],@X[7]
Packit Service 084de1
||	SWAP4	@X[7],@X[6]
Packit Service 084de1
	SWAP4	@X[8],@X[9]
Packit Service 084de1
||	SWAP4	@X[9],@X[8]
Packit Service 084de1
	SWAP4	@X[10],@X[11]
Packit Service 084de1
||	SWAP4	@X[11],@X[10]
Packit Service 084de1
	SWAP4	@X[12],@X[13]
Packit Service 084de1
||	SWAP4	@X[13],@X[12]
Packit Service 084de1
	SWAP4	@X[14],@X[15]
Packit Service 084de1
||	SWAP4	@X[15],@X[14]
Packit Service 084de1
	.else
Packit Service 084de1
	NOP	1
Packit Service 084de1
	.endif
Packit Service 084de1
Packit Service 084de1
	XOR	@X[0],@DAT[0],@DAT[0]	; xor with input
Packit Service 084de1
||	XOR	@X[1],@DAT[1],@DAT[1]
Packit Service 084de1
||	XOR	@X[2],@DAT[2],@DAT[2]
Packit Service 084de1
||	XOR	@X[3],@DAT[3],@DAT[3]
Packit Service 084de1
|| [A0]	SUB	A0,$STEP,A0		; SUB	A0,64,A0
Packit Service 084de1
	XOR	@X[4],@DAT[4],@DAT[4]
Packit Service 084de1
||	XOR	@X[5],@DAT[5],@DAT[5]
Packit Service 084de1
||	XOR	@X[6],@DAT[6],@DAT[6]
Packit Service 084de1
||	XOR	@X[7],@DAT[7],@DAT[7]
Packit Service 084de1
||	STNDW	@DAT[1]:@DAT[0],*${OUT}++[8]
Packit Service 084de1
	XOR	@X[8],@DAT[8],@DAT[8]
Packit Service 084de1
||	XOR	@X[9],@DAT[9],@DAT[9]
Packit Service 084de1
||	XOR	@X[10],@DAT[10],@DAT[10]
Packit Service 084de1
||	XOR	@X[11],@DAT[11],@DAT[11]
Packit Service 084de1
||	STNDW	@DAT[3]:@DAT[2],*${OUT}[-7]
Packit Service 084de1
	XOR	@X[12],@DAT[12],@DAT[12]
Packit Service 084de1
||	XOR	@X[13],@DAT[13],@DAT[13]
Packit Service 084de1
||	XOR	@X[14],@DAT[14],@DAT[14]
Packit Service 084de1
||	XOR	@X[15],@DAT[15],@DAT[15]
Packit Service 084de1
||	STNDW	@DAT[5]:@DAT[4],*${OUT}[-6]
Packit Service 084de1
|| [A0]	BNOP	top1x?
Packit Service 084de1
   [A0]	DMV	@Y[2],@Y[0],@X[2]:@X[0]	; duplicate key material
Packit Service 084de1
|| [A0]	DMV	@Y[3],@Y[1],@X[3]:@X[1]
Packit Service 084de1
||	STNDW	@DAT[7]:@DAT[6],*${OUT}[-5]
Packit Service 084de1
   [A0]	DMV	@Y[6],@Y[4],@X[6]:@X[4]
Packit Service 084de1
|| [A0]	DMV	@Y[7],@Y[5],@X[7]:@X[5]
Packit Service 084de1
||	STNDW	@DAT[9]:@DAT[8],*${OUT}[-4]
Packit Service 084de1
   [A0]	DMV	@Y[10],@Y[8],@X[10]:@X[8]
Packit Service 084de1
|| [A0]	DMV	@Y[11],@Y[9],@X[11]:@X[9]
Packit Service 084de1
|| [A0]	ADD	1,@Y[12],@Y[12]		; increment counter
Packit Service 084de1
||	STNDW	@DAT[11]:@DAT[10],*${OUT}[-3]
Packit Service 084de1
   [A0]	DMV	@Y[14],@Y[12],@X[14]:@X[12]
Packit Service 084de1
|| [A0]	DMV	@Y[15],@Y[13],@X[15]:@X[13]
Packit Service 084de1
||	STNDW	@DAT[13]:@DAT[12],*${OUT}[-2]
Packit Service 084de1
   [A0]	MVK	10,B0			; inner loop counter
Packit Service 084de1
||	STNDW	@DAT[15]:@DAT[14],*${OUT}[-1]
Packit Service 084de1
;;===== branch to top1x? is taken here
Packit Service 084de1
Packit Service 084de1
epilogue?:
Packit Service 084de1
	LDDW	*FP[-4],A11:A10		; ABI says so
Packit Service 084de1
	LDDW	*FP[-3],A13:A12
Packit Service 084de1
||	LDDW	*SP[3+8],B11:B10
Packit Service 084de1
	LDDW	*SP[4+8],B13:B12
Packit Service 084de1
||	BNOP	RA
Packit Service 084de1
	LDW	*++SP(40+64),FP		; restore frame pointer
Packit Service 084de1
	NOP	4
Packit Service 084de1
Packit Service 084de1
tail?:
Packit Service 084de1
	LDBU	*${INP}++[1],B24	; load byte by byte
Packit Service 084de1
||	SUB	A0,1,A0
Packit Service 084de1
||	SUB	A0,1,B1
Packit Service 084de1
  [!B1]	BNOP	epilogue?		; interrupts are disabled for whole time
Packit Service 084de1
|| [A0] LDBU	*${INP}++[1],B24
Packit Service 084de1
|| [A0]	SUB	A0,1,A0
Packit Service 084de1
||	SUB	B1,1,B1
Packit Service 084de1
  [!B1]	BNOP	epilogue?
Packit Service 084de1
|| [A0] LDBU	*${INP}++[1],B24
Packit Service 084de1
|| [A0]	SUB	A0,1,A0
Packit Service 084de1
||	SUB	B1,1,B1
Packit Service 084de1
  [!B1]	BNOP	epilogue?
Packit Service 084de1
||	ROTL	@X[0],0,A24
Packit Service 084de1
|| [A0] LDBU	*${INP}++[1],B24
Packit Service 084de1
|| [A0]	SUB	A0,1,A0
Packit Service 084de1
||	SUB	B1,1,B1
Packit Service 084de1
  [!B1]	BNOP	epilogue?
Packit Service 084de1
||	ROTL	@X[0],24,A24
Packit Service 084de1
|| [A0] LDBU	*${INP}++[1],A24
Packit Service 084de1
|| [A0]	SUB	A0,1,A0
Packit Service 084de1
||	SUB	B1,1,B1
Packit Service 084de1
  [!B1]	BNOP	epilogue?
Packit Service 084de1
||	ROTL	@X[0],16,A24
Packit Service 084de1
|| [A0] LDBU	*${INP}++[1],A24
Packit Service 084de1
|| [A0]	SUB	A0,1,A0
Packit Service 084de1
||	SUB	B1,1,B1
Packit Service 084de1
||	XOR	A24,B24,B25
Packit Service 084de1
	STB	B25,*${OUT}++[1]	; store byte by byte
Packit Service 084de1
||[!B1]	BNOP	epilogue?
Packit Service 084de1
||	ROTL	@X[0],8,A24
Packit Service 084de1
|| [A0] LDBU	*${INP}++[1],A24
Packit Service 084de1
|| [A0]	SUB	A0,1,A0
Packit Service 084de1
||	SUB	B1,1,B1
Packit Service 084de1
||	XOR	A24,B24,B25
Packit Service 084de1
	STB	B25,*${OUT}++[1]
Packit Service 084de1
___
Packit Service 084de1
sub TAIL_STEP {
Packit Service 084de1
my $Xi= shift;
Packit Service 084de1
my $T = ($Xi=~/^B/?"B24":"A24");	# match @X[i] to avoid cross path
Packit Service 084de1
my $D = $T; $D=~tr/AB/BA/;
Packit Service 084de1
my $O = $D; $O=~s/24/25/;
Packit Service 084de1
Packit Service 084de1
$code.=<<___;
Packit Service 084de1
||[!B1]	BNOP	epilogue?
Packit Service 084de1
||	ROTL	$Xi,0,$T
Packit Service 084de1
|| [A0] LDBU	*${INP}++[1],$D
Packit Service 084de1
|| [A0]	SUB	A0,1,A0
Packit Service 084de1
||	SUB	B1,1,B1
Packit Service 084de1
||	XOR	A24,B24,$O
Packit Service 084de1
	STB	$O,*${OUT}++[1]
Packit Service 084de1
||[!B1]	BNOP	epilogue?
Packit Service 084de1
||	ROTL	$Xi,24,$T
Packit Service 084de1
|| [A0] LDBU	*${INP}++[1],$T
Packit Service 084de1
|| [A0]	SUB	A0,1,A0
Packit Service 084de1
||	SUB	B1,1,B1
Packit Service 084de1
||	XOR	A24,B24,$O
Packit Service 084de1
	STB	$O,*${OUT}++[1]
Packit Service 084de1
||[!B1]	BNOP	epilogue?
Packit Service 084de1
||	ROTL	$Xi,16,$T
Packit Service 084de1
|| [A0] LDBU	*${INP}++[1],$T
Packit Service 084de1
|| [A0]	SUB	A0,1,A0
Packit Service 084de1
||	SUB	B1,1,B1
Packit Service 084de1
||	XOR	A24,B24,$O
Packit Service 084de1
	STB	$O,*${OUT}++[1]
Packit Service 084de1
||[!B1]	BNOP	epilogue?
Packit Service 084de1
||	ROTL	$Xi,8,$T
Packit Service 084de1
|| [A0] LDBU	*${INP}++[1],$T
Packit Service 084de1
|| [A0]	SUB	A0,1,A0
Packit Service 084de1
||	SUB	B1,1,B1
Packit Service 084de1
||	XOR	A24,B24,$O
Packit Service 084de1
	STB	$O,*${OUT}++[1]
Packit Service 084de1
___
Packit Service 084de1
}
Packit Service 084de1
	foreach (1..14) { TAIL_STEP(@X[$_]); }
Packit Service 084de1
$code.=<<___;
Packit Service 084de1
||[!B1]	BNOP	epilogue?
Packit Service 084de1
||	ROTL	@X[15],0,B24
Packit Service 084de1
||	XOR	A24,B24,A25
Packit Service 084de1
	STB	A25,*${OUT}++[1]
Packit Service 084de1
||	ROTL	@X[15],24,B24
Packit Service 084de1
||	XOR	A24,B24,A25
Packit Service 084de1
	STB	A25,*${OUT}++[1]
Packit Service 084de1
||	ROTL	@X[15],16,B24
Packit Service 084de1
||	XOR	A24,B24,A25
Packit Service 084de1
	STB	A25,*${OUT}++[1]
Packit Service 084de1
||	XOR	A24,B24,A25
Packit Service 084de1
	STB	A25,*${OUT}++[1]
Packit Service 084de1
||	XOR	A24,B24,B25
Packit Service 084de1
	STB	B25,*${OUT}++[1]
Packit Service 084de1
	.endasmfunc
Packit Service 084de1
Packit Service 084de1
	.sect	.const
Packit Service 084de1
	.cstring "ChaCha20 for C64x+, CRYPTOGAMS by <appro\@openssl.org>"
Packit Service 084de1
	.align	4
Packit Service 084de1
___
Packit Service 084de1
Packit Service 084de1
print $code;
Packit Service 084de1
close STDOUT or die "error closing STDOUT: $!";