1e71b7053SJung-uk Kim#! /usr/bin/env perl
2*b077aed3SPierre Pronchery# Copyright 2016-2021 The OpenSSL Project Authors. All Rights Reserved.
3e71b7053SJung-uk Kim#
4*b077aed3SPierre Pronchery# Licensed under the Apache License 2.0 (the "License").  You may not use
5e71b7053SJung-uk Kim# this file except in compliance with the License.  You can obtain a copy
6e71b7053SJung-uk Kim# in the file LICENSE in the source distribution or at
7e71b7053SJung-uk Kim# https://www.openssl.org/source/license.html
8e71b7053SJung-uk Kim
9e71b7053SJung-uk Kim#
10e71b7053SJung-uk Kim# ====================================================================
11e71b7053SJung-uk Kim# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
12e71b7053SJung-uk Kim# project. The module is, however, dual licensed under OpenSSL and
13e71b7053SJung-uk Kim# CRYPTOGAMS licenses depending on where you obtain it. For further
14e71b7053SJung-uk Kim# details see http://www.openssl.org/~appro/cryptogams/.
15e71b7053SJung-uk Kim# ====================================================================
16e71b7053SJung-uk Kim
17e71b7053SJung-uk Kim# March 2016
18e71b7053SJung-uk Kim#
19e71b7053SJung-uk Kim# Initial support for Fujitsu SPARC64 X/X+ comprises minimally
20e71b7053SJung-uk Kim# required key setup and single-block procedures.
21e71b7053SJung-uk Kim#
22e71b7053SJung-uk Kim# April 2016
23e71b7053SJung-uk Kim#
24e71b7053SJung-uk Kim# Add "teaser" CBC and CTR mode-specific subroutines. "Teaser" means
25e71b7053SJung-uk Kim# that parallelizable nature of CBC decrypt and CTR is not utilized
26e71b7053SJung-uk Kim# yet. CBC encrypt on the other hand is as good as it can possibly
27e71b7053SJung-uk Kim# get processing one byte in 4.1 cycles with 128-bit key on SPARC64 X.
28e71b7053SJung-uk Kim# This is ~6x faster than pure software implementation...
29e71b7053SJung-uk Kim#
30e71b7053SJung-uk Kim# July 2016
31e71b7053SJung-uk Kim#
32e71b7053SJung-uk Kim# Switch from faligndata to fshiftorx, which allows to omit alignaddr
33e71b7053SJung-uk Kim# instructions and improve single-block and short-input performance
34e71b7053SJung-uk Kim# with misaligned data.
35e71b7053SJung-uk Kim
36*b077aed3SPierre Pronchery$output = pop and open STDOUT,">$output";
37e71b7053SJung-uk Kim
38e71b7053SJung-uk Kim{
39e71b7053SJung-uk Kimmy ($inp,$out,$key,$rounds,$tmp,$mask) = map("%o$_",(0..5));
40e71b7053SJung-uk Kim
41e71b7053SJung-uk Kim$code.=<<___;
42*b077aed3SPierre Pronchery#ifndef __ASSEMBLER__
43*b077aed3SPierre Pronchery# define __ASSEMBLER__ 1
44*b077aed3SPierre Pronchery#endif
45*b077aed3SPierre Pronchery#include "crypto/sparc_arch.h"
46e71b7053SJung-uk Kim
47e71b7053SJung-uk Kim#define LOCALS (STACK_BIAS+STACK_FRAME)
48e71b7053SJung-uk Kim
49e71b7053SJung-uk Kim.text
50e71b7053SJung-uk Kim
51e71b7053SJung-uk Kim.globl	aes_fx_encrypt
52e71b7053SJung-uk Kim.align	32
53e71b7053SJung-uk Kimaes_fx_encrypt:
54e71b7053SJung-uk Kim	and		$inp, 7, $tmp		! is input aligned?
55e71b7053SJung-uk Kim	andn		$inp, 7, $inp
56e71b7053SJung-uk Kim	ldd		[$key +  0], %f6	! round[0]
57e71b7053SJung-uk Kim	ldd		[$key +  8], %f8
58e71b7053SJung-uk Kim	mov		%o7, %g1
59e71b7053SJung-uk Kim	ld		[$key + 240], $rounds
60e71b7053SJung-uk Kim
61e71b7053SJung-uk Kim1:	call		.+8
62e71b7053SJung-uk Kim	add		%o7, .Linp_align-1b, %o7
63e71b7053SJung-uk Kim
64e71b7053SJung-uk Kim	sll		$tmp, 3, $tmp
65e71b7053SJung-uk Kim	ldd		[$inp + 0], %f0		! load input
66e71b7053SJung-uk Kim	brz,pt		$tmp, .Lenc_inp_aligned
67e71b7053SJung-uk Kim	ldd		[$inp + 8], %f2
68e71b7053SJung-uk Kim
69e71b7053SJung-uk Kim	ldd		[%o7 + $tmp], %f14	! shift left params
70e71b7053SJung-uk Kim	ldd		[$inp + 16], %f4
71e71b7053SJung-uk Kim	fshiftorx	%f0, %f2, %f14, %f0
72e71b7053SJung-uk Kim	fshiftorx	%f2, %f4, %f14, %f2
73e71b7053SJung-uk Kim
74e71b7053SJung-uk Kim.Lenc_inp_aligned:
75e71b7053SJung-uk Kim	ldd		[$key + 16], %f10	! round[1]
76e71b7053SJung-uk Kim	ldd		[$key + 24], %f12
77e71b7053SJung-uk Kim
78e71b7053SJung-uk Kim	fxor		%f0, %f6, %f0		! ^=round[0]
79e71b7053SJung-uk Kim	fxor		%f2, %f8, %f2
80e71b7053SJung-uk Kim	ldd		[$key + 32], %f6	! round[2]
81e71b7053SJung-uk Kim	ldd		[$key + 40], %f8
82e71b7053SJung-uk Kim	add		$key, 32, $key
83e71b7053SJung-uk Kim	sub		$rounds, 4, $rounds
84e71b7053SJung-uk Kim
85e71b7053SJung-uk Kim.Loop_enc:
86e71b7053SJung-uk Kim	fmovd		%f0, %f4
87e71b7053SJung-uk Kim	faesencx	%f2, %f10, %f0
88e71b7053SJung-uk Kim	faesencx	%f4, %f12, %f2
89e71b7053SJung-uk Kim	ldd		[$key + 16], %f10
90e71b7053SJung-uk Kim	ldd		[$key + 24], %f12
91e71b7053SJung-uk Kim	add		$key, 32, $key
92e71b7053SJung-uk Kim
93e71b7053SJung-uk Kim	fmovd		%f0, %f4
94e71b7053SJung-uk Kim	faesencx	%f2, %f6, %f0
95e71b7053SJung-uk Kim	faesencx	%f4, %f8, %f2
96e71b7053SJung-uk Kim	ldd		[$key +  0], %f6
97e71b7053SJung-uk Kim	ldd		[$key +  8], %f8
98e71b7053SJung-uk Kim
99e71b7053SJung-uk Kim	brnz,a		$rounds, .Loop_enc
100e71b7053SJung-uk Kim	sub		$rounds, 2, $rounds
101e71b7053SJung-uk Kim
102e71b7053SJung-uk Kim	andcc		$out, 7, $tmp		! is output aligned?
103e71b7053SJung-uk Kim	andn		$out, 7, $out
104e71b7053SJung-uk Kim	mov		0xff, $mask
105e71b7053SJung-uk Kim	srl		$mask, $tmp, $mask
106e71b7053SJung-uk Kim	add		%o7, 64, %o7
107e71b7053SJung-uk Kim	sll		$tmp, 3, $tmp
108e71b7053SJung-uk Kim
109e71b7053SJung-uk Kim	fmovd		%f0, %f4
110e71b7053SJung-uk Kim	faesencx	%f2, %f10, %f0
111e71b7053SJung-uk Kim	faesencx	%f4, %f12, %f2
112e71b7053SJung-uk Kim	ldd		[%o7 + $tmp], %f14	! shift right params
113e71b7053SJung-uk Kim
114e71b7053SJung-uk Kim	fmovd		%f0, %f4
115e71b7053SJung-uk Kim	faesenclx	%f2, %f6, %f0
116e71b7053SJung-uk Kim	faesenclx	%f4, %f8, %f2
117e71b7053SJung-uk Kim
118e71b7053SJung-uk Kim	bnz,pn		%icc, .Lenc_out_unaligned
119e71b7053SJung-uk Kim	mov		%g1, %o7
120e71b7053SJung-uk Kim
121e71b7053SJung-uk Kim	std		%f0, [$out + 0]
122e71b7053SJung-uk Kim	retl
123e71b7053SJung-uk Kim	std		%f2, [$out + 8]
124e71b7053SJung-uk Kim
125e71b7053SJung-uk Kim.align	16
126e71b7053SJung-uk Kim.Lenc_out_unaligned:
127e71b7053SJung-uk Kim	add		$out, 16, $inp
128e71b7053SJung-uk Kim	orn		%g0, $mask, $tmp
129e71b7053SJung-uk Kim	fshiftorx	%f0, %f0, %f14, %f4
130e71b7053SJung-uk Kim	fshiftorx	%f0, %f2, %f14, %f6
131e71b7053SJung-uk Kim	fshiftorx	%f2, %f2, %f14, %f8
132e71b7053SJung-uk Kim
133e71b7053SJung-uk Kim	stda		%f4, [$out + $mask]0xc0	! partial store
134e71b7053SJung-uk Kim	std		%f6, [$out + 8]
135e71b7053SJung-uk Kim	stda		%f8, [$inp + $tmp]0xc0	! partial store
136e71b7053SJung-uk Kim	retl
137e71b7053SJung-uk Kim	nop
138e71b7053SJung-uk Kim.type	aes_fx_encrypt,#function
139e71b7053SJung-uk Kim.size	aes_fx_encrypt,.-aes_fx_encrypt
140e71b7053SJung-uk Kim
141e71b7053SJung-uk Kim.globl	aes_fx_decrypt
142e71b7053SJung-uk Kim.align	32
143e71b7053SJung-uk Kimaes_fx_decrypt:
144e71b7053SJung-uk Kim	and		$inp, 7, $tmp		! is input aligned?
145e71b7053SJung-uk Kim	andn		$inp, 7, $inp
146e71b7053SJung-uk Kim	ldd		[$key +  0], %f6	! round[0]
147e71b7053SJung-uk Kim	ldd		[$key +  8], %f8
148e71b7053SJung-uk Kim	mov		%o7, %g1
149e71b7053SJung-uk Kim	ld		[$key + 240], $rounds
150e71b7053SJung-uk Kim
151e71b7053SJung-uk Kim1:	call		.+8
152e71b7053SJung-uk Kim	add		%o7, .Linp_align-1b, %o7
153e71b7053SJung-uk Kim
154e71b7053SJung-uk Kim	sll		$tmp, 3, $tmp
155e71b7053SJung-uk Kim	ldd		[$inp + 0], %f0		! load input
156e71b7053SJung-uk Kim	brz,pt		$tmp, .Ldec_inp_aligned
157e71b7053SJung-uk Kim	ldd		[$inp + 8], %f2
158e71b7053SJung-uk Kim
159e71b7053SJung-uk Kim	ldd		[%o7 + $tmp], %f14	! shift left params
160e71b7053SJung-uk Kim	ldd		[$inp + 16], %f4
161e71b7053SJung-uk Kim	fshiftorx	%f0, %f2, %f14, %f0
162e71b7053SJung-uk Kim	fshiftorx	%f2, %f4, %f14, %f2
163e71b7053SJung-uk Kim
164e71b7053SJung-uk Kim.Ldec_inp_aligned:
165e71b7053SJung-uk Kim	ldd		[$key + 16], %f10	! round[1]
166e71b7053SJung-uk Kim	ldd		[$key + 24], %f12
167e71b7053SJung-uk Kim
168e71b7053SJung-uk Kim	fxor		%f0, %f6, %f0		! ^=round[0]
169e71b7053SJung-uk Kim	fxor		%f2, %f8, %f2
170e71b7053SJung-uk Kim	ldd		[$key + 32], %f6	! round[2]
171e71b7053SJung-uk Kim	ldd		[$key + 40], %f8
172e71b7053SJung-uk Kim	add		$key, 32, $key
173e71b7053SJung-uk Kim	sub		$rounds, 4, $rounds
174e71b7053SJung-uk Kim
175e71b7053SJung-uk Kim.Loop_dec:
176e71b7053SJung-uk Kim	fmovd		%f0, %f4
177e71b7053SJung-uk Kim	faesdecx	%f2, %f10, %f0
178e71b7053SJung-uk Kim	faesdecx	%f4, %f12, %f2
179e71b7053SJung-uk Kim	ldd		[$key + 16], %f10
180e71b7053SJung-uk Kim	ldd		[$key + 24], %f12
181e71b7053SJung-uk Kim	add		$key, 32, $key
182e71b7053SJung-uk Kim
183e71b7053SJung-uk Kim	fmovd		%f0, %f4
184e71b7053SJung-uk Kim	faesdecx	%f2, %f6, %f0
185e71b7053SJung-uk Kim	faesdecx	%f4, %f8, %f2
186e71b7053SJung-uk Kim	ldd		[$key +  0], %f6
187e71b7053SJung-uk Kim	ldd		[$key +  8], %f8
188e71b7053SJung-uk Kim
189e71b7053SJung-uk Kim	brnz,a		$rounds, .Loop_dec
190e71b7053SJung-uk Kim	sub		$rounds, 2, $rounds
191e71b7053SJung-uk Kim
192e71b7053SJung-uk Kim	andcc		$out, 7, $tmp		! is output aligned?
193e71b7053SJung-uk Kim	andn		$out, 7, $out
194e71b7053SJung-uk Kim	mov		0xff, $mask
195e71b7053SJung-uk Kim	srl		$mask, $tmp, $mask
196e71b7053SJung-uk Kim	add		%o7, 64, %o7
197e71b7053SJung-uk Kim	sll		$tmp, 3, $tmp
198e71b7053SJung-uk Kim
199e71b7053SJung-uk Kim	fmovd		%f0, %f4
200e71b7053SJung-uk Kim	faesdecx	%f2, %f10, %f0
201e71b7053SJung-uk Kim	faesdecx	%f4, %f12, %f2
202e71b7053SJung-uk Kim	ldd		[%o7 + $tmp], %f14	! shift right params
203e71b7053SJung-uk Kim
204e71b7053SJung-uk Kim	fmovd		%f0, %f4
205e71b7053SJung-uk Kim	faesdeclx	%f2, %f6, %f0
206e71b7053SJung-uk Kim	faesdeclx	%f4, %f8, %f2
207e71b7053SJung-uk Kim
208e71b7053SJung-uk Kim	bnz,pn		%icc, .Ldec_out_unaligned
209e71b7053SJung-uk Kim	mov		%g1, %o7
210e71b7053SJung-uk Kim
211e71b7053SJung-uk Kim	std		%f0, [$out + 0]
212e71b7053SJung-uk Kim	retl
213e71b7053SJung-uk Kim	std		%f2, [$out + 8]
214e71b7053SJung-uk Kim
215e71b7053SJung-uk Kim.align	16
216e71b7053SJung-uk Kim.Ldec_out_unaligned:
217e71b7053SJung-uk Kim	add		$out, 16, $inp
218e71b7053SJung-uk Kim	orn		%g0, $mask, $tmp
219e71b7053SJung-uk Kim	fshiftorx	%f0, %f0, %f14, %f4
220e71b7053SJung-uk Kim	fshiftorx	%f0, %f2, %f14, %f6
221e71b7053SJung-uk Kim	fshiftorx	%f2, %f2, %f14, %f8
222e71b7053SJung-uk Kim
223e71b7053SJung-uk Kim	stda		%f4, [$out + $mask]0xc0	! partial store
224e71b7053SJung-uk Kim	std		%f6, [$out + 8]
225e71b7053SJung-uk Kim	stda		%f8, [$inp + $tmp]0xc0	! partial store
226e71b7053SJung-uk Kim	retl
227e71b7053SJung-uk Kim	nop
228e71b7053SJung-uk Kim.type	aes_fx_decrypt,#function
229e71b7053SJung-uk Kim.size	aes_fx_decrypt,.-aes_fx_decrypt
230e71b7053SJung-uk Kim___
231e71b7053SJung-uk Kim}
232e71b7053SJung-uk Kim{
233e71b7053SJung-uk Kimmy ($inp,$bits,$out,$tmp,$inc) = map("%o$_",(0..5));
234e71b7053SJung-uk Kim$code.=<<___;
235e71b7053SJung-uk Kim.globl	aes_fx_set_decrypt_key
236e71b7053SJung-uk Kim.align	32
237e71b7053SJung-uk Kimaes_fx_set_decrypt_key:
238e71b7053SJung-uk Kim	b		.Lset_encrypt_key
239e71b7053SJung-uk Kim	mov		-1, $inc
240e71b7053SJung-uk Kim	retl
241e71b7053SJung-uk Kim	nop
242e71b7053SJung-uk Kim.type	aes_fx_set_decrypt_key,#function
243e71b7053SJung-uk Kim.size	aes_fx_set_decrypt_key,.-aes_fx_set_decrypt_key
244e71b7053SJung-uk Kim
245e71b7053SJung-uk Kim.globl	aes_fx_set_encrypt_key
246e71b7053SJung-uk Kim.align	32
247e71b7053SJung-uk Kimaes_fx_set_encrypt_key:
248e71b7053SJung-uk Kim	mov		1, $inc
249e71b7053SJung-uk Kim	nop
250e71b7053SJung-uk Kim.Lset_encrypt_key:
251e71b7053SJung-uk Kim	and		$inp, 7, $tmp
252e71b7053SJung-uk Kim	andn		$inp, 7, $inp
253e71b7053SJung-uk Kim	sll		$tmp, 3, $tmp
254e71b7053SJung-uk Kim	mov		%o7, %g1
255e71b7053SJung-uk Kim
256e71b7053SJung-uk Kim1:	call		.+8
257e71b7053SJung-uk Kim	add		%o7, .Linp_align-1b, %o7
258e71b7053SJung-uk Kim
259e71b7053SJung-uk Kim	ldd		[%o7 + $tmp], %f10	! shift left params
260e71b7053SJung-uk Kim	mov		%g1, %o7
261e71b7053SJung-uk Kim
262e71b7053SJung-uk Kim	cmp		$bits, 192
263e71b7053SJung-uk Kim	ldd		[$inp + 0], %f0
264e71b7053SJung-uk Kim	bl,pt		%icc, .L128
265e71b7053SJung-uk Kim	ldd		[$inp + 8], %f2
266e71b7053SJung-uk Kim
267e71b7053SJung-uk Kim	be,pt		%icc, .L192
268e71b7053SJung-uk Kim	ldd		[$inp + 16], %f4
269e71b7053SJung-uk Kim	brz,pt		$tmp, .L256aligned
270e71b7053SJung-uk Kim	ldd		[$inp + 24], %f6
271e71b7053SJung-uk Kim
272e71b7053SJung-uk Kim	ldd		[$inp + 32], %f8
273e71b7053SJung-uk Kim	fshiftorx	%f0, %f2, %f10, %f0
274e71b7053SJung-uk Kim	fshiftorx	%f2, %f4, %f10, %f2
275e71b7053SJung-uk Kim	fshiftorx	%f4, %f6, %f10, %f4
276e71b7053SJung-uk Kim	fshiftorx	%f6, %f8, %f10, %f6
277e71b7053SJung-uk Kim
278e71b7053SJung-uk Kim.L256aligned:
279e71b7053SJung-uk Kim	mov		14, $bits
280e71b7053SJung-uk Kim	and		$inc, `14*16`, $tmp
281e71b7053SJung-uk Kim	st		$bits, [$out + 240]	! store rounds
282e71b7053SJung-uk Kim	add		$out, $tmp, $out	! start or end of key schedule
283e71b7053SJung-uk Kim	sllx		$inc, 4, $inc		! 16 or -16
284e71b7053SJung-uk Kim___
285e71b7053SJung-uk Kimfor ($i=0; $i<6; $i++) {
286e71b7053SJung-uk Kim    $code.=<<___;
287e71b7053SJung-uk Kim	std		%f0, [$out + 0]
288e71b7053SJung-uk Kim	faeskeyx	%f6, `0x10+$i`, %f0
289e71b7053SJung-uk Kim	std		%f2, [$out + 8]
290e71b7053SJung-uk Kim	add		$out, $inc, $out
291e71b7053SJung-uk Kim	faeskeyx	%f0, 0x00, %f2
292e71b7053SJung-uk Kim	std		%f4, [$out + 0]
293e71b7053SJung-uk Kim	faeskeyx	%f2, 0x01, %f4
294e71b7053SJung-uk Kim	std		%f6, [$out + 8]
295e71b7053SJung-uk Kim	add		$out, $inc, $out
296e71b7053SJung-uk Kim	faeskeyx	%f4, 0x00, %f6
297e71b7053SJung-uk Kim___
298e71b7053SJung-uk Kim}
299e71b7053SJung-uk Kim$code.=<<___;
300e71b7053SJung-uk Kim	std		%f0, [$out + 0]
301e71b7053SJung-uk Kim	faeskeyx	%f6, `0x10+$i`, %f0
302e71b7053SJung-uk Kim	std		%f2, [$out + 8]
303e71b7053SJung-uk Kim	add		$out, $inc, $out
304e71b7053SJung-uk Kim	faeskeyx	%f0, 0x00, %f2
305e71b7053SJung-uk Kim	std		%f4,[$out + 0]
306e71b7053SJung-uk Kim	std		%f6,[$out + 8]
307e71b7053SJung-uk Kim	add		$out, $inc, $out
308e71b7053SJung-uk Kim	std		%f0,[$out + 0]
309e71b7053SJung-uk Kim	std		%f2,[$out + 8]
310e71b7053SJung-uk Kim	retl
311e71b7053SJung-uk Kim	xor		%o0, %o0, %o0		! return 0
312e71b7053SJung-uk Kim
313e71b7053SJung-uk Kim.align	16
314e71b7053SJung-uk Kim.L192:
315e71b7053SJung-uk Kim	brz,pt		$tmp, .L192aligned
316e71b7053SJung-uk Kim	nop
317e71b7053SJung-uk Kim
318e71b7053SJung-uk Kim	ldd		[$inp + 24], %f6
319e71b7053SJung-uk Kim	fshiftorx	%f0, %f2, %f10, %f0
320e71b7053SJung-uk Kim	fshiftorx	%f2, %f4, %f10, %f2
321e71b7053SJung-uk Kim	fshiftorx	%f4, %f6, %f10, %f4
322e71b7053SJung-uk Kim
323e71b7053SJung-uk Kim.L192aligned:
324e71b7053SJung-uk Kim	mov		12, $bits
325e71b7053SJung-uk Kim	and		$inc, `12*16`, $tmp
326e71b7053SJung-uk Kim	st		$bits, [$out + 240]	! store rounds
327e71b7053SJung-uk Kim	add		$out, $tmp, $out	! start or end of key schedule
328e71b7053SJung-uk Kim	sllx		$inc, 4, $inc		! 16 or -16
329e71b7053SJung-uk Kim___
330e71b7053SJung-uk Kimfor ($i=0; $i<8; $i+=2) {
331e71b7053SJung-uk Kim    $code.=<<___;
332e71b7053SJung-uk Kim	std		%f0, [$out + 0]
333e71b7053SJung-uk Kim	faeskeyx	%f4, `0x10+$i`, %f0
334e71b7053SJung-uk Kim	std		%f2, [$out + 8]
335e71b7053SJung-uk Kim	add		$out, $inc, $out
336e71b7053SJung-uk Kim	faeskeyx	%f0, 0x00, %f2
337e71b7053SJung-uk Kim	std		%f4, [$out + 0]
338e71b7053SJung-uk Kim	faeskeyx	%f2, 0x00, %f4
339e71b7053SJung-uk Kim	std		%f0, [$out + 8]
340e71b7053SJung-uk Kim	add		$out, $inc, $out
341e71b7053SJung-uk Kim	faeskeyx	%f4, `0x10+$i+1`, %f0
342e71b7053SJung-uk Kim	std		%f2, [$out + 0]
343e71b7053SJung-uk Kim	faeskeyx	%f0, 0x00, %f2
344e71b7053SJung-uk Kim	std		%f4, [$out + 8]
345e71b7053SJung-uk Kim	add		$out, $inc, $out
346e71b7053SJung-uk Kim___
347e71b7053SJung-uk Kim$code.=<<___		if ($i<6);
348e71b7053SJung-uk Kim	faeskeyx	%f2, 0x00, %f4
349e71b7053SJung-uk Kim___
350e71b7053SJung-uk Kim}
351e71b7053SJung-uk Kim$code.=<<___;
352e71b7053SJung-uk Kim	std		%f0, [$out + 0]
353e71b7053SJung-uk Kim	std		%f2, [$out + 8]
354e71b7053SJung-uk Kim	retl
355e71b7053SJung-uk Kim	xor		%o0, %o0, %o0		! return 0
356e71b7053SJung-uk Kim
357e71b7053SJung-uk Kim.align	16
358e71b7053SJung-uk Kim.L128:
359e71b7053SJung-uk Kim	brz,pt		$tmp, .L128aligned
360e71b7053SJung-uk Kim	nop
361e71b7053SJung-uk Kim
362e71b7053SJung-uk Kim	ldd		[$inp + 16], %f4
363e71b7053SJung-uk Kim	fshiftorx	%f0, %f2, %f10, %f0
364e71b7053SJung-uk Kim	fshiftorx	%f2, %f4, %f10, %f2
365e71b7053SJung-uk Kim
366e71b7053SJung-uk Kim.L128aligned:
367e71b7053SJung-uk Kim	mov		10, $bits
368e71b7053SJung-uk Kim	and		$inc, `10*16`, $tmp
369e71b7053SJung-uk Kim	st		$bits, [$out + 240]	! store rounds
370e71b7053SJung-uk Kim	add		$out, $tmp, $out	! start or end of key schedule
371e71b7053SJung-uk Kim	sllx		$inc, 4, $inc		! 16 or -16
372e71b7053SJung-uk Kim___
373e71b7053SJung-uk Kimfor ($i=0; $i<10; $i++) {
374e71b7053SJung-uk Kim    $code.=<<___;
375e71b7053SJung-uk Kim	std		%f0, [$out + 0]
376e71b7053SJung-uk Kim	faeskeyx	%f2, `0x10+$i`, %f0
377e71b7053SJung-uk Kim	std		%f2, [$out + 8]
378e71b7053SJung-uk Kim	add		$out, $inc, $out
379e71b7053SJung-uk Kim	faeskeyx	%f0, 0x00, %f2
380e71b7053SJung-uk Kim___
381e71b7053SJung-uk Kim}
382e71b7053SJung-uk Kim$code.=<<___;
383e71b7053SJung-uk Kim	std		%f0, [$out + 0]
384e71b7053SJung-uk Kim	std		%f2, [$out + 8]
385e71b7053SJung-uk Kim	retl
386e71b7053SJung-uk Kim	xor		%o0, %o0, %o0		! return 0
387e71b7053SJung-uk Kim.type	aes_fx_set_encrypt_key,#function
388e71b7053SJung-uk Kim.size	aes_fx_set_encrypt_key,.-aes_fx_set_encrypt_key
389e71b7053SJung-uk Kim___
390e71b7053SJung-uk Kim}
391e71b7053SJung-uk Kim{
392e71b7053SJung-uk Kimmy ($inp,$out,$len,$key,$ivp,$dir) = map("%i$_",(0..5));
393e71b7053SJung-uk Kimmy ($rounds,$inner,$end,$inc,$ialign,$oalign,$mask) = map("%l$_",(0..7));
394e71b7053SJung-uk Kimmy ($iv0,$iv1,$r0hi,$r0lo,$rlhi,$rllo,$in0,$in1,$intail,$outhead,$fshift)
395e71b7053SJung-uk Kim   = map("%f$_",grep { !($_ & 1) } (16 .. 62));
396e71b7053SJung-uk Kimmy ($ileft,$iright) = ($ialign,$oalign);
397e71b7053SJung-uk Kim
398e71b7053SJung-uk Kim$code.=<<___;
399e71b7053SJung-uk Kim.globl	aes_fx_cbc_encrypt
400e71b7053SJung-uk Kim.align	32
401e71b7053SJung-uk Kimaes_fx_cbc_encrypt:
402e71b7053SJung-uk Kim	save		%sp, -STACK_FRAME-16, %sp
403e71b7053SJung-uk Kim	srln		$len, 4, $len
404e71b7053SJung-uk Kim	and		$inp, 7, $ialign
405e71b7053SJung-uk Kim	andn		$inp, 7, $inp
406e71b7053SJung-uk Kim	brz,pn		$len, .Lcbc_no_data
407e71b7053SJung-uk Kim	sll		$ialign, 3, $ileft
408e71b7053SJung-uk Kim
409e71b7053SJung-uk Kim1:	call		.+8
410e71b7053SJung-uk Kim	add		%o7, .Linp_align-1b, %o7
411e71b7053SJung-uk Kim
412e71b7053SJung-uk Kim	ld		[$key + 240], $rounds
413e71b7053SJung-uk Kim	and		$out, 7, $oalign
414e71b7053SJung-uk Kim	ld		[$ivp + 0], %f0		! load ivec
415e71b7053SJung-uk Kim	andn		$out, 7, $out
416e71b7053SJung-uk Kim	ld		[$ivp + 4], %f1
417e71b7053SJung-uk Kim	sll		$oalign, 3, $mask
418e71b7053SJung-uk Kim	ld		[$ivp + 8], %f2
419e71b7053SJung-uk Kim	ld		[$ivp + 12], %f3
420e71b7053SJung-uk Kim
421e71b7053SJung-uk Kim	sll		$rounds, 4, $rounds
422e71b7053SJung-uk Kim	add		$rounds, $key, $end
423e71b7053SJung-uk Kim	ldd		[$key + 0], $r0hi	! round[0]
424e71b7053SJung-uk Kim	ldd		[$key + 8], $r0lo
425e71b7053SJung-uk Kim
426e71b7053SJung-uk Kim	add		$inp, 16, $inp
427e71b7053SJung-uk Kim	sub		$len,  1, $len
428e71b7053SJung-uk Kim	ldd		[$end + 0], $rlhi	! round[last]
429e71b7053SJung-uk Kim	ldd		[$end + 8], $rllo
430e71b7053SJung-uk Kim
431e71b7053SJung-uk Kim	mov		16, $inc
432e71b7053SJung-uk Kim	movrz		$len, 0, $inc
433e71b7053SJung-uk Kim	ldd		[$key + 16], %f10	! round[1]
434e71b7053SJung-uk Kim	ldd		[$key + 24], %f12
435e71b7053SJung-uk Kim
436e71b7053SJung-uk Kim	ldd		[%o7 + $ileft], $fshift	! shift left params
437e71b7053SJung-uk Kim	add		%o7, 64, %o7
438e71b7053SJung-uk Kim	ldd		[$inp - 16], $in0	! load input
439e71b7053SJung-uk Kim	ldd		[$inp -  8], $in1
440e71b7053SJung-uk Kim	ldda		[$inp]0x82, $intail	! non-faulting load
441e71b7053SJung-uk Kim	brz		$dir, .Lcbc_decrypt
442e71b7053SJung-uk Kim	add		$inp, $inc, $inp	! inp+=16
443e71b7053SJung-uk Kim
444e71b7053SJung-uk Kim	fxor		$r0hi, %f0, %f0		! ivec^=round[0]
445e71b7053SJung-uk Kim	fxor		$r0lo, %f2, %f2
446e71b7053SJung-uk Kim	fshiftorx	$in0, $in1, $fshift, $in0
447e71b7053SJung-uk Kim	fshiftorx	$in1, $intail, $fshift, $in1
448e71b7053SJung-uk Kim	nop
449e71b7053SJung-uk Kim
450e71b7053SJung-uk Kim.Loop_cbc_enc:
451e71b7053SJung-uk Kim	fxor		$in0, %f0, %f0		! inp^ivec^round[0]
452e71b7053SJung-uk Kim	fxor		$in1, %f2, %f2
453e71b7053SJung-uk Kim	ldd		[$key + 32], %f6	! round[2]
454e71b7053SJung-uk Kim	ldd		[$key + 40], %f8
455e71b7053SJung-uk Kim	add		$key, 32, $end
456e71b7053SJung-uk Kim	sub		$rounds, 16*6, $inner
457e71b7053SJung-uk Kim
458e71b7053SJung-uk Kim.Lcbc_enc:
459e71b7053SJung-uk Kim	fmovd		%f0, %f4
460e71b7053SJung-uk Kim	faesencx	%f2, %f10, %f0
461e71b7053SJung-uk Kim	faesencx	%f4, %f12, %f2
462e71b7053SJung-uk Kim	ldd		[$end + 16], %f10
463e71b7053SJung-uk Kim	ldd		[$end + 24], %f12
464e71b7053SJung-uk Kim	add		$end, 32, $end
465e71b7053SJung-uk Kim
466e71b7053SJung-uk Kim	fmovd		%f0, %f4
467e71b7053SJung-uk Kim	faesencx	%f2, %f6, %f0
468e71b7053SJung-uk Kim	faesencx	%f4, %f8, %f2
469e71b7053SJung-uk Kim	ldd		[$end + 0], %f6
470e71b7053SJung-uk Kim	ldd		[$end + 8], %f8
471e71b7053SJung-uk Kim
472e71b7053SJung-uk Kim	brnz,a		$inner, .Lcbc_enc
473e71b7053SJung-uk Kim	sub		$inner, 16*2, $inner
474e71b7053SJung-uk Kim
475e71b7053SJung-uk Kim	fmovd		%f0, %f4
476e71b7053SJung-uk Kim	faesencx	%f2, %f10, %f0
477e71b7053SJung-uk Kim	faesencx	%f4, %f12, %f2
478e71b7053SJung-uk Kim	ldd		[$end + 16], %f10	! round[last-1]
479e71b7053SJung-uk Kim	ldd		[$end + 24], %f12
480e71b7053SJung-uk Kim
481e71b7053SJung-uk Kim	movrz		$len, 0, $inc
482e71b7053SJung-uk Kim	fmovd		$intail, $in0
483e71b7053SJung-uk Kim	ldd		[$inp - 8], $in1	! load next input block
484e71b7053SJung-uk Kim	ldda		[$inp]0x82, $intail	! non-faulting load
485e71b7053SJung-uk Kim	add		$inp, $inc, $inp	! inp+=16
486e71b7053SJung-uk Kim
487e71b7053SJung-uk Kim	fmovd		%f0, %f4
488e71b7053SJung-uk Kim	faesencx	%f2, %f6, %f0
489e71b7053SJung-uk Kim	faesencx	%f4, %f8, %f2
490e71b7053SJung-uk Kim
491e71b7053SJung-uk Kim	fshiftorx	$in0, $in1, $fshift, $in0
492e71b7053SJung-uk Kim	fshiftorx	$in1, $intail, $fshift, $in1
493e71b7053SJung-uk Kim
494e71b7053SJung-uk Kim	fmovd		%f0, %f4
495e71b7053SJung-uk Kim	faesencx	%f2, %f10, %f0
496e71b7053SJung-uk Kim	faesencx	%f4, %f12, %f2
497e71b7053SJung-uk Kim	ldd		[$key + 16], %f10	! round[1]
498e71b7053SJung-uk Kim	ldd		[$key + 24], %f12
499e71b7053SJung-uk Kim
500e71b7053SJung-uk Kim	fxor		$r0hi, $in0, $in0	! inp^=round[0]
501e71b7053SJung-uk Kim	fxor		$r0lo, $in1, $in1
502e71b7053SJung-uk Kim
503e71b7053SJung-uk Kim	fmovd		%f0, %f4
504e71b7053SJung-uk Kim	faesenclx	%f2, $rlhi, %f0
505e71b7053SJung-uk Kim	faesenclx	%f4, $rllo, %f2
506e71b7053SJung-uk Kim
507e71b7053SJung-uk Kim	brnz,pn		$oalign, .Lcbc_enc_unaligned_out
508e71b7053SJung-uk Kim	nop
509e71b7053SJung-uk Kim
510e71b7053SJung-uk Kim	std		%f0, [$out + 0]
511e71b7053SJung-uk Kim	std		%f2, [$out + 8]
512e71b7053SJung-uk Kim	add		$out, 16, $out
513e71b7053SJung-uk Kim
514e71b7053SJung-uk Kim	brnz,a		$len, .Loop_cbc_enc
515e71b7053SJung-uk Kim	sub		$len, 1, $len
516e71b7053SJung-uk Kim
517e71b7053SJung-uk Kim	st		%f0, [$ivp + 0]		! output ivec
518e71b7053SJung-uk Kim	st		%f1, [$ivp + 4]
519e71b7053SJung-uk Kim	st		%f2, [$ivp + 8]
520e71b7053SJung-uk Kim	st		%f3, [$ivp + 12]
521e71b7053SJung-uk Kim
522e71b7053SJung-uk Kim.Lcbc_no_data:
523e71b7053SJung-uk Kim	ret
524e71b7053SJung-uk Kim	restore
525e71b7053SJung-uk Kim
526e71b7053SJung-uk Kim.align	32
527e71b7053SJung-uk Kim.Lcbc_enc_unaligned_out:
528e71b7053SJung-uk Kim	ldd		[%o7 + $mask], $fshift	! shift right params
529e71b7053SJung-uk Kim	mov		0xff, $mask
530e71b7053SJung-uk Kim	srl		$mask, $oalign, $mask
531e71b7053SJung-uk Kim	sub		%g0, $ileft, $iright
532e71b7053SJung-uk Kim
533e71b7053SJung-uk Kim	fshiftorx	%f0, %f0, $fshift, %f6
534e71b7053SJung-uk Kim	fshiftorx	%f0, %f2, $fshift, %f8
535e71b7053SJung-uk Kim
536e71b7053SJung-uk Kim	stda		%f6, [$out + $mask]0xc0	! partial store
537e71b7053SJung-uk Kim	orn		%g0, $mask, $mask
538e71b7053SJung-uk Kim	std		%f8, [$out + 8]
539e71b7053SJung-uk Kim	add		$out, 16, $out
540e71b7053SJung-uk Kim	brz		$len, .Lcbc_enc_unaligned_out_done
541e71b7053SJung-uk Kim	sub		$len, 1, $len
542e71b7053SJung-uk Kim	b		.Loop_cbc_enc_unaligned_out
543e71b7053SJung-uk Kim	nop
544e71b7053SJung-uk Kim
545e71b7053SJung-uk Kim.align	32
546e71b7053SJung-uk Kim.Loop_cbc_enc_unaligned_out:
547e71b7053SJung-uk Kim	fmovd		%f2, $outhead
548e71b7053SJung-uk Kim	fxor		$in0, %f0, %f0		! inp^ivec^round[0]
549e71b7053SJung-uk Kim	fxor		$in1, %f2, %f2
550e71b7053SJung-uk Kim	ldd		[$key + 32], %f6	! round[2]
551e71b7053SJung-uk Kim	ldd		[$key + 40], %f8
552e71b7053SJung-uk Kim
553e71b7053SJung-uk Kim	fmovd		%f0, %f4
554e71b7053SJung-uk Kim	faesencx	%f2, %f10, %f0
555e71b7053SJung-uk Kim	faesencx	%f4, %f12, %f2
556e71b7053SJung-uk Kim	ldd		[$key + 48], %f10	! round[3]
557e71b7053SJung-uk Kim	ldd		[$key + 56], %f12
558e71b7053SJung-uk Kim
559e71b7053SJung-uk Kim	ldx		[$inp - 16], %o0
560e71b7053SJung-uk Kim	ldx		[$inp -  8], %o1
561e71b7053SJung-uk Kim	brz		$ileft, .Lcbc_enc_aligned_inp
562e71b7053SJung-uk Kim	movrz		$len, 0, $inc
563e71b7053SJung-uk Kim
564e71b7053SJung-uk Kim	ldx		[$inp], %o2
565e71b7053SJung-uk Kim	sllx		%o0, $ileft, %o0
566e71b7053SJung-uk Kim	srlx		%o1, $iright, %g1
567e71b7053SJung-uk Kim	sllx		%o1, $ileft, %o1
568e71b7053SJung-uk Kim	or		%g1, %o0, %o0
569e71b7053SJung-uk Kim	srlx		%o2, $iright, %o2
570e71b7053SJung-uk Kim	or		%o2, %o1, %o1
571e71b7053SJung-uk Kim
572e71b7053SJung-uk Kim.Lcbc_enc_aligned_inp:
573e71b7053SJung-uk Kim	fmovd		%f0, %f4
574e71b7053SJung-uk Kim	faesencx	%f2, %f6, %f0
575e71b7053SJung-uk Kim	faesencx	%f4, %f8, %f2
576e71b7053SJung-uk Kim	ldd		[$key + 64], %f6	! round[4]
577e71b7053SJung-uk Kim	ldd		[$key + 72], %f8
578e71b7053SJung-uk Kim	add		$key, 64, $end
579e71b7053SJung-uk Kim	sub		$rounds, 16*8, $inner
580e71b7053SJung-uk Kim
581e71b7053SJung-uk Kim	stx		%o0, [%sp + LOCALS + 0]
582e71b7053SJung-uk Kim	stx		%o1, [%sp + LOCALS + 8]
583e71b7053SJung-uk Kim	add		$inp, $inc, $inp	! inp+=16
584e71b7053SJung-uk Kim	nop
585e71b7053SJung-uk Kim
586e71b7053SJung-uk Kim.Lcbc_enc_unaligned:
587e71b7053SJung-uk Kim	fmovd		%f0, %f4
588e71b7053SJung-uk Kim	faesencx	%f2, %f10, %f0
589e71b7053SJung-uk Kim	faesencx	%f4, %f12, %f2
590e71b7053SJung-uk Kim	ldd		[$end + 16], %f10
591e71b7053SJung-uk Kim	ldd		[$end + 24], %f12
592e71b7053SJung-uk Kim	add		$end, 32, $end
593e71b7053SJung-uk Kim
594e71b7053SJung-uk Kim	fmovd		%f0, %f4
595e71b7053SJung-uk Kim	faesencx	%f2, %f6, %f0
596e71b7053SJung-uk Kim	faesencx	%f4, %f8, %f2
597e71b7053SJung-uk Kim	ldd		[$end + 0], %f6
598e71b7053SJung-uk Kim	ldd		[$end + 8], %f8
599e71b7053SJung-uk Kim
600e71b7053SJung-uk Kim	brnz,a		$inner, .Lcbc_enc_unaligned
601e71b7053SJung-uk Kim	sub		$inner, 16*2, $inner
602e71b7053SJung-uk Kim
603e71b7053SJung-uk Kim	fmovd		%f0, %f4
604e71b7053SJung-uk Kim	faesencx	%f2, %f10, %f0
605e71b7053SJung-uk Kim	faesencx	%f4, %f12, %f2
606e71b7053SJung-uk Kim	ldd		[$end + 16], %f10	! round[last-1]
607e71b7053SJung-uk Kim	ldd		[$end + 24], %f12
608e71b7053SJung-uk Kim
609e71b7053SJung-uk Kim	fmovd		%f0, %f4
610e71b7053SJung-uk Kim	faesencx	%f2, %f6, %f0
611e71b7053SJung-uk Kim	faesencx	%f4, %f8, %f2
612e71b7053SJung-uk Kim
613e71b7053SJung-uk Kim	ldd		[%sp + LOCALS + 0], $in0
614e71b7053SJung-uk Kim	ldd		[%sp + LOCALS + 8], $in1
615e71b7053SJung-uk Kim
616e71b7053SJung-uk Kim	fmovd		%f0, %f4
617e71b7053SJung-uk Kim	faesencx	%f2, %f10, %f0
618e71b7053SJung-uk Kim	faesencx	%f4, %f12, %f2
619e71b7053SJung-uk Kim	ldd		[$key + 16], %f10	! round[1]
620e71b7053SJung-uk Kim	ldd		[$key + 24], %f12
621e71b7053SJung-uk Kim
622e71b7053SJung-uk Kim	fxor		$r0hi, $in0, $in0	! inp^=round[0]
623e71b7053SJung-uk Kim	fxor		$r0lo, $in1, $in1
624e71b7053SJung-uk Kim
625e71b7053SJung-uk Kim	fmovd		%f0, %f4
626e71b7053SJung-uk Kim	faesenclx	%f2, $rlhi, %f0
627e71b7053SJung-uk Kim	faesenclx	%f4, $rllo, %f2
628e71b7053SJung-uk Kim
629e71b7053SJung-uk Kim	fshiftorx	$outhead, %f0, $fshift, %f6
630e71b7053SJung-uk Kim	fshiftorx	%f0, %f2, $fshift, %f8
631e71b7053SJung-uk Kim	std		%f6, [$out + 0]
632e71b7053SJung-uk Kim	std		%f8, [$out + 8]
633e71b7053SJung-uk Kim	add		$out, 16, $out
634e71b7053SJung-uk Kim
635e71b7053SJung-uk Kim	brnz,a		$len, .Loop_cbc_enc_unaligned_out
636e71b7053SJung-uk Kim	sub		$len, 1, $len
637e71b7053SJung-uk Kim
638e71b7053SJung-uk Kim.Lcbc_enc_unaligned_out_done:
639e71b7053SJung-uk Kim	fshiftorx	%f2, %f2, $fshift, %f8
640e71b7053SJung-uk Kim	stda		%f8, [$out + $mask]0xc0	! partial store
641e71b7053SJung-uk Kim
642e71b7053SJung-uk Kim	st		%f0, [$ivp + 0]		! output ivec
643e71b7053SJung-uk Kim	st		%f1, [$ivp + 4]
644e71b7053SJung-uk Kim	st		%f2, [$ivp + 8]
645e71b7053SJung-uk Kim	st		%f3, [$ivp + 12]
646e71b7053SJung-uk Kim
647e71b7053SJung-uk Kim	ret
648e71b7053SJung-uk Kim	restore
649e71b7053SJung-uk Kim
650e71b7053SJung-uk Kim.align	32
651e71b7053SJung-uk Kim.Lcbc_decrypt:
652e71b7053SJung-uk Kim	fshiftorx	$in0, $in1, $fshift, $in0
653e71b7053SJung-uk Kim	fshiftorx	$in1, $intail, $fshift, $in1
654e71b7053SJung-uk Kim	fmovd		%f0, $iv0
655e71b7053SJung-uk Kim	fmovd		%f2, $iv1
656e71b7053SJung-uk Kim
657e71b7053SJung-uk Kim.Loop_cbc_dec:
658e71b7053SJung-uk Kim	fxor		$in0, $r0hi, %f0	! inp^round[0]
659e71b7053SJung-uk Kim	fxor		$in1, $r0lo, %f2
660e71b7053SJung-uk Kim	ldd		[$key + 32], %f6	! round[2]
661e71b7053SJung-uk Kim	ldd		[$key + 40], %f8
662e71b7053SJung-uk Kim	add		$key, 32, $end
663e71b7053SJung-uk Kim	sub		$rounds, 16*6, $inner
664e71b7053SJung-uk Kim
665e71b7053SJung-uk Kim.Lcbc_dec:
666e71b7053SJung-uk Kim	fmovd		%f0, %f4
667e71b7053SJung-uk Kim	faesdecx	%f2, %f10, %f0
668e71b7053SJung-uk Kim	faesdecx	%f4, %f12, %f2
669e71b7053SJung-uk Kim	ldd		[$end + 16], %f10
670e71b7053SJung-uk Kim	ldd		[$end + 24], %f12
671e71b7053SJung-uk Kim	add		$end, 32, $end
672e71b7053SJung-uk Kim
673e71b7053SJung-uk Kim	fmovd		%f0, %f4
674e71b7053SJung-uk Kim	faesdecx	%f2, %f6, %f0
675e71b7053SJung-uk Kim	faesdecx	%f4, %f8, %f2
676e71b7053SJung-uk Kim	ldd		[$end + 0], %f6
677e71b7053SJung-uk Kim	ldd		[$end + 8], %f8
678e71b7053SJung-uk Kim
679e71b7053SJung-uk Kim	brnz,a		$inner, .Lcbc_dec
680e71b7053SJung-uk Kim	sub		$inner, 16*2, $inner
681e71b7053SJung-uk Kim
682e71b7053SJung-uk Kim	fmovd		%f0, %f4
683e71b7053SJung-uk Kim	faesdecx	%f2, %f10, %f0
684e71b7053SJung-uk Kim	faesdecx	%f4, %f12, %f2
685e71b7053SJung-uk Kim	ldd		[$end + 16], %f10	! round[last-1]
686e71b7053SJung-uk Kim	ldd		[$end + 24], %f12
687e71b7053SJung-uk Kim
688e71b7053SJung-uk Kim	fmovd		%f0, %f4
689e71b7053SJung-uk Kim	faesdecx	%f2, %f6, %f0
690e71b7053SJung-uk Kim	faesdecx	%f4, %f8, %f2
691e71b7053SJung-uk Kim	fxor		$iv0, $rlhi, %f6	! ivec^round[last]
692e71b7053SJung-uk Kim	fxor		$iv1, $rllo, %f8
693e71b7053SJung-uk Kim	fmovd		$in0, $iv0
694e71b7053SJung-uk Kim	fmovd		$in1, $iv1
695e71b7053SJung-uk Kim
696e71b7053SJung-uk Kim	movrz		$len, 0, $inc
697e71b7053SJung-uk Kim	fmovd		$intail, $in0
698e71b7053SJung-uk Kim	ldd		[$inp - 8], $in1	! load next input block
699e71b7053SJung-uk Kim	ldda		[$inp]0x82, $intail	! non-faulting load
700e71b7053SJung-uk Kim	add		$inp, $inc, $inp	! inp+=16
701e71b7053SJung-uk Kim
702e71b7053SJung-uk Kim	fmovd		%f0, %f4
703e71b7053SJung-uk Kim	faesdecx	%f2, %f10, %f0
704e71b7053SJung-uk Kim	faesdecx	%f4, %f12, %f2
705e71b7053SJung-uk Kim	ldd		[$key + 16], %f10	! round[1]
706e71b7053SJung-uk Kim	ldd		[$key + 24], %f12
707e71b7053SJung-uk Kim
708e71b7053SJung-uk Kim	fshiftorx	$in0, $in1, $fshift, $in0
709e71b7053SJung-uk Kim	fshiftorx	$in1, $intail, $fshift, $in1
710e71b7053SJung-uk Kim
711e71b7053SJung-uk Kim	fmovd		%f0, %f4
712e71b7053SJung-uk Kim	faesdeclx	%f2, %f6, %f0
713e71b7053SJung-uk Kim	faesdeclx	%f4, %f8, %f2
714e71b7053SJung-uk Kim
715e71b7053SJung-uk Kim	brnz,pn		$oalign, .Lcbc_dec_unaligned_out
716e71b7053SJung-uk Kim	nop
717e71b7053SJung-uk Kim
718e71b7053SJung-uk Kim	std		%f0, [$out + 0]
719e71b7053SJung-uk Kim	std		%f2, [$out + 8]
720e71b7053SJung-uk Kim	add		$out, 16, $out
721e71b7053SJung-uk Kim
722e71b7053SJung-uk Kim	brnz,a		$len, .Loop_cbc_dec
723e71b7053SJung-uk Kim	sub		$len, 1, $len
724e71b7053SJung-uk Kim
725e71b7053SJung-uk Kim	st		$iv0,    [$ivp + 0]	! output ivec
726e71b7053SJung-uk Kim	st		$iv0#lo, [$ivp + 4]
727e71b7053SJung-uk Kim	st		$iv1,    [$ivp + 8]
728e71b7053SJung-uk Kim	st		$iv1#lo, [$ivp + 12]
729e71b7053SJung-uk Kim
730e71b7053SJung-uk Kim	ret
731e71b7053SJung-uk Kim	restore
732e71b7053SJung-uk Kim
733e71b7053SJung-uk Kim.align	32
734e71b7053SJung-uk Kim.Lcbc_dec_unaligned_out:
735e71b7053SJung-uk Kim	ldd		[%o7 + $mask], $fshift	! shift right params
736e71b7053SJung-uk Kim	mov		0xff, $mask
737e71b7053SJung-uk Kim	srl		$mask, $oalign, $mask
738e71b7053SJung-uk Kim	sub		%g0, $ileft, $iright
739e71b7053SJung-uk Kim
740e71b7053SJung-uk Kim	fshiftorx	%f0, %f0, $fshift, %f6
741e71b7053SJung-uk Kim	fshiftorx	%f0, %f2, $fshift, %f8
742e71b7053SJung-uk Kim
743e71b7053SJung-uk Kim	stda		%f6, [$out + $mask]0xc0	! partial store
744e71b7053SJung-uk Kim	orn		%g0, $mask, $mask
745e71b7053SJung-uk Kim	std		%f8, [$out + 8]
746e71b7053SJung-uk Kim	add		$out, 16, $out
747e71b7053SJung-uk Kim	brz		$len, .Lcbc_dec_unaligned_out_done
748e71b7053SJung-uk Kim	sub		$len, 1, $len
749e71b7053SJung-uk Kim	b		.Loop_cbc_dec_unaligned_out
750e71b7053SJung-uk Kim	nop
751e71b7053SJung-uk Kim
752e71b7053SJung-uk Kim.align	32
753e71b7053SJung-uk Kim.Loop_cbc_dec_unaligned_out:
754e71b7053SJung-uk Kim	fmovd		%f2, $outhead
755e71b7053SJung-uk Kim	fxor		$in0, $r0hi, %f0	! inp^round[0]
756e71b7053SJung-uk Kim	fxor		$in1, $r0lo, %f2
757e71b7053SJung-uk Kim	ldd		[$key + 32], %f6	! round[2]
758e71b7053SJung-uk Kim	ldd		[$key + 40], %f8
759e71b7053SJung-uk Kim
760e71b7053SJung-uk Kim	fmovd		%f0, %f4
761e71b7053SJung-uk Kim	faesdecx	%f2, %f10, %f0
762e71b7053SJung-uk Kim	faesdecx	%f4, %f12, %f2
763e71b7053SJung-uk Kim	ldd		[$key + 48], %f10	! round[3]
764e71b7053SJung-uk Kim	ldd		[$key + 56], %f12
765e71b7053SJung-uk Kim
766e71b7053SJung-uk Kim	ldx		[$inp - 16], %o0
767e71b7053SJung-uk Kim	ldx		[$inp - 8], %o1
768e71b7053SJung-uk Kim	brz		$ileft, .Lcbc_dec_aligned_inp
769e71b7053SJung-uk Kim	movrz		$len, 0, $inc
770e71b7053SJung-uk Kim
771e71b7053SJung-uk Kim	ldx		[$inp], %o2
772e71b7053SJung-uk Kim	sllx		%o0, $ileft, %o0
773e71b7053SJung-uk Kim	srlx		%o1, $iright, %g1
774e71b7053SJung-uk Kim	sllx		%o1, $ileft, %o1
775e71b7053SJung-uk Kim	or		%g1, %o0, %o0
776e71b7053SJung-uk Kim	srlx		%o2, $iright, %o2
777e71b7053SJung-uk Kim	or		%o2, %o1, %o1
778e71b7053SJung-uk Kim
779e71b7053SJung-uk Kim.Lcbc_dec_aligned_inp:
780e71b7053SJung-uk Kim	fmovd		%f0, %f4
781e71b7053SJung-uk Kim	faesdecx	%f2, %f6, %f0
782e71b7053SJung-uk Kim	faesdecx	%f4, %f8, %f2
783e71b7053SJung-uk Kim	ldd		[$key + 64], %f6	! round[4]
784e71b7053SJung-uk Kim	ldd		[$key + 72], %f8
785e71b7053SJung-uk Kim	add		$key, 64, $end
786e71b7053SJung-uk Kim	sub		$rounds, 16*8, $inner
787e71b7053SJung-uk Kim
788e71b7053SJung-uk Kim	stx		%o0, [%sp + LOCALS + 0]
789e71b7053SJung-uk Kim	stx		%o1, [%sp + LOCALS + 8]
790e71b7053SJung-uk Kim	add		$inp, $inc, $inp	! inp+=16
791e71b7053SJung-uk Kim	nop
792e71b7053SJung-uk Kim
793e71b7053SJung-uk Kim.Lcbc_dec_unaligned:
794e71b7053SJung-uk Kim	fmovd		%f0, %f4
795e71b7053SJung-uk Kim	faesdecx	%f2, %f10, %f0
796e71b7053SJung-uk Kim	faesdecx	%f4, %f12, %f2
797e71b7053SJung-uk Kim	ldd		[$end + 16], %f10
798e71b7053SJung-uk Kim	ldd		[$end + 24], %f12
799e71b7053SJung-uk Kim	add		$end, 32, $end
800e71b7053SJung-uk Kim
801e71b7053SJung-uk Kim	fmovd		%f0, %f4
802e71b7053SJung-uk Kim	faesdecx	%f2, %f6, %f0
803e71b7053SJung-uk Kim	faesdecx	%f4, %f8, %f2
804e71b7053SJung-uk Kim	ldd		[$end + 0], %f6
805e71b7053SJung-uk Kim	ldd		[$end + 8], %f8
806e71b7053SJung-uk Kim
807e71b7053SJung-uk Kim	brnz,a		$inner, .Lcbc_dec_unaligned
808e71b7053SJung-uk Kim	sub		$inner, 16*2, $inner
809e71b7053SJung-uk Kim
810e71b7053SJung-uk Kim	fmovd		%f0, %f4
811e71b7053SJung-uk Kim	faesdecx	%f2, %f10, %f0
812e71b7053SJung-uk Kim	faesdecx	%f4, %f12, %f2
813e71b7053SJung-uk Kim	ldd		[$end + 16], %f10	! round[last-1]
814e71b7053SJung-uk Kim	ldd		[$end + 24], %f12
815e71b7053SJung-uk Kim
816e71b7053SJung-uk Kim	fmovd		%f0, %f4
817e71b7053SJung-uk Kim	faesdecx	%f2, %f6, %f0
818e71b7053SJung-uk Kim	faesdecx	%f4, %f8, %f2
819e71b7053SJung-uk Kim
820e71b7053SJung-uk Kim	fxor		$iv0, $rlhi, %f6	! ivec^round[last]
821e71b7053SJung-uk Kim	fxor		$iv1, $rllo, %f8
822e71b7053SJung-uk Kim	fmovd		$in0, $iv0
823e71b7053SJung-uk Kim	fmovd		$in1, $iv1
824e71b7053SJung-uk Kim	ldd		[%sp + LOCALS + 0], $in0
825e71b7053SJung-uk Kim	ldd		[%sp + LOCALS + 8], $in1
826e71b7053SJung-uk Kim
827e71b7053SJung-uk Kim	fmovd		%f0, %f4
828e71b7053SJung-uk Kim	faesdecx	%f2, %f10, %f0
829e71b7053SJung-uk Kim	faesdecx	%f4, %f12, %f2
830e71b7053SJung-uk Kim	ldd		[$key + 16], %f10	! round[1]
831e71b7053SJung-uk Kim	ldd		[$key + 24], %f12
832e71b7053SJung-uk Kim
833e71b7053SJung-uk Kim	fmovd		%f0, %f4
834e71b7053SJung-uk Kim	faesdeclx	%f2, %f6, %f0
835e71b7053SJung-uk Kim	faesdeclx	%f4, %f8, %f2
836e71b7053SJung-uk Kim
837e71b7053SJung-uk Kim	fshiftorx	$outhead, %f0, $fshift, %f6
838e71b7053SJung-uk Kim	fshiftorx	%f0, %f2, $fshift, %f8
839e71b7053SJung-uk Kim	std		%f6, [$out + 0]
840e71b7053SJung-uk Kim	std		%f8, [$out + 8]
841e71b7053SJung-uk Kim	add		$out, 16, $out
842e71b7053SJung-uk Kim
843e71b7053SJung-uk Kim	brnz,a		$len, .Loop_cbc_dec_unaligned_out
844e71b7053SJung-uk Kim	sub		$len, 1, $len
845e71b7053SJung-uk Kim
846e71b7053SJung-uk Kim.Lcbc_dec_unaligned_out_done:
847e71b7053SJung-uk Kim	fshiftorx	%f2, %f2, $fshift, %f8
848e71b7053SJung-uk Kim	stda		%f8, [$out + $mask]0xc0	! partial store
849e71b7053SJung-uk Kim
850e71b7053SJung-uk Kim	st		$iv0,    [$ivp + 0]	! output ivec
851e71b7053SJung-uk Kim	st		$iv0#lo, [$ivp + 4]
852e71b7053SJung-uk Kim	st		$iv1,    [$ivp + 8]
853e71b7053SJung-uk Kim	st		$iv1#lo, [$ivp + 12]
854e71b7053SJung-uk Kim
855e71b7053SJung-uk Kim	ret
856e71b7053SJung-uk Kim	restore
857e71b7053SJung-uk Kim.type	aes_fx_cbc_encrypt,#function
858e71b7053SJung-uk Kim.size	aes_fx_cbc_encrypt,.-aes_fx_cbc_encrypt
859e71b7053SJung-uk Kim___
860e71b7053SJung-uk Kim}
861e71b7053SJung-uk Kim{
862e71b7053SJung-uk Kimmy ($inp,$out,$len,$key,$ivp) = map("%i$_",(0..5));
863e71b7053SJung-uk Kimmy ($rounds,$inner,$end,$inc,$ialign,$oalign,$mask) = map("%l$_",(0..7));
864e71b7053SJung-uk Kimmy ($ctr0,$ctr1,$r0hi,$r0lo,$rlhi,$rllo,$in0,$in1,$intail,$outhead,$fshift)
865e71b7053SJung-uk Kim   = map("%f$_",grep { !($_ & 1) } (16 .. 62));
866e71b7053SJung-uk Kimmy ($ileft,$iright) = ($ialign, $oalign);
867e71b7053SJung-uk Kimmy $one = "%f14";
868e71b7053SJung-uk Kim
869e71b7053SJung-uk Kim$code.=<<___;
870e71b7053SJung-uk Kim.globl	aes_fx_ctr32_encrypt_blocks
871e71b7053SJung-uk Kim.align	32
872e71b7053SJung-uk Kimaes_fx_ctr32_encrypt_blocks:
873e71b7053SJung-uk Kim	save		%sp, -STACK_FRAME-16, %sp
874e71b7053SJung-uk Kim	srln		$len, 0, $len
875e71b7053SJung-uk Kim	and		$inp, 7, $ialign
876e71b7053SJung-uk Kim	andn		$inp, 7, $inp
877e71b7053SJung-uk Kim	brz,pn		$len, .Lctr32_no_data
878e71b7053SJung-uk Kim	sll		$ialign, 3, $ileft
879e71b7053SJung-uk Kim
880e71b7053SJung-uk Kim.Lpic:	call		.+8
881e71b7053SJung-uk Kim	add		%o7, .Linp_align - .Lpic, %o7
882e71b7053SJung-uk Kim
883e71b7053SJung-uk Kim	ld		[$key + 240], $rounds
884e71b7053SJung-uk Kim	and		$out, 7, $oalign
885e71b7053SJung-uk Kim	ld		[$ivp +  0], $ctr0	! load counter
886e71b7053SJung-uk Kim	andn		$out, 7, $out
887e71b7053SJung-uk Kim	ld		[$ivp +  4], $ctr0#lo
888e71b7053SJung-uk Kim	sll		$oalign, 3, $mask
889e71b7053SJung-uk Kim	ld		[$ivp +  8], $ctr1
890e71b7053SJung-uk Kim	ld		[$ivp + 12], $ctr1#lo
891e71b7053SJung-uk Kim	ldd		[%o7 + 128], $one
892e71b7053SJung-uk Kim
893e71b7053SJung-uk Kim	sll		$rounds, 4, $rounds
894e71b7053SJung-uk Kim	add		$rounds, $key, $end
895e71b7053SJung-uk Kim	ldd		[$key + 0], $r0hi	! round[0]
896e71b7053SJung-uk Kim	ldd		[$key + 8], $r0lo
897e71b7053SJung-uk Kim
898e71b7053SJung-uk Kim	add		$inp, 16, $inp
899e71b7053SJung-uk Kim	sub		$len, 1, $len
900e71b7053SJung-uk Kim	ldd		[$key + 16], %f10	! round[1]
901e71b7053SJung-uk Kim	ldd		[$key + 24], %f12
902e71b7053SJung-uk Kim
903e71b7053SJung-uk Kim	mov		16, $inc
904e71b7053SJung-uk Kim	movrz		$len, 0, $inc
905e71b7053SJung-uk Kim	ldd		[$end + 0], $rlhi	! round[last]
906e71b7053SJung-uk Kim	ldd		[$end + 8], $rllo
907e71b7053SJung-uk Kim
908e71b7053SJung-uk Kim	ldd		[%o7 + $ileft], $fshift	! shiftleft params
909e71b7053SJung-uk Kim	add		%o7, 64, %o7
910e71b7053SJung-uk Kim	ldd		[$inp - 16], $in0	! load input
911e71b7053SJung-uk Kim	ldd		[$inp -  8], $in1
912e71b7053SJung-uk Kim	ldda		[$inp]0x82, $intail	! non-faulting load
913e71b7053SJung-uk Kim	add		$inp, $inc, $inp	! inp+=16
914e71b7053SJung-uk Kim
915e71b7053SJung-uk Kim	fshiftorx	$in0, $in1, $fshift, $in0
916e71b7053SJung-uk Kim	fshiftorx	$in1, $intail, $fshift, $in1
917e71b7053SJung-uk Kim
918e71b7053SJung-uk Kim.Loop_ctr32:
919e71b7053SJung-uk Kim	fxor		$ctr0, $r0hi, %f0	! counter^round[0]
920e71b7053SJung-uk Kim	fxor		$ctr1, $r0lo, %f2
921e71b7053SJung-uk Kim	ldd		[$key + 32], %f6	! round[2]
922e71b7053SJung-uk Kim	ldd		[$key + 40], %f8
923e71b7053SJung-uk Kim	add		$key, 32, $end
924e71b7053SJung-uk Kim	sub		$rounds, 16*6, $inner
925e71b7053SJung-uk Kim
926e71b7053SJung-uk Kim.Lctr32_enc:
927e71b7053SJung-uk Kim	fmovd		%f0, %f4
928e71b7053SJung-uk Kim	faesencx	%f2, %f10, %f0
929e71b7053SJung-uk Kim	faesencx	%f4, %f12, %f2
930e71b7053SJung-uk Kim	ldd		[$end + 16], %f10
931e71b7053SJung-uk Kim	ldd		[$end + 24], %f12
932e71b7053SJung-uk Kim	add		$end, 32, $end
933e71b7053SJung-uk Kim
934e71b7053SJung-uk Kim	fmovd		%f0, %f4
935e71b7053SJung-uk Kim	faesencx	%f2, %f6, %f0
936e71b7053SJung-uk Kim	faesencx	%f4, %f8, %f2
937e71b7053SJung-uk Kim	ldd		[$end + 0], %f6
938e71b7053SJung-uk Kim	ldd		[$end + 8], %f8
939e71b7053SJung-uk Kim
940e71b7053SJung-uk Kim	brnz,a		$inner, .Lctr32_enc
941e71b7053SJung-uk Kim	sub		$inner, 16*2, $inner
942e71b7053SJung-uk Kim
943e71b7053SJung-uk Kim	fmovd		%f0, %f4
944e71b7053SJung-uk Kim	faesencx	%f2, %f10, %f0
945e71b7053SJung-uk Kim	faesencx	%f4, %f12, %f2
946e71b7053SJung-uk Kim	ldd		[$end + 16], %f10	! round[last-1]
947e71b7053SJung-uk Kim	ldd		[$end + 24], %f12
948e71b7053SJung-uk Kim
949e71b7053SJung-uk Kim	fmovd		%f0, %f4
950e71b7053SJung-uk Kim	faesencx	%f2, %f6, %f0
951e71b7053SJung-uk Kim	faesencx	%f4, %f8, %f2
952e71b7053SJung-uk Kim	fxor		$in0, $rlhi, %f6	! inp^round[last]
953e71b7053SJung-uk Kim	fxor		$in1, $rllo, %f8
954e71b7053SJung-uk Kim
955e71b7053SJung-uk Kim	movrz		$len, 0, $inc
956e71b7053SJung-uk Kim	fmovd		$intail, $in0
957e71b7053SJung-uk Kim	ldd		[$inp - 8], $in1	! load next input block
958e71b7053SJung-uk Kim	ldda		[$inp]0x82, $intail	! non-faulting load
959e71b7053SJung-uk Kim	add		$inp, $inc, $inp	! inp+=16
960e71b7053SJung-uk Kim
961e71b7053SJung-uk Kim	fmovd		%f0, %f4
962e71b7053SJung-uk Kim	faesencx	%f2, %f10, %f0
963e71b7053SJung-uk Kim	faesencx	%f4, %f12, %f2
964e71b7053SJung-uk Kim	ldd		[$key + 16], %f10	! round[1]
965e71b7053SJung-uk Kim	ldd		[$key + 24], %f12
966e71b7053SJung-uk Kim
967e71b7053SJung-uk Kim	fshiftorx	$in0, $in1, $fshift, $in0
968e71b7053SJung-uk Kim	fshiftorx	$in1, $intail, $fshift, $in1
969e71b7053SJung-uk Kim	fpadd32		$ctr1, $one, $ctr1	! increment counter
970e71b7053SJung-uk Kim
971e71b7053SJung-uk Kim	fmovd		%f0, %f4
972e71b7053SJung-uk Kim	faesenclx	%f2, %f6, %f0
973e71b7053SJung-uk Kim	faesenclx	%f4, %f8, %f2
974e71b7053SJung-uk Kim
975e71b7053SJung-uk Kim	brnz,pn		$oalign, .Lctr32_unaligned_out
976e71b7053SJung-uk Kim	nop
977e71b7053SJung-uk Kim
978e71b7053SJung-uk Kim	std		%f0, [$out + 0]
979e71b7053SJung-uk Kim	std		%f2, [$out + 8]
980e71b7053SJung-uk Kim	add		$out, 16, $out
981e71b7053SJung-uk Kim
982e71b7053SJung-uk Kim	brnz,a		$len, .Loop_ctr32
983e71b7053SJung-uk Kim	sub		$len, 1, $len
984e71b7053SJung-uk Kim
985e71b7053SJung-uk Kim.Lctr32_no_data:
986e71b7053SJung-uk Kim	ret
987e71b7053SJung-uk Kim	restore
988e71b7053SJung-uk Kim
989e71b7053SJung-uk Kim.align	32
990e71b7053SJung-uk Kim.Lctr32_unaligned_out:
991e71b7053SJung-uk Kim	ldd		[%o7 + $mask], $fshift	! shift right params
992e71b7053SJung-uk Kim	mov		0xff, $mask
993e71b7053SJung-uk Kim	srl		$mask, $oalign, $mask
994e71b7053SJung-uk Kim	sub		%g0, $ileft, $iright
995e71b7053SJung-uk Kim
996e71b7053SJung-uk Kim	fshiftorx	%f0, %f0, $fshift, %f6
997e71b7053SJung-uk Kim	fshiftorx	%f0, %f2, $fshift, %f8
998e71b7053SJung-uk Kim
999e71b7053SJung-uk Kim	stda		%f6, [$out + $mask]0xc0	! partial store
1000e71b7053SJung-uk Kim	orn		%g0, $mask, $mask
1001e71b7053SJung-uk Kim	std		%f8, [$out + 8]
1002e71b7053SJung-uk Kim	add		$out, 16, $out
1003e71b7053SJung-uk Kim	brz		$len, .Lctr32_unaligned_out_done
1004e71b7053SJung-uk Kim	sub		$len, 1, $len
1005e71b7053SJung-uk Kim	b		.Loop_ctr32_unaligned_out
1006e71b7053SJung-uk Kim	nop
1007e71b7053SJung-uk Kim
1008e71b7053SJung-uk Kim.align	32
1009e71b7053SJung-uk Kim.Loop_ctr32_unaligned_out:
1010e71b7053SJung-uk Kim	fmovd		%f2, $outhead
1011e71b7053SJung-uk Kim	fxor		$ctr0, $r0hi, %f0	! counter^round[0]
1012e71b7053SJung-uk Kim	fxor		$ctr1, $r0lo, %f2
1013e71b7053SJung-uk Kim	ldd		[$key + 32], %f6	! round[2]
1014e71b7053SJung-uk Kim	ldd		[$key + 40], %f8
1015e71b7053SJung-uk Kim
1016e71b7053SJung-uk Kim	fmovd		%f0, %f4
1017e71b7053SJung-uk Kim	faesencx	%f2, %f10, %f0
1018e71b7053SJung-uk Kim	faesencx	%f4, %f12, %f2
1019e71b7053SJung-uk Kim	ldd		[$key + 48], %f10	! round[3]
1020e71b7053SJung-uk Kim	ldd		[$key + 56], %f12
1021e71b7053SJung-uk Kim
1022e71b7053SJung-uk Kim	ldx		[$inp - 16], %o0
1023e71b7053SJung-uk Kim	ldx		[$inp -  8], %o1
1024e71b7053SJung-uk Kim	brz		$ileft, .Lctr32_aligned_inp
1025e71b7053SJung-uk Kim	movrz		$len, 0, $inc
1026e71b7053SJung-uk Kim
1027e71b7053SJung-uk Kim	ldx		[$inp], %o2
1028e71b7053SJung-uk Kim	sllx		%o0, $ileft, %o0
1029e71b7053SJung-uk Kim	srlx		%o1, $iright, %g1
1030e71b7053SJung-uk Kim	sllx		%o1, $ileft, %o1
1031e71b7053SJung-uk Kim	or		%g1, %o0, %o0
1032e71b7053SJung-uk Kim	srlx		%o2, $iright, %o2
1033e71b7053SJung-uk Kim	or		%o2, %o1, %o1
1034e71b7053SJung-uk Kim
1035e71b7053SJung-uk Kim.Lctr32_aligned_inp:
1036e71b7053SJung-uk Kim	fmovd		%f0, %f4
1037e71b7053SJung-uk Kim	faesencx	%f2, %f6, %f0
1038e71b7053SJung-uk Kim	faesencx	%f4, %f8, %f2
1039e71b7053SJung-uk Kim	ldd		[$key + 64], %f6	! round[4]
1040e71b7053SJung-uk Kim	ldd		[$key + 72], %f8
1041e71b7053SJung-uk Kim	add		$key, 64, $end
1042e71b7053SJung-uk Kim	sub		$rounds, 16*8, $inner
1043e71b7053SJung-uk Kim
1044e71b7053SJung-uk Kim	stx		%o0, [%sp + LOCALS + 0]
1045e71b7053SJung-uk Kim	stx		%o1, [%sp + LOCALS + 8]
1046e71b7053SJung-uk Kim	add		$inp, $inc, $inp	! inp+=16
1047e71b7053SJung-uk Kim	nop
1048e71b7053SJung-uk Kim
1049e71b7053SJung-uk Kim.Lctr32_enc_unaligned:
1050e71b7053SJung-uk Kim	fmovd		%f0, %f4
1051e71b7053SJung-uk Kim	faesencx	%f2, %f10, %f0
1052e71b7053SJung-uk Kim	faesencx	%f4, %f12, %f2
1053e71b7053SJung-uk Kim	ldd		[$end + 16], %f10
1054e71b7053SJung-uk Kim	ldd		[$end + 24], %f12
1055e71b7053SJung-uk Kim	add		$end, 32, $end
1056e71b7053SJung-uk Kim
1057e71b7053SJung-uk Kim	fmovd		%f0, %f4
1058e71b7053SJung-uk Kim	faesencx	%f2, %f6, %f0
1059e71b7053SJung-uk Kim	faesencx	%f4, %f8, %f2
1060e71b7053SJung-uk Kim	ldd		[$end + 0], %f6
1061e71b7053SJung-uk Kim	ldd		[$end + 8], %f8
1062e71b7053SJung-uk Kim
1063e71b7053SJung-uk Kim	brnz,a		$inner, .Lctr32_enc_unaligned
1064e71b7053SJung-uk Kim	sub		$inner, 16*2, $inner
1065e71b7053SJung-uk Kim
1066e71b7053SJung-uk Kim	fmovd		%f0, %f4
1067e71b7053SJung-uk Kim	faesencx	%f2, %f10, %f0
1068e71b7053SJung-uk Kim	faesencx	%f4, %f12, %f2
1069e71b7053SJung-uk Kim	ldd		[$end + 16], %f10	! round[last-1]
1070e71b7053SJung-uk Kim	ldd		[$end + 24], %f12
1071e71b7053SJung-uk Kim	fpadd32		$ctr1, $one, $ctr1	! increment counter
1072e71b7053SJung-uk Kim
1073e71b7053SJung-uk Kim	fmovd		%f0, %f4
1074e71b7053SJung-uk Kim	faesencx	%f2, %f6, %f0
1075e71b7053SJung-uk Kim	faesencx	%f4, %f8, %f2
1076e71b7053SJung-uk Kim	fxor		$in0, $rlhi, %f6	! inp^round[last]
1077e71b7053SJung-uk Kim	fxor		$in1, $rllo, %f8
1078e71b7053SJung-uk Kim	ldd		[%sp + LOCALS + 0], $in0
1079e71b7053SJung-uk Kim	ldd		[%sp + LOCALS + 8], $in1
1080e71b7053SJung-uk Kim
1081e71b7053SJung-uk Kim	fmovd		%f0, %f4
1082e71b7053SJung-uk Kim	faesencx	%f2, %f10, %f0
1083e71b7053SJung-uk Kim	faesencx	%f4, %f12, %f2
1084e71b7053SJung-uk Kim	ldd		[$key + 16], %f10	! round[1]
1085e71b7053SJung-uk Kim	ldd		[$key + 24], %f12
1086e71b7053SJung-uk Kim
1087e71b7053SJung-uk Kim	fmovd		%f0, %f4
1088e71b7053SJung-uk Kim	faesenclx	%f2, %f6, %f0
1089e71b7053SJung-uk Kim	faesenclx	%f4, %f8, %f2
1090e71b7053SJung-uk Kim
1091e71b7053SJung-uk Kim	fshiftorx	$outhead, %f0, $fshift, %f6
1092e71b7053SJung-uk Kim	fshiftorx	%f0, %f2, $fshift, %f8
1093e71b7053SJung-uk Kim	std		%f6, [$out + 0]
1094e71b7053SJung-uk Kim	std		%f8, [$out + 8]
1095e71b7053SJung-uk Kim	add		$out, 16, $out
1096e71b7053SJung-uk Kim
1097e71b7053SJung-uk Kim	brnz,a		$len, .Loop_ctr32_unaligned_out
1098e71b7053SJung-uk Kim	sub		$len, 1, $len
1099e71b7053SJung-uk Kim
1100e71b7053SJung-uk Kim.Lctr32_unaligned_out_done:
1101e71b7053SJung-uk Kim	fshiftorx	%f2, %f2, $fshift, %f8
1102e71b7053SJung-uk Kim	stda		%f8, [$out + $mask]0xc0	! partial store
1103e71b7053SJung-uk Kim
1104e71b7053SJung-uk Kim	ret
1105e71b7053SJung-uk Kim	restore
1106e71b7053SJung-uk Kim.type	aes_fx_ctr32_encrypt_blocks,#function
1107e71b7053SJung-uk Kim.size	aes_fx_ctr32_encrypt_blocks,.-aes_fx_ctr32_encrypt_blocks
1108e71b7053SJung-uk Kim
1109e71b7053SJung-uk Kim.align	32
1110e71b7053SJung-uk Kim.Linp_align:		! fshiftorx parameters for left shift toward %rs1
1111e71b7053SJung-uk Kim	.byte	0, 0, 64,  0,	0, 64,  0, -64
1112e71b7053SJung-uk Kim	.byte	0, 0, 56,  8,	0, 56,  8, -56
1113e71b7053SJung-uk Kim	.byte	0, 0, 48, 16,	0, 48, 16, -48
1114e71b7053SJung-uk Kim	.byte	0, 0, 40, 24,	0, 40, 24, -40
1115e71b7053SJung-uk Kim	.byte	0, 0, 32, 32,	0, 32, 32, -32
1116e71b7053SJung-uk Kim	.byte	0, 0, 24, 40,	0, 24, 40, -24
1117e71b7053SJung-uk Kim	.byte	0, 0, 16, 48,	0, 16, 48, -16
1118e71b7053SJung-uk Kim	.byte	0, 0,  8, 56,	0,  8, 56, -8
1119e71b7053SJung-uk Kim.Lout_align:		! fshiftorx parameters for right shift toward %rs2
1120e71b7053SJung-uk Kim	.byte	0, 0,  0, 64,	0,  0, 64,   0
1121e71b7053SJung-uk Kim	.byte	0, 0,  8, 56,	0,  8, 56,  -8
1122e71b7053SJung-uk Kim	.byte	0, 0, 16, 48,	0, 16, 48, -16
1123e71b7053SJung-uk Kim	.byte	0, 0, 24, 40,	0, 24, 40, -24
1124e71b7053SJung-uk Kim	.byte	0, 0, 32, 32,	0, 32, 32, -32
1125e71b7053SJung-uk Kim	.byte	0, 0, 40, 24,	0, 40, 24, -40
1126e71b7053SJung-uk Kim	.byte	0, 0, 48, 16,	0, 48, 16, -48
1127e71b7053SJung-uk Kim	.byte	0, 0, 56,  8,	0, 56,  8, -56
1128e71b7053SJung-uk Kim.Lone:
1129e71b7053SJung-uk Kim	.word	0, 1
1130e71b7053SJung-uk Kim.asciz	"AES for Fujitsu SPARC64 X, CRYPTOGAMS by <appro\@openssl.org>"
1131e71b7053SJung-uk Kim.align	4
1132e71b7053SJung-uk Kim___
1133e71b7053SJung-uk Kim}
1134e71b7053SJung-uk Kim# Purpose of these subroutines is to explicitly encode VIS instructions,
1135e71b7053SJung-uk Kim# so that one can compile the module without having to specify VIS
1136e71b7053SJung-uk Kim# extensions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a.
1137e71b7053SJung-uk Kim# Idea is to reserve for option to produce "universal" binary and let
1138e71b7053SJung-uk Kim# programmer detect if current CPU is VIS capable at run-time.
1139e71b7053SJung-uk Kimsub unvis {
1140e71b7053SJung-uk Kimmy ($mnemonic,$rs1,$rs2,$rd)=@_;
1141e71b7053SJung-uk Kimmy ($ref,$opf);
1142e71b7053SJung-uk Kimmy %visopf = (	"faligndata"	=> 0x048,
1143e71b7053SJung-uk Kim		"bshuffle"	=> 0x04c,
1144e71b7053SJung-uk Kim		"fpadd32"	=> 0x052,
1145e71b7053SJung-uk Kim		"fxor"		=> 0x06c,
1146e71b7053SJung-uk Kim		"fsrc2"		=> 0x078	);
1147e71b7053SJung-uk Kim
1148e71b7053SJung-uk Kim    $ref = "$mnemonic\t$rs1,$rs2,$rd";
1149e71b7053SJung-uk Kim
1150e71b7053SJung-uk Kim    if ($opf=$visopf{$mnemonic}) {
1151e71b7053SJung-uk Kim	foreach ($rs1,$rs2,$rd) {
1152e71b7053SJung-uk Kim	    return $ref if (!/%f([0-9]{1,2})/);
1153e71b7053SJung-uk Kim	    $_=$1;
1154e71b7053SJung-uk Kim	    if ($1>=32) {
1155e71b7053SJung-uk Kim		return $ref if ($1&1);
1156e71b7053SJung-uk Kim		# re-encode for upper double register addressing
1157e71b7053SJung-uk Kim		$_=($1|$1>>5)&31;
1158e71b7053SJung-uk Kim	    }
1159e71b7053SJung-uk Kim	}
1160e71b7053SJung-uk Kim
1161e71b7053SJung-uk Kim	return	sprintf ".word\t0x%08x !%s",
1162e71b7053SJung-uk Kim			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
1163e71b7053SJung-uk Kim			$ref;
1164e71b7053SJung-uk Kim    } else {
1165e71b7053SJung-uk Kim	return $ref;
1166e71b7053SJung-uk Kim    }
1167e71b7053SJung-uk Kim}
1168e71b7053SJung-uk Kim
1169e71b7053SJung-uk Kimsub unvis3 {
1170e71b7053SJung-uk Kimmy ($mnemonic,$rs1,$rs2,$rd)=@_;
1171e71b7053SJung-uk Kimmy %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 );
1172e71b7053SJung-uk Kimmy ($ref,$opf);
1173e71b7053SJung-uk Kimmy %visopf = (	"alignaddr"	=> 0x018,
1174e71b7053SJung-uk Kim		"bmask"		=> 0x019,
1175e71b7053SJung-uk Kim		"alignaddrl"	=> 0x01a	);
1176e71b7053SJung-uk Kim
1177e71b7053SJung-uk Kim    $ref = "$mnemonic\t$rs1,$rs2,$rd";
1178e71b7053SJung-uk Kim
1179e71b7053SJung-uk Kim    if ($opf=$visopf{$mnemonic}) {
1180e71b7053SJung-uk Kim	foreach ($rs1,$rs2,$rd) {
1181e71b7053SJung-uk Kim	    return $ref if (!/%([goli])([0-9])/);
1182e71b7053SJung-uk Kim	    $_=$bias{$1}+$2;
1183e71b7053SJung-uk Kim	}
1184e71b7053SJung-uk Kim
1185e71b7053SJung-uk Kim	return	sprintf ".word\t0x%08x !%s",
1186e71b7053SJung-uk Kim			0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2,
1187e71b7053SJung-uk Kim			$ref;
1188e71b7053SJung-uk Kim    } else {
1189e71b7053SJung-uk Kim	return $ref;
1190e71b7053SJung-uk Kim    }
1191e71b7053SJung-uk Kim}
1192e71b7053SJung-uk Kim
1193e71b7053SJung-uk Kimsub unfx {
1194e71b7053SJung-uk Kimmy ($mnemonic,$rs1,$rs2,$rd)=@_;
1195e71b7053SJung-uk Kimmy ($ref,$opf);
1196e71b7053SJung-uk Kimmy %aesopf = (	"faesencx"	=> 0x90,
1197e71b7053SJung-uk Kim		"faesdecx"	=> 0x91,
1198e71b7053SJung-uk Kim		"faesenclx"	=> 0x92,
1199e71b7053SJung-uk Kim		"faesdeclx"	=> 0x93,
1200e71b7053SJung-uk Kim		"faeskeyx"	=> 0x94	);
1201e71b7053SJung-uk Kim
1202e71b7053SJung-uk Kim    $ref = "$mnemonic\t$rs1,$rs2,$rd";
1203e71b7053SJung-uk Kim
1204e71b7053SJung-uk Kim    if (defined($opf=$aesopf{$mnemonic})) {
1205e71b7053SJung-uk Kim	$rs2 = ($rs2 =~ /%f([0-6]*[02468])/) ? (($1|$1>>5)&31) : $rs2;
1206e71b7053SJung-uk Kim	$rs2 = oct($rs2) if ($rs2 =~ /^0/);
1207e71b7053SJung-uk Kim
1208e71b7053SJung-uk Kim	foreach ($rs1,$rd) {
1209e71b7053SJung-uk Kim	    return $ref if (!/%f([0-9]{1,2})/);
1210e71b7053SJung-uk Kim	    $_=$1;
1211e71b7053SJung-uk Kim	    if ($1>=32) {
1212e71b7053SJung-uk Kim		return $ref if ($1&1);
1213e71b7053SJung-uk Kim		# re-encode for upper double register addressing
1214e71b7053SJung-uk Kim		$_=($1|$1>>5)&31;
1215e71b7053SJung-uk Kim	    }
1216e71b7053SJung-uk Kim	}
1217e71b7053SJung-uk Kim
1218e71b7053SJung-uk Kim	return	sprintf ".word\t0x%08x !%s",
1219e71b7053SJung-uk Kim			2<<30|$rd<<25|0x36<<19|$rs1<<14|$opf<<5|$rs2,
1220e71b7053SJung-uk Kim			$ref;
1221e71b7053SJung-uk Kim    } else {
1222e71b7053SJung-uk Kim	return $ref;
1223e71b7053SJung-uk Kim    }
1224e71b7053SJung-uk Kim}
1225e71b7053SJung-uk Kim
1226e71b7053SJung-uk Kimsub unfx3src {
1227e71b7053SJung-uk Kimmy ($mnemonic,$rs1,$rs2,$rs3,$rd)=@_;
1228e71b7053SJung-uk Kimmy ($ref,$opf);
1229e71b7053SJung-uk Kimmy %aesopf = (	"fshiftorx"	=> 0x0b	);
1230e71b7053SJung-uk Kim
1231e71b7053SJung-uk Kim    $ref = "$mnemonic\t$rs1,$rs2,$rs3,$rd";
1232e71b7053SJung-uk Kim
1233e71b7053SJung-uk Kim    if (defined($opf=$aesopf{$mnemonic})) {
1234e71b7053SJung-uk Kim	foreach ($rs1,$rs2,$rs3,$rd) {
1235e71b7053SJung-uk Kim	    return $ref if (!/%f([0-9]{1,2})/);
1236e71b7053SJung-uk Kim	    $_=$1;
1237e71b7053SJung-uk Kim	    if ($1>=32) {
1238e71b7053SJung-uk Kim		return $ref if ($1&1);
1239e71b7053SJung-uk Kim		# re-encode for upper double register addressing
1240e71b7053SJung-uk Kim		$_=($1|$1>>5)&31;
1241e71b7053SJung-uk Kim	    }
1242e71b7053SJung-uk Kim	}
1243e71b7053SJung-uk Kim
1244e71b7053SJung-uk Kim	return	sprintf ".word\t0x%08x !%s",
1245e71b7053SJung-uk Kim			2<<30|$rd<<25|0x37<<19|$rs1<<14|$rs3<<9|$opf<<5|$rs2,
1246e71b7053SJung-uk Kim			$ref;
1247e71b7053SJung-uk Kim    } else {
1248e71b7053SJung-uk Kim	return $ref;
1249e71b7053SJung-uk Kim    }
1250e71b7053SJung-uk Kim}
1251e71b7053SJung-uk Kim
1252e71b7053SJung-uk Kimforeach (split("\n",$code)) {
1253e71b7053SJung-uk Kim    s/\`([^\`]*)\`/eval $1/ge;
1254e71b7053SJung-uk Kim
1255e71b7053SJung-uk Kim    s/%f([0-9]+)#lo/sprintf "%%f%d",$1+1/ge;
1256e71b7053SJung-uk Kim
1257e71b7053SJung-uk Kim    s/\b(faes[^x]{3,4}x)\s+(%f[0-9]{1,2}),\s*([%fx0-9]+),\s*(%f[0-9]{1,2})/
1258e71b7053SJung-uk Kim		&unfx($1,$2,$3,$4)
1259e71b7053SJung-uk Kim     /ge or
1260e71b7053SJung-uk Kim    s/\b([f][^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
1261e71b7053SJung-uk Kim		&unfx3src($1,$2,$3,$4,$5)
1262e71b7053SJung-uk Kim     /ge or
1263e71b7053SJung-uk Kim    s/\b([fb][^\s]*)\s+(%f[0-9]{1,2}),\s*(%f[0-9]{1,2}),\s*(%f[0-9]{1,2})/
1264e71b7053SJung-uk Kim		&unvis($1,$2,$3,$4)
1265e71b7053SJung-uk Kim     /ge or
1266e71b7053SJung-uk Kim    s/\b(alignaddr[l]*)\s+(%[goli][0-7]),\s*(%[goli][0-7]),\s*(%[goli][0-7])/
1267e71b7053SJung-uk Kim		&unvis3($1,$2,$3,$4)
1268e71b7053SJung-uk Kim     /ge;
1269e71b7053SJung-uk Kim    print $_,"\n";
1270e71b7053SJung-uk Kim}
1271e71b7053SJung-uk Kim
127217f01e99SJung-uk Kimclose STDOUT or die "error closing STDOUT: $!";
1273