SPARC assembler pack: fix FIPS linking errors.
[openssl.git] / crypto / des / asm / des_enc.m4
1 !  des_enc.m4
2 !  des_enc.S  (generated from des_enc.m4)
3 !
4 !  UltraSPARC assembler version of the LibDES/SSLeay/OpenSSL des_enc.c file.
5 !
6 !  Version 1.0. 32-bit version.
7 !
8 !  June 8, 2000.
9 !
10 !  Version 2.0. 32/64-bit, PIC-ification, blended CPU adaptation
11 !               by Andy Polyakov.
12 !
13 !  January 1, 2003.
14 !
15 !  Assembler version: Copyright Svend Olaf Mikkelsen.
16 !
17 !  Original C code: Copyright Eric A. Young.
18 !
19 !  This code can be freely used by LibDES/SSLeay/OpenSSL users.
20 !
21 !  The LibDES/SSLeay/OpenSSL copyright notices must be respected.
22 !
23 !  This version can be redistributed.
24 !
25 !  To expand the m4 macros: m4 -B 8192 des_enc.m4 > des_enc.S
26 !
27 !  Global registers 1 to 5 are used. This is the same as done by the
28 !  cc compiler. The UltraSPARC load/store little endian feature is used.
29 !
30 !  Instruction grouping often refers to one CPU cycle.
31 !
32 !  Assemble through gcc: gcc -c -mcpu=ultrasparc -o des_enc.o des_enc.S
33 !
34 !  Assemble through cc:  cc -c -xarch=v8plusa -o des_enc.o des_enc.S
35 !
36 !  Performance improvement according to './apps/openssl speed des'
37 !
38 !       32-bit build:
39 !               23%  faster than cc-5.2 -xarch=v8plus -xO5
40 !               115% faster than gcc-3.2.1 -m32 -mcpu=ultrasparc -O5
41 !       64-bit build:
42 !               50%  faster than cc-5.2 -xarch=v9 -xO5
43 !               100% faster than gcc-3.2.1 -m64 -mcpu=ultrasparc -O5
44 !
45
46 .ident "des_enc.m4 2.1"
47 .file  "des_enc-sparc.S"
48
49 #ifdef OPENSSL_FIPSCANISTER
50 #include <openssl/fipssyms.h>
51 #endif
52
53 #if defined(__SUNPRO_C) && defined(__sparcv9)
54 # define ABI64  /* They've said -xarch=v9 at command line */
55 #elif defined(__GNUC__) && defined(__arch64__)
56 # define ABI64  /* They've said -m64 at command line */
57 #endif
58
59 #ifdef ABI64
60   .register     %g2,#scratch
61   .register     %g3,#scratch
62 # define        FRAME   -192
63 # define        BIAS    2047
64 # define        LDPTR   ldx
65 # define        STPTR   stx
66 # define        ARG0    128
67 # define        ARGSZ   8
68 # ifndef OPENSSL_SYSNAME_ULTRASPARC
69 # define OPENSSL_SYSNAME_ULTRASPARC
70 # endif
71 #else
72 # define        FRAME   -96
73 # define        BIAS    0
74 # define        LDPTR   ld
75 # define        STPTR   st
76 # define        ARG0    68
77 # define        ARGSZ   4
78 #endif
79
80 #define LOOPS 7
81
82 #define global0 %g0
83 #define global1 %g1
84 #define global2 %g2
85 #define global3 %g3
86 #define global4 %g4
87 #define global5 %g5
88
89 #define local0 %l0
90 #define local1 %l1
91 #define local2 %l2
92 #define local3 %l3
93 #define local4 %l4
94 #define local5 %l5
95 #define local7 %l6
96 #define local6 %l7
97
98 #define in0 %i0
99 #define in1 %i1
100 #define in2 %i2
101 #define in3 %i3
102 #define in4 %i4
103 #define in5 %i5
104 #define in6 %i6
105 #define in7 %i7
106
107 #define out0 %o0
108 #define out1 %o1
109 #define out2 %o2
110 #define out3 %o3
111 #define out4 %o4
112 #define out5 %o5
113 #define out6 %o6
114 #define out7 %o7
115
116 #define stub stb
117
118 changequote({,})
119
120
121 ! Macro definitions:
122
123
124 ! {ip_macro}
125 !
126 ! The logic used in initial and final permutations is the same as in
127 ! the C code. The permutations are done with a clever shift, xor, and
128 ! technique.
129 !
130 ! The macro also loads address sbox 1 to 5 to global 1 to 5, address
131 ! sbox 6 to local6, and addres sbox 8 to out3.
132 !
133 ! Rotates the halfs 3 left to bring the sbox bits in convenient positions.
134 !
135 ! Loads key first round from address in parameter 5 to out0, out1.
136 !
137 ! After the the original LibDES initial permutation, the resulting left
138 ! is in the variable initially used for right and vice versa. The macro
139 ! implements the possibility to keep the halfs in the original registers.
140 !
141 ! parameter 1  left
142 ! parameter 2  right
143 ! parameter 3  result left (modify in first round)
144 ! parameter 4  result right (use in first round)
145 ! parameter 5  key address
146 ! parameter 6  1/2 for include encryption/decryption
147 ! parameter 7  1 for move in1 to in3
148 ! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
149 ! parameter 9  1 for load ks3 and ks2 to in4 and in3
150
151 define(ip_macro, {
152
153 ! {ip_macro}
154 ! $1 $2 $4 $3 $5 $6 $7 $8 $9
155
156         ld      [out2+256], local1
157         srl     $2, 4, local4
158
159         xor     local4, $1, local4
160         ifelse($7,1,{mov in1, in3},{nop})
161
162         ld      [out2+260], local2
163         and     local4, local1, local4
164         ifelse($8,1,{mov in3, in4},{})
165         ifelse($8,2,{mov in4, in3},{})
166
167         ld      [out2+280], out4          ! loop counter
168         sll     local4, 4, local1
169         xor     $1, local4, $1
170
171         ld      [out2+264], local3
172         srl     $1, 16, local4
173         xor     $2, local1, $2
174
175         ifelse($9,1,{LDPTR      KS3, in4},{})
176         xor     local4, $2, local4
177         nop     !sethi  %hi(DES_SPtrans), global1 ! sbox addr
178
179         ifelse($9,1,{LDPTR      KS2, in3},{})
180         and     local4, local2, local4
181         nop     !or     global1, %lo(DES_SPtrans), global1   ! sbox addr
182
183         sll     local4, 16, local1
184         xor     $2, local4, $2
185
186         srl     $2, 2, local4
187         xor     $1, local1, $1
188
189         sethi   %hi(16711680), local5
190         xor     local4, $1, local4
191
192         and     local4, local3, local4
193         or      local5, 255, local5
194
195         sll     local4, 2, local2
196         xor     $1, local4, $1
197
198         srl     $1, 8, local4
199         xor     $2, local2, $2
200
201         xor     local4, $2, local4
202         add     global1, 768, global4
203
204         and     local4, local5, local4
205         add     global1, 1024, global5
206
207         ld      [out2+272], local7
208         sll     local4, 8, local1
209         xor     $2, local4, $2
210
211         srl     $2, 1, local4
212         xor     $1, local1, $1
213
214         ld      [$5], out0                ! key 7531
215         xor     local4, $1, local4
216         add     global1, 256, global2
217
218         ld      [$5+4], out1              ! key 8642
219         and     local4, local7, local4
220         add     global1, 512, global3
221
222         sll     local4, 1, local1
223         xor     $1, local4, $1
224
225         sll     $1, 3, local3
226         xor     $2, local1, $2
227
228         sll     $2, 3, local2
229         add     global1, 1280, local6     ! address sbox 8
230
231         srl     $1, 29, local4
232         add     global1, 1792, out3       ! address sbox 8
233
234         srl     $2, 29, local1
235         or      local4, local3, $4
236
237         or      local2, local1, $3
238
239         ifelse($6, 1, {
240
241                 ld      [out2+284], local5     ! 0x0000FC00 used in the rounds
242                 or      local2, local1, $3
243                 xor     $4, out0, local1
244
245                 call .des_enc.1
246                 and     local1, 252, local1
247
248         },{})
249
250         ifelse($6, 2, {
251
252                 ld      [out2+284], local5     ! 0x0000FC00 used in the rounds
253                 or      local2, local1, $3
254                 xor     $4, out0, local1
255
256                 call .des_dec.1
257                 and     local1, 252, local1
258
259         },{})
260 })
261
262
263 ! {rounds_macro}
264 !
265 ! The logic used in the DES rounds is the same as in the C code,
266 ! except that calculations for sbox 1 and sbox 5 begin before
267 ! the previous round is finished.
268 !
269 ! In each round one half (work) is modified based on key and the
270 ! other half (use).
271 !
272 ! In this version we do two rounds in a loop repeated 7 times
273 ! and two rounds seperately.
274 !
275 ! One half has the bits for the sboxes in the following positions:
276 !
277 !       777777xx555555xx333333xx111111xx
278 !
279 !       88xx666666xx444444xx222222xx8888
280 !
281 ! The bits for each sbox are xor-ed with the key bits for that box.
282 ! The above xx bits are cleared, and the result used for lookup in
283 ! the sbox table. Each sbox entry contains the 4 output bits permuted
284 ! into 32 bits according to the P permutation.
285 !
286 ! In the description of DES, left and right are switched after
287 ! each round, except after last round. In this code the original
288 ! left and right are kept in the same register in all rounds, meaning
289 ! that after the 16 rounds the result for right is in the register
290 ! originally used for left.
291 !
292 ! parameter 1  first work (left in first round)
293 ! parameter 2  first use (right in first round)
294 ! parameter 3  enc/dec  1/-1
295 ! parameter 4  loop label
296 ! parameter 5  key address register
297 ! parameter 6  optional address for key next encryption/decryption
298 ! parameter 7  not empty for include retl
299 !
300 ! also compares in2 to 8
301
302 define(rounds_macro, {
303
304 ! {rounds_macro}
305 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
306
307         xor     $2, out0, local1
308
309         ld      [out2+284], local5        ! 0x0000FC00
310         ba      $4
311         and     local1, 252, local1
312
313         .align 32
314
315 $4:
316         ! local6 is address sbox 6
317         ! out3   is address sbox 8
318         ! out4   is loop counter
319
320         ld      [global1+local1], local1
321         xor     $2, out1, out1            ! 8642
322         xor     $2, out0, out0            ! 7531
323         ! fmovs %f0, %f0                  ! fxor used for alignment
324
325         srl     out1, 4, local0           ! rotate 4 right
326         and     out0, local5, local3      ! 3
327         ! fmovs %f0, %f0
328
329         ld      [$5+$3*8], local7         ! key 7531 next round
330         srl     local3, 8, local3         ! 3
331         and     local0, 252, local2       ! 2
332         ! fmovs %f0, %f0
333
334         ld      [global3+local3],local3   ! 3
335         sll     out1, 28, out1            ! rotate
336         xor     $1, local1, $1            ! 1 finished, local1 now sbox 7
337
338         ld      [global2+local2], local2  ! 2 
339         srl     out0, 24, local1          ! 7
340         or      out1, local0, out1        ! rotate
341
342         ldub    [out2+local1], local1     ! 7 (and 0xFC)
343         srl     out1, 24, local0          ! 8
344         and     out1, local5, local4      ! 4
345
346         ldub    [out2+local0], local0     ! 8 (and 0xFC)
347         srl     local4, 8, local4         ! 4
348         xor     $1, local2, $1            ! 2 finished local2 now sbox 6
349
350         ld      [global4+local4],local4   ! 4
351         srl     out1, 16, local2          ! 6
352         xor     $1, local3, $1            ! 3 finished local3 now sbox 5
353
354         ld      [out3+local0],local0      ! 8
355         and     local2, 252, local2       ! 6
356         add     global1, 1536, local5     ! address sbox 7
357
358         ld      [local6+local2], local2   ! 6
359         srl     out0, 16, local3          ! 5
360         xor     $1, local4, $1            ! 4 finished
361
362         ld      [local5+local1],local1    ! 7
363         and     local3, 252, local3       ! 5
364         xor     $1, local0, $1            ! 8 finished
365
366         ld      [global5+local3],local3   ! 5
367         xor     $1, local2, $1            ! 6 finished
368         subcc   out4, 1, out4
369
370         ld      [$5+$3*8+4], out0         ! key 8642 next round
371         xor     $1, local7, local2        ! sbox 5 next round
372         xor     $1, local1, $1            ! 7 finished
373
374         srl     local2, 16, local2        ! sbox 5 next round
375         xor     $1, local3, $1            ! 5 finished
376
377         ld      [$5+$3*16+4], out1        ! key 8642 next round again
378         and     local2, 252, local2       ! sbox5 next round
379 ! next round
380         xor     $1, local7, local7        ! 7531
381
382         ld      [global5+local2], local2  ! 5
383         srl     local7, 24, local3        ! 7
384         xor     $1, out0, out0            ! 8642
385
386         ldub    [out2+local3], local3     ! 7 (and 0xFC)
387         srl     out0, 4, local0           ! rotate 4 right
388         and     local7, 252, local1       ! 1
389
390         sll     out0, 28, out0            ! rotate
391         xor     $2, local2, $2            ! 5 finished local2 used
392
393         srl     local0, 8, local4         ! 4
394         and     local0, 252, local2       ! 2
395         ld      [local5+local3], local3   ! 7
396
397         srl     local0, 16, local5        ! 6
398         or      out0, local0, out0        ! rotate
399         ld      [global2+local2], local2  ! 2
400
401         srl     out0, 24, local0
402         ld      [$5+$3*16], out0          ! key 7531 next round
403         and     local4, 252, local4       ! 4
404
405         and     local5, 252, local5       ! 6
406         ld      [global4+local4], local4  ! 4
407         xor     $2, local3, $2            ! 7 finished local3 used
408
409         and     local0, 252, local0       ! 8
410         ld      [local6+local5], local5   ! 6
411         xor     $2, local2, $2            ! 2 finished local2 now sbox 3
412
413         srl     local7, 8, local2         ! 3 start
414         ld      [out3+local0], local0     ! 8
415         xor     $2, local4, $2            ! 4 finished
416
417         and     local2, 252, local2       ! 3
418         ld      [global1+local1], local1  ! 1
419         xor     $2, local5, $2            ! 6 finished local5 used
420
421         ld      [global3+local2], local2  ! 3
422         xor     $2, local0, $2            ! 8 finished
423         add     $5, $3*16, $5             ! enc add 8, dec add -8 to key pointer
424
425         ld      [out2+284], local5        ! 0x0000FC00
426         xor     $2, out0, local4          ! sbox 1 next round
427         xor     $2, local1, $2            ! 1 finished
428
429         xor     $2, local2, $2            ! 3 finished
430 #ifdef OPENSSL_SYSNAME_ULTRASPARC
431         bne,pt  %icc, $4
432 #else
433         bne     $4
434 #endif
435         and     local4, 252, local1       ! sbox 1 next round
436
437 ! two rounds more:
438
439         ld      [global1+local1], local1
440         xor     $2, out1, out1
441         xor     $2, out0, out0
442
443         srl     out1, 4, local0           ! rotate
444         and     out0, local5, local3
445
446         ld      [$5+$3*8], local7         ! key 7531
447         srl     local3, 8, local3
448         and     local0, 252, local2
449
450         ld      [global3+local3],local3
451         sll     out1, 28, out1            ! rotate
452         xor     $1, local1, $1            ! 1 finished, local1 now sbox 7
453
454         ld      [global2+local2], local2
455         srl     out0, 24, local1
456         or      out1, local0, out1        ! rotate
457
458         ldub    [out2+local1], local1
459         srl     out1, 24, local0
460         and     out1, local5, local4
461
462         ldub    [out2+local0], local0
463         srl     local4, 8, local4
464         xor     $1, local2, $1            ! 2 finished local2 now sbox 6
465
466         ld      [global4+local4],local4
467         srl     out1, 16, local2
468         xor     $1, local3, $1            ! 3 finished local3 now sbox 5
469
470         ld      [out3+local0],local0
471         and     local2, 252, local2
472         add     global1, 1536, local5     ! address sbox 7
473
474         ld      [local6+local2], local2
475         srl     out0, 16, local3
476         xor     $1, local4, $1            ! 4 finished
477
478         ld      [local5+local1],local1
479         and     local3, 252, local3
480         xor     $1, local0, $1
481
482         ld      [global5+local3],local3
483         xor     $1, local2, $1            ! 6 finished
484         cmp     in2, 8
485
486         ifelse($6,{}, {}, {ld   [out2+280], out4})  ! loop counter
487         xor     $1, local7, local2        ! sbox 5 next round
488         xor     $1, local1, $1            ! 7 finished
489
490         ld      [$5+$3*8+4], out0
491         srl     local2, 16, local2        ! sbox 5 next round
492         xor     $1, local3, $1            ! 5 finished
493
494         and     local2, 252, local2
495 ! next round (two rounds more)
496         xor     $1, local7, local7        ! 7531
497
498         ld      [global5+local2], local2
499         srl     local7, 24, local3
500         xor     $1, out0, out0            ! 8642
501
502         ldub    [out2+local3], local3
503         srl     out0, 4, local0           ! rotate
504         and     local7, 252, local1
505
506         sll     out0, 28, out0            ! rotate
507         xor     $2, local2, $2            ! 5 finished local2 used
508
509         srl     local0, 8, local4
510         and     local0, 252, local2
511         ld      [local5+local3], local3
512
513         srl     local0, 16, local5
514         or      out0, local0, out0        ! rotate
515         ld      [global2+local2], local2
516
517         srl     out0, 24, local0
518         ifelse($6,{}, {}, {ld   [$6], out0})   ! key next encryption/decryption
519         and     local4, 252, local4
520
521         and     local5, 252, local5
522         ld      [global4+local4], local4
523         xor     $2, local3, $2            ! 7 finished local3 used
524
525         and     local0, 252, local0
526         ld      [local6+local5], local5
527         xor     $2, local2, $2            ! 2 finished local2 now sbox 3
528
529         srl     local7, 8, local2         ! 3 start
530         ld      [out3+local0], local0
531         xor     $2, local4, $2
532
533         and     local2, 252, local2
534         ld      [global1+local1], local1
535         xor     $2, local5, $2            ! 6 finished local5 used
536
537         ld      [global3+local2], local2
538         srl     $1, 3, local3
539         xor     $2, local0, $2
540
541         ifelse($6,{}, {}, {ld   [$6+4], out1}) ! key next encryption/decryption
542         sll     $1, 29, local4
543         xor     $2, local1, $2
544
545         ifelse($7,{}, {}, {retl})
546         xor     $2, local2, $2
547 })
548
549
550 ! {fp_macro}
551 !
552 !  parameter 1   right (original left)
553 !  parameter 2   left (original right)
554 !  parameter 3   1 for optional store to [in0]
555 !  parameter 4   1 for load input/output address to local5/7
556 !
557 !  The final permutation logic switches the halfes, meaning that
558 !  left and right ends up the the registers originally used.
559
560 define(fp_macro, {
561
562 ! {fp_macro}
563 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
564
565         ! initially undo the rotate 3 left done after initial permutation
566         ! original left is received shifted 3 right and 29 left in local3/4
567
568         sll     $2, 29, local1
569         or      local3, local4, $1
570
571         srl     $2, 3, $2
572         sethi   %hi(0x55555555), local2
573
574         or      $2, local1, $2
575         or      local2, %lo(0x55555555), local2
576
577         srl     $2, 1, local3
578         sethi   %hi(0x00ff00ff), local1
579         xor     local3, $1, local3
580         or      local1, %lo(0x00ff00ff), local1
581         and     local3, local2, local3
582         sethi   %hi(0x33333333), local4
583         sll     local3, 1, local2
584
585         xor     $1, local3, $1
586
587         srl     $1, 8, local3
588         xor     $2, local2, $2
589         xor     local3, $2, local3
590         or      local4, %lo(0x33333333), local4
591         and     local3, local1, local3
592         sethi   %hi(0x0000ffff), local1
593         sll     local3, 8, local2
594
595         xor     $2, local3, $2
596
597         srl     $2, 2, local3
598         xor     $1, local2, $1
599         xor     local3, $1, local3
600         or      local1, %lo(0x0000ffff), local1
601         and     local3, local4, local3
602         sethi   %hi(0x0f0f0f0f), local4
603         sll     local3, 2, local2
604
605         ifelse($4,1, {LDPTR INPUT, local5})
606         xor     $1, local3, $1
607
608         ifelse($4,1, {LDPTR OUTPUT, local7})
609         srl     $1, 16, local3
610         xor     $2, local2, $2
611         xor     local3, $2, local3
612         or      local4, %lo(0x0f0f0f0f), local4
613         and     local3, local1, local3
614         sll     local3, 16, local2
615
616         xor     $2, local3, local1
617
618         srl     local1, 4, local3
619         xor     $1, local2, $1
620         xor     local3, $1, local3
621         and     local3, local4, local3
622         sll     local3, 4, local2
623
624         xor     $1, local3, $1
625
626         ! optional store:
627
628         ifelse($3,1, {st $1, [in0]})
629
630         xor     local1, local2, $2
631
632         ifelse($3,1, {st $2, [in0+4]})
633
634 })
635
636
637 ! {fp_ip_macro}
638 !
639 ! Does initial permutation for next block mixed with
640 ! final permutation for current block.
641 !
642 ! parameter 1   original left
643 ! parameter 2   original right
644 ! parameter 3   left ip
645 ! parameter 4   right ip
646 ! parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
647 !                2: mov in4 to in3
648 !
649 ! also adds -8 to length in2 and loads loop counter to out4
650
651 define(fp_ip_macro, {
652
653 ! {fp_ip_macro}
654 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
655
656         define({temp1},{out4})
657         define({temp2},{local3})
658
659         define({ip1},{local1})
660         define({ip2},{local2})
661         define({ip4},{local4})
662         define({ip5},{local5})
663
664         ! $1 in local3, local4
665
666         ld      [out2+256], ip1
667         sll     out5, 29, temp1
668         or      local3, local4, $1
669
670         srl     out5, 3, $2
671         ifelse($5,2,{mov in4, in3})
672
673         ld      [out2+272], ip5
674         srl     $4, 4, local0
675         or      $2, temp1, $2
676
677         srl     $2, 1, temp1
678         xor     temp1, $1, temp1
679
680         and     temp1, ip5, temp1
681         xor     local0, $3, local0
682
683         sll     temp1, 1, temp2
684         xor     $1, temp1, $1
685
686         and     local0, ip1, local0
687         add     in2, -8, in2
688
689         sll     local0, 4, local7
690         xor     $3, local0, $3
691
692         ld      [out2+268], ip4
693         srl     $1, 8, temp1
694         xor     $2, temp2, $2
695         ld      [out2+260], ip2
696         srl     $3, 16, local0
697         xor     $4, local7, $4
698         xor     temp1, $2, temp1
699         xor     local0, $4, local0
700         and     temp1, ip4, temp1
701         and     local0, ip2, local0
702         sll     temp1, 8, temp2
703         xor     $2, temp1, $2
704         sll     local0, 16, local7
705         xor     $4, local0, $4
706
707         srl     $2, 2, temp1
708         xor     $1, temp2, $1
709
710         ld      [out2+264], temp2         ! ip3
711         srl     $4, 2, local0
712         xor     $3, local7, $3
713         xor     temp1, $1, temp1
714         xor     local0, $3, local0
715         and     temp1, temp2, temp1
716         and     local0, temp2, local0
717         sll     temp1, 2, temp2
718         xor     $1, temp1, $1
719         sll     local0, 2, local7
720         xor     $3, local0, $3
721
722         srl     $1, 16, temp1
723         xor     $2, temp2, $2
724         srl     $3, 8, local0
725         xor     $4, local7, $4
726         xor     temp1, $2, temp1
727         xor     local0, $4, local0
728         and     temp1, ip2, temp1
729         and     local0, ip4, local0
730         sll     temp1, 16, temp2
731         xor     $2, temp1, local4
732         sll     local0, 8, local7
733         xor     $4, local0, $4
734
735         srl     $4, 1, local0
736         xor     $3, local7, $3
737
738         srl     local4, 4, temp1
739         xor     local0, $3, local0
740
741         xor     $1, temp2, $1
742         and     local0, ip5, local0
743
744         sll     local0, 1, local7
745         xor     temp1, $1, temp1
746
747         xor     $3, local0, $3
748         xor     $4, local7, $4
749
750         sll     $3, 3, local5
751         and     temp1, ip1, temp1
752
753         sll     temp1, 4, temp2
754         xor     $1, temp1, $1
755
756         ifelse($5,1,{LDPTR      KS2, in4})
757         sll     $4, 3, local2
758         xor     local4, temp2, $2
759
760         ! reload since used as temporar:
761
762         ld      [out2+280], out4          ! loop counter
763
764         srl     $3, 29, local0
765         ifelse($5,1,{add in4, 120, in4})
766
767         ifelse($5,1,{LDPTR      KS1, in3})
768         srl     $4, 29, local7
769
770         or      local0, local5, $4
771         or      local2, local7, $3
772
773 })
774
775
776
777 ! {load_little_endian}
778 !
779 ! parameter 1  address
780 ! parameter 2  destination left
781 ! parameter 3  destination right
782 ! parameter 4  temporar
783 ! parameter 5  label
784
785 define(load_little_endian, {
786
787 ! {load_little_endian}
788 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
789
790         ! first in memory to rightmost in register
791
792 #ifdef OPENSSL_SYSNAME_ULTRASPARC
793         andcc   $1, 3, global0
794         bne,pn  %icc, $5
795         nop
796
797         lda     [$1] 0x88, $2
798         add     $1, 4, $4
799
800         ba,pt   %icc, $5a
801         lda     [$4] 0x88, $3
802 #endif
803
804 $5:
805         ldub    [$1+3], $2
806
807         ldub    [$1+2], $4
808         sll     $2, 8, $2
809         or      $2, $4, $2
810
811         ldub    [$1+1], $4
812         sll     $2, 8, $2
813         or      $2, $4, $2
814
815         ldub    [$1+0], $4
816         sll     $2, 8, $2
817         or      $2, $4, $2
818
819
820         ldub    [$1+3+4], $3
821
822         ldub    [$1+2+4], $4
823         sll     $3, 8, $3
824         or      $3, $4, $3
825
826         ldub    [$1+1+4], $4
827         sll     $3, 8, $3
828         or      $3, $4, $3
829
830         ldub    [$1+0+4], $4
831         sll     $3, 8, $3
832         or      $3, $4, $3
833 $5a:
834
835 })
836
837
838 ! {load_little_endian_inc}
839 !
840 ! parameter 1  address
841 ! parameter 2  destination left
842 ! parameter 3  destination right
843 ! parameter 4  temporar
844 ! parameter 4  label
845 !
846 ! adds 8 to address
847
848 define(load_little_endian_inc, {
849
850 ! {load_little_endian_inc}
851 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
852
853         ! first in memory to rightmost in register
854
855 #ifdef OPENSSL_SYSNAME_ULTRASPARC
856         andcc   $1, 3, global0
857         bne,pn  %icc, $5
858         nop
859
860         lda     [$1] 0x88, $2
861         add     $1, 4, $1
862
863         lda     [$1] 0x88, $3
864         ba,pt   %icc, $5a
865         add     $1, 4, $1
866 #endif
867
868 $5:
869         ldub    [$1+3], $2
870
871         ldub    [$1+2], $4
872         sll     $2, 8, $2
873         or      $2, $4, $2
874
875         ldub    [$1+1], $4
876         sll     $2, 8, $2
877         or      $2, $4, $2
878
879         ldub    [$1+0], $4
880         sll     $2, 8, $2
881         or      $2, $4, $2
882
883         ldub    [$1+3+4], $3
884         add     $1, 8, $1
885
886         ldub    [$1+2+4-8], $4
887         sll     $3, 8, $3
888         or      $3, $4, $3
889
890         ldub    [$1+1+4-8], $4
891         sll     $3, 8, $3
892         or      $3, $4, $3
893
894         ldub    [$1+0+4-8], $4
895         sll     $3, 8, $3
896         or      $3, $4, $3
897 $5a:
898
899 })
900
901
902 ! {load_n_bytes}
903 !
904 ! Loads 1 to 7 bytes little endian
905 ! Remaining bytes are zeroed.
906 !
907 ! parameter 1  address
908 ! parameter 2  length
909 ! parameter 3  destination register left
910 ! parameter 4  destination register right
911 ! parameter 5  temp
912 ! parameter 6  temp2
913 ! parameter 7  label
914 ! parameter 8  return label
915
916 define(load_n_bytes, {
917
918 ! {load_n_bytes}
919 ! $1 $2 $5 $6 $7 $8 $7 $8 $9
920
921 $7.0:   call    .+8
922         sll     $2, 2, $6
923
924         add     %o7,$7.jmp.table-$7.0,$5
925
926         add     $5, $6, $5
927         mov     0, $4
928
929         ld      [$5], $5
930
931         jmp     %o7+$5
932         mov     0, $3
933
934 $7.7:
935         ldub    [$1+6], $5
936         sll     $5, 16, $5
937         or      $3, $5, $3
938 $7.6:
939         ldub    [$1+5], $5
940         sll     $5, 8, $5
941         or      $3, $5, $3
942 $7.5:
943         ldub    [$1+4], $5
944         or      $3, $5, $3
945 $7.4:
946         ldub    [$1+3], $5
947         sll     $5, 24, $5
948         or      $4, $5, $4
949 $7.3:
950         ldub    [$1+2], $5
951         sll     $5, 16, $5
952         or      $4, $5, $4
953 $7.2:
954         ldub    [$1+1], $5
955         sll     $5, 8, $5
956         or      $4, $5, $4
957 $7.1:
958         ldub    [$1+0], $5
959         ba      $8
960         or      $4, $5, $4
961
962         .align 4
963
964 $7.jmp.table:
965         .word   0
966         .word   $7.1-$7.0
967         .word   $7.2-$7.0
968         .word   $7.3-$7.0
969         .word   $7.4-$7.0
970         .word   $7.5-$7.0
971         .word   $7.6-$7.0
972         .word   $7.7-$7.0
973 })
974
975
976 ! {store_little_endian}
977 !
978 ! parameter 1  address
979 ! parameter 2  source left
980 ! parameter 3  source right
981 ! parameter 4  temporar
982
983 define(store_little_endian, {
984
985 ! {store_little_endian}
986 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
987
988         ! rightmost in register to first in memory
989
990 #ifdef OPENSSL_SYSNAME_ULTRASPARC
991         andcc   $1, 3, global0
992         bne,pn  %icc, $5
993         nop
994
995         sta     $2, [$1] 0x88
996         add     $1, 4, $4
997
998         ba,pt   %icc, $5a
999         sta     $3, [$4] 0x88
1000 #endif
1001
1002 $5:
1003         and     $2, 255, $4
1004         stub    $4, [$1+0]
1005
1006         srl     $2, 8, $4
1007         and     $4, 255, $4
1008         stub    $4, [$1+1]
1009
1010         srl     $2, 16, $4
1011         and     $4, 255, $4
1012         stub    $4, [$1+2]
1013
1014         srl     $2, 24, $4
1015         stub    $4, [$1+3]
1016
1017
1018         and     $3, 255, $4
1019         stub    $4, [$1+0+4]
1020
1021         srl     $3, 8, $4
1022         and     $4, 255, $4
1023         stub    $4, [$1+1+4]
1024
1025         srl     $3, 16, $4
1026         and     $4, 255, $4
1027         stub    $4, [$1+2+4]
1028
1029         srl     $3, 24, $4
1030         stub    $4, [$1+3+4]
1031
1032 $5a:
1033
1034 })
1035
1036
1037 ! {store_n_bytes}
1038 !
1039 ! Stores 1 to 7 bytes little endian
1040 !
1041 ! parameter 1  address
1042 ! parameter 2  length
1043 ! parameter 3  source register left
1044 ! parameter 4  source register right
1045 ! parameter 5  temp
1046 ! parameter 6  temp2
1047 ! parameter 7  label
1048 ! parameter 8  return label
1049
1050 define(store_n_bytes, {
1051
1052 ! {store_n_bytes}
1053 ! $1 $2 $5 $6 $7 $8 $7 $8 $9
1054
1055 $7.0:   call    .+8
1056         sll     $2, 2, $6
1057
1058         add     %o7,$7.jmp.table-$7.0,$5
1059
1060         add     $5, $6, $5
1061
1062         ld      [$5], $5
1063
1064         jmp     %o7+$5
1065         nop
1066
1067 $7.7:
1068         srl     $3, 16, $5
1069         and     $5, 0xff, $5
1070         stub    $5, [$1+6]
1071 $7.6:
1072         srl     $3, 8, $5
1073         and     $5, 0xff, $5
1074         stub    $5, [$1+5]
1075 $7.5:
1076         and     $3, 0xff, $5
1077         stub    $5, [$1+4]
1078 $7.4:
1079         srl     $4, 24, $5
1080         stub    $5, [$1+3]
1081 $7.3:
1082         srl     $4, 16, $5
1083         and     $5, 0xff, $5
1084         stub    $5, [$1+2]
1085 $7.2:
1086         srl     $4, 8, $5
1087         and     $5, 0xff, $5
1088         stub    $5, [$1+1]
1089 $7.1:
1090         and     $4, 0xff, $5
1091
1092
1093         ba      $8
1094         stub    $5, [$1]
1095
1096         .align 4
1097
1098 $7.jmp.table:
1099
1100         .word   0
1101         .word   $7.1-$7.0
1102         .word   $7.2-$7.0
1103         .word   $7.3-$7.0
1104         .word   $7.4-$7.0
1105         .word   $7.5-$7.0
1106         .word   $7.6-$7.0
1107         .word   $7.7-$7.0
1108 })
1109
1110
1111 define(testvalue,{1})
1112
1113 define(register_init, {
1114
1115 ! For test purposes:
1116
1117         sethi   %hi(testvalue), local0
1118         or      local0, %lo(testvalue), local0
1119
1120         ifelse($1,{},{}, {mov   local0, $1})
1121         ifelse($2,{},{}, {mov   local0, $2})
1122         ifelse($3,{},{}, {mov   local0, $3})
1123         ifelse($4,{},{}, {mov   local0, $4})
1124         ifelse($5,{},{}, {mov   local0, $5})
1125         ifelse($6,{},{}, {mov   local0, $6})
1126         ifelse($7,{},{}, {mov   local0, $7})
1127         ifelse($8,{},{}, {mov   local0, $8})
1128
1129         mov     local0, local1
1130         mov     local0, local2
1131         mov     local0, local3
1132         mov     local0, local4
1133         mov     local0, local5
1134         mov     local0, local7
1135         mov     local0, local6
1136         mov     local0, out0
1137         mov     local0, out1
1138         mov     local0, out2
1139         mov     local0, out3
1140         mov     local0, out4
1141         mov     local0, out5
1142         mov     local0, global1
1143         mov     local0, global2
1144         mov     local0, global3
1145         mov     local0, global4
1146         mov     local0, global5
1147
1148 })
1149
1150 .section        ".text"
1151
1152         .align 32
1153
1154 .des_enc:
1155
1156         ! key address in3
1157         ! loads key next encryption/decryption first round from [in4]
1158
1159         rounds_macro(in5, out5, 1, .des_enc.1, in3, in4, retl)
1160
1161
1162         .align 32
1163
1164 .des_dec:
1165
1166         ! implemented with out5 as first parameter to avoid
1167         ! register exchange in ede modes
1168
1169         ! key address in4
1170         ! loads key next encryption/decryption first round from [in3]
1171
1172         rounds_macro(out5, in5, -1, .des_dec.1, in4, in3, retl)
1173
1174
1175
1176 ! void DES_encrypt1(data, ks, enc)
1177 ! *******************************
1178
1179         .align 32
1180         .global DES_encrypt1
1181         .type    DES_encrypt1,#function
1182
1183 DES_encrypt1:
1184
1185         save    %sp, FRAME, %sp
1186
1187         sethi   %hi(.PIC.DES_SPtrans-1f),global1
1188         or      global1,%lo(.PIC.DES_SPtrans-1f),global1
1189 1:      call    .+8
1190         add     %o7,global1,global1
1191         sub     global1,.PIC.DES_SPtrans-.des_and,out2
1192
1193         ld      [in0], in5                ! left
1194         cmp     in2, 0                    ! enc
1195
1196 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1197         be,pn   %icc, .encrypt.dec        ! enc/dec
1198 #else
1199         be      .encrypt.dec
1200 #endif
1201         ld      [in0+4], out5             ! right
1202
1203         ! parameter 6  1/2 for include encryption/decryption
1204         ! parameter 7  1 for move in1 to in3
1205         ! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
1206
1207         ip_macro(in5, out5, in5, out5, in3, 0, 1, 1)
1208
1209         rounds_macro(in5, out5, 1, .des_encrypt1.1, in3, in4) ! in4 not used
1210
1211         fp_macro(in5, out5, 1)            ! 1 for store to [in0]
1212
1213         ret
1214         restore
1215
1216 .encrypt.dec:
1217
1218         add     in1, 120, in3             ! use last subkey for first round
1219
1220         ! parameter 6  1/2 for include encryption/decryption
1221         ! parameter 7  1 for move in1 to in3
1222         ! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
1223
1224         ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include dec,  ks in4
1225
1226         fp_macro(out5, in5, 1)            ! 1 for store to [in0]
1227
1228         ret
1229         restore
1230
1231 .DES_encrypt1.end:
1232         .size    DES_encrypt1,.DES_encrypt1.end-DES_encrypt1
1233
1234
1235 ! void DES_encrypt2(data, ks, enc)
1236 !*********************************
1237
1238         ! encrypts/decrypts without initial/final permutation
1239
1240         .align 32
1241         .global DES_encrypt2
1242         .type    DES_encrypt2,#function
1243
1244 DES_encrypt2:
1245
1246         save    %sp, FRAME, %sp
1247
1248         sethi   %hi(.PIC.DES_SPtrans-1f),global1
1249         or      global1,%lo(.PIC.DES_SPtrans-1f),global1
1250 1:      call    .+8
1251         add     %o7,global1,global1
1252         sub     global1,.PIC.DES_SPtrans-.des_and,out2
1253
1254         ! Set sbox address 1 to 6 and rotate halfs 3 left
1255         ! Errors caught by destest? Yes. Still? *NO*
1256
1257         !sethi  %hi(DES_SPtrans), global1 ! address sbox 1
1258
1259         !or     global1, %lo(DES_SPtrans), global1  ! sbox 1
1260
1261         add     global1, 256, global2     ! sbox 2
1262         add     global1, 512, global3     ! sbox 3
1263
1264         ld      [in0], out5               ! right
1265         add     global1, 768, global4     ! sbox 4
1266         add     global1, 1024, global5    ! sbox 5
1267
1268         ld      [in0+4], in5              ! left
1269         add     global1, 1280, local6     ! sbox 6
1270         add     global1, 1792, out3       ! sbox 8
1271
1272         ! rotate
1273
1274         sll     in5, 3, local5
1275         mov     in1, in3                  ! key address to in3
1276
1277         sll     out5, 3, local7
1278         srl     in5, 29, in5
1279
1280         srl     out5, 29, out5
1281         add     in5, local5, in5
1282
1283         add     out5, local7, out5
1284         cmp     in2, 0
1285
1286         ! we use our own stackframe
1287
1288 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1289         be,pn   %icc, .encrypt2.dec       ! decryption
1290 #else
1291         be      .encrypt2.dec
1292 #endif
1293         STPTR   in0, [%sp+BIAS+ARG0+0*ARGSZ]
1294
1295         ld      [in3], out0               ! key 7531 first round
1296         mov     LOOPS, out4               ! loop counter
1297
1298         ld      [in3+4], out1             ! key 8642 first round
1299         sethi   %hi(0x0000FC00), local5
1300
1301         call .des_enc
1302         mov     in3, in4
1303
1304         ! rotate
1305         sll     in5, 29, in0
1306         srl     in5, 3, in5
1307         sll     out5, 29, in1
1308         add     in5, in0, in5
1309         srl     out5, 3, out5
1310         LDPTR   [%sp+BIAS+ARG0+0*ARGSZ], in0
1311         add     out5, in1, out5
1312         st      in5, [in0]
1313         st      out5, [in0+4]
1314
1315         ret
1316         restore
1317
1318
1319 .encrypt2.dec:
1320
1321         add in3, 120, in4
1322
1323         ld      [in4], out0               ! key 7531 first round
1324         mov     LOOPS, out4               ! loop counter
1325
1326         ld      [in4+4], out1             ! key 8642 first round
1327         sethi   %hi(0x0000FC00), local5
1328
1329         mov     in5, local1               ! left expected in out5
1330         mov     out5, in5
1331
1332         call .des_dec
1333         mov     local1, out5
1334
1335 .encrypt2.finish:
1336
1337         ! rotate
1338         sll     in5, 29, in0
1339         srl     in5, 3, in5
1340         sll     out5, 29, in1
1341         add     in5, in0, in5
1342         srl     out5, 3, out5
1343         LDPTR   [%sp+BIAS+ARG0+0*ARGSZ], in0
1344         add     out5, in1, out5
1345         st      out5, [in0]
1346         st      in5, [in0+4]
1347
1348         ret
1349         restore
1350
1351 .DES_encrypt2.end:
1352         .size    DES_encrypt2, .DES_encrypt2.end-DES_encrypt2
1353
1354
1355 ! void DES_encrypt3(data, ks1, ks2, ks3)
1356 ! **************************************
1357
1358         .align 32
1359         .global DES_encrypt3
1360         .type    DES_encrypt3,#function
1361
1362 DES_encrypt3:
1363
1364         save    %sp, FRAME, %sp
1365         
1366         sethi   %hi(.PIC.DES_SPtrans-1f),global1
1367         or      global1,%lo(.PIC.DES_SPtrans-1f),global1
1368 1:      call    .+8
1369         add     %o7,global1,global1
1370         sub     global1,.PIC.DES_SPtrans-.des_and,out2
1371
1372         ld      [in0], in5                ! left
1373         add     in2, 120, in4             ! ks2
1374
1375         ld      [in0+4], out5             ! right
1376         mov     in3, in2                  ! save ks3
1377
1378         ! parameter 6  1/2 for include encryption/decryption
1379         ! parameter 7  1 for mov in1 to in3
1380         ! parameter 8  1 for mov in3 to in4
1381         ! parameter 9  1 for load ks3 and ks2 to in4 and in3
1382
1383         ip_macro(in5, out5, in5, out5, in3, 1, 1, 0, 0)
1384
1385         call    .des_dec
1386         mov     in2, in3                  ! preload ks3
1387
1388         call    .des_enc
1389         nop
1390
1391         fp_macro(in5, out5, 1)
1392
1393         ret
1394         restore
1395
1396 .DES_encrypt3.end:
1397         .size    DES_encrypt3,.DES_encrypt3.end-DES_encrypt3
1398
1399
1400 ! void DES_decrypt3(data, ks1, ks2, ks3)
1401 ! **************************************
1402
1403         .align 32
1404         .global DES_decrypt3
1405         .type    DES_decrypt3,#function
1406
1407 DES_decrypt3:
1408
1409         save    %sp, FRAME, %sp
1410         
1411         sethi   %hi(.PIC.DES_SPtrans-1f),global1
1412         or      global1,%lo(.PIC.DES_SPtrans-1f),global1
1413 1:      call    .+8
1414         add     %o7,global1,global1
1415         sub     global1,.PIC.DES_SPtrans-.des_and,out2
1416
1417         ld      [in0], in5                ! left
1418         add     in3, 120, in4             ! ks3
1419
1420         ld      [in0+4], out5             ! right
1421         mov     in2, in3                  ! ks2
1422
1423         ! parameter 6  1/2 for include encryption/decryption
1424         ! parameter 7  1 for mov in1 to in3
1425         ! parameter 8  1 for mov in3 to in4
1426         ! parameter 9  1 for load ks3 and ks2 to in4 and in3
1427
1428         ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 0)
1429
1430         call    .des_enc
1431         add     in1, 120, in4             ! preload ks1
1432
1433         call    .des_dec
1434         nop
1435
1436         fp_macro(out5, in5, 1)
1437
1438         ret
1439         restore
1440
1441 .DES_decrypt3.end:
1442         .size    DES_decrypt3,.DES_decrypt3.end-DES_decrypt3
1443
1444 ! void DES_ncbc_encrypt(input, output, length, schedule, ivec, enc)
1445 ! *****************************************************************
1446
1447
1448         .align 32
1449         .global DES_ncbc_encrypt
1450         .type    DES_ncbc_encrypt,#function
1451
1452 DES_ncbc_encrypt:
1453
1454         save    %sp, FRAME, %sp
1455         
1456         define({INPUT},  { [%sp+BIAS+ARG0+0*ARGSZ] })
1457         define({OUTPUT}, { [%sp+BIAS+ARG0+1*ARGSZ] })
1458         define({IVEC},   { [%sp+BIAS+ARG0+4*ARGSZ] })
1459
1460         sethi   %hi(.PIC.DES_SPtrans-1f),global1
1461         or      global1,%lo(.PIC.DES_SPtrans-1f),global1
1462 1:      call    .+8
1463         add     %o7,global1,global1
1464         sub     global1,.PIC.DES_SPtrans-.des_and,out2
1465
1466         cmp     in5, 0                    ! enc   
1467
1468 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1469         be,pn   %icc, .ncbc.dec
1470 #else
1471         be      .ncbc.dec
1472 #endif
1473         STPTR   in4, IVEC
1474
1475         ! addr  left  right  temp  label
1476         load_little_endian(in4, in5, out5, local3, .LLE1)  ! iv
1477
1478         addcc   in2, -8, in2              ! bytes missing when first block done
1479
1480 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1481         bl,pn   %icc, .ncbc.enc.seven.or.less
1482 #else
1483         bl      .ncbc.enc.seven.or.less
1484 #endif
1485         mov     in3, in4                  ! schedule
1486
1487 .ncbc.enc.next.block:
1488
1489         load_little_endian(in0, out4, global4, local3, .LLE2)  ! block
1490
1491 .ncbc.enc.next.block_1:
1492
1493         xor     in5, out4, in5            ! iv xor
1494         xor     out5, global4, out5       ! iv xor
1495
1496         ! parameter 8  1 for move in3 to in4, 2 for move in4 to in3
1497         ip_macro(in5, out5, in5, out5, in3, 0, 0, 2)
1498
1499 .ncbc.enc.next.block_2:
1500
1501 !//     call .des_enc                     ! compares in2 to 8
1502 !       rounds inlined for alignment purposes
1503
1504         add     global1, 768, global4     ! address sbox 4 since register used below
1505
1506         rounds_macro(in5, out5, 1, .ncbc.enc.1, in3, in4) ! include encryption  ks in3
1507
1508 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1509         bl,pn   %icc, .ncbc.enc.next.block_fp
1510 #else
1511         bl      .ncbc.enc.next.block_fp
1512 #endif
1513         add     in0, 8, in0               ! input address
1514
1515         ! If 8 or more bytes are to be encrypted after this block,
1516         ! we combine final permutation for this block with initial
1517         ! permutation for next block. Load next block:
1518
1519         load_little_endian(in0, global3, global4, local5, .LLE12)
1520
1521         !  parameter 1   original left
1522         !  parameter 2   original right
1523         !  parameter 3   left ip
1524         !  parameter 4   right ip
1525         !  parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
1526         !                2: mov in4 to in3
1527         !
1528         ! also adds -8 to length in2 and loads loop counter to out4
1529
1530         fp_ip_macro(out0, out1, global3, global4, 2)
1531
1532         store_little_endian(in1, out0, out1, local3, .SLE10)  ! block
1533
1534         ld      [in3], out0               ! key 7531 first round next block
1535         mov     in5, local1
1536         xor     global3, out5, in5        ! iv xor next block
1537
1538         ld      [in3+4], out1             ! key 8642
1539         add     global1, 512, global3     ! address sbox 3 since register used
1540         xor     global4, local1, out5     ! iv xor next block
1541
1542         ba      .ncbc.enc.next.block_2
1543         add     in1, 8, in1               ! output adress
1544
1545 .ncbc.enc.next.block_fp:
1546
1547         fp_macro(in5, out5)
1548
1549         store_little_endian(in1, in5, out5, local3, .SLE1)  ! block
1550
1551         addcc   in2, -8, in2              ! bytes missing when next block done
1552
1553 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1554         bpos,pt %icc, .ncbc.enc.next.block  ! also jumps if 0
1555 #else
1556         bpos    .ncbc.enc.next.block
1557 #endif
1558         add     in1, 8, in1
1559
1560 .ncbc.enc.seven.or.less:
1561
1562         cmp     in2, -8
1563
1564 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1565         ble,pt  %icc, .ncbc.enc.finish
1566 #else
1567         ble     .ncbc.enc.finish
1568 #endif
1569         nop
1570
1571         add     in2, 8, local1            ! bytes to load
1572
1573         ! addr, length, dest left, dest right, temp, temp2, label, ret label
1574         load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB1, .ncbc.enc.next.block_1)
1575
1576         ! Loads 1 to 7 bytes little endian to global4, out4
1577
1578
1579 .ncbc.enc.finish:
1580
1581         LDPTR   IVEC, local4
1582         store_little_endian(local4, in5, out5, local5, .SLE2)  ! ivec
1583
1584         ret
1585         restore
1586
1587
1588 .ncbc.dec:
1589
1590         STPTR   in0, INPUT
1591         cmp     in2, 0                    ! length
1592         add     in3, 120, in3
1593
1594         LDPTR   IVEC, local7              ! ivec
1595 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1596         ble,pn  %icc, .ncbc.dec.finish
1597 #else
1598         ble     .ncbc.dec.finish
1599 #endif
1600         mov     in3, in4                  ! schedule
1601
1602         STPTR   in1, OUTPUT
1603         mov     in0, local5               ! input
1604
1605         load_little_endian(local7, in0, in1, local3, .LLE3)   ! ivec
1606
1607 .ncbc.dec.next.block:
1608
1609         load_little_endian(local5, in5, out5, local3, .LLE4)  ! block
1610
1611         ! parameter 6  1/2 for include encryption/decryption
1612         ! parameter 7  1 for mov in1 to in3
1613         ! parameter 8  1 for mov in3 to in4
1614
1615         ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include decryprion  ks in4
1616
1617         fp_macro(out5, in5, 0, 1) ! 1 for input and output address to local5/7
1618
1619         ! in2 is bytes left to be stored
1620         ! in2 is compared to 8 in the rounds
1621
1622         xor     out5, in0, out4           ! iv xor
1623 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1624         bl,pn   %icc, .ncbc.dec.seven.or.less
1625 #else
1626         bl      .ncbc.dec.seven.or.less
1627 #endif
1628         xor     in5, in1, global4         ! iv xor
1629
1630         ! Load ivec next block now, since input and output address might be the same.
1631
1632         load_little_endian_inc(local5, in0, in1, local3, .LLE5)  ! iv
1633
1634         store_little_endian(local7, out4, global4, local3, .SLE3)
1635
1636         STPTR   local5, INPUT
1637         add     local7, 8, local7
1638         addcc   in2, -8, in2
1639
1640 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1641         bg,pt   %icc, .ncbc.dec.next.block
1642 #else
1643         bg      .ncbc.dec.next.block
1644 #endif
1645         STPTR   local7, OUTPUT
1646
1647
1648 .ncbc.dec.store.iv:
1649
1650         LDPTR   IVEC, local4              ! ivec
1651         store_little_endian(local4, in0, in1, local5, .SLE4)
1652
1653 .ncbc.dec.finish:
1654
1655         ret
1656         restore
1657
1658 .ncbc.dec.seven.or.less:
1659
1660         load_little_endian_inc(local5, in0, in1, local3, .LLE13)     ! ivec
1661
1662         store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB1, .ncbc.dec.store.iv)
1663
1664
1665 .DES_ncbc_encrypt.end:
1666         .size    DES_ncbc_encrypt, .DES_ncbc_encrypt.end-DES_ncbc_encrypt
1667
1668
1669 ! void DES_ede3_cbc_encrypt(input, output, lenght, ks1, ks2, ks3, ivec, enc)
1670 ! **************************************************************************
1671
1672
1673         .align 32
1674         .global DES_ede3_cbc_encrypt
1675         .type    DES_ede3_cbc_encrypt,#function
1676
1677 DES_ede3_cbc_encrypt:
1678
1679         save    %sp, FRAME, %sp
1680
1681         define({KS1}, { [%sp+BIAS+ARG0+3*ARGSZ] })
1682         define({KS2}, { [%sp+BIAS+ARG0+4*ARGSZ] })
1683         define({KS3}, { [%sp+BIAS+ARG0+5*ARGSZ] })
1684
1685         sethi   %hi(.PIC.DES_SPtrans-1f),global1
1686         or      global1,%lo(.PIC.DES_SPtrans-1f),global1
1687 1:      call    .+8
1688         add     %o7,global1,global1
1689         sub     global1,.PIC.DES_SPtrans-.des_and,out2
1690
1691         LDPTR   [%fp+BIAS+ARG0+7*ARGSZ], local3          ! enc
1692         LDPTR   [%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
1693         cmp     local3, 0                 ! enc
1694
1695 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1696         be,pn   %icc, .ede3.dec
1697 #else
1698         be      .ede3.dec
1699 #endif
1700         STPTR   in4, KS2
1701
1702         STPTR   in5, KS3
1703
1704         load_little_endian(local4, in5, out5, local3, .LLE6)  ! ivec
1705
1706         addcc   in2, -8, in2              ! bytes missing after next block
1707
1708 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1709         bl,pn   %icc,  .ede3.enc.seven.or.less
1710 #else
1711         bl      .ede3.enc.seven.or.less
1712 #endif
1713         STPTR   in3, KS1
1714
1715 .ede3.enc.next.block:
1716
1717         load_little_endian(in0, out4, global4, local3, .LLE7)
1718
1719 .ede3.enc.next.block_1:
1720
1721         LDPTR   KS2, in4
1722         xor     in5, out4, in5            ! iv xor
1723         xor     out5, global4, out5       ! iv xor
1724
1725         LDPTR   KS1, in3
1726         add     in4, 120, in4             ! for decryption we use last subkey first
1727         nop
1728
1729         ip_macro(in5, out5, in5, out5, in3)
1730
1731 .ede3.enc.next.block_2:
1732
1733         call .des_enc                     ! ks1 in3
1734         nop
1735
1736         call .des_dec                     ! ks2 in4
1737         LDPTR   KS3, in3
1738
1739         call .des_enc                     ! ks3 in3  compares in2 to 8
1740         nop
1741
1742 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1743         bl,pn   %icc, .ede3.enc.next.block_fp
1744 #else
1745         bl      .ede3.enc.next.block_fp
1746 #endif
1747         add     in0, 8, in0
1748
1749         ! If 8 or more bytes are to be encrypted after this block,
1750         ! we combine final permutation for this block with initial
1751         ! permutation for next block. Load next block:
1752
1753         load_little_endian(in0, global3, global4, local5, .LLE11)
1754
1755         !  parameter 1   original left
1756         !  parameter 2   original right
1757         !  parameter 3   left ip
1758         !  parameter 4   right ip
1759         !  parameter 5   1: load ks1/ks2 to in3/in4, add 120 to in4
1760         !                2: mov in4 to in3
1761         !
1762         ! also adds -8 to length in2 and loads loop counter to out4
1763
1764         fp_ip_macro(out0, out1, global3, global4, 1)
1765
1766         store_little_endian(in1, out0, out1, local3, .SLE9)  ! block
1767
1768         mov     in5, local1
1769         xor     global3, out5, in5        ! iv xor next block
1770
1771         ld      [in3], out0               ! key 7531
1772         add     global1, 512, global3     ! address sbox 3
1773         xor     global4, local1, out5     ! iv xor next block
1774
1775         ld      [in3+4], out1             ! key 8642
1776         add     global1, 768, global4     ! address sbox 4
1777         ba      .ede3.enc.next.block_2
1778         add     in1, 8, in1
1779
1780 .ede3.enc.next.block_fp:
1781
1782         fp_macro(in5, out5)
1783
1784         store_little_endian(in1, in5, out5, local3, .SLE5)  ! block
1785
1786         addcc   in2, -8, in2              ! bytes missing when next block done
1787
1788 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1789         bpos,pt %icc, .ede3.enc.next.block
1790 #else
1791         bpos    .ede3.enc.next.block
1792 #endif
1793         add     in1, 8, in1
1794
1795 .ede3.enc.seven.or.less:
1796
1797         cmp     in2, -8
1798
1799 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1800         ble,pt  %icc, .ede3.enc.finish
1801 #else
1802         ble     .ede3.enc.finish
1803 #endif
1804         nop
1805
1806         add     in2, 8, local1            ! bytes to load
1807
1808         ! addr, length, dest left, dest right, temp, temp2, label, ret label
1809         load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB2, .ede3.enc.next.block_1)
1810
1811 .ede3.enc.finish:
1812
1813         LDPTR   [%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
1814         store_little_endian(local4, in5, out5, local5, .SLE6)  ! ivec
1815
1816         ret
1817         restore
1818
1819 .ede3.dec:
1820
1821         STPTR   in0, INPUT
1822         add     in5, 120, in5
1823
1824         STPTR   in1, OUTPUT
1825         mov     in0, local5
1826         add     in3, 120, in3
1827
1828         STPTR   in3, KS1
1829         cmp     in2, 0
1830
1831 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1832         ble     %icc, .ede3.dec.finish
1833 #else
1834         ble     .ede3.dec.finish
1835 #endif
1836         STPTR   in5, KS3
1837
1838         LDPTR   [%fp+BIAS+ARG0+6*ARGSZ], local7          ! iv
1839         load_little_endian(local7, in0, in1, local3, .LLE8)
1840
1841 .ede3.dec.next.block:
1842
1843         load_little_endian(local5, in5, out5, local3, .LLE9)
1844
1845         ! parameter 6  1/2 for include encryption/decryption
1846         ! parameter 7  1 for mov in1 to in3
1847         ! parameter 8  1 for mov in3 to in4
1848         ! parameter 9  1 for load ks3 and ks2 to in4 and in3
1849
1850         ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 1) ! inc .des_dec ks3 in4
1851
1852         call .des_enc                     ! ks2 in3
1853         LDPTR   KS1, in4
1854
1855         call .des_dec                     ! ks1 in4
1856         nop
1857
1858         fp_macro(out5, in5, 0, 1)   ! 1 for input and output address local5/7
1859
1860         ! in2 is bytes left to be stored
1861         ! in2 is compared to 8 in the rounds
1862
1863         xor     out5, in0, out4
1864 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1865         bl,pn   %icc, .ede3.dec.seven.or.less
1866 #else
1867         bl      .ede3.dec.seven.or.less
1868 #endif
1869         xor     in5, in1, global4
1870
1871         load_little_endian_inc(local5, in0, in1, local3, .LLE10)   ! iv next block
1872
1873         store_little_endian(local7, out4, global4, local3, .SLE7)  ! block
1874
1875         STPTR   local5, INPUT
1876         addcc   in2, -8, in2
1877         add     local7, 8, local7
1878
1879 #ifdef OPENSSL_SYSNAME_ULTRASPARC
1880         bg,pt   %icc, .ede3.dec.next.block
1881 #else
1882         bg      .ede3.dec.next.block
1883 #endif
1884         STPTR   local7, OUTPUT
1885
1886 .ede3.dec.store.iv:
1887
1888         LDPTR   [%fp+BIAS+ARG0+6*ARGSZ], local4          ! ivec
1889         store_little_endian(local4, in0, in1, local5, .SLE8)  ! ivec
1890
1891 .ede3.dec.finish:
1892
1893         ret
1894         restore
1895
1896 .ede3.dec.seven.or.less:
1897
1898         load_little_endian_inc(local5, in0, in1, local3, .LLE14)     ! iv
1899
1900         store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB2, .ede3.dec.store.iv)
1901
1902
1903 .DES_ede3_cbc_encrypt.end:
1904         .size    DES_ede3_cbc_encrypt,.DES_ede3_cbc_encrypt.end-DES_ede3_cbc_encrypt
1905
1906         .align  256
1907         .type    .des_and,#object
1908         .size    .des_and,284
1909
1910 .des_and:
1911
1912 ! This table is used for AND 0xFC when it is known that register
1913 ! bits 8-31 are zero. Makes it possible to do three arithmetic
1914 ! operations in one cycle.
1915
1916         .byte  0, 0, 0, 0, 4, 4, 4, 4
1917         .byte  8, 8, 8, 8, 12, 12, 12, 12
1918         .byte  16, 16, 16, 16, 20, 20, 20, 20
1919         .byte  24, 24, 24, 24, 28, 28, 28, 28
1920         .byte  32, 32, 32, 32, 36, 36, 36, 36
1921         .byte  40, 40, 40, 40, 44, 44, 44, 44
1922         .byte  48, 48, 48, 48, 52, 52, 52, 52
1923         .byte  56, 56, 56, 56, 60, 60, 60, 60
1924         .byte  64, 64, 64, 64, 68, 68, 68, 68
1925         .byte  72, 72, 72, 72, 76, 76, 76, 76
1926         .byte  80, 80, 80, 80, 84, 84, 84, 84
1927         .byte  88, 88, 88, 88, 92, 92, 92, 92
1928         .byte  96, 96, 96, 96, 100, 100, 100, 100
1929         .byte  104, 104, 104, 104, 108, 108, 108, 108
1930         .byte  112, 112, 112, 112, 116, 116, 116, 116
1931         .byte  120, 120, 120, 120, 124, 124, 124, 124
1932         .byte  128, 128, 128, 128, 132, 132, 132, 132
1933         .byte  136, 136, 136, 136, 140, 140, 140, 140
1934         .byte  144, 144, 144, 144, 148, 148, 148, 148
1935         .byte  152, 152, 152, 152, 156, 156, 156, 156
1936         .byte  160, 160, 160, 160, 164, 164, 164, 164
1937         .byte  168, 168, 168, 168, 172, 172, 172, 172
1938         .byte  176, 176, 176, 176, 180, 180, 180, 180
1939         .byte  184, 184, 184, 184, 188, 188, 188, 188
1940         .byte  192, 192, 192, 192, 196, 196, 196, 196
1941         .byte  200, 200, 200, 200, 204, 204, 204, 204
1942         .byte  208, 208, 208, 208, 212, 212, 212, 212
1943         .byte  216, 216, 216, 216, 220, 220, 220, 220
1944         .byte  224, 224, 224, 224, 228, 228, 228, 228
1945         .byte  232, 232, 232, 232, 236, 236, 236, 236
1946         .byte  240, 240, 240, 240, 244, 244, 244, 244
1947         .byte  248, 248, 248, 248, 252, 252, 252, 252
1948
1949         ! 5 numbers for initil/final permutation
1950
1951         .word   0x0f0f0f0f                ! offset 256
1952         .word   0x0000ffff                ! 260
1953         .word   0x33333333                ! 264
1954         .word   0x00ff00ff                ! 268
1955         .word   0x55555555                ! 272
1956
1957         .word   0                         ! 276
1958         .word   LOOPS                     ! 280
1959         .word   0x0000FC00                ! 284
1960
1961         .global DES_SPtrans
1962         .type   DES_SPtrans,#object
1963         .size   DES_SPtrans,2048
1964 .align  64
1965 DES_SPtrans:
1966 .PIC.DES_SPtrans:
1967         ! nibble 0
1968         .word   0x02080800, 0x00080000, 0x02000002, 0x02080802
1969         .word   0x02000000, 0x00080802, 0x00080002, 0x02000002
1970         .word   0x00080802, 0x02080800, 0x02080000, 0x00000802
1971         .word   0x02000802, 0x02000000, 0x00000000, 0x00080002
1972         .word   0x00080000, 0x00000002, 0x02000800, 0x00080800
1973         .word   0x02080802, 0x02080000, 0x00000802, 0x02000800
1974         .word   0x00000002, 0x00000800, 0x00080800, 0x02080002
1975         .word   0x00000800, 0x02000802, 0x02080002, 0x00000000
1976         .word   0x00000000, 0x02080802, 0x02000800, 0x00080002
1977         .word   0x02080800, 0x00080000, 0x00000802, 0x02000800
1978         .word   0x02080002, 0x00000800, 0x00080800, 0x02000002
1979         .word   0x00080802, 0x00000002, 0x02000002, 0x02080000
1980         .word   0x02080802, 0x00080800, 0x02080000, 0x02000802
1981         .word   0x02000000, 0x00000802, 0x00080002, 0x00000000
1982         .word   0x00080000, 0x02000000, 0x02000802, 0x02080800
1983         .word   0x00000002, 0x02080002, 0x00000800, 0x00080802
1984         ! nibble 1
1985         .word   0x40108010, 0x00000000, 0x00108000, 0x40100000
1986         .word   0x40000010, 0x00008010, 0x40008000, 0x00108000
1987         .word   0x00008000, 0x40100010, 0x00000010, 0x40008000
1988         .word   0x00100010, 0x40108000, 0x40100000, 0x00000010
1989         .word   0x00100000, 0x40008010, 0x40100010, 0x00008000
1990         .word   0x00108010, 0x40000000, 0x00000000, 0x00100010
1991         .word   0x40008010, 0x00108010, 0x40108000, 0x40000010
1992         .word   0x40000000, 0x00100000, 0x00008010, 0x40108010
1993         .word   0x00100010, 0x40108000, 0x40008000, 0x00108010
1994         .word   0x40108010, 0x00100010, 0x40000010, 0x00000000
1995         .word   0x40000000, 0x00008010, 0x00100000, 0x40100010
1996         .word   0x00008000, 0x40000000, 0x00108010, 0x40008010
1997         .word   0x40108000, 0x00008000, 0x00000000, 0x40000010
1998         .word   0x00000010, 0x40108010, 0x00108000, 0x40100000
1999         .word   0x40100010, 0x00100000, 0x00008010, 0x40008000
2000         .word   0x40008010, 0x00000010, 0x40100000, 0x00108000
2001         ! nibble 2
2002         .word   0x04000001, 0x04040100, 0x00000100, 0x04000101
2003         .word   0x00040001, 0x04000000, 0x04000101, 0x00040100
2004         .word   0x04000100, 0x00040000, 0x04040000, 0x00000001
2005         .word   0x04040101, 0x00000101, 0x00000001, 0x04040001
2006         .word   0x00000000, 0x00040001, 0x04040100, 0x00000100
2007         .word   0x00000101, 0x04040101, 0x00040000, 0x04000001
2008         .word   0x04040001, 0x04000100, 0x00040101, 0x04040000
2009         .word   0x00040100, 0x00000000, 0x04000000, 0x00040101
2010         .word   0x04040100, 0x00000100, 0x00000001, 0x00040000
2011         .word   0x00000101, 0x00040001, 0x04040000, 0x04000101
2012         .word   0x00000000, 0x04040100, 0x00040100, 0x04040001
2013         .word   0x00040001, 0x04000000, 0x04040101, 0x00000001
2014         .word   0x00040101, 0x04000001, 0x04000000, 0x04040101
2015         .word   0x00040000, 0x04000100, 0x04000101, 0x00040100
2016         .word   0x04000100, 0x00000000, 0x04040001, 0x00000101
2017         .word   0x04000001, 0x00040101, 0x00000100, 0x04040000
2018         ! nibble 3
2019         .word   0x00401008, 0x10001000, 0x00000008, 0x10401008
2020         .word   0x00000000, 0x10400000, 0x10001008, 0x00400008
2021         .word   0x10401000, 0x10000008, 0x10000000, 0x00001008
2022         .word   0x10000008, 0x00401008, 0x00400000, 0x10000000
2023         .word   0x10400008, 0x00401000, 0x00001000, 0x00000008
2024         .word   0x00401000, 0x10001008, 0x10400000, 0x00001000
2025         .word   0x00001008, 0x00000000, 0x00400008, 0x10401000
2026         .word   0x10001000, 0x10400008, 0x10401008, 0x00400000
2027         .word   0x10400008, 0x00001008, 0x00400000, 0x10000008
2028         .word   0x00401000, 0x10001000, 0x00000008, 0x10400000
2029         .word   0x10001008, 0x00000000, 0x00001000, 0x00400008
2030         .word   0x00000000, 0x10400008, 0x10401000, 0x00001000
2031         .word   0x10000000, 0x10401008, 0x00401008, 0x00400000
2032         .word   0x10401008, 0x00000008, 0x10001000, 0x00401008
2033         .word   0x00400008, 0x00401000, 0x10400000, 0x10001008
2034         .word   0x00001008, 0x10000000, 0x10000008, 0x10401000
2035         ! nibble 4
2036         .word   0x08000000, 0x00010000, 0x00000400, 0x08010420
2037         .word   0x08010020, 0x08000400, 0x00010420, 0x08010000
2038         .word   0x00010000, 0x00000020, 0x08000020, 0x00010400
2039         .word   0x08000420, 0x08010020, 0x08010400, 0x00000000
2040         .word   0x00010400, 0x08000000, 0x00010020, 0x00000420
2041         .word   0x08000400, 0x00010420, 0x00000000, 0x08000020
2042         .word   0x00000020, 0x08000420, 0x08010420, 0x00010020
2043         .word   0x08010000, 0x00000400, 0x00000420, 0x08010400
2044         .word   0x08010400, 0x08000420, 0x00010020, 0x08010000
2045         .word   0x00010000, 0x00000020, 0x08000020, 0x08000400
2046         .word   0x08000000, 0x00010400, 0x08010420, 0x00000000
2047         .word   0x00010420, 0x08000000, 0x00000400, 0x00010020
2048         .word   0x08000420, 0x00000400, 0x00000000, 0x08010420
2049         .word   0x08010020, 0x08010400, 0x00000420, 0x00010000
2050         .word   0x00010400, 0x08010020, 0x08000400, 0x00000420
2051         .word   0x00000020, 0x00010420, 0x08010000, 0x08000020
2052         ! nibble 5
2053         .word   0x80000040, 0x00200040, 0x00000000, 0x80202000
2054         .word   0x00200040, 0x00002000, 0x80002040, 0x00200000
2055         .word   0x00002040, 0x80202040, 0x00202000, 0x80000000
2056         .word   0x80002000, 0x80000040, 0x80200000, 0x00202040
2057         .word   0x00200000, 0x80002040, 0x80200040, 0x00000000
2058         .word   0x00002000, 0x00000040, 0x80202000, 0x80200040
2059         .word   0x80202040, 0x80200000, 0x80000000, 0x00002040
2060         .word   0x00000040, 0x00202000, 0x00202040, 0x80002000
2061         .word   0x00002040, 0x80000000, 0x80002000, 0x00202040
2062         .word   0x80202000, 0x00200040, 0x00000000, 0x80002000
2063         .word   0x80000000, 0x00002000, 0x80200040, 0x00200000
2064         .word   0x00200040, 0x80202040, 0x00202000, 0x00000040
2065         .word   0x80202040, 0x00202000, 0x00200000, 0x80002040
2066         .word   0x80000040, 0x80200000, 0x00202040, 0x00000000
2067         .word   0x00002000, 0x80000040, 0x80002040, 0x80202000
2068         .word   0x80200000, 0x00002040, 0x00000040, 0x80200040
2069         ! nibble 6
2070         .word   0x00004000, 0x00000200, 0x01000200, 0x01000004
2071         .word   0x01004204, 0x00004004, 0x00004200, 0x00000000
2072         .word   0x01000000, 0x01000204, 0x00000204, 0x01004000
2073         .word   0x00000004, 0x01004200, 0x01004000, 0x00000204
2074         .word   0x01000204, 0x00004000, 0x00004004, 0x01004204
2075         .word   0x00000000, 0x01000200, 0x01000004, 0x00004200
2076         .word   0x01004004, 0x00004204, 0x01004200, 0x00000004
2077         .word   0x00004204, 0x01004004, 0x00000200, 0x01000000
2078         .word   0x00004204, 0x01004000, 0x01004004, 0x00000204
2079         .word   0x00004000, 0x00000200, 0x01000000, 0x01004004
2080         .word   0x01000204, 0x00004204, 0x00004200, 0x00000000
2081         .word   0x00000200, 0x01000004, 0x00000004, 0x01000200
2082         .word   0x00000000, 0x01000204, 0x01000200, 0x00004200
2083         .word   0x00000204, 0x00004000, 0x01004204, 0x01000000
2084         .word   0x01004200, 0x00000004, 0x00004004, 0x01004204
2085         .word   0x01000004, 0x01004200, 0x01004000, 0x00004004
2086         ! nibble 7
2087         .word   0x20800080, 0x20820000, 0x00020080, 0x00000000
2088         .word   0x20020000, 0x00800080, 0x20800000, 0x20820080
2089         .word   0x00000080, 0x20000000, 0x00820000, 0x00020080
2090         .word   0x00820080, 0x20020080, 0x20000080, 0x20800000
2091         .word   0x00020000, 0x00820080, 0x00800080, 0x20020000
2092         .word   0x20820080, 0x20000080, 0x00000000, 0x00820000
2093         .word   0x20000000, 0x00800000, 0x20020080, 0x20800080
2094         .word   0x00800000, 0x00020000, 0x20820000, 0x00000080
2095         .word   0x00800000, 0x00020000, 0x20000080, 0x20820080
2096         .word   0x00020080, 0x20000000, 0x00000000, 0x00820000
2097         .word   0x20800080, 0x20020080, 0x20020000, 0x00800080
2098         .word   0x20820000, 0x00000080, 0x00800080, 0x20020000
2099         .word   0x20820080, 0x00800000, 0x20800000, 0x20000080
2100         .word   0x00820000, 0x00020080, 0x20020080, 0x20800000
2101         .word   0x00000080, 0x20820000, 0x00820080, 0x00000000
2102         .word   0x20000000, 0x20800080, 0x00020000, 0x00820080
2103