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