1160814Ssimon!  des_enc.m4
2160814Ssimon!  des_enc.S  (generated from des_enc.m4)
3160814Ssimon!
4160814Ssimon!  UltraSPARC assembler version of the LibDES/SSLeay/OpenSSL des_enc.c file.
5160814Ssimon!
6160814Ssimon!  Version 1.0. 32-bit version.
7160814Ssimon!
8160814Ssimon!  June 8, 2000.
9160814Ssimon!
10160814Ssimon!  Version 2.0. 32/64-bit, PIC-ification, blended CPU adaptation
11160814Ssimon!		by Andy Polyakov.
12160814Ssimon!
13160814Ssimon!  January 1, 2003.
14160814Ssimon!
15160814Ssimon!  Assembler version: Copyright Svend Olaf Mikkelsen.
16160814Ssimon!
17160814Ssimon!  Original C code: Copyright Eric A. Young.
18160814Ssimon!
19160814Ssimon!  This code can be freely used by LibDES/SSLeay/OpenSSL users.
20160814Ssimon!
21160814Ssimon!  The LibDES/SSLeay/OpenSSL copyright notices must be respected.
22160814Ssimon!
23160814Ssimon!  This version can be redistributed.
24160814Ssimon!
25160814Ssimon!  To expand the m4 macros: m4 -B 8192 des_enc.m4 > des_enc.S
26160814Ssimon!
27160814Ssimon!  Global registers 1 to 5 are used. This is the same as done by the
28160814Ssimon!  cc compiler. The UltraSPARC load/store little endian feature is used.
29160814Ssimon!
30160814Ssimon!  Instruction grouping often refers to one CPU cycle.
31160814Ssimon!
32160814Ssimon!  Assemble through gcc: gcc -c -mcpu=ultrasparc -o des_enc.o des_enc.S
33160814Ssimon!
34160814Ssimon!  Assemble through cc:  cc -c -xarch=v8plusa -o des_enc.o des_enc.S
35160814Ssimon!
36160814Ssimon!  Performance improvement according to './apps/openssl speed des'
37160814Ssimon!
38160814Ssimon!	32-bit build:
39160814Ssimon!		23%  faster than cc-5.2 -xarch=v8plus -xO5
40160814Ssimon!		115% faster than gcc-3.2.1 -m32 -mcpu=ultrasparc -O5
41160814Ssimon!	64-bit build:
42160814Ssimon!		50%  faster than cc-5.2 -xarch=v9 -xO5
43160814Ssimon!		100% faster than gcc-3.2.1 -m64 -mcpu=ultrasparc -O5
44160814Ssimon!
45160814Ssimon
46160814Ssimon.ident "des_enc.m4 2.1"
47194206Ssimon.file  "des_enc-sparc.S"
48160814Ssimon
49160814Ssimon#if defined(__SUNPRO_C) && defined(__sparcv9)
50160814Ssimon# define ABI64  /* They've said -xarch=v9 at command line */
51160814Ssimon#elif defined(__GNUC__) && defined(__arch64__)
52160814Ssimon# define ABI64  /* They've said -m64 at command line */
53160814Ssimon#endif
54160814Ssimon
55160814Ssimon#ifdef ABI64
56160814Ssimon  .register	%g2,#scratch
57160814Ssimon  .register	%g3,#scratch
58160814Ssimon# define	FRAME	-192
59160814Ssimon# define	BIAS	2047
60160814Ssimon# define	LDPTR	ldx
61160814Ssimon# define	STPTR	stx
62160814Ssimon# define	ARG0	128
63160814Ssimon# define	ARGSZ	8
64160814Ssimon# ifndef OPENSSL_SYSNAME_ULTRASPARC
65160814Ssimon# define OPENSSL_SYSNAME_ULTRASPARC
66160814Ssimon# endif
67160814Ssimon#else
68160814Ssimon# define	FRAME	-96
69160814Ssimon# define	BIAS	0
70160814Ssimon# define	LDPTR	ld
71160814Ssimon# define	STPTR	st
72160814Ssimon# define	ARG0	68
73160814Ssimon# define	ARGSZ	4
74160814Ssimon#endif
75160814Ssimon
76160814Ssimon#define LOOPS 7
77160814Ssimon
78160814Ssimon#define global0 %g0
79160814Ssimon#define global1 %g1
80160814Ssimon#define global2 %g2
81160814Ssimon#define global3 %g3
82160814Ssimon#define global4 %g4
83160814Ssimon#define global5 %g5
84160814Ssimon
85160814Ssimon#define local0 %l0
86160814Ssimon#define local1 %l1
87160814Ssimon#define local2 %l2
88160814Ssimon#define local3 %l3
89160814Ssimon#define local4 %l4
90160814Ssimon#define local5 %l5
91160814Ssimon#define local7 %l6
92160814Ssimon#define local6 %l7
93160814Ssimon
94160814Ssimon#define in0 %i0
95160814Ssimon#define in1 %i1
96160814Ssimon#define in2 %i2
97160814Ssimon#define in3 %i3
98160814Ssimon#define in4 %i4
99160814Ssimon#define in5 %i5
100160814Ssimon#define in6 %i6
101160814Ssimon#define in7 %i7
102160814Ssimon
103160814Ssimon#define out0 %o0
104160814Ssimon#define out1 %o1
105160814Ssimon#define out2 %o2
106160814Ssimon#define out3 %o3
107160814Ssimon#define out4 %o4
108160814Ssimon#define out5 %o5
109160814Ssimon#define out6 %o6
110160814Ssimon#define out7 %o7
111160814Ssimon
112160814Ssimon#define stub stb
113160814Ssimon
114160814Ssimonchangequote({,})
115160814Ssimon
116160814Ssimon
117160814Ssimon! Macro definitions:
118160814Ssimon
119160814Ssimon
120160814Ssimon! {ip_macro}
121160814Ssimon!
122160814Ssimon! The logic used in initial and final permutations is the same as in
123160814Ssimon! the C code. The permutations are done with a clever shift, xor, and
124160814Ssimon! technique.
125160814Ssimon!
126160814Ssimon! The macro also loads address sbox 1 to 5 to global 1 to 5, address
127160814Ssimon! sbox 6 to local6, and addres sbox 8 to out3.
128160814Ssimon!
129160814Ssimon! Rotates the halfs 3 left to bring the sbox bits in convenient positions.
130160814Ssimon!
131160814Ssimon! Loads key first round from address in parameter 5 to out0, out1.
132160814Ssimon!
133160814Ssimon! After the the original LibDES initial permutation, the resulting left
134160814Ssimon! is in the variable initially used for right and vice versa. The macro
135160814Ssimon! implements the possibility to keep the halfs in the original registers.
136160814Ssimon!
137160814Ssimon! parameter 1  left
138160814Ssimon! parameter 2  right
139160814Ssimon! parameter 3  result left (modify in first round)
140160814Ssimon! parameter 4  result right (use in first round)
141160814Ssimon! parameter 5  key address
142160814Ssimon! parameter 6  1/2 for include encryption/decryption
143160814Ssimon! parameter 7  1 for move in1 to in3
144160814Ssimon! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
145160814Ssimon! parameter 9  1 for load ks3 and ks2 to in4 and in3
146160814Ssimon
147160814Ssimondefine(ip_macro, {
148160814Ssimon
149160814Ssimon! {ip_macro}
150160814Ssimon! $1 $2 $4 $3 $5 $6 $7 $8 $9
151160814Ssimon
152160814Ssimon	ld	[out2+256], local1
153160814Ssimon	srl	$2, 4, local4
154160814Ssimon
155160814Ssimon	xor	local4, $1, local4
156160814Ssimon	ifelse($7,1,{mov in1, in3},{nop})
157160814Ssimon
158160814Ssimon	ld	[out2+260], local2
159160814Ssimon	and	local4, local1, local4
160160814Ssimon	ifelse($8,1,{mov in3, in4},{})
161160814Ssimon	ifelse($8,2,{mov in4, in3},{})
162160814Ssimon
163160814Ssimon	ld	[out2+280], out4          ! loop counter
164160814Ssimon	sll	local4, 4, local1
165160814Ssimon	xor	$1, local4, $1
166160814Ssimon
167160814Ssimon	ld	[out2+264], local3
168160814Ssimon	srl	$1, 16, local4
169160814Ssimon	xor	$2, local1, $2
170160814Ssimon
171160814Ssimon	ifelse($9,1,{LDPTR	KS3, in4},{})
172160814Ssimon	xor	local4, $2, local4
173160814Ssimon	nop	!sethi	%hi(DES_SPtrans), global1 ! sbox addr
174160814Ssimon
175160814Ssimon	ifelse($9,1,{LDPTR	KS2, in3},{})
176160814Ssimon	and	local4, local2, local4
177160814Ssimon	nop	!or	global1, %lo(DES_SPtrans), global1   ! sbox addr
178160814Ssimon
179160814Ssimon	sll	local4, 16, local1
180160814Ssimon	xor	$2, local4, $2
181160814Ssimon
182160814Ssimon	srl	$2, 2, local4
183160814Ssimon	xor	$1, local1, $1
184160814Ssimon
185160814Ssimon	sethi	%hi(16711680), local5
186160814Ssimon	xor	local4, $1, local4
187160814Ssimon
188160814Ssimon	and	local4, local3, local4
189160814Ssimon	or	local5, 255, local5
190160814Ssimon
191160814Ssimon	sll	local4, 2, local2
192160814Ssimon	xor	$1, local4, $1
193160814Ssimon
194160814Ssimon	srl	$1, 8, local4
195160814Ssimon	xor	$2, local2, $2
196160814Ssimon
197160814Ssimon	xor	local4, $2, local4
198160814Ssimon	add	global1, 768, global4
199160814Ssimon
200160814Ssimon	and	local4, local5, local4
201160814Ssimon	add	global1, 1024, global5
202160814Ssimon
203160814Ssimon	ld	[out2+272], local7
204160814Ssimon	sll	local4, 8, local1
205160814Ssimon	xor	$2, local4, $2
206160814Ssimon
207160814Ssimon	srl	$2, 1, local4
208160814Ssimon	xor	$1, local1, $1
209160814Ssimon
210160814Ssimon	ld	[$5], out0                ! key 7531
211160814Ssimon	xor	local4, $1, local4
212160814Ssimon	add	global1, 256, global2
213160814Ssimon
214160814Ssimon	ld	[$5+4], out1              ! key 8642
215160814Ssimon	and	local4, local7, local4
216160814Ssimon	add	global1, 512, global3
217160814Ssimon
218160814Ssimon	sll	local4, 1, local1
219160814Ssimon	xor	$1, local4, $1
220160814Ssimon
221160814Ssimon	sll	$1, 3, local3
222160814Ssimon	xor	$2, local1, $2
223160814Ssimon
224160814Ssimon	sll	$2, 3, local2
225160814Ssimon	add	global1, 1280, local6     ! address sbox 8
226160814Ssimon
227160814Ssimon	srl	$1, 29, local4
228160814Ssimon	add	global1, 1792, out3       ! address sbox 8
229160814Ssimon
230160814Ssimon	srl	$2, 29, local1
231160814Ssimon	or	local4, local3, $4
232160814Ssimon
233160814Ssimon	or	local2, local1, $3
234160814Ssimon
235160814Ssimon	ifelse($6, 1, {
236160814Ssimon
237160814Ssimon		ld	[out2+284], local5     ! 0x0000FC00 used in the rounds
238160814Ssimon		or	local2, local1, $3
239160814Ssimon		xor	$4, out0, local1
240160814Ssimon
241160814Ssimon		call .des_enc.1
242160814Ssimon		and	local1, 252, local1
243160814Ssimon
244160814Ssimon	},{})
245160814Ssimon
246160814Ssimon	ifelse($6, 2, {
247160814Ssimon
248160814Ssimon		ld	[out2+284], local5     ! 0x0000FC00 used in the rounds
249160814Ssimon		or	local2, local1, $3
250160814Ssimon		xor	$4, out0, local1
251160814Ssimon
252160814Ssimon		call .des_dec.1
253160814Ssimon		and	local1, 252, local1
254160814Ssimon
255160814Ssimon	},{})
256160814Ssimon})
257160814Ssimon
258160814Ssimon
259160814Ssimon! {rounds_macro}
260160814Ssimon!
261160814Ssimon! The logic used in the DES rounds is the same as in the C code,
262160814Ssimon! except that calculations for sbox 1 and sbox 5 begin before
263160814Ssimon! the previous round is finished.
264160814Ssimon!
265160814Ssimon! In each round one half (work) is modified based on key and the
266160814Ssimon! other half (use).
267160814Ssimon!
268160814Ssimon! In this version we do two rounds in a loop repeated 7 times
269160814Ssimon! and two rounds seperately.
270160814Ssimon!
271160814Ssimon! One half has the bits for the sboxes in the following positions:
272160814Ssimon!
273160814Ssimon!	777777xx555555xx333333xx111111xx
274160814Ssimon!
275160814Ssimon!	88xx666666xx444444xx222222xx8888
276160814Ssimon!
277160814Ssimon! The bits for each sbox are xor-ed with the key bits for that box.
278160814Ssimon! The above xx bits are cleared, and the result used for lookup in
279160814Ssimon! the sbox table. Each sbox entry contains the 4 output bits permuted
280160814Ssimon! into 32 bits according to the P permutation.
281160814Ssimon!
282160814Ssimon! In the description of DES, left and right are switched after
283160814Ssimon! each round, except after last round. In this code the original
284160814Ssimon! left and right are kept in the same register in all rounds, meaning
285160814Ssimon! that after the 16 rounds the result for right is in the register
286160814Ssimon! originally used for left.
287160814Ssimon!
288160814Ssimon! parameter 1  first work (left in first round)
289160814Ssimon! parameter 2  first use (right in first round)
290160814Ssimon! parameter 3  enc/dec  1/-1
291160814Ssimon! parameter 4  loop label
292160814Ssimon! parameter 5  key address register
293160814Ssimon! parameter 6  optional address for key next encryption/decryption
294160814Ssimon! parameter 7  not empty for include retl
295160814Ssimon!
296160814Ssimon! also compares in2 to 8
297160814Ssimon
298160814Ssimondefine(rounds_macro, {
299160814Ssimon
300160814Ssimon! {rounds_macro}
301160814Ssimon! $1 $2 $3 $4 $5 $6 $7 $8 $9
302160814Ssimon
303160814Ssimon	xor	$2, out0, local1
304160814Ssimon
305160814Ssimon	ld	[out2+284], local5        ! 0x0000FC00
306160814Ssimon	ba	$4
307160814Ssimon	and	local1, 252, local1
308160814Ssimon
309160814Ssimon	.align 32
310160814Ssimon
311160814Ssimon$4:
312160814Ssimon	! local6 is address sbox 6
313160814Ssimon	! out3   is address sbox 8
314160814Ssimon	! out4   is loop counter
315160814Ssimon
316160814Ssimon	ld	[global1+local1], local1
317160814Ssimon	xor	$2, out1, out1            ! 8642
318160814Ssimon	xor	$2, out0, out0            ! 7531
319194206Ssimon	! fmovs	%f0, %f0                  ! fxor used for alignment
320160814Ssimon
321160814Ssimon	srl	out1, 4, local0           ! rotate 4 right
322160814Ssimon	and	out0, local5, local3      ! 3
323194206Ssimon	! fmovs	%f0, %f0
324160814Ssimon
325160814Ssimon	ld	[$5+$3*8], local7         ! key 7531 next round
326160814Ssimon	srl	local3, 8, local3         ! 3
327160814Ssimon	and	local0, 252, local2       ! 2
328194206Ssimon	! fmovs	%f0, %f0
329160814Ssimon
330160814Ssimon	ld	[global3+local3],local3   ! 3
331160814Ssimon	sll	out1, 28, out1            ! rotate
332160814Ssimon	xor	$1, local1, $1            ! 1 finished, local1 now sbox 7
333160814Ssimon
334160814Ssimon	ld	[global2+local2], local2  ! 2 
335160814Ssimon	srl	out0, 24, local1          ! 7
336160814Ssimon	or	out1, local0, out1        ! rotate
337160814Ssimon
338160814Ssimon	ldub	[out2+local1], local1     ! 7 (and 0xFC)
339160814Ssimon	srl	out1, 24, local0          ! 8
340160814Ssimon	and	out1, local5, local4      ! 4
341160814Ssimon
342160814Ssimon	ldub	[out2+local0], local0     ! 8 (and 0xFC)
343160814Ssimon	srl	local4, 8, local4         ! 4
344160814Ssimon	xor	$1, local2, $1            ! 2 finished local2 now sbox 6
345160814Ssimon
346160814Ssimon	ld	[global4+local4],local4   ! 4
347160814Ssimon	srl	out1, 16, local2          ! 6
348160814Ssimon	xor	$1, local3, $1            ! 3 finished local3 now sbox 5
349160814Ssimon
350160814Ssimon	ld	[out3+local0],local0      ! 8
351160814Ssimon	and	local2, 252, local2       ! 6
352160814Ssimon	add	global1, 1536, local5     ! address sbox 7
353160814Ssimon
354160814Ssimon	ld	[local6+local2], local2   ! 6
355160814Ssimon	srl	out0, 16, local3          ! 5
356160814Ssimon	xor	$1, local4, $1            ! 4 finished
357160814Ssimon
358160814Ssimon	ld	[local5+local1],local1    ! 7
359160814Ssimon	and	local3, 252, local3       ! 5
360160814Ssimon	xor	$1, local0, $1            ! 8 finished
361160814Ssimon
362160814Ssimon	ld	[global5+local3],local3   ! 5
363160814Ssimon	xor	$1, local2, $1            ! 6 finished
364160814Ssimon	subcc	out4, 1, out4
365160814Ssimon
366160814Ssimon	ld	[$5+$3*8+4], out0         ! key 8642 next round
367160814Ssimon	xor	$1, local7, local2        ! sbox 5 next round
368160814Ssimon	xor	$1, local1, $1            ! 7 finished
369160814Ssimon
370160814Ssimon	srl	local2, 16, local2        ! sbox 5 next round
371160814Ssimon	xor	$1, local3, $1            ! 5 finished
372160814Ssimon
373160814Ssimon	ld	[$5+$3*16+4], out1        ! key 8642 next round again
374160814Ssimon	and	local2, 252, local2       ! sbox5 next round
375160814Ssimon! next round
376160814Ssimon	xor	$1, local7, local7        ! 7531
377160814Ssimon
378160814Ssimon	ld	[global5+local2], local2  ! 5
379160814Ssimon	srl	local7, 24, local3        ! 7
380160814Ssimon	xor	$1, out0, out0            ! 8642
381160814Ssimon
382160814Ssimon	ldub	[out2+local3], local3     ! 7 (and 0xFC)
383160814Ssimon	srl	out0, 4, local0           ! rotate 4 right
384160814Ssimon	and	local7, 252, local1       ! 1
385160814Ssimon
386160814Ssimon	sll	out0, 28, out0            ! rotate
387160814Ssimon	xor	$2, local2, $2            ! 5 finished local2 used
388160814Ssimon
389160814Ssimon	srl	local0, 8, local4         ! 4
390160814Ssimon	and	local0, 252, local2       ! 2
391160814Ssimon	ld	[local5+local3], local3   ! 7
392160814Ssimon
393160814Ssimon	srl	local0, 16, local5        ! 6
394160814Ssimon	or	out0, local0, out0        ! rotate
395160814Ssimon	ld	[global2+local2], local2  ! 2
396160814Ssimon
397160814Ssimon	srl	out0, 24, local0
398160814Ssimon	ld	[$5+$3*16], out0          ! key 7531 next round
399160814Ssimon	and	local4, 252, local4	  ! 4
400160814Ssimon
401160814Ssimon	and	local5, 252, local5       ! 6
402160814Ssimon	ld	[global4+local4], local4  ! 4
403160814Ssimon	xor	$2, local3, $2            ! 7 finished local3 used
404160814Ssimon
405160814Ssimon	and	local0, 252, local0       ! 8
406160814Ssimon	ld	[local6+local5], local5   ! 6
407160814Ssimon	xor	$2, local2, $2            ! 2 finished local2 now sbox 3
408160814Ssimon
409160814Ssimon	srl	local7, 8, local2         ! 3 start
410160814Ssimon	ld	[out3+local0], local0     ! 8
411160814Ssimon	xor	$2, local4, $2            ! 4 finished
412160814Ssimon
413160814Ssimon	and	local2, 252, local2       ! 3
414160814Ssimon	ld	[global1+local1], local1  ! 1
415160814Ssimon	xor	$2, local5, $2            ! 6 finished local5 used
416160814Ssimon
417160814Ssimon	ld	[global3+local2], local2  ! 3
418160814Ssimon	xor	$2, local0, $2            ! 8 finished
419160814Ssimon	add	$5, $3*16, $5             ! enc add 8, dec add -8 to key pointer
420160814Ssimon
421160814Ssimon	ld	[out2+284], local5        ! 0x0000FC00
422160814Ssimon	xor	$2, out0, local4          ! sbox 1 next round
423160814Ssimon	xor	$2, local1, $2            ! 1 finished
424160814Ssimon
425160814Ssimon	xor	$2, local2, $2            ! 3 finished
426160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
427160814Ssimon	bne,pt	%icc, $4
428160814Ssimon#else
429160814Ssimon	bne	$4
430160814Ssimon#endif
431160814Ssimon	and	local4, 252, local1       ! sbox 1 next round
432160814Ssimon
433160814Ssimon! two rounds more:
434160814Ssimon
435160814Ssimon	ld	[global1+local1], local1
436160814Ssimon	xor	$2, out1, out1
437160814Ssimon	xor	$2, out0, out0
438160814Ssimon
439160814Ssimon	srl	out1, 4, local0           ! rotate
440160814Ssimon	and	out0, local5, local3
441160814Ssimon
442160814Ssimon	ld	[$5+$3*8], local7         ! key 7531
443160814Ssimon	srl	local3, 8, local3
444160814Ssimon	and	local0, 252, local2
445160814Ssimon
446160814Ssimon	ld	[global3+local3],local3
447160814Ssimon	sll	out1, 28, out1            ! rotate
448160814Ssimon	xor	$1, local1, $1            ! 1 finished, local1 now sbox 7
449160814Ssimon
450160814Ssimon	ld	[global2+local2], local2
451160814Ssimon	srl	out0, 24, local1
452160814Ssimon	or	out1, local0, out1        ! rotate
453160814Ssimon
454160814Ssimon	ldub	[out2+local1], local1
455160814Ssimon	srl	out1, 24, local0
456160814Ssimon	and	out1, local5, local4
457160814Ssimon
458160814Ssimon	ldub	[out2+local0], local0
459160814Ssimon	srl	local4, 8, local4
460160814Ssimon	xor	$1, local2, $1            ! 2 finished local2 now sbox 6
461160814Ssimon
462160814Ssimon	ld	[global4+local4],local4
463160814Ssimon	srl	out1, 16, local2
464160814Ssimon	xor	$1, local3, $1            ! 3 finished local3 now sbox 5
465160814Ssimon
466160814Ssimon	ld	[out3+local0],local0
467160814Ssimon	and	local2, 252, local2
468160814Ssimon	add	global1, 1536, local5     ! address sbox 7
469160814Ssimon
470160814Ssimon	ld	[local6+local2], local2
471160814Ssimon	srl	out0, 16, local3
472160814Ssimon	xor	$1, local4, $1            ! 4 finished
473160814Ssimon
474160814Ssimon	ld	[local5+local1],local1
475160814Ssimon	and	local3, 252, local3
476160814Ssimon	xor	$1, local0, $1
477160814Ssimon
478160814Ssimon	ld	[global5+local3],local3
479160814Ssimon	xor	$1, local2, $1            ! 6 finished
480160814Ssimon	cmp	in2, 8
481160814Ssimon
482160814Ssimon	ifelse($6,{}, {}, {ld	[out2+280], out4})  ! loop counter
483160814Ssimon	xor	$1, local7, local2        ! sbox 5 next round
484160814Ssimon	xor	$1, local1, $1            ! 7 finished
485160814Ssimon
486160814Ssimon	ld	[$5+$3*8+4], out0
487160814Ssimon	srl	local2, 16, local2        ! sbox 5 next round
488160814Ssimon	xor	$1, local3, $1            ! 5 finished
489160814Ssimon
490160814Ssimon	and	local2, 252, local2
491160814Ssimon! next round (two rounds more)
492160814Ssimon	xor	$1, local7, local7        ! 7531
493160814Ssimon
494160814Ssimon	ld	[global5+local2], local2
495160814Ssimon	srl	local7, 24, local3
496160814Ssimon	xor	$1, out0, out0            ! 8642
497160814Ssimon
498160814Ssimon	ldub	[out2+local3], local3
499160814Ssimon	srl	out0, 4, local0           ! rotate
500160814Ssimon	and	local7, 252, local1
501160814Ssimon
502160814Ssimon	sll	out0, 28, out0            ! rotate
503160814Ssimon	xor	$2, local2, $2            ! 5 finished local2 used
504160814Ssimon
505160814Ssimon	srl	local0, 8, local4
506160814Ssimon	and	local0, 252, local2
507160814Ssimon	ld	[local5+local3], local3
508160814Ssimon
509160814Ssimon	srl	local0, 16, local5
510160814Ssimon	or	out0, local0, out0        ! rotate
511160814Ssimon	ld	[global2+local2], local2
512160814Ssimon
513160814Ssimon	srl	out0, 24, local0
514160814Ssimon	ifelse($6,{}, {}, {ld	[$6], out0})   ! key next encryption/decryption
515160814Ssimon	and	local4, 252, local4
516160814Ssimon
517160814Ssimon	and	local5, 252, local5
518160814Ssimon	ld	[global4+local4], local4
519160814Ssimon	xor	$2, local3, $2            ! 7 finished local3 used
520160814Ssimon
521160814Ssimon	and	local0, 252, local0
522160814Ssimon	ld	[local6+local5], local5
523160814Ssimon	xor	$2, local2, $2            ! 2 finished local2 now sbox 3
524160814Ssimon
525160814Ssimon	srl	local7, 8, local2         ! 3 start
526160814Ssimon	ld	[out3+local0], local0
527160814Ssimon	xor	$2, local4, $2
528160814Ssimon
529160814Ssimon	and	local2, 252, local2
530160814Ssimon	ld	[global1+local1], local1
531160814Ssimon	xor	$2, local5, $2            ! 6 finished local5 used
532160814Ssimon
533160814Ssimon	ld	[global3+local2], local2
534160814Ssimon	srl	$1, 3, local3
535160814Ssimon	xor	$2, local0, $2
536160814Ssimon
537160814Ssimon	ifelse($6,{}, {}, {ld	[$6+4], out1}) ! key next encryption/decryption
538160814Ssimon	sll	$1, 29, local4
539160814Ssimon	xor	$2, local1, $2
540160814Ssimon
541160814Ssimon	ifelse($7,{}, {}, {retl})
542160814Ssimon	xor	$2, local2, $2
543160814Ssimon})
544160814Ssimon
545160814Ssimon
546160814Ssimon! {fp_macro}
547160814Ssimon!
548160814Ssimon!  parameter 1   right (original left)
549160814Ssimon!  parameter 2   left (original right)
550160814Ssimon!  parameter 3   1 for optional store to [in0]
551160814Ssimon!  parameter 4   1 for load input/output address to local5/7
552160814Ssimon!
553160814Ssimon!  The final permutation logic switches the halfes, meaning that
554160814Ssimon!  left and right ends up the the registers originally used.
555160814Ssimon
556160814Ssimondefine(fp_macro, {
557160814Ssimon
558160814Ssimon! {fp_macro}
559160814Ssimon! $1 $2 $3 $4 $5 $6 $7 $8 $9
560160814Ssimon
561160814Ssimon	! initially undo the rotate 3 left done after initial permutation
562160814Ssimon	! original left is received shifted 3 right and 29 left in local3/4
563160814Ssimon
564160814Ssimon	sll	$2, 29, local1
565160814Ssimon	or	local3, local4, $1
566160814Ssimon
567160814Ssimon	srl	$2, 3, $2
568160814Ssimon	sethi	%hi(0x55555555), local2
569160814Ssimon
570160814Ssimon	or	$2, local1, $2
571160814Ssimon	or	local2, %lo(0x55555555), local2
572160814Ssimon
573160814Ssimon	srl	$2, 1, local3
574160814Ssimon	sethi	%hi(0x00ff00ff), local1
575160814Ssimon	xor	local3, $1, local3
576160814Ssimon	or	local1, %lo(0x00ff00ff), local1
577160814Ssimon	and	local3, local2, local3
578160814Ssimon	sethi	%hi(0x33333333), local4
579160814Ssimon	sll	local3, 1, local2
580160814Ssimon
581160814Ssimon	xor	$1, local3, $1
582160814Ssimon
583160814Ssimon	srl	$1, 8, local3
584160814Ssimon	xor	$2, local2, $2
585160814Ssimon	xor	local3, $2, local3
586160814Ssimon	or	local4, %lo(0x33333333), local4
587160814Ssimon	and	local3, local1, local3
588160814Ssimon	sethi	%hi(0x0000ffff), local1
589160814Ssimon	sll	local3, 8, local2
590160814Ssimon
591160814Ssimon	xor	$2, local3, $2
592160814Ssimon
593160814Ssimon	srl	$2, 2, local3
594160814Ssimon	xor	$1, local2, $1
595160814Ssimon	xor	local3, $1, local3
596160814Ssimon	or	local1, %lo(0x0000ffff), local1
597160814Ssimon	and	local3, local4, local3
598160814Ssimon	sethi	%hi(0x0f0f0f0f), local4
599160814Ssimon	sll	local3, 2, local2
600160814Ssimon
601160814Ssimon	ifelse($4,1, {LDPTR INPUT, local5})
602160814Ssimon	xor	$1, local3, $1
603160814Ssimon
604160814Ssimon	ifelse($4,1, {LDPTR OUTPUT, local7})
605160814Ssimon	srl	$1, 16, local3
606160814Ssimon	xor	$2, local2, $2
607160814Ssimon	xor	local3, $2, local3
608160814Ssimon	or	local4, %lo(0x0f0f0f0f), local4
609160814Ssimon	and	local3, local1, local3
610160814Ssimon	sll	local3, 16, local2
611160814Ssimon
612160814Ssimon	xor	$2, local3, local1
613160814Ssimon
614160814Ssimon	srl	local1, 4, local3
615160814Ssimon	xor	$1, local2, $1
616160814Ssimon	xor	local3, $1, local3
617160814Ssimon	and	local3, local4, local3
618160814Ssimon	sll	local3, 4, local2
619160814Ssimon
620160814Ssimon	xor	$1, local3, $1
621160814Ssimon
622160814Ssimon	! optional store:
623160814Ssimon
624160814Ssimon	ifelse($3,1, {st $1, [in0]})
625160814Ssimon
626160814Ssimon	xor	local1, local2, $2
627160814Ssimon
628160814Ssimon	ifelse($3,1, {st $2, [in0+4]})
629160814Ssimon
630160814Ssimon})
631160814Ssimon
632160814Ssimon
633160814Ssimon! {fp_ip_macro}
634160814Ssimon!
635160814Ssimon! Does initial permutation for next block mixed with
636160814Ssimon! final permutation for current block.
637160814Ssimon!
638160814Ssimon! parameter 1   original left
639160814Ssimon! parameter 2   original right
640160814Ssimon! parameter 3   left ip
641160814Ssimon! parameter 4   right ip
642160814Ssimon! parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
643160814Ssimon!                2: mov in4 to in3
644160814Ssimon!
645160814Ssimon! also adds -8 to length in2 and loads loop counter to out4
646160814Ssimon
647160814Ssimondefine(fp_ip_macro, {
648160814Ssimon
649160814Ssimon! {fp_ip_macro}
650160814Ssimon! $1 $2 $3 $4 $5 $6 $7 $8 $9
651160814Ssimon
652160814Ssimon	define({temp1},{out4})
653160814Ssimon	define({temp2},{local3})
654160814Ssimon
655160814Ssimon	define({ip1},{local1})
656160814Ssimon	define({ip2},{local2})
657160814Ssimon	define({ip4},{local4})
658160814Ssimon	define({ip5},{local5})
659160814Ssimon
660160814Ssimon	! $1 in local3, local4
661160814Ssimon
662160814Ssimon	ld	[out2+256], ip1
663160814Ssimon	sll	out5, 29, temp1
664160814Ssimon	or	local3, local4, $1
665160814Ssimon
666160814Ssimon	srl	out5, 3, $2
667160814Ssimon	ifelse($5,2,{mov in4, in3})
668160814Ssimon
669160814Ssimon	ld	[out2+272], ip5
670160814Ssimon	srl	$4, 4, local0
671160814Ssimon	or	$2, temp1, $2
672160814Ssimon
673160814Ssimon	srl	$2, 1, temp1
674160814Ssimon	xor	temp1, $1, temp1
675160814Ssimon
676160814Ssimon	and	temp1, ip5, temp1
677160814Ssimon	xor	local0, $3, local0
678160814Ssimon
679160814Ssimon	sll	temp1, 1, temp2
680160814Ssimon	xor	$1, temp1, $1
681160814Ssimon
682160814Ssimon	and	local0, ip1, local0
683160814Ssimon	add	in2, -8, in2
684160814Ssimon
685160814Ssimon	sll	local0, 4, local7
686160814Ssimon	xor	$3, local0, $3
687160814Ssimon
688160814Ssimon	ld	[out2+268], ip4
689160814Ssimon	srl	$1, 8, temp1
690160814Ssimon	xor	$2, temp2, $2
691160814Ssimon	ld	[out2+260], ip2
692160814Ssimon	srl	$3, 16, local0
693160814Ssimon	xor	$4, local7, $4
694160814Ssimon	xor	temp1, $2, temp1
695160814Ssimon	xor	local0, $4, local0
696160814Ssimon	and	temp1, ip4, temp1
697160814Ssimon	and	local0, ip2, local0
698160814Ssimon	sll	temp1, 8, temp2
699160814Ssimon	xor	$2, temp1, $2
700160814Ssimon	sll	local0, 16, local7
701160814Ssimon	xor	$4, local0, $4
702160814Ssimon
703160814Ssimon	srl	$2, 2, temp1
704160814Ssimon	xor	$1, temp2, $1
705160814Ssimon
706160814Ssimon	ld	[out2+264], temp2         ! ip3
707160814Ssimon	srl	$4, 2, local0
708160814Ssimon	xor	$3, local7, $3
709160814Ssimon	xor	temp1, $1, temp1
710160814Ssimon	xor	local0, $3, local0
711160814Ssimon	and	temp1, temp2, temp1
712160814Ssimon	and	local0, temp2, local0
713160814Ssimon	sll	temp1, 2, temp2
714160814Ssimon	xor	$1, temp1, $1
715160814Ssimon	sll	local0, 2, local7
716160814Ssimon	xor	$3, local0, $3
717160814Ssimon
718160814Ssimon	srl	$1, 16, temp1
719160814Ssimon	xor	$2, temp2, $2
720160814Ssimon	srl	$3, 8, local0
721160814Ssimon	xor	$4, local7, $4
722160814Ssimon	xor	temp1, $2, temp1
723160814Ssimon	xor	local0, $4, local0
724160814Ssimon	and	temp1, ip2, temp1
725160814Ssimon	and	local0, ip4, local0
726160814Ssimon	sll	temp1, 16, temp2
727160814Ssimon	xor	$2, temp1, local4
728160814Ssimon	sll	local0, 8, local7
729160814Ssimon	xor	$4, local0, $4
730160814Ssimon
731160814Ssimon	srl	$4, 1, local0
732160814Ssimon	xor	$3, local7, $3
733160814Ssimon
734160814Ssimon	srl	local4, 4, temp1
735160814Ssimon	xor	local0, $3, local0
736160814Ssimon
737160814Ssimon	xor	$1, temp2, $1
738160814Ssimon	and	local0, ip5, local0
739160814Ssimon
740160814Ssimon	sll	local0, 1, local7
741160814Ssimon	xor	temp1, $1, temp1
742160814Ssimon
743160814Ssimon	xor	$3, local0, $3
744160814Ssimon	xor	$4, local7, $4
745160814Ssimon
746160814Ssimon	sll	$3, 3, local5
747160814Ssimon	and	temp1, ip1, temp1
748160814Ssimon
749160814Ssimon	sll	temp1, 4, temp2
750160814Ssimon	xor	$1, temp1, $1
751160814Ssimon
752160814Ssimon	ifelse($5,1,{LDPTR	KS2, in4})
753160814Ssimon	sll	$4, 3, local2
754160814Ssimon	xor	local4, temp2, $2
755160814Ssimon
756160814Ssimon	! reload since used as temporar:
757160814Ssimon
758160814Ssimon	ld	[out2+280], out4          ! loop counter
759160814Ssimon
760160814Ssimon	srl	$3, 29, local0
761160814Ssimon	ifelse($5,1,{add in4, 120, in4})
762160814Ssimon
763160814Ssimon	ifelse($5,1,{LDPTR	KS1, in3})
764160814Ssimon	srl	$4, 29, local7
765160814Ssimon
766160814Ssimon	or	local0, local5, $4
767160814Ssimon	or	local2, local7, $3
768160814Ssimon
769160814Ssimon})
770160814Ssimon
771160814Ssimon
772160814Ssimon
773160814Ssimon! {load_little_endian}
774160814Ssimon!
775160814Ssimon! parameter 1  address
776160814Ssimon! parameter 2  destination left
777160814Ssimon! parameter 3  destination right
778160814Ssimon! parameter 4  temporar
779160814Ssimon! parameter 5  label
780160814Ssimon
781160814Ssimondefine(load_little_endian, {
782160814Ssimon
783160814Ssimon! {load_little_endian}
784160814Ssimon! $1 $2 $3 $4 $5 $6 $7 $8 $9
785160814Ssimon
786160814Ssimon	! first in memory to rightmost in register
787160814Ssimon
788160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
789160814Ssimon	andcc	$1, 3, global0
790160814Ssimon	bne,pn	%icc, $5
791160814Ssimon	nop
792160814Ssimon
793160814Ssimon	lda	[$1] 0x88, $2
794160814Ssimon	add	$1, 4, $4
795160814Ssimon
796160814Ssimon	ba,pt	%icc, $5a
797160814Ssimon	lda	[$4] 0x88, $3
798160814Ssimon#endif
799160814Ssimon
800160814Ssimon$5:
801160814Ssimon	ldub	[$1+3], $2
802160814Ssimon
803160814Ssimon	ldub	[$1+2], $4
804160814Ssimon	sll	$2, 8, $2
805160814Ssimon	or	$2, $4, $2
806160814Ssimon
807160814Ssimon	ldub	[$1+1], $4
808160814Ssimon	sll	$2, 8, $2
809160814Ssimon	or	$2, $4, $2
810160814Ssimon
811160814Ssimon	ldub	[$1+0], $4
812160814Ssimon	sll	$2, 8, $2
813160814Ssimon	or	$2, $4, $2
814160814Ssimon
815160814Ssimon
816160814Ssimon	ldub	[$1+3+4], $3
817160814Ssimon
818160814Ssimon	ldub	[$1+2+4], $4
819160814Ssimon	sll	$3, 8, $3
820160814Ssimon	or	$3, $4, $3
821160814Ssimon
822160814Ssimon	ldub	[$1+1+4], $4
823160814Ssimon	sll	$3, 8, $3
824160814Ssimon	or	$3, $4, $3
825160814Ssimon
826160814Ssimon	ldub	[$1+0+4], $4
827160814Ssimon	sll	$3, 8, $3
828160814Ssimon	or	$3, $4, $3
829160814Ssimon$5a:
830160814Ssimon
831160814Ssimon})
832160814Ssimon
833160814Ssimon
834160814Ssimon! {load_little_endian_inc}
835160814Ssimon!
836160814Ssimon! parameter 1  address
837160814Ssimon! parameter 2  destination left
838160814Ssimon! parameter 3  destination right
839160814Ssimon! parameter 4  temporar
840160814Ssimon! parameter 4  label
841160814Ssimon!
842160814Ssimon! adds 8 to address
843160814Ssimon
844160814Ssimondefine(load_little_endian_inc, {
845160814Ssimon
846160814Ssimon! {load_little_endian_inc}
847160814Ssimon! $1 $2 $3 $4 $5 $6 $7 $8 $9
848160814Ssimon
849160814Ssimon	! first in memory to rightmost in register
850160814Ssimon
851160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
852160814Ssimon	andcc	$1, 3, global0
853160814Ssimon	bne,pn	%icc, $5
854160814Ssimon	nop
855160814Ssimon
856160814Ssimon	lda	[$1] 0x88, $2
857160814Ssimon	add	$1, 4, $1
858160814Ssimon
859160814Ssimon	lda	[$1] 0x88, $3
860160814Ssimon	ba,pt	%icc, $5a
861160814Ssimon	add	$1, 4, $1
862160814Ssimon#endif
863160814Ssimon
864160814Ssimon$5:
865160814Ssimon	ldub	[$1+3], $2
866160814Ssimon
867160814Ssimon	ldub	[$1+2], $4
868160814Ssimon	sll	$2, 8, $2
869160814Ssimon	or	$2, $4, $2
870160814Ssimon
871160814Ssimon	ldub	[$1+1], $4
872160814Ssimon	sll	$2, 8, $2
873160814Ssimon	or	$2, $4, $2
874160814Ssimon
875160814Ssimon	ldub	[$1+0], $4
876160814Ssimon	sll	$2, 8, $2
877160814Ssimon	or	$2, $4, $2
878160814Ssimon
879160814Ssimon	ldub	[$1+3+4], $3
880160814Ssimon	add	$1, 8, $1
881160814Ssimon
882160814Ssimon	ldub	[$1+2+4-8], $4
883160814Ssimon	sll	$3, 8, $3
884160814Ssimon	or	$3, $4, $3
885160814Ssimon
886160814Ssimon	ldub	[$1+1+4-8], $4
887160814Ssimon	sll	$3, 8, $3
888160814Ssimon	or	$3, $4, $3
889160814Ssimon
890160814Ssimon	ldub	[$1+0+4-8], $4
891160814Ssimon	sll	$3, 8, $3
892160814Ssimon	or	$3, $4, $3
893160814Ssimon$5a:
894160814Ssimon
895160814Ssimon})
896160814Ssimon
897160814Ssimon
898160814Ssimon! {load_n_bytes}
899160814Ssimon!
900160814Ssimon! Loads 1 to 7 bytes little endian
901160814Ssimon! Remaining bytes are zeroed.
902160814Ssimon!
903160814Ssimon! parameter 1  address
904160814Ssimon! parameter 2  length
905160814Ssimon! parameter 3  destination register left
906160814Ssimon! parameter 4  destination register right
907160814Ssimon! parameter 5  temp
908160814Ssimon! parameter 6  temp2
909160814Ssimon! parameter 7  label
910160814Ssimon! parameter 8  return label
911160814Ssimon
912160814Ssimondefine(load_n_bytes, {
913160814Ssimon
914160814Ssimon! {load_n_bytes}
915160814Ssimon! $1 $2 $5 $6 $7 $8 $7 $8 $9
916160814Ssimon
917160814Ssimon$7.0:	call	.+8
918160814Ssimon	sll	$2, 2, $6
919160814Ssimon
920160814Ssimon	add	%o7,$7.jmp.table-$7.0,$5
921160814Ssimon
922160814Ssimon	add	$5, $6, $5
923160814Ssimon	mov	0, $4
924160814Ssimon
925160814Ssimon	ld	[$5], $5
926160814Ssimon
927160814Ssimon	jmp	%o7+$5
928160814Ssimon	mov	0, $3
929160814Ssimon
930160814Ssimon$7.7:
931160814Ssimon	ldub	[$1+6], $5
932160814Ssimon	sll	$5, 16, $5
933160814Ssimon	or	$3, $5, $3
934160814Ssimon$7.6:
935160814Ssimon	ldub	[$1+5], $5
936160814Ssimon	sll	$5, 8, $5
937160814Ssimon	or	$3, $5, $3
938160814Ssimon$7.5:
939160814Ssimon	ldub	[$1+4], $5
940160814Ssimon	or	$3, $5, $3
941160814Ssimon$7.4:
942160814Ssimon	ldub	[$1+3], $5
943160814Ssimon	sll	$5, 24, $5
944160814Ssimon	or	$4, $5, $4
945160814Ssimon$7.3:
946160814Ssimon	ldub	[$1+2], $5
947160814Ssimon	sll	$5, 16, $5
948160814Ssimon	or	$4, $5, $4
949160814Ssimon$7.2:
950160814Ssimon	ldub	[$1+1], $5
951160814Ssimon	sll	$5, 8, $5
952160814Ssimon	or	$4, $5, $4
953160814Ssimon$7.1:
954160814Ssimon	ldub	[$1+0], $5
955160814Ssimon	ba	$8
956160814Ssimon	or	$4, $5, $4
957160814Ssimon
958160814Ssimon	.align 4
959160814Ssimon
960160814Ssimon$7.jmp.table:
961160814Ssimon	.word	0
962160814Ssimon	.word	$7.1-$7.0
963160814Ssimon	.word	$7.2-$7.0
964160814Ssimon	.word	$7.3-$7.0
965160814Ssimon	.word	$7.4-$7.0
966160814Ssimon	.word	$7.5-$7.0
967160814Ssimon	.word	$7.6-$7.0
968160814Ssimon	.word	$7.7-$7.0
969160814Ssimon})
970160814Ssimon
971160814Ssimon
972160814Ssimon! {store_little_endian}
973160814Ssimon!
974160814Ssimon! parameter 1  address
975160814Ssimon! parameter 2  source left
976160814Ssimon! parameter 3  source right
977160814Ssimon! parameter 4  temporar
978160814Ssimon
979160814Ssimondefine(store_little_endian, {
980160814Ssimon
981160814Ssimon! {store_little_endian}
982160814Ssimon! $1 $2 $3 $4 $5 $6 $7 $8 $9
983160814Ssimon
984160814Ssimon	! rightmost in register to first in memory
985160814Ssimon
986160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
987160814Ssimon	andcc	$1, 3, global0
988160814Ssimon	bne,pn	%icc, $5
989160814Ssimon	nop
990160814Ssimon
991160814Ssimon	sta	$2, [$1] 0x88
992160814Ssimon	add	$1, 4, $4
993160814Ssimon
994160814Ssimon	ba,pt	%icc, $5a
995160814Ssimon	sta	$3, [$4] 0x88
996160814Ssimon#endif
997160814Ssimon
998160814Ssimon$5:
999160814Ssimon	and	$2, 255, $4
1000160814Ssimon	stub	$4, [$1+0]
1001160814Ssimon
1002160814Ssimon	srl	$2, 8, $4
1003160814Ssimon	and	$4, 255, $4
1004160814Ssimon	stub	$4, [$1+1]
1005160814Ssimon
1006160814Ssimon	srl	$2, 16, $4
1007160814Ssimon	and	$4, 255, $4
1008160814Ssimon	stub	$4, [$1+2]
1009160814Ssimon
1010160814Ssimon	srl	$2, 24, $4
1011160814Ssimon	stub	$4, [$1+3]
1012160814Ssimon
1013160814Ssimon
1014160814Ssimon	and	$3, 255, $4
1015160814Ssimon	stub	$4, [$1+0+4]
1016160814Ssimon
1017160814Ssimon	srl	$3, 8, $4
1018160814Ssimon	and	$4, 255, $4
1019160814Ssimon	stub	$4, [$1+1+4]
1020160814Ssimon
1021160814Ssimon	srl	$3, 16, $4
1022160814Ssimon	and	$4, 255, $4
1023160814Ssimon	stub	$4, [$1+2+4]
1024160814Ssimon
1025160814Ssimon	srl	$3, 24, $4
1026160814Ssimon	stub	$4, [$1+3+4]
1027160814Ssimon
1028160814Ssimon$5a:
1029160814Ssimon
1030160814Ssimon})
1031160814Ssimon
1032160814Ssimon
1033160814Ssimon! {store_n_bytes}
1034160814Ssimon!
1035160814Ssimon! Stores 1 to 7 bytes little endian
1036160814Ssimon!
1037160814Ssimon! parameter 1  address
1038160814Ssimon! parameter 2  length
1039160814Ssimon! parameter 3  source register left
1040160814Ssimon! parameter 4  source register right
1041160814Ssimon! parameter 5  temp
1042160814Ssimon! parameter 6  temp2
1043160814Ssimon! parameter 7  label
1044160814Ssimon! parameter 8  return label
1045160814Ssimon
1046160814Ssimondefine(store_n_bytes, {
1047160814Ssimon
1048160814Ssimon! {store_n_bytes}
1049160814Ssimon! $1 $2 $5 $6 $7 $8 $7 $8 $9
1050160814Ssimon
1051160814Ssimon$7.0:	call	.+8
1052160814Ssimon	sll	$2, 2, $6
1053160814Ssimon
1054160814Ssimon	add	%o7,$7.jmp.table-$7.0,$5
1055160814Ssimon
1056160814Ssimon	add	$5, $6, $5
1057160814Ssimon
1058160814Ssimon	ld	[$5], $5
1059160814Ssimon
1060160814Ssimon	jmp	%o7+$5
1061160814Ssimon	nop
1062160814Ssimon
1063160814Ssimon$7.7:
1064160814Ssimon	srl	$3, 16, $5
1065160814Ssimon	and	$5, 0xff, $5
1066160814Ssimon	stub	$5, [$1+6]
1067160814Ssimon$7.6:
1068160814Ssimon	srl	$3, 8, $5
1069160814Ssimon	and	$5, 0xff, $5
1070160814Ssimon	stub	$5, [$1+5]
1071160814Ssimon$7.5:
1072160814Ssimon	and	$3, 0xff, $5
1073160814Ssimon	stub	$5, [$1+4]
1074160814Ssimon$7.4:
1075160814Ssimon	srl	$4, 24, $5
1076160814Ssimon	stub	$5, [$1+3]
1077160814Ssimon$7.3:
1078160814Ssimon	srl	$4, 16, $5
1079160814Ssimon	and	$5, 0xff, $5
1080160814Ssimon	stub	$5, [$1+2]
1081160814Ssimon$7.2:
1082160814Ssimon	srl	$4, 8, $5
1083160814Ssimon	and	$5, 0xff, $5
1084160814Ssimon	stub	$5, [$1+1]
1085160814Ssimon$7.1:
1086160814Ssimon	and	$4, 0xff, $5
1087160814Ssimon
1088160814Ssimon
1089160814Ssimon	ba	$8
1090160814Ssimon	stub	$5, [$1]
1091160814Ssimon
1092160814Ssimon	.align 4
1093160814Ssimon
1094160814Ssimon$7.jmp.table:
1095160814Ssimon
1096160814Ssimon	.word	0
1097160814Ssimon	.word	$7.1-$7.0
1098160814Ssimon	.word	$7.2-$7.0
1099160814Ssimon	.word	$7.3-$7.0
1100160814Ssimon	.word	$7.4-$7.0
1101160814Ssimon	.word	$7.5-$7.0
1102160814Ssimon	.word	$7.6-$7.0
1103160814Ssimon	.word	$7.7-$7.0
1104160814Ssimon})
1105160814Ssimon
1106160814Ssimon
1107160814Ssimondefine(testvalue,{1})
1108160814Ssimon
1109160814Ssimondefine(register_init, {
1110160814Ssimon
1111160814Ssimon! For test purposes:
1112160814Ssimon
1113160814Ssimon	sethi	%hi(testvalue), local0
1114160814Ssimon	or	local0, %lo(testvalue), local0
1115160814Ssimon
1116160814Ssimon	ifelse($1,{},{}, {mov	local0, $1})
1117160814Ssimon	ifelse($2,{},{}, {mov	local0, $2})
1118160814Ssimon	ifelse($3,{},{}, {mov	local0, $3})
1119160814Ssimon	ifelse($4,{},{}, {mov	local0, $4})
1120160814Ssimon	ifelse($5,{},{}, {mov	local0, $5})
1121160814Ssimon	ifelse($6,{},{}, {mov	local0, $6})
1122160814Ssimon	ifelse($7,{},{}, {mov	local0, $7})
1123160814Ssimon	ifelse($8,{},{}, {mov	local0, $8})
1124160814Ssimon
1125160814Ssimon	mov	local0, local1
1126160814Ssimon	mov	local0, local2
1127160814Ssimon	mov	local0, local3
1128160814Ssimon	mov	local0, local4
1129160814Ssimon	mov	local0, local5
1130160814Ssimon	mov	local0, local7
1131160814Ssimon	mov	local0, local6
1132160814Ssimon	mov	local0, out0
1133160814Ssimon	mov	local0, out1
1134160814Ssimon	mov	local0, out2
1135160814Ssimon	mov	local0, out3
1136160814Ssimon	mov	local0, out4
1137160814Ssimon	mov	local0, out5
1138160814Ssimon	mov	local0, global1
1139160814Ssimon	mov	local0, global2
1140160814Ssimon	mov	local0, global3
1141160814Ssimon	mov	local0, global4
1142160814Ssimon	mov	local0, global5
1143160814Ssimon
1144160814Ssimon})
1145160814Ssimon
1146160814Ssimon.section	".text"
1147160814Ssimon
1148160814Ssimon	.align 32
1149160814Ssimon
1150160814Ssimon.des_enc:
1151160814Ssimon
1152160814Ssimon	! key address in3
1153160814Ssimon	! loads key next encryption/decryption first round from [in4]
1154160814Ssimon
1155160814Ssimon	rounds_macro(in5, out5, 1, .des_enc.1, in3, in4, retl)
1156160814Ssimon
1157160814Ssimon
1158160814Ssimon	.align 32
1159160814Ssimon
1160160814Ssimon.des_dec:
1161160814Ssimon
1162160814Ssimon	! implemented with out5 as first parameter to avoid
1163160814Ssimon	! register exchange in ede modes
1164160814Ssimon
1165160814Ssimon	! key address in4
1166160814Ssimon	! loads key next encryption/decryption first round from [in3]
1167160814Ssimon
1168160814Ssimon	rounds_macro(out5, in5, -1, .des_dec.1, in4, in3, retl)
1169160814Ssimon
1170160814Ssimon
1171160814Ssimon
1172160814Ssimon! void DES_encrypt1(data, ks, enc)
1173160814Ssimon! *******************************
1174160814Ssimon
1175160814Ssimon	.align 32
1176160814Ssimon	.global DES_encrypt1
1177160814Ssimon	.type	 DES_encrypt1,#function
1178160814Ssimon
1179160814SsimonDES_encrypt1:
1180160814Ssimon
1181160814Ssimon	save	%sp, FRAME, %sp
1182160814Ssimon
1183194206Ssimon	sethi	%hi(.PIC.DES_SPtrans-1f),global1
1184194206Ssimon	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
1185194206Ssimon1:	call	.+8
1186194206Ssimon	add	%o7,global1,global1
1187194206Ssimon	sub	global1,.PIC.DES_SPtrans-.des_and,out2
1188160814Ssimon
1189160814Ssimon	ld	[in0], in5                ! left
1190160814Ssimon	cmp	in2, 0                    ! enc
1191160814Ssimon
1192160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1193160814Ssimon	be,pn	%icc, .encrypt.dec        ! enc/dec
1194160814Ssimon#else
1195160814Ssimon	be	.encrypt.dec
1196160814Ssimon#endif
1197160814Ssimon	ld	[in0+4], out5             ! right
1198160814Ssimon
1199160814Ssimon	! parameter 6  1/2 for include encryption/decryption
1200160814Ssimon	! parameter 7  1 for move in1 to in3
1201160814Ssimon	! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
1202160814Ssimon
1203160814Ssimon	ip_macro(in5, out5, in5, out5, in3, 0, 1, 1)
1204160814Ssimon
1205160814Ssimon	rounds_macro(in5, out5, 1, .des_encrypt1.1, in3, in4) ! in4 not used
1206160814Ssimon
1207160814Ssimon	fp_macro(in5, out5, 1)            ! 1 for store to [in0]
1208160814Ssimon
1209160814Ssimon	ret
1210160814Ssimon	restore
1211160814Ssimon
1212160814Ssimon.encrypt.dec:
1213160814Ssimon
1214160814Ssimon	add	in1, 120, in3             ! use last subkey for first round
1215160814Ssimon
1216160814Ssimon	! parameter 6  1/2 for include encryption/decryption
1217160814Ssimon	! parameter 7  1 for move in1 to in3
1218160814Ssimon	! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
1219160814Ssimon
1220160814Ssimon	ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include dec,  ks in4
1221160814Ssimon
1222160814Ssimon	fp_macro(out5, in5, 1)            ! 1 for store to [in0]
1223160814Ssimon
1224160814Ssimon	ret
1225160814Ssimon	restore
1226160814Ssimon
1227160814Ssimon.DES_encrypt1.end:
1228160814Ssimon	.size	 DES_encrypt1,.DES_encrypt1.end-DES_encrypt1
1229160814Ssimon
1230160814Ssimon
1231160814Ssimon! void DES_encrypt2(data, ks, enc)
1232160814Ssimon!*********************************
1233160814Ssimon
1234160814Ssimon	! encrypts/decrypts without initial/final permutation
1235160814Ssimon
1236160814Ssimon	.align 32
1237160814Ssimon	.global DES_encrypt2
1238160814Ssimon	.type	 DES_encrypt2,#function
1239160814Ssimon
1240160814SsimonDES_encrypt2:
1241160814Ssimon
1242160814Ssimon	save	%sp, FRAME, %sp
1243160814Ssimon
1244194206Ssimon	sethi	%hi(.PIC.DES_SPtrans-1f),global1
1245194206Ssimon	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
1246194206Ssimon1:	call	.+8
1247194206Ssimon	add	%o7,global1,global1
1248194206Ssimon	sub	global1,.PIC.DES_SPtrans-.des_and,out2
1249160814Ssimon
1250160814Ssimon	! Set sbox address 1 to 6 and rotate halfs 3 left
1251160814Ssimon	! Errors caught by destest? Yes. Still? *NO*
1252160814Ssimon
1253160814Ssimon	!sethi	%hi(DES_SPtrans), global1 ! address sbox 1
1254160814Ssimon
1255160814Ssimon	!or	global1, %lo(DES_SPtrans), global1  ! sbox 1
1256160814Ssimon
1257160814Ssimon	add	global1, 256, global2     ! sbox 2
1258160814Ssimon	add	global1, 512, global3     ! sbox 3
1259160814Ssimon
1260160814Ssimon	ld	[in0], out5               ! right
1261160814Ssimon	add	global1, 768, global4     ! sbox 4
1262160814Ssimon	add	global1, 1024, global5    ! sbox 5
1263160814Ssimon
1264160814Ssimon	ld	[in0+4], in5              ! left
1265160814Ssimon	add	global1, 1280, local6     ! sbox 6
1266160814Ssimon	add	global1, 1792, out3       ! sbox 8
1267160814Ssimon
1268160814Ssimon	! rotate
1269160814Ssimon
1270160814Ssimon	sll	in5, 3, local5
1271160814Ssimon	mov	in1, in3                  ! key address to in3
1272160814Ssimon
1273160814Ssimon	sll	out5, 3, local7
1274160814Ssimon	srl	in5, 29, in5
1275160814Ssimon
1276160814Ssimon	srl	out5, 29, out5
1277160814Ssimon	add	in5, local5, in5
1278160814Ssimon
1279160814Ssimon	add	out5, local7, out5
1280160814Ssimon	cmp	in2, 0
1281160814Ssimon
1282160814Ssimon	! we use our own stackframe
1283160814Ssimon
1284160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1285160814Ssimon	be,pn	%icc, .encrypt2.dec       ! decryption
1286160814Ssimon#else
1287160814Ssimon	be	.encrypt2.dec
1288160814Ssimon#endif
1289160814Ssimon	STPTR	in0, [%sp+BIAS+ARG0+0*ARGSZ]
1290160814Ssimon
1291160814Ssimon	ld	[in3], out0               ! key 7531 first round
1292160814Ssimon	mov	LOOPS, out4               ! loop counter
1293160814Ssimon
1294160814Ssimon	ld	[in3+4], out1             ! key 8642 first round
1295160814Ssimon	sethi	%hi(0x0000FC00), local5
1296160814Ssimon
1297160814Ssimon	call .des_enc
1298160814Ssimon	mov	in3, in4
1299160814Ssimon
1300160814Ssimon	! rotate
1301160814Ssimon	sll	in5, 29, in0
1302160814Ssimon	srl	in5, 3, in5
1303160814Ssimon	sll	out5, 29, in1
1304160814Ssimon	add	in5, in0, in5
1305160814Ssimon	srl	out5, 3, out5
1306160814Ssimon	LDPTR	[%sp+BIAS+ARG0+0*ARGSZ], in0
1307160814Ssimon	add	out5, in1, out5
1308160814Ssimon	st	in5, [in0]
1309160814Ssimon	st	out5, [in0+4]
1310160814Ssimon
1311160814Ssimon	ret
1312160814Ssimon	restore
1313160814Ssimon
1314160814Ssimon
1315160814Ssimon.encrypt2.dec:
1316160814Ssimon
1317160814Ssimon	add in3, 120, in4
1318160814Ssimon
1319160814Ssimon	ld	[in4], out0               ! key 7531 first round
1320160814Ssimon	mov	LOOPS, out4               ! loop counter
1321160814Ssimon
1322160814Ssimon	ld	[in4+4], out1             ! key 8642 first round
1323160814Ssimon	sethi	%hi(0x0000FC00), local5
1324160814Ssimon
1325160814Ssimon	mov	in5, local1               ! left expected in out5
1326160814Ssimon	mov	out5, in5
1327160814Ssimon
1328160814Ssimon	call .des_dec
1329160814Ssimon	mov	local1, out5
1330160814Ssimon
1331160814Ssimon.encrypt2.finish:
1332160814Ssimon
1333160814Ssimon	! rotate
1334160814Ssimon	sll	in5, 29, in0
1335160814Ssimon	srl	in5, 3, in5
1336160814Ssimon	sll	out5, 29, in1
1337160814Ssimon	add	in5, in0, in5
1338160814Ssimon	srl	out5, 3, out5
1339160814Ssimon	LDPTR	[%sp+BIAS+ARG0+0*ARGSZ], in0
1340160814Ssimon	add	out5, in1, out5
1341160814Ssimon	st	out5, [in0]
1342160814Ssimon	st	in5, [in0+4]
1343160814Ssimon
1344160814Ssimon	ret
1345160814Ssimon	restore
1346160814Ssimon
1347160814Ssimon.DES_encrypt2.end:
1348160814Ssimon	.size	 DES_encrypt2, .DES_encrypt2.end-DES_encrypt2
1349160814Ssimon
1350160814Ssimon
1351160814Ssimon! void DES_encrypt3(data, ks1, ks2, ks3)
1352160814Ssimon! **************************************
1353160814Ssimon
1354160814Ssimon	.align 32
1355160814Ssimon	.global DES_encrypt3
1356160814Ssimon	.type	 DES_encrypt3,#function
1357160814Ssimon
1358160814SsimonDES_encrypt3:
1359160814Ssimon
1360160814Ssimon	save	%sp, FRAME, %sp
1361160814Ssimon	
1362194206Ssimon	sethi	%hi(.PIC.DES_SPtrans-1f),global1
1363194206Ssimon	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
1364194206Ssimon1:	call	.+8
1365194206Ssimon	add	%o7,global1,global1
1366194206Ssimon	sub	global1,.PIC.DES_SPtrans-.des_and,out2
1367160814Ssimon
1368160814Ssimon	ld	[in0], in5                ! left
1369160814Ssimon	add	in2, 120, in4             ! ks2
1370160814Ssimon
1371160814Ssimon	ld	[in0+4], out5             ! right
1372160814Ssimon	mov	in3, in2                  ! save ks3
1373160814Ssimon
1374160814Ssimon	! parameter 6  1/2 for include encryption/decryption
1375160814Ssimon	! parameter 7  1 for mov in1 to in3
1376160814Ssimon	! parameter 8  1 for mov in3 to in4
1377160814Ssimon	! parameter 9  1 for load ks3 and ks2 to in4 and in3
1378160814Ssimon
1379160814Ssimon	ip_macro(in5, out5, in5, out5, in3, 1, 1, 0, 0)
1380160814Ssimon
1381160814Ssimon	call	.des_dec
1382160814Ssimon	mov	in2, in3                  ! preload ks3
1383160814Ssimon
1384160814Ssimon	call	.des_enc
1385160814Ssimon	nop
1386160814Ssimon
1387160814Ssimon	fp_macro(in5, out5, 1)
1388160814Ssimon
1389160814Ssimon	ret
1390160814Ssimon	restore
1391160814Ssimon
1392160814Ssimon.DES_encrypt3.end:
1393160814Ssimon	.size	 DES_encrypt3,.DES_encrypt3.end-DES_encrypt3
1394160814Ssimon
1395160814Ssimon
1396160814Ssimon! void DES_decrypt3(data, ks1, ks2, ks3)
1397160814Ssimon! **************************************
1398160814Ssimon
1399160814Ssimon	.align 32
1400160814Ssimon	.global DES_decrypt3
1401160814Ssimon	.type	 DES_decrypt3,#function
1402160814Ssimon
1403160814SsimonDES_decrypt3:
1404160814Ssimon
1405160814Ssimon	save	%sp, FRAME, %sp
1406160814Ssimon	
1407194206Ssimon	sethi	%hi(.PIC.DES_SPtrans-1f),global1
1408194206Ssimon	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
1409194206Ssimon1:	call	.+8
1410194206Ssimon	add	%o7,global1,global1
1411194206Ssimon	sub	global1,.PIC.DES_SPtrans-.des_and,out2
1412160814Ssimon
1413160814Ssimon	ld	[in0], in5                ! left
1414160814Ssimon	add	in3, 120, in4             ! ks3
1415160814Ssimon
1416160814Ssimon	ld	[in0+4], out5             ! right
1417160814Ssimon	mov	in2, in3                  ! ks2
1418160814Ssimon
1419160814Ssimon	! parameter 6  1/2 for include encryption/decryption
1420160814Ssimon	! parameter 7  1 for mov in1 to in3
1421160814Ssimon	! parameter 8  1 for mov in3 to in4
1422160814Ssimon	! parameter 9  1 for load ks3 and ks2 to in4 and in3
1423160814Ssimon
1424160814Ssimon	ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 0)
1425160814Ssimon
1426160814Ssimon	call	.des_enc
1427160814Ssimon	add	in1, 120, in4             ! preload ks1
1428160814Ssimon
1429160814Ssimon	call	.des_dec
1430160814Ssimon	nop
1431160814Ssimon
1432160814Ssimon	fp_macro(out5, in5, 1)
1433160814Ssimon
1434160814Ssimon	ret
1435160814Ssimon	restore
1436160814Ssimon
1437160814Ssimon.DES_decrypt3.end:
1438160814Ssimon	.size	 DES_decrypt3,.DES_decrypt3.end-DES_decrypt3
1439160814Ssimon
1440160814Ssimon! void DES_ncbc_encrypt(input, output, length, schedule, ivec, enc)
1441160814Ssimon! *****************************************************************
1442160814Ssimon
1443160814Ssimon
1444160814Ssimon	.align 32
1445160814Ssimon	.global DES_ncbc_encrypt
1446160814Ssimon	.type	 DES_ncbc_encrypt,#function
1447160814Ssimon
1448160814SsimonDES_ncbc_encrypt:
1449160814Ssimon
1450160814Ssimon	save	%sp, FRAME, %sp
1451160814Ssimon	
1452160814Ssimon	define({INPUT},  { [%sp+BIAS+ARG0+0*ARGSZ] })
1453160814Ssimon	define({OUTPUT}, { [%sp+BIAS+ARG0+1*ARGSZ] })
1454160814Ssimon	define({IVEC},   { [%sp+BIAS+ARG0+4*ARGSZ] })
1455160814Ssimon
1456194206Ssimon	sethi	%hi(.PIC.DES_SPtrans-1f),global1
1457194206Ssimon	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
1458194206Ssimon1:	call	.+8
1459194206Ssimon	add	%o7,global1,global1
1460194206Ssimon	sub	global1,.PIC.DES_SPtrans-.des_and,out2
1461160814Ssimon
1462160814Ssimon	cmp	in5, 0                    ! enc   
1463160814Ssimon
1464160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1465160814Ssimon	be,pn	%icc, .ncbc.dec
1466160814Ssimon#else
1467160814Ssimon	be	.ncbc.dec
1468160814Ssimon#endif
1469160814Ssimon	STPTR	in4, IVEC
1470160814Ssimon
1471160814Ssimon	! addr  left  right  temp  label
1472160814Ssimon	load_little_endian(in4, in5, out5, local3, .LLE1)  ! iv
1473160814Ssimon
1474160814Ssimon	addcc	in2, -8, in2              ! bytes missing when first block done
1475160814Ssimon
1476160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1477160814Ssimon	bl,pn	%icc, .ncbc.enc.seven.or.less
1478160814Ssimon#else
1479160814Ssimon	bl	.ncbc.enc.seven.or.less
1480160814Ssimon#endif
1481160814Ssimon	mov	in3, in4                  ! schedule
1482160814Ssimon
1483160814Ssimon.ncbc.enc.next.block:
1484160814Ssimon
1485160814Ssimon	load_little_endian(in0, out4, global4, local3, .LLE2)  ! block
1486160814Ssimon
1487160814Ssimon.ncbc.enc.next.block_1:
1488160814Ssimon
1489160814Ssimon	xor	in5, out4, in5            ! iv xor
1490160814Ssimon	xor	out5, global4, out5       ! iv xor
1491160814Ssimon
1492160814Ssimon	! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
1493160814Ssimon	ip_macro(in5, out5, in5, out5, in3, 0, 0, 2)
1494160814Ssimon
1495160814Ssimon.ncbc.enc.next.block_2:
1496160814Ssimon
1497160814Ssimon!//	call .des_enc                     ! compares in2 to 8
1498160814Ssimon!	rounds inlined for alignment purposes
1499160814Ssimon
1500160814Ssimon	add	global1, 768, global4     ! address sbox 4 since register used below
1501160814Ssimon
1502160814Ssimon	rounds_macro(in5, out5, 1, .ncbc.enc.1, in3, in4) ! include encryption  ks in3
1503160814Ssimon
1504160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1505160814Ssimon	bl,pn	%icc, .ncbc.enc.next.block_fp
1506160814Ssimon#else
1507160814Ssimon	bl	.ncbc.enc.next.block_fp
1508160814Ssimon#endif
1509160814Ssimon	add	in0, 8, in0               ! input address
1510160814Ssimon
1511160814Ssimon	! If 8 or more bytes are to be encrypted after this block,
1512160814Ssimon	! we combine final permutation for this block with initial
1513160814Ssimon	! permutation for next block. Load next block:
1514160814Ssimon
1515160814Ssimon	load_little_endian(in0, global3, global4, local5, .LLE12)
1516160814Ssimon
1517160814Ssimon	!  parameter 1   original left
1518160814Ssimon	!  parameter 2   original right
1519160814Ssimon	!  parameter 3   left ip
1520160814Ssimon	!  parameter 4   right ip
1521160814Ssimon	!  parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
1522160814Ssimon	!                2: mov in4 to in3
1523160814Ssimon	!
1524160814Ssimon	! also adds -8 to length in2 and loads loop counter to out4
1525160814Ssimon
1526160814Ssimon	fp_ip_macro(out0, out1, global3, global4, 2)
1527160814Ssimon
1528160814Ssimon	store_little_endian(in1, out0, out1, local3, .SLE10)  ! block
1529160814Ssimon
1530160814Ssimon	ld	[in3], out0               ! key 7531 first round next block
1531160814Ssimon	mov 	in5, local1
1532160814Ssimon	xor	global3, out5, in5        ! iv xor next block
1533160814Ssimon
1534160814Ssimon	ld	[in3+4], out1             ! key 8642
1535160814Ssimon	add	global1, 512, global3     ! address sbox 3 since register used
1536160814Ssimon	xor	global4, local1, out5     ! iv xor next block
1537160814Ssimon
1538160814Ssimon	ba	.ncbc.enc.next.block_2
1539160814Ssimon	add	in1, 8, in1               ! output adress
1540160814Ssimon
1541160814Ssimon.ncbc.enc.next.block_fp:
1542160814Ssimon
1543160814Ssimon	fp_macro(in5, out5)
1544160814Ssimon
1545160814Ssimon	store_little_endian(in1, in5, out5, local3, .SLE1)  ! block
1546160814Ssimon
1547160814Ssimon	addcc   in2, -8, in2              ! bytes missing when next block done
1548160814Ssimon
1549160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1550160814Ssimon	bpos,pt	%icc, .ncbc.enc.next.block  ! also jumps if 0
1551160814Ssimon#else
1552160814Ssimon	bpos	.ncbc.enc.next.block
1553160814Ssimon#endif
1554160814Ssimon	add	in1, 8, in1
1555160814Ssimon
1556160814Ssimon.ncbc.enc.seven.or.less:
1557160814Ssimon
1558160814Ssimon	cmp	in2, -8
1559160814Ssimon
1560160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1561160814Ssimon	ble,pt	%icc, .ncbc.enc.finish
1562160814Ssimon#else
1563160814Ssimon	ble	.ncbc.enc.finish
1564160814Ssimon#endif
1565160814Ssimon	nop
1566160814Ssimon
1567160814Ssimon	add	in2, 8, local1            ! bytes to load
1568160814Ssimon
1569160814Ssimon	! addr, length, dest left, dest right, temp, temp2, label, ret label
1570160814Ssimon	load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB1, .ncbc.enc.next.block_1)
1571160814Ssimon
1572160814Ssimon	! Loads 1 to 7 bytes little endian to global4, out4
1573160814Ssimon
1574160814Ssimon
1575160814Ssimon.ncbc.enc.finish:
1576160814Ssimon
1577160814Ssimon	LDPTR	IVEC, local4
1578160814Ssimon	store_little_endian(local4, in5, out5, local5, .SLE2)  ! ivec
1579160814Ssimon
1580160814Ssimon	ret
1581160814Ssimon	restore
1582160814Ssimon
1583160814Ssimon
1584160814Ssimon.ncbc.dec:
1585160814Ssimon
1586160814Ssimon	STPTR	in0, INPUT
1587160814Ssimon	cmp	in2, 0                    ! length
1588160814Ssimon	add	in3, 120, in3
1589160814Ssimon
1590160814Ssimon	LDPTR	IVEC, local7              ! ivec
1591160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1592160814Ssimon	ble,pn	%icc, .ncbc.dec.finish
1593160814Ssimon#else
1594160814Ssimon	ble	.ncbc.dec.finish
1595160814Ssimon#endif
1596160814Ssimon	mov	in3, in4                  ! schedule
1597160814Ssimon
1598160814Ssimon	STPTR	in1, OUTPUT
1599160814Ssimon	mov	in0, local5               ! input
1600160814Ssimon
1601160814Ssimon	load_little_endian(local7, in0, in1, local3, .LLE3)   ! ivec
1602160814Ssimon
1603160814Ssimon.ncbc.dec.next.block:
1604160814Ssimon
1605160814Ssimon	load_little_endian(local5, in5, out5, local3, .LLE4)  ! block
1606160814Ssimon
1607160814Ssimon	! parameter 6  1/2 for include encryption/decryption
1608160814Ssimon	! parameter 7  1 for mov in1 to in3
1609160814Ssimon	! parameter 8  1 for mov in3 to in4
1610160814Ssimon
1611160814Ssimon	ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include decryprion  ks in4
1612160814Ssimon
1613160814Ssimon	fp_macro(out5, in5, 0, 1) ! 1 for input and output address to local5/7
1614160814Ssimon
1615160814Ssimon	! in2 is bytes left to be stored
1616160814Ssimon	! in2 is compared to 8 in the rounds
1617160814Ssimon
1618160814Ssimon	xor	out5, in0, out4           ! iv xor
1619160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1620160814Ssimon	bl,pn	%icc, .ncbc.dec.seven.or.less
1621160814Ssimon#else
1622160814Ssimon	bl	.ncbc.dec.seven.or.less
1623160814Ssimon#endif
1624160814Ssimon	xor	in5, in1, global4         ! iv xor
1625160814Ssimon
1626160814Ssimon	! Load ivec next block now, since input and output address might be the same.
1627160814Ssimon
1628160814Ssimon	load_little_endian_inc(local5, in0, in1, local3, .LLE5)  ! iv
1629160814Ssimon
1630160814Ssimon	store_little_endian(local7, out4, global4, local3, .SLE3)
1631160814Ssimon
1632160814Ssimon	STPTR	local5, INPUT
1633160814Ssimon	add	local7, 8, local7
1634160814Ssimon	addcc   in2, -8, in2
1635160814Ssimon
1636160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1637160814Ssimon	bg,pt	%icc, .ncbc.dec.next.block
1638160814Ssimon#else
1639160814Ssimon	bg	.ncbc.dec.next.block
1640160814Ssimon#endif
1641160814Ssimon	STPTR	local7, OUTPUT
1642160814Ssimon
1643160814Ssimon
1644160814Ssimon.ncbc.dec.store.iv:
1645160814Ssimon
1646160814Ssimon	LDPTR	IVEC, local4              ! ivec
1647160814Ssimon	store_little_endian(local4, in0, in1, local5, .SLE4)
1648160814Ssimon
1649160814Ssimon.ncbc.dec.finish:
1650160814Ssimon
1651160814Ssimon	ret
1652160814Ssimon	restore
1653160814Ssimon
1654160814Ssimon.ncbc.dec.seven.or.less:
1655160814Ssimon
1656160814Ssimon	load_little_endian_inc(local5, in0, in1, local3, .LLE13)     ! ivec
1657160814Ssimon
1658160814Ssimon	store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB1, .ncbc.dec.store.iv)
1659160814Ssimon
1660160814Ssimon
1661160814Ssimon.DES_ncbc_encrypt.end:
1662160814Ssimon	.size	 DES_ncbc_encrypt, .DES_ncbc_encrypt.end-DES_ncbc_encrypt
1663160814Ssimon
1664160814Ssimon
1665160814Ssimon! void DES_ede3_cbc_encrypt(input, output, lenght, ks1, ks2, ks3, ivec, enc)
1666160814Ssimon! **************************************************************************
1667160814Ssimon
1668160814Ssimon
1669160814Ssimon	.align 32
1670160814Ssimon	.global DES_ede3_cbc_encrypt
1671160814Ssimon	.type	 DES_ede3_cbc_encrypt,#function
1672160814Ssimon
1673160814SsimonDES_ede3_cbc_encrypt:
1674160814Ssimon
1675160814Ssimon	save	%sp, FRAME, %sp
1676160814Ssimon
1677160814Ssimon	define({KS1}, { [%sp+BIAS+ARG0+3*ARGSZ] })
1678160814Ssimon	define({KS2}, { [%sp+BIAS+ARG0+4*ARGSZ] })
1679160814Ssimon	define({KS3}, { [%sp+BIAS+ARG0+5*ARGSZ] })
1680160814Ssimon
1681194206Ssimon	sethi	%hi(.PIC.DES_SPtrans-1f),global1
1682194206Ssimon	or	global1,%lo(.PIC.DES_SPtrans-1f),global1
1683194206Ssimon1:	call	.+8
1684194206Ssimon	add	%o7,global1,global1
1685194206Ssimon	sub	global1,.PIC.DES_SPtrans-.des_and,out2
1686160814Ssimon
1687160814Ssimon	LDPTR	[%fp+BIAS+ARG0+7*ARGSZ], local3          ! enc
1688160814Ssimon	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
1689160814Ssimon	cmp	local3, 0                 ! enc
1690160814Ssimon
1691160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1692160814Ssimon	be,pn	%icc, .ede3.dec
1693160814Ssimon#else
1694160814Ssimon	be	.ede3.dec
1695160814Ssimon#endif
1696160814Ssimon	STPTR	in4, KS2
1697160814Ssimon
1698160814Ssimon	STPTR	in5, KS3
1699160814Ssimon
1700160814Ssimon	load_little_endian(local4, in5, out5, local3, .LLE6)  ! ivec
1701160814Ssimon
1702160814Ssimon	addcc	in2, -8, in2              ! bytes missing after next block
1703160814Ssimon
1704160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1705160814Ssimon	bl,pn	%icc,  .ede3.enc.seven.or.less
1706160814Ssimon#else
1707160814Ssimon	bl	.ede3.enc.seven.or.less
1708160814Ssimon#endif
1709160814Ssimon	STPTR	in3, KS1
1710160814Ssimon
1711160814Ssimon.ede3.enc.next.block:
1712160814Ssimon
1713160814Ssimon	load_little_endian(in0, out4, global4, local3, .LLE7)
1714160814Ssimon
1715160814Ssimon.ede3.enc.next.block_1:
1716160814Ssimon
1717160814Ssimon	LDPTR	KS2, in4
1718160814Ssimon	xor	in5, out4, in5            ! iv xor
1719160814Ssimon	xor	out5, global4, out5       ! iv xor
1720160814Ssimon
1721160814Ssimon	LDPTR	KS1, in3
1722160814Ssimon	add	in4, 120, in4             ! for decryption we use last subkey first
1723160814Ssimon	nop
1724160814Ssimon
1725160814Ssimon	ip_macro(in5, out5, in5, out5, in3)
1726160814Ssimon
1727160814Ssimon.ede3.enc.next.block_2:
1728160814Ssimon
1729160814Ssimon	call .des_enc                     ! ks1 in3
1730160814Ssimon	nop
1731160814Ssimon
1732160814Ssimon	call .des_dec                     ! ks2 in4
1733160814Ssimon	LDPTR	KS3, in3
1734160814Ssimon
1735160814Ssimon	call .des_enc                     ! ks3 in3  compares in2 to 8
1736160814Ssimon	nop
1737160814Ssimon
1738160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1739160814Ssimon	bl,pn	%icc, .ede3.enc.next.block_fp
1740160814Ssimon#else
1741160814Ssimon	bl	.ede3.enc.next.block_fp
1742160814Ssimon#endif
1743160814Ssimon	add	in0, 8, in0
1744160814Ssimon
1745160814Ssimon	! If 8 or more bytes are to be encrypted after this block,
1746160814Ssimon	! we combine final permutation for this block with initial
1747160814Ssimon	! permutation for next block. Load next block:
1748160814Ssimon
1749160814Ssimon	load_little_endian(in0, global3, global4, local5, .LLE11)
1750160814Ssimon
1751160814Ssimon	!  parameter 1   original left
1752160814Ssimon	!  parameter 2   original right
1753160814Ssimon	!  parameter 3   left ip
1754160814Ssimon	!  parameter 4   right ip
1755160814Ssimon	!  parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
1756160814Ssimon	!                2: mov in4 to in3
1757160814Ssimon	!
1758160814Ssimon	! also adds -8 to length in2 and loads loop counter to out4
1759160814Ssimon
1760160814Ssimon	fp_ip_macro(out0, out1, global3, global4, 1)
1761160814Ssimon
1762160814Ssimon	store_little_endian(in1, out0, out1, local3, .SLE9)  ! block
1763160814Ssimon
1764160814Ssimon	mov 	in5, local1
1765160814Ssimon	xor	global3, out5, in5        ! iv xor next block
1766160814Ssimon
1767160814Ssimon	ld	[in3], out0               ! key 7531
1768160814Ssimon	add	global1, 512, global3     ! address sbox 3
1769160814Ssimon	xor	global4, local1, out5     ! iv xor next block
1770160814Ssimon
1771160814Ssimon	ld	[in3+4], out1             ! key 8642
1772160814Ssimon	add	global1, 768, global4     ! address sbox 4
1773160814Ssimon	ba	.ede3.enc.next.block_2
1774160814Ssimon	add	in1, 8, in1
1775160814Ssimon
1776160814Ssimon.ede3.enc.next.block_fp:
1777160814Ssimon
1778160814Ssimon	fp_macro(in5, out5)
1779160814Ssimon
1780160814Ssimon	store_little_endian(in1, in5, out5, local3, .SLE5)  ! block
1781160814Ssimon
1782160814Ssimon	addcc   in2, -8, in2              ! bytes missing when next block done
1783160814Ssimon
1784160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1785160814Ssimon	bpos,pt	%icc, .ede3.enc.next.block
1786160814Ssimon#else
1787160814Ssimon	bpos	.ede3.enc.next.block
1788160814Ssimon#endif
1789160814Ssimon	add	in1, 8, in1
1790160814Ssimon
1791160814Ssimon.ede3.enc.seven.or.less:
1792160814Ssimon
1793160814Ssimon	cmp	in2, -8
1794160814Ssimon
1795160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1796160814Ssimon	ble,pt	%icc, .ede3.enc.finish
1797160814Ssimon#else
1798160814Ssimon	ble	.ede3.enc.finish
1799160814Ssimon#endif
1800160814Ssimon	nop
1801160814Ssimon
1802160814Ssimon	add	in2, 8, local1            ! bytes to load
1803160814Ssimon
1804160814Ssimon	! addr, length, dest left, dest right, temp, temp2, label, ret label
1805160814Ssimon	load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB2, .ede3.enc.next.block_1)
1806160814Ssimon
1807160814Ssimon.ede3.enc.finish:
1808160814Ssimon
1809160814Ssimon	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
1810160814Ssimon	store_little_endian(local4, in5, out5, local5, .SLE6)  ! ivec
1811160814Ssimon
1812160814Ssimon	ret
1813160814Ssimon	restore
1814160814Ssimon
1815160814Ssimon.ede3.dec:
1816160814Ssimon
1817160814Ssimon	STPTR	in0, INPUT
1818160814Ssimon	add	in5, 120, in5
1819160814Ssimon
1820160814Ssimon	STPTR	in1, OUTPUT
1821160814Ssimon	mov	in0, local5
1822160814Ssimon	add	in3, 120, in3
1823160814Ssimon
1824160814Ssimon	STPTR	in3, KS1
1825160814Ssimon	cmp	in2, 0
1826160814Ssimon
1827160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1828160814Ssimon	ble	%icc, .ede3.dec.finish
1829160814Ssimon#else
1830160814Ssimon	ble	.ede3.dec.finish
1831160814Ssimon#endif
1832160814Ssimon	STPTR	in5, KS3
1833160814Ssimon
1834160814Ssimon	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local7          ! iv
1835160814Ssimon	load_little_endian(local7, in0, in1, local3, .LLE8)
1836160814Ssimon
1837160814Ssimon.ede3.dec.next.block:
1838160814Ssimon
1839160814Ssimon	load_little_endian(local5, in5, out5, local3, .LLE9)
1840160814Ssimon
1841160814Ssimon	! parameter 6  1/2 for include encryption/decryption
1842160814Ssimon	! parameter 7  1 for mov in1 to in3
1843160814Ssimon	! parameter 8  1 for mov in3 to in4
1844160814Ssimon	! parameter 9  1 for load ks3 and ks2 to in4 and in3
1845160814Ssimon
1846160814Ssimon	ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 1) ! inc .des_dec ks3 in4
1847160814Ssimon
1848160814Ssimon	call .des_enc                     ! ks2 in3
1849160814Ssimon	LDPTR	KS1, in4
1850160814Ssimon
1851160814Ssimon	call .des_dec                     ! ks1 in4
1852160814Ssimon	nop
1853160814Ssimon
1854160814Ssimon	fp_macro(out5, in5, 0, 1)   ! 1 for input and output address local5/7
1855160814Ssimon
1856160814Ssimon	! in2 is bytes left to be stored
1857160814Ssimon	! in2 is compared to 8 in the rounds
1858160814Ssimon
1859160814Ssimon	xor	out5, in0, out4
1860160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1861160814Ssimon	bl,pn	%icc, .ede3.dec.seven.or.less
1862160814Ssimon#else
1863160814Ssimon	bl	.ede3.dec.seven.or.less
1864160814Ssimon#endif
1865160814Ssimon	xor	in5, in1, global4
1866160814Ssimon
1867160814Ssimon	load_little_endian_inc(local5, in0, in1, local3, .LLE10)   ! iv next block
1868160814Ssimon
1869160814Ssimon	store_little_endian(local7, out4, global4, local3, .SLE7)  ! block
1870160814Ssimon
1871160814Ssimon	STPTR	local5, INPUT
1872160814Ssimon	addcc   in2, -8, in2
1873160814Ssimon	add	local7, 8, local7
1874160814Ssimon
1875160814Ssimon#ifdef OPENSSL_SYSNAME_ULTRASPARC
1876160814Ssimon	bg,pt	%icc, .ede3.dec.next.block
1877160814Ssimon#else
1878160814Ssimon	bg	.ede3.dec.next.block
1879160814Ssimon#endif
1880160814Ssimon	STPTR	local7, OUTPUT
1881160814Ssimon
1882160814Ssimon.ede3.dec.store.iv:
1883160814Ssimon
1884160814Ssimon	LDPTR	[%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
1885160814Ssimon	store_little_endian(local4, in0, in1, local5, .SLE8)  ! ivec
1886160814Ssimon
1887160814Ssimon.ede3.dec.finish:
1888160814Ssimon
1889160814Ssimon	ret
1890160814Ssimon	restore
1891160814Ssimon
1892160814Ssimon.ede3.dec.seven.or.less:
1893160814Ssimon
1894160814Ssimon	load_little_endian_inc(local5, in0, in1, local3, .LLE14)     ! iv
1895160814Ssimon
1896160814Ssimon	store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB2, .ede3.dec.store.iv)
1897160814Ssimon
1898160814Ssimon
1899160814Ssimon.DES_ede3_cbc_encrypt.end:
1900160814Ssimon	.size	 DES_ede3_cbc_encrypt,.DES_ede3_cbc_encrypt.end-DES_ede3_cbc_encrypt
1901194206Ssimon
1902194206Ssimon	.align	256
1903194206Ssimon	.type	 .des_and,#object
1904194206Ssimon	.size	 .des_and,284
1905194206Ssimon
1906194206Ssimon.des_and:
1907194206Ssimon
1908194206Ssimon! This table is used for AND 0xFC when it is known that register
1909194206Ssimon! bits 8-31 are zero. Makes it possible to do three arithmetic
1910194206Ssimon! operations in one cycle.
1911194206Ssimon
1912194206Ssimon	.byte  0, 0, 0, 0, 4, 4, 4, 4
1913194206Ssimon	.byte  8, 8, 8, 8, 12, 12, 12, 12
1914194206Ssimon	.byte  16, 16, 16, 16, 20, 20, 20, 20
1915194206Ssimon	.byte  24, 24, 24, 24, 28, 28, 28, 28
1916194206Ssimon	.byte  32, 32, 32, 32, 36, 36, 36, 36
1917194206Ssimon	.byte  40, 40, 40, 40, 44, 44, 44, 44
1918194206Ssimon	.byte  48, 48, 48, 48, 52, 52, 52, 52
1919194206Ssimon	.byte  56, 56, 56, 56, 60, 60, 60, 60
1920194206Ssimon	.byte  64, 64, 64, 64, 68, 68, 68, 68
1921194206Ssimon	.byte  72, 72, 72, 72, 76, 76, 76, 76
1922194206Ssimon	.byte  80, 80, 80, 80, 84, 84, 84, 84
1923194206Ssimon	.byte  88, 88, 88, 88, 92, 92, 92, 92
1924194206Ssimon	.byte  96, 96, 96, 96, 100, 100, 100, 100
1925194206Ssimon	.byte  104, 104, 104, 104, 108, 108, 108, 108
1926194206Ssimon	.byte  112, 112, 112, 112, 116, 116, 116, 116
1927194206Ssimon	.byte  120, 120, 120, 120, 124, 124, 124, 124
1928194206Ssimon	.byte  128, 128, 128, 128, 132, 132, 132, 132
1929194206Ssimon	.byte  136, 136, 136, 136, 140, 140, 140, 140
1930194206Ssimon	.byte  144, 144, 144, 144, 148, 148, 148, 148
1931194206Ssimon	.byte  152, 152, 152, 152, 156, 156, 156, 156
1932194206Ssimon	.byte  160, 160, 160, 160, 164, 164, 164, 164
1933194206Ssimon	.byte  168, 168, 168, 168, 172, 172, 172, 172
1934194206Ssimon	.byte  176, 176, 176, 176, 180, 180, 180, 180
1935194206Ssimon	.byte  184, 184, 184, 184, 188, 188, 188, 188
1936194206Ssimon	.byte  192, 192, 192, 192, 196, 196, 196, 196
1937194206Ssimon	.byte  200, 200, 200, 200, 204, 204, 204, 204
1938194206Ssimon	.byte  208, 208, 208, 208, 212, 212, 212, 212
1939194206Ssimon	.byte  216, 216, 216, 216, 220, 220, 220, 220
1940194206Ssimon	.byte  224, 224, 224, 224, 228, 228, 228, 228
1941194206Ssimon	.byte  232, 232, 232, 232, 236, 236, 236, 236
1942194206Ssimon	.byte  240, 240, 240, 240, 244, 244, 244, 244
1943194206Ssimon	.byte  248, 248, 248, 248, 252, 252, 252, 252
1944194206Ssimon
1945194206Ssimon	! 5 numbers for initil/final permutation
1946194206Ssimon
1947194206Ssimon	.word   0x0f0f0f0f                ! offset 256
1948194206Ssimon	.word	0x0000ffff                ! 260
1949194206Ssimon	.word	0x33333333                ! 264
1950194206Ssimon	.word	0x00ff00ff                ! 268
1951194206Ssimon	.word	0x55555555                ! 272
1952194206Ssimon
1953194206Ssimon	.word	0                         ! 276
1954194206Ssimon	.word	LOOPS                     ! 280
1955194206Ssimon	.word	0x0000FC00                ! 284
1956194206Ssimon
1957238405Sjkim	.global	DES_SPtrans
1958238405Sjkim	.type	DES_SPtrans,#object
1959238405Sjkim	.size	DES_SPtrans,2048
1960194206Ssimon.align	64
1961238405SjkimDES_SPtrans:
1962194206Ssimon.PIC.DES_SPtrans:
1963194206Ssimon	! nibble 0
1964194206Ssimon	.word	0x02080800, 0x00080000, 0x02000002, 0x02080802
1965194206Ssimon	.word	0x02000000, 0x00080802, 0x00080002, 0x02000002
1966194206Ssimon	.word	0x00080802, 0x02080800, 0x02080000, 0x00000802
1967194206Ssimon	.word	0x02000802, 0x02000000, 0x00000000, 0x00080002
1968194206Ssimon	.word	0x00080000, 0x00000002, 0x02000800, 0x00080800
1969194206Ssimon	.word	0x02080802, 0x02080000, 0x00000802, 0x02000800
1970194206Ssimon	.word	0x00000002, 0x00000800, 0x00080800, 0x02080002
1971194206Ssimon	.word	0x00000800, 0x02000802, 0x02080002, 0x00000000
1972194206Ssimon	.word	0x00000000, 0x02080802, 0x02000800, 0x00080002
1973194206Ssimon	.word	0x02080800, 0x00080000, 0x00000802, 0x02000800
1974194206Ssimon	.word	0x02080002, 0x00000800, 0x00080800, 0x02000002
1975194206Ssimon	.word	0x00080802, 0x00000002, 0x02000002, 0x02080000
1976194206Ssimon	.word	0x02080802, 0x00080800, 0x02080000, 0x02000802
1977194206Ssimon	.word	0x02000000, 0x00000802, 0x00080002, 0x00000000
1978194206Ssimon	.word	0x00080000, 0x02000000, 0x02000802, 0x02080800
1979194206Ssimon	.word	0x00000002, 0x02080002, 0x00000800, 0x00080802
1980194206Ssimon	! nibble 1
1981194206Ssimon	.word	0x40108010, 0x00000000, 0x00108000, 0x40100000
1982194206Ssimon	.word	0x40000010, 0x00008010, 0x40008000, 0x00108000
1983194206Ssimon	.word	0x00008000, 0x40100010, 0x00000010, 0x40008000
1984194206Ssimon	.word	0x00100010, 0x40108000, 0x40100000, 0x00000010
1985194206Ssimon	.word	0x00100000, 0x40008010, 0x40100010, 0x00008000
1986194206Ssimon	.word	0x00108010, 0x40000000, 0x00000000, 0x00100010
1987194206Ssimon	.word	0x40008010, 0x00108010, 0x40108000, 0x40000010
1988194206Ssimon	.word	0x40000000, 0x00100000, 0x00008010, 0x40108010
1989194206Ssimon	.word	0x00100010, 0x40108000, 0x40008000, 0x00108010
1990194206Ssimon	.word	0x40108010, 0x00100010, 0x40000010, 0x00000000
1991194206Ssimon	.word	0x40000000, 0x00008010, 0x00100000, 0x40100010
1992194206Ssimon	.word	0x00008000, 0x40000000, 0x00108010, 0x40008010
1993194206Ssimon	.word	0x40108000, 0x00008000, 0x00000000, 0x40000010
1994194206Ssimon	.word	0x00000010, 0x40108010, 0x00108000, 0x40100000
1995194206Ssimon	.word	0x40100010, 0x00100000, 0x00008010, 0x40008000
1996194206Ssimon	.word	0x40008010, 0x00000010, 0x40100000, 0x00108000
1997194206Ssimon	! nibble 2
1998194206Ssimon	.word	0x04000001, 0x04040100, 0x00000100, 0x04000101
1999194206Ssimon	.word	0x00040001, 0x04000000, 0x04000101, 0x00040100
2000194206Ssimon	.word	0x04000100, 0x00040000, 0x04040000, 0x00000001
2001194206Ssimon	.word	0x04040101, 0x00000101, 0x00000001, 0x04040001
2002194206Ssimon	.word	0x00000000, 0x00040001, 0x04040100, 0x00000100
2003194206Ssimon	.word	0x00000101, 0x04040101, 0x00040000, 0x04000001
2004194206Ssimon	.word	0x04040001, 0x04000100, 0x00040101, 0x04040000
2005194206Ssimon	.word	0x00040100, 0x00000000, 0x04000000, 0x00040101
2006194206Ssimon	.word	0x04040100, 0x00000100, 0x00000001, 0x00040000
2007194206Ssimon	.word	0x00000101, 0x00040001, 0x04040000, 0x04000101
2008194206Ssimon	.word	0x00000000, 0x04040100, 0x00040100, 0x04040001
2009194206Ssimon	.word	0x00040001, 0x04000000, 0x04040101, 0x00000001
2010194206Ssimon	.word	0x00040101, 0x04000001, 0x04000000, 0x04040101
2011194206Ssimon	.word	0x00040000, 0x04000100, 0x04000101, 0x00040100
2012194206Ssimon	.word	0x04000100, 0x00000000, 0x04040001, 0x00000101
2013194206Ssimon	.word	0x04000001, 0x00040101, 0x00000100, 0x04040000
2014194206Ssimon	! nibble 3
2015194206Ssimon	.word	0x00401008, 0x10001000, 0x00000008, 0x10401008
2016194206Ssimon	.word	0x00000000, 0x10400000, 0x10001008, 0x00400008
2017194206Ssimon	.word	0x10401000, 0x10000008, 0x10000000, 0x00001008
2018194206Ssimon	.word	0x10000008, 0x00401008, 0x00400000, 0x10000000
2019194206Ssimon	.word	0x10400008, 0x00401000, 0x00001000, 0x00000008
2020194206Ssimon	.word	0x00401000, 0x10001008, 0x10400000, 0x00001000
2021194206Ssimon	.word	0x00001008, 0x00000000, 0x00400008, 0x10401000
2022194206Ssimon	.word	0x10001000, 0x10400008, 0x10401008, 0x00400000
2023194206Ssimon	.word	0x10400008, 0x00001008, 0x00400000, 0x10000008
2024194206Ssimon	.word	0x00401000, 0x10001000, 0x00000008, 0x10400000
2025194206Ssimon	.word	0x10001008, 0x00000000, 0x00001000, 0x00400008
2026194206Ssimon	.word	0x00000000, 0x10400008, 0x10401000, 0x00001000
2027194206Ssimon	.word	0x10000000, 0x10401008, 0x00401008, 0x00400000
2028194206Ssimon	.word	0x10401008, 0x00000008, 0x10001000, 0x00401008
2029194206Ssimon	.word	0x00400008, 0x00401000, 0x10400000, 0x10001008
2030194206Ssimon	.word	0x00001008, 0x10000000, 0x10000008, 0x10401000
2031194206Ssimon	! nibble 4
2032194206Ssimon	.word	0x08000000, 0x00010000, 0x00000400, 0x08010420
2033194206Ssimon	.word	0x08010020, 0x08000400, 0x00010420, 0x08010000
2034194206Ssimon	.word	0x00010000, 0x00000020, 0x08000020, 0x00010400
2035194206Ssimon	.word	0x08000420, 0x08010020, 0x08010400, 0x00000000
2036194206Ssimon	.word	0x00010400, 0x08000000, 0x00010020, 0x00000420
2037194206Ssimon	.word	0x08000400, 0x00010420, 0x00000000, 0x08000020
2038194206Ssimon	.word	0x00000020, 0x08000420, 0x08010420, 0x00010020
2039194206Ssimon	.word	0x08010000, 0x00000400, 0x00000420, 0x08010400
2040194206Ssimon	.word	0x08010400, 0x08000420, 0x00010020, 0x08010000
2041194206Ssimon	.word	0x00010000, 0x00000020, 0x08000020, 0x08000400
2042194206Ssimon	.word	0x08000000, 0x00010400, 0x08010420, 0x00000000
2043194206Ssimon	.word	0x00010420, 0x08000000, 0x00000400, 0x00010020
2044194206Ssimon	.word	0x08000420, 0x00000400, 0x00000000, 0x08010420
2045194206Ssimon	.word	0x08010020, 0x08010400, 0x00000420, 0x00010000
2046194206Ssimon	.word	0x00010400, 0x08010020, 0x08000400, 0x00000420
2047194206Ssimon	.word	0x00000020, 0x00010420, 0x08010000, 0x08000020
2048194206Ssimon	! nibble 5
2049194206Ssimon	.word	0x80000040, 0x00200040, 0x00000000, 0x80202000
2050194206Ssimon	.word	0x00200040, 0x00002000, 0x80002040, 0x00200000
2051194206Ssimon	.word	0x00002040, 0x80202040, 0x00202000, 0x80000000
2052194206Ssimon	.word	0x80002000, 0x80000040, 0x80200000, 0x00202040
2053194206Ssimon	.word	0x00200000, 0x80002040, 0x80200040, 0x00000000
2054194206Ssimon	.word	0x00002000, 0x00000040, 0x80202000, 0x80200040
2055194206Ssimon	.word	0x80202040, 0x80200000, 0x80000000, 0x00002040
2056194206Ssimon	.word	0x00000040, 0x00202000, 0x00202040, 0x80002000
2057194206Ssimon	.word	0x00002040, 0x80000000, 0x80002000, 0x00202040
2058194206Ssimon	.word	0x80202000, 0x00200040, 0x00000000, 0x80002000
2059194206Ssimon	.word	0x80000000, 0x00002000, 0x80200040, 0x00200000
2060194206Ssimon	.word	0x00200040, 0x80202040, 0x00202000, 0x00000040
2061194206Ssimon	.word	0x80202040, 0x00202000, 0x00200000, 0x80002040
2062194206Ssimon	.word	0x80000040, 0x80200000, 0x00202040, 0x00000000
2063194206Ssimon	.word	0x00002000, 0x80000040, 0x80002040, 0x80202000
2064194206Ssimon	.word	0x80200000, 0x00002040, 0x00000040, 0x80200040
2065194206Ssimon	! nibble 6
2066194206Ssimon	.word	0x00004000, 0x00000200, 0x01000200, 0x01000004
2067194206Ssimon	.word	0x01004204, 0x00004004, 0x00004200, 0x00000000
2068194206Ssimon	.word	0x01000000, 0x01000204, 0x00000204, 0x01004000
2069194206Ssimon	.word	0x00000004, 0x01004200, 0x01004000, 0x00000204
2070194206Ssimon	.word	0x01000204, 0x00004000, 0x00004004, 0x01004204
2071194206Ssimon	.word	0x00000000, 0x01000200, 0x01000004, 0x00004200
2072194206Ssimon	.word	0x01004004, 0x00004204, 0x01004200, 0x00000004
2073194206Ssimon	.word	0x00004204, 0x01004004, 0x00000200, 0x01000000
2074194206Ssimon	.word	0x00004204, 0x01004000, 0x01004004, 0x00000204
2075194206Ssimon	.word	0x00004000, 0x00000200, 0x01000000, 0x01004004
2076194206Ssimon	.word	0x01000204, 0x00004204, 0x00004200, 0x00000000
2077194206Ssimon	.word	0x00000200, 0x01000004, 0x00000004, 0x01000200
2078194206Ssimon	.word	0x00000000, 0x01000204, 0x01000200, 0x00004200
2079194206Ssimon	.word	0x00000204, 0x00004000, 0x01004204, 0x01000000
2080194206Ssimon	.word	0x01004200, 0x00000004, 0x00004004, 0x01004204
2081194206Ssimon	.word	0x01000004, 0x01004200, 0x01004000, 0x00004004
2082194206Ssimon	! nibble 7
2083194206Ssimon	.word	0x20800080, 0x20820000, 0x00020080, 0x00000000
2084194206Ssimon	.word	0x20020000, 0x00800080, 0x20800000, 0x20820080
2085194206Ssimon	.word	0x00000080, 0x20000000, 0x00820000, 0x00020080
2086194206Ssimon	.word	0x00820080, 0x20020080, 0x20000080, 0x20800000
2087194206Ssimon	.word	0x00020000, 0x00820080, 0x00800080, 0x20020000
2088194206Ssimon	.word	0x20820080, 0x20000080, 0x00000000, 0x00820000
2089194206Ssimon	.word	0x20000000, 0x00800000, 0x20020080, 0x20800080
2090194206Ssimon	.word	0x00800000, 0x00020000, 0x20820000, 0x00000080
2091194206Ssimon	.word	0x00800000, 0x00020000, 0x20000080, 0x20820080
2092194206Ssimon	.word	0x00020080, 0x20000000, 0x00000000, 0x00820000
2093194206Ssimon	.word	0x20800080, 0x20020080, 0x20020000, 0x00800080
2094194206Ssimon	.word	0x20820000, 0x00000080, 0x00800080, 0x20020000
2095194206Ssimon	.word	0x20820080, 0x00800000, 0x20800000, 0x20000080
2096194206Ssimon	.word	0x00820000, 0x00020080, 0x20020080, 0x20800000
2097194206Ssimon	.word	0x00000080, 0x20820000, 0x00820080, 0x00000000
2098194206Ssimon	.word	0x20000000, 0x20800080, 0x00020000, 0x00820080
2099194206Ssimon
2100