2 ! des_enc.S (generated from des_enc.m4)
4 ! UltraSPARC assembler version of the LibDES/SSLeay/OpenSSL des_enc.c file.
6 ! Version 1.0. 32-bit version.
10 ! Version 2.0. 32/64-bit, PIC-ification, blended CPU adaptation
15 ! Assembler version: Copyright Svend Olaf Mikkelsen.
17 ! Original C code: Copyright Eric A. Young.
19 ! This code can be freely used by LibDES/SSLeay/OpenSSL users.
21 ! The LibDES/SSLeay/OpenSSL copyright notices must be respected.
23 ! This version can be redistributed.
25 ! To expand the m4 macros: m4 -B 8192 des_enc.m4 > des_enc.S
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.
30 ! Instruction grouping often refers to one CPU cycle.
32 ! Assemble through gcc: gcc -c -mcpu=ultrasparc -o des_enc.o des_enc.S
34 ! Assemble through cc: cc -c -xarch=v8plusa -o des_enc.o des_enc.S
36 ! Performance improvement according to './apps/openssl speed des'
39 ! 23% faster than cc-5.2 -xarch=v8plus -xO5
40 ! 115% faster than gcc-3.2.1 -m32 -mcpu=ultrasparc -O5
42 ! 50% faster than cc-5.2 -xarch=v9 -xO5
43 ! 100% faster than gcc-3.2.1 -m64 -mcpu=ultrasparc -O5
46 .ident "des_enc.m4 2.1"
47 .file "des_enc-sparc.S"
49 #include <openssl/opensslconf.h>
51 #ifdef OPENSSL_FIPSCANISTER
52 #include <openssl/fipssyms.h>
55 #if defined(__SUNPRO_C) && defined(__sparcv9)
56 # define ABI64 /* They've said -xarch=v9 at command line */
57 #elif defined(__GNUC__) && defined(__arch64__)
58 # define ABI64 /* They've said -m64 at command line */
62 .register %g2,#scratch
63 .register %g3,#scratch
125 ! The logic used in initial and final permutations is the same as in
126 ! the C code. The permutations are done with a clever shift, xor, and
129 ! The macro also loads address sbox 1 to 5 to global 1 to 5, address
130 ! sbox 6 to local6, and addres sbox 8 to out3.
132 ! Rotates the halfs 3 left to bring the sbox bits in convenient positions.
134 ! Loads key first round from address in parameter 5 to out0, out1.
136 ! After the the original LibDES initial permutation, the resulting left
137 ! is in the variable initially used for right and vice versa. The macro
138 ! implements the possibility to keep the halfs in the original registers.
142 ! parameter 3 result left (modify in first round)
143 ! parameter 4 result right (use in first round)
144 ! parameter 5 key address
145 ! parameter 6 1/2 for include encryption/decryption
146 ! parameter 7 1 for move in1 to in3
147 ! parameter 8 1 for move in3 to in4, 2 for move in4 to in3
148 ! parameter 9 1 for load ks3 and ks2 to in4 and in3
153 ! $1 $2 $4 $3 $5 $6 $7 $8 $9
155 ld [out2+256], local1
158 xor local4, $1, local4
159 ifelse($7,1,{mov in1, in3},{nop})
161 ld [out2+260], local2
162 and local4, local1, local4
163 ifelse($8,1,{mov in3, in4},{})
164 ifelse($8,2,{mov in4, in3},{})
166 ld [out2+280], out4 ! loop counter
167 sll local4, 4, local1
170 ld [out2+264], local3
174 ifelse($9,1,{LDPTR KS3, in4},{})
175 xor local4, $2, local4
176 nop !sethi %hi(DES_SPtrans), global1 ! sbox addr
178 ifelse($9,1,{LDPTR KS2, in3},{})
179 and local4, local2, local4
180 nop !or global1, %lo(DES_SPtrans), global1 ! sbox addr
182 sll local4, 16, local1
188 sethi %hi(16711680), local5
189 xor local4, $1, local4
191 and local4, local3, local4
192 or local5, 255, local5
194 sll local4, 2, local2
200 xor local4, $2, local4
201 add global1, 768, global4
203 and local4, local5, local4
204 add global1, 1024, global5
206 ld [out2+272], local7
207 sll local4, 8, local1
213 ld [$5], out0 ! key 7531
214 xor local4, $1, local4
215 add global1, 256, global2
217 ld [$5+4], out1 ! key 8642
218 and local4, local7, local4
219 add global1, 512, global3
221 sll local4, 1, local1
228 add global1, 1280, local6 ! address sbox 8
231 add global1, 1792, out3 ! address sbox 8
234 or local4, local3, $4
236 or local2, local1, $3
240 ld [out2+284], local5 ! 0x0000FC00 used in the rounds
241 or local2, local1, $3
245 and local1, 252, local1
251 ld [out2+284], local5 ! 0x0000FC00 used in the rounds
252 or local2, local1, $3
256 and local1, 252, local1
264 ! The logic used in the DES rounds is the same as in the C code,
265 ! except that calculations for sbox 1 and sbox 5 begin before
266 ! the previous round is finished.
268 ! In each round one half (work) is modified based on key and the
271 ! In this version we do two rounds in a loop repeated 7 times
272 ! and two rounds separately.
274 ! One half has the bits for the sboxes in the following positions:
276 ! 777777xx555555xx333333xx111111xx
278 ! 88xx666666xx444444xx222222xx8888
280 ! The bits for each sbox are xor-ed with the key bits for that box.
281 ! The above xx bits are cleared, and the result used for lookup in
282 ! the sbox table. Each sbox entry contains the 4 output bits permuted
283 ! into 32 bits according to the P permutation.
285 ! In the description of DES, left and right are switched after
286 ! each round, except after last round. In this code the original
287 ! left and right are kept in the same register in all rounds, meaning
288 ! that after the 16 rounds the result for right is in the register
289 ! originally used for left.
291 ! parameter 1 first work (left in first round)
292 ! parameter 2 first use (right in first round)
293 ! parameter 3 enc/dec 1/-1
294 ! parameter 4 loop label
295 ! parameter 5 key address register
296 ! parameter 6 optional address for key next encryption/decryption
297 ! parameter 7 not empty for include retl
299 ! also compares in2 to 8
301 define(rounds_macro, {
304 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
308 ld [out2+284], local5 ! 0x0000FC00
310 and local1, 252, local1
315 ! local6 is address sbox 6
316 ! out3 is address sbox 8
317 ! out4 is loop counter
319 ld [global1+local1], local1
320 xor $2, out1, out1 ! 8642
321 xor $2, out0, out0 ! 7531
322 ! fmovs %f0, %f0 ! fxor used for alignment
324 srl out1, 4, local0 ! rotate 4 right
325 and out0, local5, local3 ! 3
328 ld [$5+$3*8], local7 ! key 7531 next round
329 srl local3, 8, local3 ! 3
330 and local0, 252, local2 ! 2
333 ld [global3+local3],local3 ! 3
334 sll out1, 28, out1 ! rotate
335 xor $1, local1, $1 ! 1 finished, local1 now sbox 7
337 ld [global2+local2], local2 ! 2
338 srl out0, 24, local1 ! 7
339 or out1, local0, out1 ! rotate
341 ldub [out2+local1], local1 ! 7 (and 0xFC)
342 srl out1, 24, local0 ! 8
343 and out1, local5, local4 ! 4
345 ldub [out2+local0], local0 ! 8 (and 0xFC)
346 srl local4, 8, local4 ! 4
347 xor $1, local2, $1 ! 2 finished local2 now sbox 6
349 ld [global4+local4],local4 ! 4
350 srl out1, 16, local2 ! 6
351 xor $1, local3, $1 ! 3 finished local3 now sbox 5
353 ld [out3+local0],local0 ! 8
354 and local2, 252, local2 ! 6
355 add global1, 1536, local5 ! address sbox 7
357 ld [local6+local2], local2 ! 6
358 srl out0, 16, local3 ! 5
359 xor $1, local4, $1 ! 4 finished
361 ld [local5+local1],local1 ! 7
362 and local3, 252, local3 ! 5
363 xor $1, local0, $1 ! 8 finished
365 ld [global5+local3],local3 ! 5
366 xor $1, local2, $1 ! 6 finished
369 ld [$5+$3*8+4], out0 ! key 8642 next round
370 xor $1, local7, local2 ! sbox 5 next round
371 xor $1, local1, $1 ! 7 finished
373 srl local2, 16, local2 ! sbox 5 next round
374 xor $1, local3, $1 ! 5 finished
376 ld [$5+$3*16+4], out1 ! key 8642 next round again
377 and local2, 252, local2 ! sbox5 next round
379 xor $1, local7, local7 ! 7531
381 ld [global5+local2], local2 ! 5
382 srl local7, 24, local3 ! 7
383 xor $1, out0, out0 ! 8642
385 ldub [out2+local3], local3 ! 7 (and 0xFC)
386 srl out0, 4, local0 ! rotate 4 right
387 and local7, 252, local1 ! 1
389 sll out0, 28, out0 ! rotate
390 xor $2, local2, $2 ! 5 finished local2 used
392 srl local0, 8, local4 ! 4
393 and local0, 252, local2 ! 2
394 ld [local5+local3], local3 ! 7
396 srl local0, 16, local5 ! 6
397 or out0, local0, out0 ! rotate
398 ld [global2+local2], local2 ! 2
401 ld [$5+$3*16], out0 ! key 7531 next round
402 and local4, 252, local4 ! 4
404 and local5, 252, local5 ! 6
405 ld [global4+local4], local4 ! 4
406 xor $2, local3, $2 ! 7 finished local3 used
408 and local0, 252, local0 ! 8
409 ld [local6+local5], local5 ! 6
410 xor $2, local2, $2 ! 2 finished local2 now sbox 3
412 srl local7, 8, local2 ! 3 start
413 ld [out3+local0], local0 ! 8
414 xor $2, local4, $2 ! 4 finished
416 and local2, 252, local2 ! 3
417 ld [global1+local1], local1 ! 1
418 xor $2, local5, $2 ! 6 finished local5 used
420 ld [global3+local2], local2 ! 3
421 xor $2, local0, $2 ! 8 finished
422 add $5, $3*16, $5 ! enc add 8, dec add -8 to key pointer
424 ld [out2+284], local5 ! 0x0000FC00
425 xor $2, out0, local4 ! sbox 1 next round
426 xor $2, local1, $2 ! 1 finished
428 xor $2, local2, $2 ! 3 finished
430 and local4, 252, local1 ! sbox 1 next round
434 ld [global1+local1], local1
438 srl out1, 4, local0 ! rotate
439 and out0, local5, local3
441 ld [$5+$3*8], local7 ! key 7531
442 srl local3, 8, local3
443 and local0, 252, local2
445 ld [global3+local3],local3
446 sll out1, 28, out1 ! rotate
447 xor $1, local1, $1 ! 1 finished, local1 now sbox 7
449 ld [global2+local2], local2
451 or out1, local0, out1 ! rotate
453 ldub [out2+local1], local1
455 and out1, local5, local4
457 ldub [out2+local0], local0
458 srl local4, 8, local4
459 xor $1, local2, $1 ! 2 finished local2 now sbox 6
461 ld [global4+local4],local4
463 xor $1, local3, $1 ! 3 finished local3 now sbox 5
465 ld [out3+local0],local0
466 and local2, 252, local2
467 add global1, 1536, local5 ! address sbox 7
469 ld [local6+local2], local2
471 xor $1, local4, $1 ! 4 finished
473 ld [local5+local1],local1
474 and local3, 252, local3
477 ld [global5+local3],local3
478 xor $1, local2, $1 ! 6 finished
481 ifelse($6,{}, {}, {ld [out2+280], out4}) ! loop counter
482 xor $1, local7, local2 ! sbox 5 next round
483 xor $1, local1, $1 ! 7 finished
486 srl local2, 16, local2 ! sbox 5 next round
487 xor $1, local3, $1 ! 5 finished
489 and local2, 252, local2
490 ! next round (two rounds more)
491 xor $1, local7, local7 ! 7531
493 ld [global5+local2], local2
494 srl local7, 24, local3
495 xor $1, out0, out0 ! 8642
497 ldub [out2+local3], local3
498 srl out0, 4, local0 ! rotate
499 and local7, 252, local1
501 sll out0, 28, out0 ! rotate
502 xor $2, local2, $2 ! 5 finished local2 used
504 srl local0, 8, local4
505 and local0, 252, local2
506 ld [local5+local3], local3
508 srl local0, 16, local5
509 or out0, local0, out0 ! rotate
510 ld [global2+local2], local2
513 ifelse($6,{}, {}, {ld [$6], out0}) ! key next encryption/decryption
514 and local4, 252, local4
516 and local5, 252, local5
517 ld [global4+local4], local4
518 xor $2, local3, $2 ! 7 finished local3 used
520 and local0, 252, local0
521 ld [local6+local5], local5
522 xor $2, local2, $2 ! 2 finished local2 now sbox 3
524 srl local7, 8, local2 ! 3 start
525 ld [out3+local0], local0
528 and local2, 252, local2
529 ld [global1+local1], local1
530 xor $2, local5, $2 ! 6 finished local5 used
532 ld [global3+local2], local2
536 ifelse($6,{}, {}, {ld [$6+4], out1}) ! key next encryption/decryption
540 ifelse($7,{}, {}, {retl})
547 ! parameter 1 right (original left)
548 ! parameter 2 left (original right)
549 ! parameter 3 1 for optional store to [in0]
550 ! parameter 4 1 for load input/output address to local5/7
552 ! The final permutation logic switches the halfes, meaning that
553 ! left and right ends up the the registers originally used.
558 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
560 ! initially undo the rotate 3 left done after initial permutation
561 ! original left is received shifted 3 right and 29 left in local3/4
564 or local3, local4, $1
567 sethi %hi(0x55555555), local2
570 or local2, %lo(0x55555555), local2
573 sethi %hi(0x00ff00ff), local1
574 xor local3, $1, local3
575 or local1, %lo(0x00ff00ff), local1
576 and local3, local2, local3
577 sethi %hi(0x33333333), local4
578 sll local3, 1, local2
584 xor local3, $2, local3
585 or local4, %lo(0x33333333), local4
586 and local3, local1, local3
587 sethi %hi(0x0000ffff), local1
588 sll local3, 8, local2
594 xor local3, $1, local3
595 or local1, %lo(0x0000ffff), local1
596 and local3, local4, local3
597 sethi %hi(0x0f0f0f0f), local4
598 sll local3, 2, local2
600 ifelse($4,1, {LDPTR INPUT, local5})
603 ifelse($4,1, {LDPTR OUTPUT, local7})
606 xor local3, $2, local3
607 or local4, %lo(0x0f0f0f0f), local4
608 and local3, local1, local3
609 sll local3, 16, local2
611 xor $2, local3, local1
613 srl local1, 4, local3
615 xor local3, $1, local3
616 and local3, local4, local3
617 sll local3, 4, local2
623 ifelse($3,1, {st $1, [in0]})
625 xor local1, local2, $2
627 ifelse($3,1, {st $2, [in0+4]})
634 ! Does initial permutation for next block mixed with
635 ! final permutation for current block.
637 ! parameter 1 original left
638 ! parameter 2 original right
639 ! parameter 3 left ip
640 ! parameter 4 right ip
641 ! parameter 5 1: load ks1/ks2 to in3/in4, add 120 to in4
644 ! also adds -8 to length in2 and loads loop counter to out4
646 define(fp_ip_macro, {
649 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
651 define({temp1},{out4})
652 define({temp2},{local3})
654 define({ip1},{local1})
655 define({ip2},{local2})
656 define({ip4},{local4})
657 define({ip5},{local5})
659 ! $1 in local3, local4
663 or local3, local4, $1
666 ifelse($5,2,{mov in4, in3})
675 and temp1, ip5, temp1
676 xor local0, $3, local0
681 and local0, ip1, local0
684 sll local0, 4, local7
694 xor local0, $4, local0
695 and temp1, ip4, temp1
696 and local0, ip2, local0
699 sll local0, 16, local7
705 ld [out2+264], temp2 ! ip3
709 xor local0, $3, local0
710 and temp1, temp2, temp1
711 and local0, temp2, local0
714 sll local0, 2, local7
722 xor local0, $4, local0
723 and temp1, ip2, temp1
724 and local0, ip4, local0
726 xor $2, temp1, local4
727 sll local0, 8, local7
734 xor local0, $3, local0
737 and local0, ip5, local0
739 sll local0, 1, local7
746 and temp1, ip1, temp1
751 ifelse($5,1,{LDPTR KS2, in4})
753 xor local4, temp2, $2
755 ! reload since used as temporar:
757 ld [out2+280], out4 ! loop counter
760 ifelse($5,1,{add in4, 120, in4})
762 ifelse($5,1,{LDPTR KS1, in3})
765 or local0, local5, $4
766 or local2, local7, $3
772 ! {load_little_endian}
774 ! parameter 1 address
775 ! parameter 2 destination left
776 ! parameter 3 destination right
777 ! parameter 4 temporar
780 define(load_little_endian, {
782 ! {load_little_endian}
783 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
785 ! first in memory to rightmost in register
821 ! {load_little_endian_inc}
823 ! parameter 1 address
824 ! parameter 2 destination left
825 ! parameter 3 destination right
826 ! parameter 4 temporar
831 define(load_little_endian_inc, {
833 ! {load_little_endian_inc}
834 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
836 ! first in memory to rightmost in register
874 ! Loads 1 to 7 bytes little endian
875 ! Remaining bytes are zeroed.
877 ! parameter 1 address
879 ! parameter 3 destination register left
880 ! parameter 4 destination register right
884 ! parameter 8 return label
886 define(load_n_bytes, {
889 ! $1 $2 $5 $6 $7 $8 $7 $8 $9
894 add %o7,$7.jmp.table-$7.0,$5
946 ! {store_little_endian}
948 ! parameter 1 address
949 ! parameter 2 source left
950 ! parameter 3 source right
951 ! parameter 4 temporar
953 define(store_little_endian, {
955 ! {store_little_endian}
956 ! $1 $2 $3 $4 $5 $6 $7 $8 $9
958 ! rightmost in register to first in memory
997 ! Stores 1 to 7 bytes little endian
999 ! parameter 1 address
1000 ! parameter 2 length
1001 ! parameter 3 source register left
1002 ! parameter 4 source register right
1006 ! parameter 8 return label
1008 define(store_n_bytes, {
1011 ! $1 $2 $5 $6 $7 $8 $7 $8 $9
1016 add %o7,$7.jmp.table-$7.0,$5
1069 define(testvalue,{1})
1071 define(register_init, {
1073 ! For test purposes:
1075 sethi %hi(testvalue), local0
1076 or local0, %lo(testvalue), local0
1078 ifelse($1,{},{}, {mov local0, $1})
1079 ifelse($2,{},{}, {mov local0, $2})
1080 ifelse($3,{},{}, {mov local0, $3})
1081 ifelse($4,{},{}, {mov local0, $4})
1082 ifelse($5,{},{}, {mov local0, $5})
1083 ifelse($6,{},{}, {mov local0, $6})
1084 ifelse($7,{},{}, {mov local0, $7})
1085 ifelse($8,{},{}, {mov local0, $8})
1115 ! loads key next encryption/decryption first round from [in4]
1117 rounds_macro(in5, out5, 1, .des_enc.1, in3, in4, retl)
1124 ! implemented with out5 as first parameter to avoid
1125 ! register exchange in ede modes
1128 ! loads key next encryption/decryption first round from [in3]
1130 rounds_macro(out5, in5, -1, .des_dec.1, in4, in3, retl)
1134 ! void DES_encrypt1(data, ks, enc)
1135 ! *******************************
1138 .global DES_encrypt1
1139 .type DES_encrypt1,#function
1143 save %sp, FRAME, %sp
1145 sethi %hi(.PIC.DES_SPtrans-1f),global1
1146 or global1,%lo(.PIC.DES_SPtrans-1f),global1
1148 add %o7,global1,global1
1149 sub global1,.PIC.DES_SPtrans-.des_and,out2
1151 ld [in0], in5 ! left
1155 ld [in0+4], out5 ! right
1157 ! parameter 6 1/2 for include encryption/decryption
1158 ! parameter 7 1 for move in1 to in3
1159 ! parameter 8 1 for move in3 to in4, 2 for move in4 to in3
1161 ip_macro(in5, out5, in5, out5, in3, 0, 1, 1)
1163 rounds_macro(in5, out5, 1, .des_encrypt1.1, in3, in4) ! in4 not used
1165 fp_macro(in5, out5, 1) ! 1 for store to [in0]
1172 add in1, 120, in3 ! use last subkey for first round
1174 ! parameter 6 1/2 for include encryption/decryption
1175 ! parameter 7 1 for move in1 to in3
1176 ! parameter 8 1 for move in3 to in4, 2 for move in4 to in3
1178 ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include dec, ks in4
1180 fp_macro(out5, in5, 1) ! 1 for store to [in0]
1186 .size DES_encrypt1,.DES_encrypt1.end-DES_encrypt1
1189 ! void DES_encrypt2(data, ks, enc)
1190 !*********************************
1192 ! encrypts/decrypts without initial/final permutation
1195 .global DES_encrypt2
1196 .type DES_encrypt2,#function
1200 save %sp, FRAME, %sp
1202 sethi %hi(.PIC.DES_SPtrans-1f),global1
1203 or global1,%lo(.PIC.DES_SPtrans-1f),global1
1205 add %o7,global1,global1
1206 sub global1,.PIC.DES_SPtrans-.des_and,out2
1208 ! Set sbox address 1 to 6 and rotate halfs 3 left
1209 ! Errors caught by destest? Yes. Still? *NO*
1211 !sethi %hi(DES_SPtrans), global1 ! address sbox 1
1213 !or global1, %lo(DES_SPtrans), global1 ! sbox 1
1215 add global1, 256, global2 ! sbox 2
1216 add global1, 512, global3 ! sbox 3
1218 ld [in0], out5 ! right
1219 add global1, 768, global4 ! sbox 4
1220 add global1, 1024, global5 ! sbox 5
1222 ld [in0+4], in5 ! left
1223 add global1, 1280, local6 ! sbox 6
1224 add global1, 1792, out3 ! sbox 8
1229 mov in1, in3 ! key address to in3
1235 add in5, local5, in5
1237 add out5, local7, out5
1240 ! we use our own stackframe
1243 STPTR in0, [%sp+BIAS+ARG0+0*ARGSZ]
1245 ld [in3], out0 ! key 7531 first round
1246 mov LOOPS, out4 ! loop counter
1248 ld [in3+4], out1 ! key 8642 first round
1249 sethi %hi(0x0000FC00), local5
1260 LDPTR [%sp+BIAS+ARG0+0*ARGSZ], in0
1273 ld [in4], out0 ! key 7531 first round
1274 mov LOOPS, out4 ! loop counter
1276 ld [in4+4], out1 ! key 8642 first round
1277 sethi %hi(0x0000FC00), local5
1279 mov in5, local1 ! left expected in out5
1293 LDPTR [%sp+BIAS+ARG0+0*ARGSZ], in0
1302 .size DES_encrypt2, .DES_encrypt2.end-DES_encrypt2
1305 ! void DES_encrypt3(data, ks1, ks2, ks3)
1306 ! **************************************
1309 .global DES_encrypt3
1310 .type DES_encrypt3,#function
1314 save %sp, FRAME, %sp
1316 sethi %hi(.PIC.DES_SPtrans-1f),global1
1317 or global1,%lo(.PIC.DES_SPtrans-1f),global1
1319 add %o7,global1,global1
1320 sub global1,.PIC.DES_SPtrans-.des_and,out2
1322 ld [in0], in5 ! left
1323 add in2, 120, in4 ! ks2
1325 ld [in0+4], out5 ! right
1326 mov in3, in2 ! save ks3
1328 ! parameter 6 1/2 for include encryption/decryption
1329 ! parameter 7 1 for mov in1 to in3
1330 ! parameter 8 1 for mov in3 to in4
1331 ! parameter 9 1 for load ks3 and ks2 to in4 and in3
1333 ip_macro(in5, out5, in5, out5, in3, 1, 1, 0, 0)
1336 mov in2, in3 ! preload ks3
1341 fp_macro(in5, out5, 1)
1347 .size DES_encrypt3,.DES_encrypt3.end-DES_encrypt3
1350 ! void DES_decrypt3(data, ks1, ks2, ks3)
1351 ! **************************************
1354 .global DES_decrypt3
1355 .type DES_decrypt3,#function
1359 save %sp, FRAME, %sp
1361 sethi %hi(.PIC.DES_SPtrans-1f),global1
1362 or global1,%lo(.PIC.DES_SPtrans-1f),global1
1364 add %o7,global1,global1
1365 sub global1,.PIC.DES_SPtrans-.des_and,out2
1367 ld [in0], in5 ! left
1368 add in3, 120, in4 ! ks3
1370 ld [in0+4], out5 ! right
1373 ! parameter 6 1/2 for include encryption/decryption
1374 ! parameter 7 1 for mov in1 to in3
1375 ! parameter 8 1 for mov in3 to in4
1376 ! parameter 9 1 for load ks3 and ks2 to in4 and in3
1378 ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 0)
1381 add in1, 120, in4 ! preload ks1
1386 fp_macro(out5, in5, 1)
1392 .size DES_decrypt3,.DES_decrypt3.end-DES_decrypt3
1394 ! void DES_ncbc_encrypt(input, output, length, schedule, ivec, enc)
1395 ! *****************************************************************
1399 .global DES_ncbc_encrypt
1400 .type DES_ncbc_encrypt,#function
1404 save %sp, FRAME, %sp
1406 define({INPUT}, { [%sp+BIAS+ARG0+0*ARGSZ] })
1407 define({OUTPUT}, { [%sp+BIAS+ARG0+1*ARGSZ] })
1408 define({IVEC}, { [%sp+BIAS+ARG0+4*ARGSZ] })
1410 sethi %hi(.PIC.DES_SPtrans-1f),global1
1411 or global1,%lo(.PIC.DES_SPtrans-1f),global1
1413 add %o7,global1,global1
1414 sub global1,.PIC.DES_SPtrans-.des_and,out2
1421 ! addr left right temp label
1422 load_little_endian(in4, in5, out5, local3, .LLE1) ! iv
1424 addcc in2, -8, in2 ! bytes missing when first block done
1426 bl .ncbc.enc.seven.or.less
1427 mov in3, in4 ! schedule
1429 .ncbc.enc.next.block:
1431 load_little_endian(in0, out4, global4, local3, .LLE2) ! block
1433 .ncbc.enc.next.block_1:
1435 xor in5, out4, in5 ! iv xor
1436 xor out5, global4, out5 ! iv xor
1438 ! parameter 8 1 for move in3 to in4, 2 for move in4 to in3
1439 ip_macro(in5, out5, in5, out5, in3, 0, 0, 2)
1441 .ncbc.enc.next.block_2:
1443 !// call .des_enc ! compares in2 to 8
1444 ! rounds inlined for alignment purposes
1446 add global1, 768, global4 ! address sbox 4 since register used below
1448 rounds_macro(in5, out5, 1, .ncbc.enc.1, in3, in4) ! include encryption ks in3
1450 bl .ncbc.enc.next.block_fp
1451 add in0, 8, in0 ! input address
1453 ! If 8 or more bytes are to be encrypted after this block,
1454 ! we combine final permutation for this block with initial
1455 ! permutation for next block. Load next block:
1457 load_little_endian(in0, global3, global4, local5, .LLE12)
1459 ! parameter 1 original left
1460 ! parameter 2 original right
1461 ! parameter 3 left ip
1462 ! parameter 4 right ip
1463 ! parameter 5 1: load ks1/ks2 to in3/in4, add 120 to in4
1466 ! also adds -8 to length in2 and loads loop counter to out4
1468 fp_ip_macro(out0, out1, global3, global4, 2)
1470 store_little_endian(in1, out0, out1, local3, .SLE10) ! block
1472 ld [in3], out0 ! key 7531 first round next block
1474 xor global3, out5, in5 ! iv xor next block
1476 ld [in3+4], out1 ! key 8642
1477 add global1, 512, global3 ! address sbox 3 since register used
1478 xor global4, local1, out5 ! iv xor next block
1480 ba .ncbc.enc.next.block_2
1481 add in1, 8, in1 ! output address
1483 .ncbc.enc.next.block_fp:
1487 store_little_endian(in1, in5, out5, local3, .SLE1) ! block
1489 addcc in2, -8, in2 ! bytes missing when next block done
1491 bpos .ncbc.enc.next.block
1494 .ncbc.enc.seven.or.less:
1498 ble .ncbc.enc.finish
1501 add in2, 8, local1 ! bytes to load
1503 ! addr, length, dest left, dest right, temp, temp2, label, ret label
1504 load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB1, .ncbc.enc.next.block_1)
1506 ! Loads 1 to 7 bytes little endian to global4, out4
1512 store_little_endian(local4, in5, out5, local5, .SLE2) ! ivec
1524 LDPTR IVEC, local7 ! ivec
1525 ble .ncbc.dec.finish
1526 mov in3, in4 ! schedule
1529 mov in0, local5 ! input
1531 load_little_endian(local7, in0, in1, local3, .LLE3) ! ivec
1533 .ncbc.dec.next.block:
1535 load_little_endian(local5, in5, out5, local3, .LLE4) ! block
1537 ! parameter 6 1/2 for include encryption/decryption
1538 ! parameter 7 1 for mov in1 to in3
1539 ! parameter 8 1 for mov in3 to in4
1541 ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include decryprion ks in4
1543 fp_macro(out5, in5, 0, 1) ! 1 for input and output address to local5/7
1545 ! in2 is bytes left to be stored
1546 ! in2 is compared to 8 in the rounds
1548 xor out5, in0, out4 ! iv xor
1549 bl .ncbc.dec.seven.or.less
1550 xor in5, in1, global4 ! iv xor
1552 ! Load ivec next block now, since input and output address might be the same.
1554 load_little_endian_inc(local5, in0, in1, local3, .LLE5) ! iv
1556 store_little_endian(local7, out4, global4, local3, .SLE3)
1559 add local7, 8, local7
1562 bg .ncbc.dec.next.block
1563 STPTR local7, OUTPUT
1568 LDPTR IVEC, local4 ! ivec
1569 store_little_endian(local4, in0, in1, local5, .SLE4)
1576 .ncbc.dec.seven.or.less:
1578 load_little_endian_inc(local5, in0, in1, local3, .LLE13) ! ivec
1580 store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB1, .ncbc.dec.store.iv)
1583 .DES_ncbc_encrypt.end:
1584 .size DES_ncbc_encrypt, .DES_ncbc_encrypt.end-DES_ncbc_encrypt
1587 ! void DES_ede3_cbc_encrypt(input, output, lenght, ks1, ks2, ks3, ivec, enc)
1588 ! **************************************************************************
1592 .global DES_ede3_cbc_encrypt
1593 .type DES_ede3_cbc_encrypt,#function
1595 DES_ede3_cbc_encrypt:
1597 save %sp, FRAME, %sp
1599 define({KS1}, { [%sp+BIAS+ARG0+3*ARGSZ] })
1600 define({KS2}, { [%sp+BIAS+ARG0+4*ARGSZ] })
1601 define({KS3}, { [%sp+BIAS+ARG0+5*ARGSZ] })
1603 sethi %hi(.PIC.DES_SPtrans-1f),global1
1604 or global1,%lo(.PIC.DES_SPtrans-1f),global1
1606 add %o7,global1,global1
1607 sub global1,.PIC.DES_SPtrans-.des_and,out2
1609 LDPTR [%fp+BIAS+ARG0+7*ARGSZ], local3 ! enc
1610 LDPTR [%fp+BIAS+ARG0+6*ARGSZ], local4 ! ivec
1617 load_little_endian(local4, in5, out5, local3, .LLE6) ! ivec
1619 addcc in2, -8, in2 ! bytes missing after next block
1621 bl .ede3.enc.seven.or.less
1624 .ede3.enc.next.block:
1626 load_little_endian(in0, out4, global4, local3, .LLE7)
1628 .ede3.enc.next.block_1:
1631 xor in5, out4, in5 ! iv xor
1632 xor out5, global4, out5 ! iv xor
1635 add in4, 120, in4 ! for decryption we use last subkey first
1638 ip_macro(in5, out5, in5, out5, in3)
1640 .ede3.enc.next.block_2:
1642 call .des_enc ! ks1 in3
1645 call .des_dec ! ks2 in4
1648 call .des_enc ! ks3 in3 compares in2 to 8
1651 bl .ede3.enc.next.block_fp
1654 ! If 8 or more bytes are to be encrypted after this block,
1655 ! we combine final permutation for this block with initial
1656 ! permutation for next block. Load next block:
1658 load_little_endian(in0, global3, global4, local5, .LLE11)
1660 ! parameter 1 original left
1661 ! parameter 2 original right
1662 ! parameter 3 left ip
1663 ! parameter 4 right ip
1664 ! parameter 5 1: load ks1/ks2 to in3/in4, add 120 to in4
1667 ! also adds -8 to length in2 and loads loop counter to out4
1669 fp_ip_macro(out0, out1, global3, global4, 1)
1671 store_little_endian(in1, out0, out1, local3, .SLE9) ! block
1674 xor global3, out5, in5 ! iv xor next block
1676 ld [in3], out0 ! key 7531
1677 add global1, 512, global3 ! address sbox 3
1678 xor global4, local1, out5 ! iv xor next block
1680 ld [in3+4], out1 ! key 8642
1681 add global1, 768, global4 ! address sbox 4
1682 ba .ede3.enc.next.block_2
1685 .ede3.enc.next.block_fp:
1689 store_little_endian(in1, in5, out5, local3, .SLE5) ! block
1691 addcc in2, -8, in2 ! bytes missing when next block done
1693 bpos .ede3.enc.next.block
1696 .ede3.enc.seven.or.less:
1700 ble .ede3.enc.finish
1703 add in2, 8, local1 ! bytes to load
1705 ! addr, length, dest left, dest right, temp, temp2, label, ret label
1706 load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB2, .ede3.enc.next.block_1)
1710 LDPTR [%fp+BIAS+ARG0+6*ARGSZ], local4 ! ivec
1711 store_little_endian(local4, in5, out5, local5, .SLE6) ! ivec
1728 ble .ede3.dec.finish
1731 LDPTR [%fp+BIAS+ARG0+6*ARGSZ], local7 ! iv
1732 load_little_endian(local7, in0, in1, local3, .LLE8)
1734 .ede3.dec.next.block:
1736 load_little_endian(local5, in5, out5, local3, .LLE9)
1738 ! parameter 6 1/2 for include encryption/decryption
1739 ! parameter 7 1 for mov in1 to in3
1740 ! parameter 8 1 for mov in3 to in4
1741 ! parameter 9 1 for load ks3 and ks2 to in4 and in3
1743 ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 1) ! inc .des_dec ks3 in4
1745 call .des_enc ! ks2 in3
1748 call .des_dec ! ks1 in4
1751 fp_macro(out5, in5, 0, 1) ! 1 for input and output address local5/7
1753 ! in2 is bytes left to be stored
1754 ! in2 is compared to 8 in the rounds
1757 bl .ede3.dec.seven.or.less
1758 xor in5, in1, global4
1760 load_little_endian_inc(local5, in0, in1, local3, .LLE10) ! iv next block
1762 store_little_endian(local7, out4, global4, local3, .SLE7) ! block
1766 add local7, 8, local7
1768 bg .ede3.dec.next.block
1769 STPTR local7, OUTPUT
1773 LDPTR [%fp+BIAS+ARG0+6*ARGSZ], local4 ! ivec
1774 store_little_endian(local4, in0, in1, local5, .SLE8) ! ivec
1781 .ede3.dec.seven.or.less:
1783 load_little_endian_inc(local5, in0, in1, local3, .LLE14) ! iv
1785 store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB2, .ede3.dec.store.iv)
1788 .DES_ede3_cbc_encrypt.end:
1789 .size DES_ede3_cbc_encrypt,.DES_ede3_cbc_encrypt.end-DES_ede3_cbc_encrypt
1792 .type .des_and,#object
1797 ! This table is used for AND 0xFC when it is known that register
1798 ! bits 8-31 are zero. Makes it possible to do three arithmetic
1799 ! operations in one cycle.
1801 .byte 0, 0, 0, 0, 4, 4, 4, 4
1802 .byte 8, 8, 8, 8, 12, 12, 12, 12
1803 .byte 16, 16, 16, 16, 20, 20, 20, 20
1804 .byte 24, 24, 24, 24, 28, 28, 28, 28
1805 .byte 32, 32, 32, 32, 36, 36, 36, 36
1806 .byte 40, 40, 40, 40, 44, 44, 44, 44
1807 .byte 48, 48, 48, 48, 52, 52, 52, 52
1808 .byte 56, 56, 56, 56, 60, 60, 60, 60
1809 .byte 64, 64, 64, 64, 68, 68, 68, 68
1810 .byte 72, 72, 72, 72, 76, 76, 76, 76
1811 .byte 80, 80, 80, 80, 84, 84, 84, 84
1812 .byte 88, 88, 88, 88, 92, 92, 92, 92
1813 .byte 96, 96, 96, 96, 100, 100, 100, 100
1814 .byte 104, 104, 104, 104, 108, 108, 108, 108
1815 .byte 112, 112, 112, 112, 116, 116, 116, 116
1816 .byte 120, 120, 120, 120, 124, 124, 124, 124
1817 .byte 128, 128, 128, 128, 132, 132, 132, 132
1818 .byte 136, 136, 136, 136, 140, 140, 140, 140
1819 .byte 144, 144, 144, 144, 148, 148, 148, 148
1820 .byte 152, 152, 152, 152, 156, 156, 156, 156
1821 .byte 160, 160, 160, 160, 164, 164, 164, 164
1822 .byte 168, 168, 168, 168, 172, 172, 172, 172
1823 .byte 176, 176, 176, 176, 180, 180, 180, 180
1824 .byte 184, 184, 184, 184, 188, 188, 188, 188
1825 .byte 192, 192, 192, 192, 196, 196, 196, 196
1826 .byte 200, 200, 200, 200, 204, 204, 204, 204
1827 .byte 208, 208, 208, 208, 212, 212, 212, 212
1828 .byte 216, 216, 216, 216, 220, 220, 220, 220
1829 .byte 224, 224, 224, 224, 228, 228, 228, 228
1830 .byte 232, 232, 232, 232, 236, 236, 236, 236
1831 .byte 240, 240, 240, 240, 244, 244, 244, 244
1832 .byte 248, 248, 248, 248, 252, 252, 252, 252
1834 ! 5 numbers for initil/final permutation
1836 .word 0x0f0f0f0f ! offset 256
1837 .word 0x0000ffff ! 260
1838 .word 0x33333333 ! 264
1839 .word 0x00ff00ff ! 268
1840 .word 0x55555555 ! 272
1844 .word 0x0000FC00 ! 284
1847 .type DES_SPtrans,#object
1848 .size DES_SPtrans,2048
1853 .word 0x02080800, 0x00080000, 0x02000002, 0x02080802
1854 .word 0x02000000, 0x00080802, 0x00080002, 0x02000002
1855 .word 0x00080802, 0x02080800, 0x02080000, 0x00000802
1856 .word 0x02000802, 0x02000000, 0x00000000, 0x00080002
1857 .word 0x00080000, 0x00000002, 0x02000800, 0x00080800
1858 .word 0x02080802, 0x02080000, 0x00000802, 0x02000800
1859 .word 0x00000002, 0x00000800, 0x00080800, 0x02080002
1860 .word 0x00000800, 0x02000802, 0x02080002, 0x00000000
1861 .word 0x00000000, 0x02080802, 0x02000800, 0x00080002
1862 .word 0x02080800, 0x00080000, 0x00000802, 0x02000800
1863 .word 0x02080002, 0x00000800, 0x00080800, 0x02000002
1864 .word 0x00080802, 0x00000002, 0x02000002, 0x02080000
1865 .word 0x02080802, 0x00080800, 0x02080000, 0x02000802
1866 .word 0x02000000, 0x00000802, 0x00080002, 0x00000000
1867 .word 0x00080000, 0x02000000, 0x02000802, 0x02080800
1868 .word 0x00000002, 0x02080002, 0x00000800, 0x00080802
1870 .word 0x40108010, 0x00000000, 0x00108000, 0x40100000
1871 .word 0x40000010, 0x00008010, 0x40008000, 0x00108000
1872 .word 0x00008000, 0x40100010, 0x00000010, 0x40008000
1873 .word 0x00100010, 0x40108000, 0x40100000, 0x00000010
1874 .word 0x00100000, 0x40008010, 0x40100010, 0x00008000
1875 .word 0x00108010, 0x40000000, 0x00000000, 0x00100010
1876 .word 0x40008010, 0x00108010, 0x40108000, 0x40000010
1877 .word 0x40000000, 0x00100000, 0x00008010, 0x40108010
1878 .word 0x00100010, 0x40108000, 0x40008000, 0x00108010
1879 .word 0x40108010, 0x00100010, 0x40000010, 0x00000000
1880 .word 0x40000000, 0x00008010, 0x00100000, 0x40100010
1881 .word 0x00008000, 0x40000000, 0x00108010, 0x40008010
1882 .word 0x40108000, 0x00008000, 0x00000000, 0x40000010
1883 .word 0x00000010, 0x40108010, 0x00108000, 0x40100000
1884 .word 0x40100010, 0x00100000, 0x00008010, 0x40008000
1885 .word 0x40008010, 0x00000010, 0x40100000, 0x00108000
1887 .word 0x04000001, 0x04040100, 0x00000100, 0x04000101
1888 .word 0x00040001, 0x04000000, 0x04000101, 0x00040100
1889 .word 0x04000100, 0x00040000, 0x04040000, 0x00000001
1890 .word 0x04040101, 0x00000101, 0x00000001, 0x04040001
1891 .word 0x00000000, 0x00040001, 0x04040100, 0x00000100
1892 .word 0x00000101, 0x04040101, 0x00040000, 0x04000001
1893 .word 0x04040001, 0x04000100, 0x00040101, 0x04040000
1894 .word 0x00040100, 0x00000000, 0x04000000, 0x00040101
1895 .word 0x04040100, 0x00000100, 0x00000001, 0x00040000
1896 .word 0x00000101, 0x00040001, 0x04040000, 0x04000101
1897 .word 0x00000000, 0x04040100, 0x00040100, 0x04040001
1898 .word 0x00040001, 0x04000000, 0x04040101, 0x00000001
1899 .word 0x00040101, 0x04000001, 0x04000000, 0x04040101
1900 .word 0x00040000, 0x04000100, 0x04000101, 0x00040100
1901 .word 0x04000100, 0x00000000, 0x04040001, 0x00000101
1902 .word 0x04000001, 0x00040101, 0x00000100, 0x04040000
1904 .word 0x00401008, 0x10001000, 0x00000008, 0x10401008
1905 .word 0x00000000, 0x10400000, 0x10001008, 0x00400008
1906 .word 0x10401000, 0x10000008, 0x10000000, 0x00001008
1907 .word 0x10000008, 0x00401008, 0x00400000, 0x10000000
1908 .word 0x10400008, 0x00401000, 0x00001000, 0x00000008
1909 .word 0x00401000, 0x10001008, 0x10400000, 0x00001000
1910 .word 0x00001008, 0x00000000, 0x00400008, 0x10401000
1911 .word 0x10001000, 0x10400008, 0x10401008, 0x00400000
1912 .word 0x10400008, 0x00001008, 0x00400000, 0x10000008
1913 .word 0x00401000, 0x10001000, 0x00000008, 0x10400000
1914 .word 0x10001008, 0x00000000, 0x00001000, 0x00400008
1915 .word 0x00000000, 0x10400008, 0x10401000, 0x00001000
1916 .word 0x10000000, 0x10401008, 0x00401008, 0x00400000
1917 .word 0x10401008, 0x00000008, 0x10001000, 0x00401008
1918 .word 0x00400008, 0x00401000, 0x10400000, 0x10001008
1919 .word 0x00001008, 0x10000000, 0x10000008, 0x10401000
1921 .word 0x08000000, 0x00010000, 0x00000400, 0x08010420
1922 .word 0x08010020, 0x08000400, 0x00010420, 0x08010000
1923 .word 0x00010000, 0x00000020, 0x08000020, 0x00010400
1924 .word 0x08000420, 0x08010020, 0x08010400, 0x00000000
1925 .word 0x00010400, 0x08000000, 0x00010020, 0x00000420
1926 .word 0x08000400, 0x00010420, 0x00000000, 0x08000020
1927 .word 0x00000020, 0x08000420, 0x08010420, 0x00010020
1928 .word 0x08010000, 0x00000400, 0x00000420, 0x08010400
1929 .word 0x08010400, 0x08000420, 0x00010020, 0x08010000
1930 .word 0x00010000, 0x00000020, 0x08000020, 0x08000400
1931 .word 0x08000000, 0x00010400, 0x08010420, 0x00000000
1932 .word 0x00010420, 0x08000000, 0x00000400, 0x00010020
1933 .word 0x08000420, 0x00000400, 0x00000000, 0x08010420
1934 .word 0x08010020, 0x08010400, 0x00000420, 0x00010000
1935 .word 0x00010400, 0x08010020, 0x08000400, 0x00000420
1936 .word 0x00000020, 0x00010420, 0x08010000, 0x08000020
1938 .word 0x80000040, 0x00200040, 0x00000000, 0x80202000
1939 .word 0x00200040, 0x00002000, 0x80002040, 0x00200000
1940 .word 0x00002040, 0x80202040, 0x00202000, 0x80000000
1941 .word 0x80002000, 0x80000040, 0x80200000, 0x00202040
1942 .word 0x00200000, 0x80002040, 0x80200040, 0x00000000
1943 .word 0x00002000, 0x00000040, 0x80202000, 0x80200040
1944 .word 0x80202040, 0x80200000, 0x80000000, 0x00002040
1945 .word 0x00000040, 0x00202000, 0x00202040, 0x80002000
1946 .word 0x00002040, 0x80000000, 0x80002000, 0x00202040
1947 .word 0x80202000, 0x00200040, 0x00000000, 0x80002000
1948 .word 0x80000000, 0x00002000, 0x80200040, 0x00200000
1949 .word 0x00200040, 0x80202040, 0x00202000, 0x00000040
1950 .word 0x80202040, 0x00202000, 0x00200000, 0x80002040
1951 .word 0x80000040, 0x80200000, 0x00202040, 0x00000000
1952 .word 0x00002000, 0x80000040, 0x80002040, 0x80202000
1953 .word 0x80200000, 0x00002040, 0x00000040, 0x80200040
1955 .word 0x00004000, 0x00000200, 0x01000200, 0x01000004
1956 .word 0x01004204, 0x00004004, 0x00004200, 0x00000000
1957 .word 0x01000000, 0x01000204, 0x00000204, 0x01004000
1958 .word 0x00000004, 0x01004200, 0x01004000, 0x00000204
1959 .word 0x01000204, 0x00004000, 0x00004004, 0x01004204
1960 .word 0x00000000, 0x01000200, 0x01000004, 0x00004200
1961 .word 0x01004004, 0x00004204, 0x01004200, 0x00000004
1962 .word 0x00004204, 0x01004004, 0x00000200, 0x01000000
1963 .word 0x00004204, 0x01004000, 0x01004004, 0x00000204
1964 .word 0x00004000, 0x00000200, 0x01000000, 0x01004004
1965 .word 0x01000204, 0x00004204, 0x00004200, 0x00000000
1966 .word 0x00000200, 0x01000004, 0x00000004, 0x01000200
1967 .word 0x00000000, 0x01000204, 0x01000200, 0x00004200
1968 .word 0x00000204, 0x00004000, 0x01004204, 0x01000000
1969 .word 0x01004200, 0x00000004, 0x00004004, 0x01004204
1970 .word 0x01000004, 0x01004200, 0x01004000, 0x00004004
1972 .word 0x20800080, 0x20820000, 0x00020080, 0x00000000
1973 .word 0x20020000, 0x00800080, 0x20800000, 0x20820080
1974 .word 0x00000080, 0x20000000, 0x00820000, 0x00020080
1975 .word 0x00820080, 0x20020080, 0x20000080, 0x20800000
1976 .word 0x00020000, 0x00820080, 0x00800080, 0x20020000
1977 .word 0x20820080, 0x20000080, 0x00000000, 0x00820000
1978 .word 0x20000000, 0x00800000, 0x20020080, 0x20800080
1979 .word 0x00800000, 0x00020000, 0x20820000, 0x00000080
1980 .word 0x00800000, 0x00020000, 0x20000080, 0x20820080
1981 .word 0x00020080, 0x20000000, 0x00000000, 0x00820000
1982 .word 0x20800080, 0x20020080, 0x20020000, 0x00800080
1983 .word 0x20820000, 0x00000080, 0x00800080, 0x20020000
1984 .word 0x20820080, 0x00800000, 0x20800000, 0x20000080
1985 .word 0x00820000, 0x00020080, 0x20020080, 0x20800000
1986 .word 0x00000080, 0x20820000, 0x00820080, 0x00000000
1987 .word 0x20000000, 0x20800080, 0x00020000, 0x00820080