1289848Sjkim#!/usr/bin/env perl
2289848Sjkim
3289848Sjkim# ====================================================================
4289848Sjkim# Written by David S. Miller <davem@devemloft.net> and Andy Polyakov
5289848Sjkim# <appro@openssl.org>. The module is licensed under 2-clause BSD
6289848Sjkim# license. October 2012. All rights reserved.
7289848Sjkim# ====================================================================
8289848Sjkim
9289848Sjkim######################################################################
10289848Sjkim# Camellia for SPARC T4.
11289848Sjkim#
12289848Sjkim# As with AES below results [for aligned data] are virtually identical
13289848Sjkim# to critical path lenths for 3-cycle instruction latency:
14289848Sjkim#
15289848Sjkim#		128-bit key	192/256-
16289848Sjkim# CBC encrypt	4.14/4.21(*)	5.46/5.52
17289848Sjkim#			 (*) numbers after slash are for
18289848Sjkim#			     misaligned data.
19289848Sjkim#
20289848Sjkim# As with Intel AES-NI, question is if it's possible to improve
21289848Sjkim# performance of parallelizeable modes by interleaving round
22289848Sjkim# instructions. In Camellia every instruction is dependent on
23289848Sjkim# previous, which means that there is place for 2 additional ones
24289848Sjkim# in between two dependent. Can we expect 3x performance improvement?
25289848Sjkim# At least one can argue that it should be possible to break 2x
26289848Sjkim# barrier... For some reason not even 2x appears to be possible:
27289848Sjkim#
28289848Sjkim#		128-bit key	192/256-
29289848Sjkim# CBC decrypt	2.21/2.74	2.99/3.40
30289848Sjkim# CTR		2.15/2.68(*)	2.93/3.34
31289848Sjkim#			 (*) numbers after slash are for
32289848Sjkim#			     misaligned data.
33289848Sjkim#
34289848Sjkim# This is for 2x interleave. But compared to 1x interleave CBC decrypt
35289848Sjkim# improved by ... 0% for 128-bit key, and 11% for 192/256-bit one.
36289848Sjkim# So that out-of-order execution logic can take non-interleaved code
37289848Sjkim# to 1.87x, but can't take 2x interleaved one any further. There
38289848Sjkim# surely is some explanation... As result 3x interleave was not even
39289848Sjkim# attempted. Instead an effort was made to share specific modes
40289848Sjkim# implementations with AES module (therefore sparct4_modes.pl).
41289848Sjkim#
42289848Sjkim# To anchor to something else, software C implementation processes
43289848Sjkim# one byte in 38 cycles with 128-bit key on same processor.
44289848Sjkim
45289848Sjkim$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
46289848Sjkimpush(@INC,"${dir}","${dir}../../perlasm");
47289848Sjkimrequire "sparcv9_modes.pl";
48289848Sjkim
49289848Sjkim&asm_init(@ARGV);
50289848Sjkim
51289848Sjkim$::evp=1;	# if $evp is set to 0, script generates module with
52289848Sjkim# Camellia_[en|de]crypt, Camellia_set_key and Camellia_cbc_encrypt
53289848Sjkim# entry points. These are fully compatible with openssl/camellia.h.
54289848Sjkim
55289848Sjkim######################################################################
56289848Sjkim# single-round subroutines
57289848Sjkim#
58289848Sjkim{
59289848Sjkimmy ($inp,$out,$key,$rounds,$tmp,$mask)=map("%o$_",(0..5));
60289848Sjkim
61289848Sjkim$code=<<___;
62289848Sjkim.text
63289848Sjkim
64289848Sjkim.globl	cmll_t4_encrypt
65289848Sjkim.align	32
66289848Sjkimcmll_t4_encrypt:
67289848Sjkim	andcc		$inp, 7, %g1		! is input aligned?
68289848Sjkim	andn		$inp, 7, $inp
69289848Sjkim
70289848Sjkim	ldx		[$key + 0], %g4
71289848Sjkim	ldx		[$key + 8], %g5
72289848Sjkim
73289848Sjkim	ldx		[$inp + 0], %o4
74289848Sjkim	bz,pt		%icc, 1f
75289848Sjkim	ldx		[$inp + 8], %o5
76289848Sjkim	ldx		[$inp + 16], $inp
77289848Sjkim	sll		%g1, 3, %g1
78289848Sjkim	sub		%g0, %g1, %o3
79289848Sjkim	sllx		%o4, %g1, %o4
80289848Sjkim	sllx		%o5, %g1, %g1
81289848Sjkim	srlx		%o5, %o3, %o5
82289848Sjkim	srlx		$inp, %o3, %o3
83289848Sjkim	or		%o5, %o4, %o4
84289848Sjkim	or		%o3, %g1, %o5
85289848Sjkim1:
86289848Sjkim	ld		[$key + 272], $rounds	! grandRounds, 3 or 4
87289848Sjkim	ldd		[$key + 16], %f12
88289848Sjkim	ldd		[$key + 24], %f14
89289848Sjkim	xor		%g4, %o4, %o4
90289848Sjkim	xor		%g5, %o5, %o5
91289848Sjkim	ldd		[$key + 32], %f16
92289848Sjkim	ldd		[$key + 40], %f18
93289848Sjkim	movxtod		%o4, %f0
94289848Sjkim	movxtod		%o5, %f2
95289848Sjkim	ldd		[$key + 48], %f20
96289848Sjkim	ldd		[$key + 56], %f22
97289848Sjkim	sub		$rounds, 1, $rounds
98289848Sjkim	ldd		[$key + 64], %f24
99289848Sjkim	ldd		[$key + 72], %f26
100289848Sjkim	add		$key, 80, $key
101289848Sjkim
102289848Sjkim.Lenc:
103289848Sjkim	camellia_f	%f12, %f2, %f0, %f2
104289848Sjkim	ldd		[$key + 0], %f12
105289848Sjkim	sub		$rounds,1,$rounds
106289848Sjkim	camellia_f	%f14, %f0, %f2, %f0
107289848Sjkim	ldd		[$key + 8], %f14
108289848Sjkim	camellia_f	%f16, %f2, %f0, %f2
109289848Sjkim	ldd		[$key + 16], %f16
110289848Sjkim	camellia_f	%f18, %f0, %f2, %f0
111289848Sjkim	ldd		[$key + 24], %f18
112289848Sjkim	camellia_f	%f20, %f2, %f0, %f2
113289848Sjkim	ldd		[$key + 32], %f20
114289848Sjkim	camellia_f	%f22, %f0, %f2, %f0
115289848Sjkim	ldd		[$key + 40], %f22
116289848Sjkim	camellia_fl	%f24, %f0, %f0
117289848Sjkim	ldd		[$key + 48], %f24
118289848Sjkim	camellia_fli	%f26, %f2, %f2
119289848Sjkim	ldd		[$key + 56], %f26
120289848Sjkim	brnz,pt		$rounds, .Lenc
121289848Sjkim	add		$key, 64, $key
122289848Sjkim
123289848Sjkim	andcc		$out, 7, $tmp		! is output aligned?
124289848Sjkim	camellia_f	%f12, %f2, %f0, %f2
125289848Sjkim	camellia_f	%f14, %f0, %f2, %f0
126289848Sjkim	camellia_f	%f16, %f2, %f0, %f2
127289848Sjkim	camellia_f	%f18, %f0, %f2, %f0
128289848Sjkim	camellia_f	%f20, %f2, %f0, %f4
129289848Sjkim	camellia_f	%f22, %f0, %f4, %f2
130289848Sjkim	fxor		%f24, %f4, %f0
131289848Sjkim	fxor		%f26, %f2, %f2
132289848Sjkim
133289848Sjkim	bnz,pn		%icc, 2f
134289848Sjkim	nop
135289848Sjkim
136289848Sjkim	std		%f0, [$out + 0]
137289848Sjkim	retl
138289848Sjkim	std		%f2, [$out + 8]
139289848Sjkim
140289848Sjkim2:	alignaddrl	$out, %g0, $out
141289848Sjkim	mov		0xff, $mask
142289848Sjkim	srl		$mask, $tmp, $mask
143289848Sjkim
144289848Sjkim	faligndata	%f0, %f0, %f4
145289848Sjkim	faligndata	%f0, %f2, %f6
146289848Sjkim	faligndata	%f2, %f2, %f8
147289848Sjkim
148289848Sjkim	stda		%f4, [$out + $mask]0xc0	! partial store
149289848Sjkim	std		%f6, [$out + 8]
150289848Sjkim	add		$out, 16, $out
151289848Sjkim	orn		%g0, $mask, $mask
152289848Sjkim	retl
153289848Sjkim	stda		%f8, [$out + $mask]0xc0	! partial store
154289848Sjkim.type	cmll_t4_encrypt,#function
155289848Sjkim.size	cmll_t4_encrypt,.-cmll_t4_encrypt
156289848Sjkim
157289848Sjkim.globl	cmll_t4_decrypt
158289848Sjkim.align	32
159289848Sjkimcmll_t4_decrypt:
160289848Sjkim	ld		[$key + 272], $rounds	! grandRounds, 3 or 4
161289848Sjkim	andcc		$inp, 7, %g1		! is input aligned?
162289848Sjkim	andn		$inp, 7, $inp
163289848Sjkim
164289848Sjkim	sll		$rounds, 6, $rounds
165289848Sjkim	add		$rounds, $key, $key
166289848Sjkim
167289848Sjkim	ldx		[$inp + 0], %o4
168289848Sjkim	bz,pt		%icc, 1f
169289848Sjkim	ldx		[$inp + 8], %o5
170289848Sjkim	ldx		[$inp + 16], $inp
171289848Sjkim	sll		%g1, 3, %g1
172289848Sjkim	sub		%g0, %g1, %g4
173289848Sjkim	sllx		%o4, %g1, %o4
174289848Sjkim	sllx		%o5, %g1, %g1
175289848Sjkim	srlx		%o5, %g4, %o5
176289848Sjkim	srlx		$inp, %g4, %g4
177289848Sjkim	or		%o5, %o4, %o4
178289848Sjkim	or		%g4, %g1, %o5
179289848Sjkim1:
180289848Sjkim	ldx		[$key + 0], %g4
181289848Sjkim	ldx		[$key + 8], %g5
182289848Sjkim	ldd		[$key - 8], %f12
183289848Sjkim	ldd		[$key - 16], %f14
184289848Sjkim	xor		%g4, %o4, %o4
185289848Sjkim	xor		%g5, %o5, %o5
186289848Sjkim	ldd		[$key - 24], %f16
187289848Sjkim	ldd		[$key - 32], %f18
188289848Sjkim	movxtod		%o4, %f0
189289848Sjkim	movxtod		%o5, %f2
190289848Sjkim	ldd		[$key - 40], %f20
191289848Sjkim	ldd		[$key - 48], %f22
192289848Sjkim	sub		$rounds, 64, $rounds
193289848Sjkim	ldd		[$key - 56], %f24
194289848Sjkim	ldd		[$key - 64], %f26
195289848Sjkim	sub		$key, 64, $key
196289848Sjkim
197289848Sjkim.Ldec:
198289848Sjkim	camellia_f	%f12, %f2, %f0, %f2
199289848Sjkim	ldd		[$key - 8], %f12
200289848Sjkim	sub		$rounds, 64, $rounds
201289848Sjkim	camellia_f	%f14, %f0, %f2, %f0
202289848Sjkim	ldd		[$key - 16], %f14
203289848Sjkim	camellia_f	%f16, %f2, %f0, %f2
204289848Sjkim	ldd		[$key - 24], %f16
205289848Sjkim	camellia_f	%f18, %f0, %f2, %f0
206289848Sjkim	ldd		[$key - 32], %f18
207289848Sjkim	camellia_f	%f20, %f2, %f0, %f2
208289848Sjkim	ldd		[$key - 40], %f20
209289848Sjkim	camellia_f	%f22, %f0, %f2, %f0
210289848Sjkim	ldd		[$key - 48], %f22
211289848Sjkim	camellia_fl	%f24, %f0, %f0
212289848Sjkim	ldd		[$key - 56], %f24
213289848Sjkim	camellia_fli	%f26, %f2, %f2
214289848Sjkim	ldd		[$key - 64], %f26
215289848Sjkim	brnz,pt		$rounds, .Ldec
216289848Sjkim	sub		$key, 64, $key
217289848Sjkim
218289848Sjkim	andcc		$out, 7, $tmp		! is output aligned?
219289848Sjkim	camellia_f	%f12, %f2, %f0, %f2
220289848Sjkim	camellia_f	%f14, %f0, %f2, %f0
221289848Sjkim	camellia_f	%f16, %f2, %f0, %f2
222289848Sjkim	camellia_f	%f18, %f0, %f2, %f0
223289848Sjkim	camellia_f	%f20, %f2, %f0, %f4
224289848Sjkim	camellia_f	%f22, %f0, %f4, %f2
225289848Sjkim	fxor		%f26, %f4, %f0
226289848Sjkim	fxor		%f24, %f2, %f2
227289848Sjkim
228289848Sjkim	bnz,pn		%icc, 2f
229289848Sjkim	nop
230289848Sjkim
231289848Sjkim	std		%f0, [$out + 0]
232289848Sjkim	retl
233289848Sjkim	std		%f2, [$out + 8]
234289848Sjkim
235289848Sjkim2:	alignaddrl	$out, %g0, $out
236289848Sjkim	mov		0xff, $mask
237289848Sjkim	srl		$mask, $tmp, $mask
238289848Sjkim
239289848Sjkim	faligndata	%f0, %f0, %f4
240289848Sjkim	faligndata	%f0, %f2, %f6
241289848Sjkim	faligndata	%f2, %f2, %f8
242289848Sjkim
243289848Sjkim	stda		%f4, [$out + $mask]0xc0	! partial store
244289848Sjkim	std		%f6, [$out + 8]
245289848Sjkim	add		$out, 16, $out
246289848Sjkim	orn		%g0, $mask, $mask
247289848Sjkim	retl
248289848Sjkim	stda		%f8, [$out + $mask]0xc0	! partial store
249289848Sjkim.type	cmll_t4_decrypt,#function
250289848Sjkim.size	cmll_t4_decrypt,.-cmll_t4_decrypt
251289848Sjkim___
252289848Sjkim}
253289848Sjkim
254289848Sjkim######################################################################
255289848Sjkim# key setup subroutines
256289848Sjkim#
257289848Sjkim{
258289848Sjkimsub ROTL128 {
259289848Sjkim  my $rot = shift;
260289848Sjkim
261289848Sjkim	"srlx	%o4, 64-$rot, %g4\n\t".
262289848Sjkim	"sllx	%o4, $rot, %o4\n\t".
263289848Sjkim	"srlx	%o5, 64-$rot, %g5\n\t".
264289848Sjkim	"sllx	%o5, $rot, %o5\n\t".
265289848Sjkim	"or	%o4, %g5, %o4\n\t".
266289848Sjkim	"or	%o5, %g4, %o5";
267289848Sjkim}
268289848Sjkim
269289848Sjkimmy ($inp,$bits,$out,$tmp)=map("%o$_",(0..5));
270289848Sjkim$code.=<<___;
271289848Sjkim.globl	cmll_t4_set_key
272289848Sjkim.align	32
273289848Sjkimcmll_t4_set_key:
274289848Sjkim	and		$inp, 7, $tmp
275289848Sjkim	alignaddr	$inp, %g0, $inp
276289848Sjkim	cmp		$bits, 192
277289848Sjkim	ldd		[$inp + 0], %f0
278289848Sjkim	bl,pt		%icc,.L128
279289848Sjkim	ldd		[$inp + 8], %f2
280289848Sjkim
281289848Sjkim	be,pt		%icc,.L192
282289848Sjkim	ldd		[$inp + 16], %f4
283289848Sjkim
284289848Sjkim	brz,pt		$tmp, .L256aligned
285289848Sjkim	ldd		[$inp + 24], %f6
286289848Sjkim
287289848Sjkim	ldd		[$inp + 32], %f8
288289848Sjkim	faligndata	%f0, %f2, %f0
289289848Sjkim	faligndata	%f2, %f4, %f2
290289848Sjkim	faligndata	%f4, %f6, %f4
291289848Sjkim	b		.L256aligned
292289848Sjkim	faligndata	%f6, %f8, %f6
293289848Sjkim
294289848Sjkim.align	16
295289848Sjkim.L192:
296289848Sjkim	brz,a,pt	$tmp, .L256aligned
297289848Sjkim	fnot2		%f4, %f6
298289848Sjkim
299289848Sjkim	ldd		[$inp + 24], %f6
300289848Sjkim	nop
301289848Sjkim	faligndata	%f0, %f2, %f0
302289848Sjkim	faligndata	%f2, %f4, %f2
303289848Sjkim	faligndata	%f4, %f6, %f4
304289848Sjkim	fnot2		%f4, %f6
305289848Sjkim
306289848Sjkim.L256aligned:
307289848Sjkim	std		%f0, [$out + 0]		! k[0, 1]
308289848Sjkim	fsrc2		%f0, %f28
309289848Sjkim	std		%f2, [$out + 8]		! k[2, 3]
310289848Sjkim	fsrc2		%f2, %f30
311289848Sjkim	fxor		%f4, %f0, %f0
312289848Sjkim	b		.L128key
313289848Sjkim	fxor		%f6, %f2, %f2
314289848Sjkim
315289848Sjkim.align	16
316289848Sjkim.L128:
317289848Sjkim	brz,pt		$tmp, .L128aligned
318289848Sjkim	nop
319289848Sjkim
320289848Sjkim	ldd		[$inp + 16], %f4
321289848Sjkim	nop
322289848Sjkim	faligndata	%f0, %f2, %f0
323289848Sjkim	faligndata	%f2, %f4, %f2
324289848Sjkim
325289848Sjkim.L128aligned:
326289848Sjkim	std		%f0, [$out + 0]		! k[0, 1]
327289848Sjkim	fsrc2		%f0, %f28
328289848Sjkim	std		%f2, [$out + 8]		! k[2, 3]
329289848Sjkim	fsrc2		%f2, %f30
330289848Sjkim
331289848Sjkim.L128key:
332289848Sjkim	mov		%o7, %o5
333289848Sjkim1:	call		.+8
334289848Sjkim	add		%o7, SIGMA-1b, %o4
335289848Sjkim	mov		%o5, %o7
336289848Sjkim
337289848Sjkim	ldd		[%o4 + 0], %f16
338289848Sjkim	ldd		[%o4 + 8], %f18
339289848Sjkim	ldd		[%o4 + 16], %f20
340289848Sjkim	ldd		[%o4 + 24], %f22
341289848Sjkim
342289848Sjkim	camellia_f	%f16, %f2, %f0, %f2
343289848Sjkim	camellia_f	%f18, %f0, %f2, %f0
344289848Sjkim	fxor		%f28, %f0, %f0
345289848Sjkim	fxor		%f30, %f2, %f2
346289848Sjkim	camellia_f	%f20, %f2, %f0, %f2
347289848Sjkim	camellia_f	%f22, %f0, %f2, %f0
348289848Sjkim
349289848Sjkim	bge,pn		%icc, .L256key
350289848Sjkim	nop
351289848Sjkim	std	%f0, [$out + 0x10]	! k[ 4,  5]
352289848Sjkim	std	%f2, [$out + 0x18]	! k[ 6,  7]
353289848Sjkim
354289848Sjkim	movdtox	%f0, %o4
355289848Sjkim	movdtox	%f2, %o5
356289848Sjkim	`&ROTL128(15)`
357289848Sjkim	stx	%o4, [$out + 0x30]	! k[12, 13]
358289848Sjkim	stx	%o5, [$out + 0x38]	! k[14, 15]
359289848Sjkim	`&ROTL128(15)`
360289848Sjkim	stx	%o4, [$out + 0x40]	! k[16, 17]
361289848Sjkim	stx	%o5, [$out + 0x48]	! k[18, 19]
362289848Sjkim	`&ROTL128(15)`
363289848Sjkim	stx	%o4, [$out + 0x60]	! k[24, 25]
364289848Sjkim	`&ROTL128(15)`
365289848Sjkim	stx	%o4, [$out + 0x70]	! k[28, 29]
366289848Sjkim	stx	%o5, [$out + 0x78]	! k[30, 31]
367289848Sjkim	`&ROTL128(34)`
368289848Sjkim	stx	%o4, [$out + 0xa0]	! k[40, 41]
369289848Sjkim	stx	%o5, [$out + 0xa8]	! k[42, 43]
370289848Sjkim	`&ROTL128(17)`
371289848Sjkim	stx	%o4, [$out + 0xc0]	! k[48, 49]
372289848Sjkim	stx	%o5, [$out + 0xc8]	! k[50, 51]
373289848Sjkim
374289848Sjkim	movdtox	%f28, %o4		! k[ 0,  1]
375289848Sjkim	movdtox	%f30, %o5		! k[ 2,  3]
376289848Sjkim	`&ROTL128(15)`
377289848Sjkim	stx	%o4, [$out + 0x20]	! k[ 8,  9]
378289848Sjkim	stx	%o5, [$out + 0x28]	! k[10, 11]
379289848Sjkim	`&ROTL128(30)`
380289848Sjkim	stx	%o4, [$out + 0x50]	! k[20, 21]
381289848Sjkim	stx	%o5, [$out + 0x58]	! k[22, 23]
382289848Sjkim	`&ROTL128(15)`
383289848Sjkim	stx	%o5, [$out + 0x68]	! k[26, 27]
384289848Sjkim	`&ROTL128(17)`
385289848Sjkim	stx	%o4, [$out + 0x80]	! k[32, 33]
386289848Sjkim	stx	%o5, [$out + 0x88]	! k[34, 35]
387289848Sjkim	`&ROTL128(17)`
388289848Sjkim	stx	%o4, [$out + 0x90]	! k[36, 37]
389289848Sjkim	stx	%o5, [$out + 0x98]	! k[38, 39]
390289848Sjkim	`&ROTL128(17)`
391289848Sjkim	stx	%o4, [$out + 0xb0]	! k[44, 45]
392289848Sjkim	stx	%o5, [$out + 0xb8]	! k[46, 47]
393289848Sjkim
394289848Sjkim	mov		3, $tmp
395289848Sjkim	st		$tmp, [$out + 0x110]
396289848Sjkim	retl
397289848Sjkim	xor		%o0, %o0, %o0
398289848Sjkim
399289848Sjkim.align	16
400289848Sjkim.L256key:
401289848Sjkim	ldd		[%o4 + 32], %f24
402289848Sjkim	ldd		[%o4 + 40], %f26
403289848Sjkim
404289848Sjkim	std		%f0, [$out + 0x30]	! k[12, 13]
405289848Sjkim	std		%f2, [$out + 0x38]	! k[14, 15]
406289848Sjkim
407289848Sjkim	fxor		%f4, %f0, %f0
408289848Sjkim	fxor		%f6, %f2, %f2
409289848Sjkim	camellia_f	%f24, %f2, %f0, %f2
410289848Sjkim	camellia_f	%f26, %f0, %f2, %f0
411289848Sjkim
412289848Sjkim	std	%f0, [$out + 0x10]	! k[ 4,  5]
413289848Sjkim	std	%f2, [$out + 0x18]	! k[ 6,  7]
414289848Sjkim
415289848Sjkim	movdtox	%f0, %o4
416289848Sjkim	movdtox	%f2, %o5
417289848Sjkim	`&ROTL128(30)`
418289848Sjkim	stx	%o4, [$out + 0x50]	! k[20, 21]
419289848Sjkim	stx	%o5, [$out + 0x58]	! k[22, 23]
420289848Sjkim	`&ROTL128(30)`
421289848Sjkim	stx	%o4, [$out + 0xa0]	! k[40, 41]
422289848Sjkim	stx	%o5, [$out + 0xa8]	! k[42, 43]
423289848Sjkim	`&ROTL128(51)`
424289848Sjkim	stx	%o4, [$out + 0x100]	! k[64, 65]
425289848Sjkim	stx	%o5, [$out + 0x108]	! k[66, 67]
426289848Sjkim
427289848Sjkim	movdtox	%f4, %o4		! k[ 8,  9]
428289848Sjkim	movdtox	%f6, %o5		! k[10, 11]
429289848Sjkim	`&ROTL128(15)`
430289848Sjkim	stx	%o4, [$out + 0x20]	! k[ 8,  9]
431289848Sjkim	stx	%o5, [$out + 0x28]	! k[10, 11]
432289848Sjkim	`&ROTL128(15)`
433289848Sjkim	stx	%o4, [$out + 0x40]	! k[16, 17]
434289848Sjkim	stx	%o5, [$out + 0x48]	! k[18, 19]
435289848Sjkim	`&ROTL128(30)`
436289848Sjkim	stx	%o4, [$out + 0x90]	! k[36, 37]
437289848Sjkim	stx	%o5, [$out + 0x98]	! k[38, 39]
438289848Sjkim	`&ROTL128(34)`
439289848Sjkim	stx	%o4, [$out + 0xd0]	! k[52, 53]
440289848Sjkim	stx	%o5, [$out + 0xd8]	! k[54, 55]
441289848Sjkim	ldx	[$out + 0x30], %o4	! k[12, 13]
442289848Sjkim	ldx	[$out + 0x38], %o5	! k[14, 15]
443289848Sjkim	`&ROTL128(15)`
444289848Sjkim	stx	%o4, [$out + 0x30]	! k[12, 13]
445289848Sjkim	stx	%o5, [$out + 0x38]	! k[14, 15]
446289848Sjkim	`&ROTL128(30)`
447289848Sjkim	stx	%o4, [$out + 0x70]	! k[28, 29]
448289848Sjkim	stx	%o5, [$out + 0x78]	! k[30, 31]
449289848Sjkim	srlx	%o4, 32, %g4
450289848Sjkim	srlx	%o5, 32, %g5
451289848Sjkim	st	%o4, [$out + 0xc0]	! k[48]
452289848Sjkim	st	%g5, [$out + 0xc4]	! k[49]
453289848Sjkim	st	%o5, [$out + 0xc8]	! k[50]
454289848Sjkim	st	%g4, [$out + 0xcc]	! k[51]
455289848Sjkim	`&ROTL128(49)`
456289848Sjkim	stx	%o4, [$out + 0xe0]	! k[56, 57]
457289848Sjkim	stx	%o5, [$out + 0xe8]	! k[58, 59]
458289848Sjkim
459289848Sjkim	movdtox	%f28, %o4		! k[ 0,  1]
460289848Sjkim	movdtox	%f30, %o5		! k[ 2,  3]
461289848Sjkim	`&ROTL128(45)`
462289848Sjkim	stx	%o4, [$out + 0x60]	! k[24, 25]
463289848Sjkim	stx	%o5, [$out + 0x68]	! k[26, 27]
464289848Sjkim	`&ROTL128(15)`
465289848Sjkim	stx	%o4, [$out + 0x80]	! k[32, 33]
466289848Sjkim	stx	%o5, [$out + 0x88]	! k[34, 35]
467289848Sjkim	`&ROTL128(17)`
468289848Sjkim	stx	%o4, [$out + 0xb0]	! k[44, 45]
469289848Sjkim	stx	%o5, [$out + 0xb8]	! k[46, 47]
470289848Sjkim	`&ROTL128(34)`
471289848Sjkim	stx	%o4, [$out + 0xf0]	! k[60, 61]
472289848Sjkim	stx	%o5, [$out + 0xf8]	! k[62, 63]
473289848Sjkim
474289848Sjkim	mov		4, $tmp
475289848Sjkim	st		$tmp, [$out + 0x110]
476289848Sjkim	retl
477289848Sjkim	xor		%o0, %o0, %o0
478289848Sjkim.type	cmll_t4_set_key,#function
479289848Sjkim.size	cmll_t4_set_key,.-cmll_t4_set_key
480289848Sjkim.align	32
481289848SjkimSIGMA:
482289848Sjkim	.long	0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2
483289848Sjkim	.long	0xc6ef372f, 0xe94f82be, 0x54ff53a5, 0xf1d36f1c
484289848Sjkim	.long	0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd
485289848Sjkim.type	SIGMA,#object
486289848Sjkim.size	SIGMA,.-SIGMA
487289848Sjkim.asciz	"Camellia for SPARC T4, David S. Miller, Andy Polyakov"
488289848Sjkim___
489289848Sjkim}
490289848Sjkim
491289848Sjkim{{{
492289848Sjkimmy ($inp,$out,$len,$key,$ivec,$enc)=map("%i$_",(0..5));
493289848Sjkimmy ($ileft,$iright,$ooff,$omask,$ivoff)=map("%l$_",(1..7));
494289848Sjkim
495289848Sjkim$code.=<<___;
496289848Sjkim.align	32
497289848Sjkim_cmll128_load_enckey:
498289848Sjkim	ldx		[$key + 0], %g4
499289848Sjkim	ldx		[$key + 8], %g5
500289848Sjkim___
501289848Sjkimfor ($i=2; $i<26;$i++) {			# load key schedule
502289848Sjkim    $code.=<<___;
503289848Sjkim	ldd		[$key + `8*$i`], %f`12+2*$i`
504289848Sjkim___
505289848Sjkim}
506289848Sjkim$code.=<<___;
507289848Sjkim	retl
508289848Sjkim	nop
509289848Sjkim.type	_cmll128_load_enckey,#function
510289848Sjkim.size	_cmll128_load_enckey,.-_cmll128_load_enckey
511289848Sjkim_cmll256_load_enckey=_cmll128_load_enckey
512289848Sjkim
513289848Sjkim.align	32
514289848Sjkim_cmll256_load_deckey:
515289848Sjkim	ldd		[$key + 64], %f62
516289848Sjkim	ldd		[$key + 72], %f60
517289848Sjkim	b		.Load_deckey
518289848Sjkim	add		$key, 64, $key
519289848Sjkim_cmll128_load_deckey:
520289848Sjkim	ldd		[$key + 0], %f60
521289848Sjkim	ldd		[$key + 8], %f62
522289848Sjkim.Load_deckey:
523289848Sjkim___
524289848Sjkimfor ($i=2; $i<24;$i++) {			# load key schedule
525289848Sjkim    $code.=<<___;
526289848Sjkim	ldd		[$key + `8*$i`], %f`62-2*$i`
527289848Sjkim___
528289848Sjkim}
529289848Sjkim$code.=<<___;
530289848Sjkim	ldx		[$key + 192], %g4
531289848Sjkim	retl
532289848Sjkim	ldx		[$key + 200], %g5
533289848Sjkim.type	_cmll256_load_deckey,#function
534289848Sjkim.size	_cmll256_load_deckey,.-_cmll256_load_deckey
535289848Sjkim
536289848Sjkim.align	32
537289848Sjkim_cmll128_encrypt_1x:
538289848Sjkim___
539289848Sjkimfor ($i=0; $i<3; $i++) {
540289848Sjkim    $code.=<<___;
541289848Sjkim	camellia_f	%f`16+16*$i+0`, %f2, %f0, %f2
542289848Sjkim	camellia_f	%f`16+16*$i+2`, %f0, %f2, %f0
543289848Sjkim	camellia_f	%f`16+16*$i+4`, %f2, %f0, %f2
544289848Sjkim	camellia_f	%f`16+16*$i+6`, %f0, %f2, %f0
545289848Sjkim___
546289848Sjkim$code.=<<___ if ($i<2);
547289848Sjkim	camellia_f	%f`16+16*$i+8`, %f2, %f0, %f2
548289848Sjkim	camellia_f	%f`16+16*$i+10`, %f0, %f2, %f0
549289848Sjkim	camellia_fl	%f`16+16*$i+12`, %f0,      %f0
550289848Sjkim	camellia_fli	%f`16+16*$i+14`, %f2,      %f2
551289848Sjkim___
552289848Sjkim}
553289848Sjkim$code.=<<___;
554289848Sjkim	camellia_f	%f56, %f2, %f0, %f4
555289848Sjkim	camellia_f	%f58, %f0, %f4, %f2
556289848Sjkim	fxor		%f60, %f4, %f0
557289848Sjkim	retl
558289848Sjkim	fxor		%f62, %f2, %f2
559289848Sjkim.type	_cmll128_encrypt_1x,#function
560289848Sjkim.size	_cmll128_encrypt_1x,.-_cmll128_encrypt_1x
561289848Sjkim_cmll128_decrypt_1x=_cmll128_encrypt_1x
562289848Sjkim
563289848Sjkim.align	32
564289848Sjkim_cmll128_encrypt_2x:
565289848Sjkim___
566289848Sjkimfor ($i=0; $i<3; $i++) {
567289848Sjkim    $code.=<<___;
568289848Sjkim	camellia_f	%f`16+16*$i+0`, %f2, %f0, %f2
569289848Sjkim	camellia_f	%f`16+16*$i+0`, %f6, %f4, %f6
570289848Sjkim	camellia_f	%f`16+16*$i+2`, %f0, %f2, %f0
571289848Sjkim	camellia_f	%f`16+16*$i+2`, %f4, %f6, %f4
572289848Sjkim	camellia_f	%f`16+16*$i+4`, %f2, %f0, %f2
573289848Sjkim	camellia_f	%f`16+16*$i+4`, %f6, %f4, %f6
574289848Sjkim	camellia_f	%f`16+16*$i+6`, %f0, %f2, %f0
575289848Sjkim	camellia_f	%f`16+16*$i+6`, %f4, %f6, %f4
576289848Sjkim___
577289848Sjkim$code.=<<___ if ($i<2);
578289848Sjkim	camellia_f	%f`16+16*$i+8`, %f2, %f0, %f2
579289848Sjkim	camellia_f	%f`16+16*$i+8`, %f6, %f4, %f6
580289848Sjkim	camellia_f	%f`16+16*$i+10`, %f0, %f2, %f0
581289848Sjkim	camellia_f	%f`16+16*$i+10`, %f4, %f6, %f4
582289848Sjkim	camellia_fl	%f`16+16*$i+12`, %f0,      %f0
583289848Sjkim	camellia_fl	%f`16+16*$i+12`, %f4,      %f4
584289848Sjkim	camellia_fli	%f`16+16*$i+14`, %f2,      %f2
585289848Sjkim	camellia_fli	%f`16+16*$i+14`, %f6,      %f6
586289848Sjkim___
587289848Sjkim}
588289848Sjkim$code.=<<___;
589289848Sjkim	camellia_f	%f56, %f2, %f0, %f8
590289848Sjkim	camellia_f	%f56, %f6, %f4, %f10
591289848Sjkim	camellia_f	%f58, %f0, %f8, %f2
592289848Sjkim	camellia_f	%f58, %f4, %f10, %f6
593289848Sjkim	fxor		%f60, %f8, %f0
594289848Sjkim	fxor		%f60, %f10, %f4
595289848Sjkim	fxor		%f62, %f2, %f2
596289848Sjkim	retl
597289848Sjkim	fxor		%f62, %f6, %f6
598289848Sjkim.type	_cmll128_encrypt_2x,#function
599289848Sjkim.size	_cmll128_encrypt_2x,.-_cmll128_encrypt_2x
600289848Sjkim_cmll128_decrypt_2x=_cmll128_encrypt_2x
601289848Sjkim
602289848Sjkim.align	32
603289848Sjkim_cmll256_encrypt_1x:
604289848Sjkim	camellia_f	%f16, %f2, %f0, %f2
605289848Sjkim	camellia_f	%f18, %f0, %f2, %f0
606289848Sjkim	ldd		[$key + 208], %f16
607289848Sjkim	ldd		[$key + 216], %f18
608289848Sjkim	camellia_f	%f20, %f2, %f0, %f2
609289848Sjkim	camellia_f	%f22, %f0, %f2, %f0
610289848Sjkim	ldd		[$key + 224], %f20
611289848Sjkim	ldd		[$key + 232], %f22
612289848Sjkim	camellia_f	%f24, %f2, %f0, %f2
613289848Sjkim	camellia_f	%f26, %f0, %f2, %f0
614289848Sjkim	ldd		[$key + 240], %f24
615289848Sjkim	ldd		[$key + 248], %f26
616289848Sjkim	camellia_fl	%f28, %f0, %f0
617289848Sjkim	camellia_fli	%f30, %f2, %f2
618289848Sjkim	ldd		[$key + 256], %f28
619289848Sjkim	ldd		[$key + 264], %f30
620289848Sjkim___
621289848Sjkimfor ($i=1; $i<3; $i++) {
622289848Sjkim    $code.=<<___;
623289848Sjkim	camellia_f	%f`16+16*$i+0`, %f2, %f0, %f2
624289848Sjkim	camellia_f	%f`16+16*$i+2`, %f0, %f2, %f0
625289848Sjkim	camellia_f	%f`16+16*$i+4`, %f2, %f0, %f2
626289848Sjkim	camellia_f	%f`16+16*$i+6`, %f0, %f2, %f0
627289848Sjkim	camellia_f	%f`16+16*$i+8`, %f2, %f0, %f2
628289848Sjkim	camellia_f	%f`16+16*$i+10`, %f0, %f2, %f0
629289848Sjkim	camellia_fl	%f`16+16*$i+12`, %f0,      %f0
630289848Sjkim	camellia_fli	%f`16+16*$i+14`, %f2,      %f2
631289848Sjkim___
632289848Sjkim}
633289848Sjkim$code.=<<___;
634289848Sjkim	camellia_f	%f16, %f2, %f0, %f2
635289848Sjkim	camellia_f	%f18, %f0, %f2, %f0
636289848Sjkim	ldd		[$key + 16], %f16
637289848Sjkim	ldd		[$key + 24], %f18
638289848Sjkim	camellia_f	%f20, %f2, %f0, %f2
639289848Sjkim	camellia_f	%f22, %f0, %f2, %f0
640289848Sjkim	ldd		[$key + 32], %f20
641289848Sjkim	ldd		[$key + 40], %f22
642289848Sjkim	camellia_f	%f24, %f2, %f0, %f4
643289848Sjkim	camellia_f	%f26, %f0, %f4, %f2
644289848Sjkim	ldd		[$key + 48], %f24
645289848Sjkim	ldd		[$key + 56], %f26
646289848Sjkim	fxor		%f28, %f4, %f0
647289848Sjkim	fxor		%f30, %f2, %f2
648289848Sjkim	ldd		[$key + 64], %f28
649289848Sjkim	retl
650289848Sjkim	ldd		[$key + 72], %f30
651289848Sjkim.type	_cmll256_encrypt_1x,#function
652289848Sjkim.size	_cmll256_encrypt_1x,.-_cmll256_encrypt_1x
653289848Sjkim
654289848Sjkim.align	32
655289848Sjkim_cmll256_encrypt_2x:
656289848Sjkim	camellia_f	%f16, %f2, %f0, %f2
657289848Sjkim	camellia_f	%f16, %f6, %f4, %f6
658289848Sjkim	camellia_f	%f18, %f0, %f2, %f0
659289848Sjkim	camellia_f	%f18, %f4, %f6, %f4
660289848Sjkim	ldd		[$key + 208], %f16
661289848Sjkim	ldd		[$key + 216], %f18
662289848Sjkim	camellia_f	%f20, %f2, %f0, %f2
663289848Sjkim	camellia_f	%f20, %f6, %f4, %f6
664289848Sjkim	camellia_f	%f22, %f0, %f2, %f0
665289848Sjkim	camellia_f	%f22, %f4, %f6, %f4
666289848Sjkim	ldd		[$key + 224], %f20
667289848Sjkim	ldd		[$key + 232], %f22
668289848Sjkim	camellia_f	%f24, %f2, %f0, %f2
669289848Sjkim	camellia_f	%f24, %f6, %f4, %f6
670289848Sjkim	camellia_f	%f26, %f0, %f2, %f0
671289848Sjkim	camellia_f	%f26, %f4, %f6, %f4
672289848Sjkim	ldd		[$key + 240], %f24
673289848Sjkim	ldd		[$key + 248], %f26
674289848Sjkim	camellia_fl	%f28, %f0, %f0
675289848Sjkim	camellia_fl	%f28, %f4, %f4
676289848Sjkim	camellia_fli	%f30, %f2, %f2
677289848Sjkim	camellia_fli	%f30, %f6, %f6
678289848Sjkim	ldd		[$key + 256], %f28
679289848Sjkim	ldd		[$key + 264], %f30
680289848Sjkim___
681289848Sjkimfor ($i=1; $i<3; $i++) {
682289848Sjkim    $code.=<<___;
683289848Sjkim	camellia_f	%f`16+16*$i+0`, %f2, %f0, %f2
684289848Sjkim	camellia_f	%f`16+16*$i+0`, %f6, %f4, %f6
685289848Sjkim	camellia_f	%f`16+16*$i+2`, %f0, %f2, %f0
686289848Sjkim	camellia_f	%f`16+16*$i+2`, %f4, %f6, %f4
687289848Sjkim	camellia_f	%f`16+16*$i+4`, %f2, %f0, %f2
688289848Sjkim	camellia_f	%f`16+16*$i+4`, %f6, %f4, %f6
689289848Sjkim	camellia_f	%f`16+16*$i+6`, %f0, %f2, %f0
690289848Sjkim	camellia_f	%f`16+16*$i+6`, %f4, %f6, %f4
691289848Sjkim	camellia_f	%f`16+16*$i+8`, %f2, %f0, %f2
692289848Sjkim	camellia_f	%f`16+16*$i+8`, %f6, %f4, %f6
693289848Sjkim	camellia_f	%f`16+16*$i+10`, %f0, %f2, %f0
694289848Sjkim	camellia_f	%f`16+16*$i+10`, %f4, %f6, %f4
695289848Sjkim	camellia_fl	%f`16+16*$i+12`, %f0,      %f0
696289848Sjkim	camellia_fl	%f`16+16*$i+12`, %f4,      %f4
697289848Sjkim	camellia_fli	%f`16+16*$i+14`, %f2,      %f2
698289848Sjkim	camellia_fli	%f`16+16*$i+14`, %f6,      %f6
699289848Sjkim___
700289848Sjkim}
701289848Sjkim$code.=<<___;
702289848Sjkim	camellia_f	%f16, %f2, %f0, %f2
703289848Sjkim	camellia_f	%f16, %f6, %f4, %f6
704289848Sjkim	camellia_f	%f18, %f0, %f2, %f0
705289848Sjkim	camellia_f	%f18, %f4, %f6, %f4
706289848Sjkim	ldd		[$key + 16], %f16
707289848Sjkim	ldd		[$key + 24], %f18
708289848Sjkim	camellia_f	%f20, %f2, %f0, %f2
709289848Sjkim	camellia_f	%f20, %f6, %f4, %f6
710289848Sjkim	camellia_f	%f22, %f0, %f2, %f0
711289848Sjkim	camellia_f	%f22, %f4, %f6, %f4
712289848Sjkim	ldd		[$key + 32], %f20
713289848Sjkim	ldd		[$key + 40], %f22
714289848Sjkim	camellia_f	%f24, %f2, %f0, %f8
715289848Sjkim	camellia_f	%f24, %f6, %f4, %f10
716289848Sjkim	camellia_f	%f26, %f0, %f8, %f2
717289848Sjkim	camellia_f	%f26, %f4, %f10, %f6
718289848Sjkim	ldd		[$key + 48], %f24
719289848Sjkim	ldd		[$key + 56], %f26
720289848Sjkim	fxor		%f28, %f8, %f0
721289848Sjkim	fxor		%f28, %f10, %f4
722289848Sjkim	fxor		%f30, %f2, %f2
723289848Sjkim	fxor		%f30, %f6, %f6
724289848Sjkim	ldd		[$key + 64], %f28
725289848Sjkim	retl
726289848Sjkim	ldd		[$key + 72], %f30
727289848Sjkim.type	_cmll256_encrypt_2x,#function
728289848Sjkim.size	_cmll256_encrypt_2x,.-_cmll256_encrypt_2x
729289848Sjkim
730289848Sjkim.align	32
731289848Sjkim_cmll256_decrypt_1x:
732289848Sjkim	camellia_f	%f16, %f2, %f0, %f2
733289848Sjkim	camellia_f	%f18, %f0, %f2, %f0
734289848Sjkim	ldd		[$key - 8], %f16
735289848Sjkim	ldd		[$key - 16], %f18
736289848Sjkim	camellia_f	%f20, %f2, %f0, %f2
737289848Sjkim	camellia_f	%f22, %f0, %f2, %f0
738289848Sjkim	ldd		[$key - 24], %f20
739289848Sjkim	ldd		[$key - 32], %f22
740289848Sjkim	camellia_f	%f24, %f2, %f0, %f2
741289848Sjkim	camellia_f	%f26, %f0, %f2, %f0
742289848Sjkim	ldd		[$key - 40], %f24
743289848Sjkim	ldd		[$key - 48], %f26
744289848Sjkim	camellia_fl	%f28, %f0, %f0
745289848Sjkim	camellia_fli	%f30, %f2, %f2
746289848Sjkim	ldd		[$key - 56], %f28
747289848Sjkim	ldd		[$key - 64], %f30
748289848Sjkim___
749289848Sjkimfor ($i=1; $i<3; $i++) {
750289848Sjkim    $code.=<<___;
751289848Sjkim	camellia_f	%f`16+16*$i+0`, %f2, %f0, %f2
752289848Sjkim	camellia_f	%f`16+16*$i+2`, %f0, %f2, %f0
753289848Sjkim	camellia_f	%f`16+16*$i+4`, %f2, %f0, %f2
754289848Sjkim	camellia_f	%f`16+16*$i+6`, %f0, %f2, %f0
755289848Sjkim	camellia_f	%f`16+16*$i+8`, %f2, %f0, %f2
756289848Sjkim	camellia_f	%f`16+16*$i+10`, %f0, %f2, %f0
757289848Sjkim	camellia_fl	%f`16+16*$i+12`, %f0,      %f0
758289848Sjkim	camellia_fli	%f`16+16*$i+14`, %f2,      %f2
759289848Sjkim___
760289848Sjkim}
761289848Sjkim$code.=<<___;
762289848Sjkim	camellia_f	%f16, %f2, %f0, %f2
763289848Sjkim	camellia_f	%f18, %f0, %f2, %f0
764289848Sjkim	ldd		[$key + 184], %f16
765289848Sjkim	ldd		[$key + 176], %f18
766289848Sjkim	camellia_f	%f20, %f2, %f0, %f2
767289848Sjkim	camellia_f	%f22, %f0, %f2, %f0
768289848Sjkim	ldd		[$key + 168], %f20
769289848Sjkim	ldd		[$key + 160], %f22
770289848Sjkim	camellia_f	%f24, %f2, %f0, %f4
771289848Sjkim	camellia_f	%f26, %f0, %f4, %f2
772289848Sjkim	ldd		[$key + 152], %f24
773289848Sjkim	ldd		[$key + 144], %f26
774289848Sjkim	fxor		%f30, %f4, %f0
775289848Sjkim	fxor		%f28, %f2, %f2
776289848Sjkim	ldd		[$key + 136], %f28
777289848Sjkim	retl
778289848Sjkim	ldd		[$key + 128], %f30
779289848Sjkim.type	_cmll256_decrypt_1x,#function
780289848Sjkim.size	_cmll256_decrypt_1x,.-_cmll256_decrypt_1x
781289848Sjkim
782289848Sjkim.align	32
783289848Sjkim_cmll256_decrypt_2x:
784289848Sjkim	camellia_f	%f16, %f2, %f0, %f2
785289848Sjkim	camellia_f	%f16, %f6, %f4, %f6
786289848Sjkim	camellia_f	%f18, %f0, %f2, %f0
787289848Sjkim	camellia_f	%f18, %f4, %f6, %f4
788289848Sjkim	ldd		[$key - 8], %f16
789289848Sjkim	ldd		[$key - 16], %f18
790289848Sjkim	camellia_f	%f20, %f2, %f0, %f2
791289848Sjkim	camellia_f	%f20, %f6, %f4, %f6
792289848Sjkim	camellia_f	%f22, %f0, %f2, %f0
793289848Sjkim	camellia_f	%f22, %f4, %f6, %f4
794289848Sjkim	ldd		[$key - 24], %f20
795289848Sjkim	ldd		[$key - 32], %f22
796289848Sjkim	camellia_f	%f24, %f2, %f0, %f2
797289848Sjkim	camellia_f	%f24, %f6, %f4, %f6
798289848Sjkim	camellia_f	%f26, %f0, %f2, %f0
799289848Sjkim	camellia_f	%f26, %f4, %f6, %f4
800289848Sjkim	ldd		[$key - 40], %f24
801289848Sjkim	ldd		[$key - 48], %f26
802289848Sjkim	camellia_fl	%f28, %f0, %f0
803289848Sjkim	camellia_fl	%f28, %f4, %f4
804289848Sjkim	camellia_fli	%f30, %f2, %f2
805289848Sjkim	camellia_fli	%f30, %f6, %f6
806289848Sjkim	ldd		[$key - 56], %f28
807289848Sjkim	ldd		[$key - 64], %f30
808289848Sjkim___
809289848Sjkimfor ($i=1; $i<3; $i++) {
810289848Sjkim    $code.=<<___;
811289848Sjkim	camellia_f	%f`16+16*$i+0`, %f2, %f0, %f2
812289848Sjkim	camellia_f	%f`16+16*$i+0`, %f6, %f4, %f6
813289848Sjkim	camellia_f	%f`16+16*$i+2`, %f0, %f2, %f0
814289848Sjkim	camellia_f	%f`16+16*$i+2`, %f4, %f6, %f4
815289848Sjkim	camellia_f	%f`16+16*$i+4`, %f2, %f0, %f2
816289848Sjkim	camellia_f	%f`16+16*$i+4`, %f6, %f4, %f6
817289848Sjkim	camellia_f	%f`16+16*$i+6`, %f0, %f2, %f0
818289848Sjkim	camellia_f	%f`16+16*$i+6`, %f4, %f6, %f4
819289848Sjkim	camellia_f	%f`16+16*$i+8`, %f2, %f0, %f2
820289848Sjkim	camellia_f	%f`16+16*$i+8`, %f6, %f4, %f6
821289848Sjkim	camellia_f	%f`16+16*$i+10`, %f0, %f2, %f0
822289848Sjkim	camellia_f	%f`16+16*$i+10`, %f4, %f6, %f4
823289848Sjkim	camellia_fl	%f`16+16*$i+12`, %f0,      %f0
824289848Sjkim	camellia_fl	%f`16+16*$i+12`, %f4,      %f4
825289848Sjkim	camellia_fli	%f`16+16*$i+14`, %f2,      %f2
826289848Sjkim	camellia_fli	%f`16+16*$i+14`, %f6,      %f6
827289848Sjkim___
828289848Sjkim}
829289848Sjkim$code.=<<___;
830289848Sjkim	camellia_f	%f16, %f2, %f0, %f2
831289848Sjkim	camellia_f	%f16, %f6, %f4, %f6
832289848Sjkim	camellia_f	%f18, %f0, %f2, %f0
833289848Sjkim	camellia_f	%f18, %f4, %f6, %f4
834289848Sjkim	ldd		[$key + 184], %f16
835289848Sjkim	ldd		[$key + 176], %f18
836289848Sjkim	camellia_f	%f20, %f2, %f0, %f2
837289848Sjkim	camellia_f	%f20, %f6, %f4, %f6
838289848Sjkim	camellia_f	%f22, %f0, %f2, %f0
839289848Sjkim	camellia_f	%f22, %f4, %f6, %f4
840289848Sjkim	ldd		[$key + 168], %f20
841289848Sjkim	ldd		[$key + 160], %f22
842289848Sjkim	camellia_f	%f24, %f2, %f0, %f8
843289848Sjkim	camellia_f	%f24, %f6, %f4, %f10
844289848Sjkim	camellia_f	%f26, %f0, %f8, %f2
845289848Sjkim	camellia_f	%f26, %f4, %f10, %f6
846289848Sjkim	ldd		[$key + 152], %f24
847289848Sjkim	ldd		[$key + 144], %f26
848289848Sjkim	fxor		%f30, %f8, %f0
849289848Sjkim	fxor		%f30, %f10, %f4
850289848Sjkim	fxor		%f28, %f2, %f2
851289848Sjkim	fxor		%f28, %f6, %f6
852289848Sjkim	ldd		[$key + 136], %f28
853289848Sjkim	retl
854289848Sjkim	ldd		[$key + 128], %f30
855289848Sjkim.type	_cmll256_decrypt_2x,#function
856289848Sjkim.size	_cmll256_decrypt_2x,.-_cmll256_decrypt_2x
857289848Sjkim___
858289848Sjkim
859289848Sjkim&alg_cbc_encrypt_implement("cmll",128);
860289848Sjkim&alg_cbc_encrypt_implement("cmll",256);
861289848Sjkim
862289848Sjkim&alg_cbc_decrypt_implement("cmll",128);
863289848Sjkim&alg_cbc_decrypt_implement("cmll",256);
864289848Sjkim
865289848Sjkimif ($::evp) {
866289848Sjkim    &alg_ctr32_implement("cmll",128);
867289848Sjkim    &alg_ctr32_implement("cmll",256);
868289848Sjkim}
869289848Sjkim}}}
870289848Sjkim
871289848Sjkimif (!$::evp) {
872289848Sjkim$code.=<<___;
873289848Sjkim.global	Camellia_encrypt
874289848SjkimCamellia_encrypt=cmll_t4_encrypt
875289848Sjkim.global	Camellia_decrypt
876289848SjkimCamellia_decrypt=cmll_t4_decrypt
877289848Sjkim.global	Camellia_set_key
878289848Sjkim.align	32
879289848SjkimCamellia_set_key:
880289848Sjkim	andcc		%o2, 7, %g0		! double-check alignment
881289848Sjkim	bnz,a,pn	%icc, 1f
882289848Sjkim	mov		-1, %o0
883289848Sjkim	brz,a,pn	%o0, 1f
884289848Sjkim	mov		-1, %o0
885289848Sjkim	brz,a,pn	%o2, 1f
886289848Sjkim	mov		-1, %o0
887289848Sjkim	andncc		%o1, 0x1c0, %g0
888289848Sjkim	bnz,a,pn	%icc, 1f
889289848Sjkim	mov		-2, %o0
890289848Sjkim	cmp		%o1, 128
891289848Sjkim	bl,a,pn		%icc, 1f
892289848Sjkim	mov		-2, %o0
893289848Sjkim	b		cmll_t4_set_key
894289848Sjkim	nop
895289848Sjkim1:	retl
896289848Sjkim	nop
897289848Sjkim.type	Camellia_set_key,#function
898289848Sjkim.size	Camellia_set_key,.-Camellia_set_key
899289848Sjkim___
900289848Sjkim
901289848Sjkimmy ($inp,$out,$len,$key,$ivec,$enc)=map("%o$_",(0..5));
902289848Sjkim
903289848Sjkim$code.=<<___;
904289848Sjkim.globl	Camellia_cbc_encrypt
905289848Sjkim.align	32
906289848SjkimCamellia_cbc_encrypt:
907289848Sjkim	ld		[$key + 272], %g1
908289848Sjkim	nop
909289848Sjkim	brz		$enc, .Lcbc_decrypt
910289848Sjkim	cmp		%g1, 3
911289848Sjkim
912289848Sjkim	be,pt		%icc, cmll128_t4_cbc_encrypt
913289848Sjkim	nop
914289848Sjkim	ba		cmll256_t4_cbc_encrypt
915289848Sjkim	nop
916289848Sjkim
917289848Sjkim.Lcbc_decrypt:
918289848Sjkim	be,pt		%icc, cmll128_t4_cbc_decrypt
919289848Sjkim	nop
920289848Sjkim	ba		cmll256_t4_cbc_decrypt
921289848Sjkim	nop
922289848Sjkim.type	Camellia_cbc_encrypt,#function
923289848Sjkim.size	Camellia_cbc_encrypt,.-Camellia_cbc_encrypt
924289848Sjkim___
925289848Sjkim}
926289848Sjkim
927289848Sjkim&emit_assembler();
928289848Sjkim
929289848Sjkimclose STDOUT;
930