C64x+ assembler pack. linux-c64xplus build is *not* tested nor can it be
[openssl.git] / crypto / sha / asm / sha1-c64xplus.pl
1 #!/usr/bin/env perl
2 #
3 # ====================================================================
4 # Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
5 # project. The module is, however, dual licensed under OpenSSL and
6 # CRYPTOGAMS licenses depending on where you obtain it. For further
7 # details see http://www.openssl.org/~appro/cryptogams/.
8 # ====================================================================
9 #
10 # SHA1 for C64x+.
11 #
12 # November 2011
13 #
14 # If compared to compiler-generated code with similar characteristics,
15 # i.e. compiled with OPENSSL_SMALL_FOOTPRINT and utilizing SPLOOPs,
16 # this implementation is 25% smaller and >2x faster. In absolute terms
17 # performance is (quite impressive) ~6.5 cycles per processed byte.
18 # Fully unrolled assembler would be ~5x larger and is likely to be
19 # ~15% faster. It would be free from references to intermediate ring
20 # buffer, but put more pressure on L1P [both because the code would be
21 # larger and won't be using SPLOOP buffer]. There are no plans to
22 # realize fully unrolled variant though...
23 #
24 # !!! Note that this module uses AMR, which means that all interrupt
25 # service routines are expected to preserve it and for own well-being
26 # zero it upon entry.
27
28 while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
29 open STDOUT,">$output";
30
31 ($CTX,$INP,$NUM) = ("A4","B4","A6");            # arguments
32
33 ($A,$B,$C,$D,$E, $Arot,$F,$F0,$T,$K) = map("A$_",(16..20, 21..25));
34 ($X0,$X2,$X8,$X13) = ("A26","B26","A27","B27");
35 ($TX0,$TX1,$TX2,$TX3) = map("B$_",(28..31));
36 ($XPA,$XPB) = ("A5","B5");                      # X circular buffer
37 ($Actx,$Bctx,$Cctx,$Dctx,$Ectx) = map("A$_",(3,6..9));  # zaps $NUM
38
39 $code=<<___;
40         .text
41
42         .asg    B3,RA
43         .asg    A15,FP
44         .asg    B15,SP
45
46         .if     .BIG_ENDIAN
47         .asg    MV,SWAP2
48         .asg    MV,SWAP4
49         .endif
50
51         .global _sha1_block_data_order
52 _sha1_block_data_order:
53         .asmfunc stack_usage(64)
54         MV      $NUM,A0                 ; reassign $NUM
55 ||      MVK     -64,B0
56   [!A0] BNOP    RA                      ; if ($NUM==0) return;
57 || [A0] STW     FP,*SP--[16]            ; save frame pointer and alloca(64)
58 || [A0] MV      SP,FP
59    [A0] LDW     *${CTX}[0],$A           ; load A-E...
60 || [A0] AND     B0,SP,SP                ; align stack at 64 bytes
61    [A0] LDW     *${CTX}[1],$B
62 || [A0] SUBAW   SP,2,SP                 ; reserve two words above buffer
63    [A0] LDW     *${CTX}[2],$C
64 || [A0] MVK     0x00404,B0
65    [A0] LDW     *${CTX}[3],$D
66 || [A0] MVKH    0x50000,B0              ; 0x050404, 64 bytes for $XP[AB]
67    [A0] LDW     *${CTX}[4],$E
68 || [A0] MVC     B0,AMR                  ; setup circular addressing
69         LDNW    *${INP}++,$TX1          ; pre-fetch input
70         NOP     1
71
72 loop?:
73         MVK     0x00007999,$K
74 ||      ADDAW   SP,2,$XPA
75 ||      SUB     A0,1,A0
76 ||      MVK     13,B0
77         MVKH    0x5a820000,$K           ; K_00_19
78 ||      ADDAW   SP,2,$XPB
79 ||      MV      $A,$Actx
80 ||      MV      $B,$Bctx
81 ;;==================================================
82         SPLOOPD 5                       ; BODY_00_13
83 ||      MV      $C,$Cctx
84 ||      MV      $D,$Dctx
85 ||      MV      $E,$Ectx
86 ||      MVC     B0,ILC
87
88         ROTL    $A,5,$Arot
89 ||      AND     $C,$B,$F
90 ||      ANDN    $D,$B,$F0
91 ||      ADD     $K,$E,$T                ; T=E+K
92
93         XOR     $F0,$F,$F               ; F_00_19(B,C,D)
94 ||      MV      $D,$E                   ; E=D
95 ||      MV      $C,$D                   ; D=C
96 ||      SWAP2   $TX1,$TX2
97 ||      LDNW    *${INP}++,$TX1
98
99         ADD     $F,$T,$T                ; T+=F_00_19(B,C,D)
100 ||      ROTL    $B,30,$C                ; C=ROL(B,30)
101 ||      SWAP4   $TX2,$TX3               ; byte swap
102
103         ADD     $Arot,$T,$T             ; T+=ROL(A,5)
104 ||      MV      $A,$B                   ; B=A
105
106         ADD     $TX3,$T,$A              ; A=T+Xi
107 ||      STW     $TX3,*${XPB}++
108         SPKERNEL
109 ;;==================================================
110         ROTL    $A,5,$Arot              ; BODY_14
111 ||      AND     $C,$B,$F
112 ||      ANDN    $D,$B,$F0
113 ||      ADD     $K,$E,$T                ; T=E+K
114
115         XOR     $F0,$F,$F               ; F_00_19(B,C,D)
116 ||      MV      $D,$E                   ; E=D
117 ||      MV      $C,$D                   ; D=C
118 ||      SWAP2   $TX1,$TX2
119 ||      LDNW    *${INP}++,$TX1
120
121         ADD     $F,$T,$T                ; T+=F_00_19(B,C,D)
122 ||      ROTL    $B,30,$C                ; C=ROL(B,30)
123 ||      SWAP4   $TX2,$TX2               ; byte swap
124 ||      LDW     *${XPA}++,$X0           ; fetches from X ring buffer are
125 ||      LDW     *${XPB}[4],$X2          ; 2 iterations ahead
126
127         ADD     $Arot,$T,$T             ; T+=ROL(A,5)
128 ||      MV      $A,$B                   ; B=A
129 ||      LDW     *${XPA}[7],$X8
130 ||      MV      $TX3,$X13               ; ||    LDW     *${XPB}[15],$X13
131 ||      MV      $TX2,$TX3
132
133         ADD     $TX2,$T,$A              ; A=T+Xi
134 ||      STW     $TX2,*${XPB}++
135 ;;==================================================
136         ROTL    $A,5,$Arot              ; BODY_15
137 ||      AND     $C,$B,$F
138 ||      ANDN    $D,$B,$F0
139 ||      ADD     $K,$E,$T                ; T=E+K
140
141         XOR     $F0,$F,$F               ; F_00_19(B,C,D)
142 ||      MV      $D,$E                   ; E=D
143 ||      MV      $C,$D                   ; D=C
144 ||      SWAP2   $TX1,$TX2
145
146         ADD     $F,$T,$T                ; T+=F_00_19(B,C,D)
147 ||      ROTL    $B,30,$C                ; C=ROL(B,30)
148 ||      SWAP4   $TX2,$TX2               ; byte swap
149 ||      XOR     $X0,$X2,$TX0            ; Xupdate XORs are 1 iteration ahead
150 ||      LDW     *${XPA}++,$X0
151 ||      LDW     *${XPB}[4],$X2
152
153         ADD     $Arot,$T,$T             ; T+=ROL(A,5)
154 ||      MV      $A,$B                   ; B=A
155 ||      XOR     $X8,$X13,$TX1
156 ||      LDW     *${XPA}[7],$X8
157 ||      MV      $TX3,$X13               ; ||    LDW     *${XPB}[15],$X13
158 ||      MV      $TX2,$TX3
159
160         ADD     $TX2,$T,$A              ; A=T+Xi
161 ||      STW     $TX2,*${XPB}++
162 ||      XOR     $TX0,$TX1,$TX1
163 ||      MVK     3,B0
164 ;;==================================================
165         SPLOOPD 5                       ; BODY_16_19
166 ||      MVC     B0,ILC
167
168         ROTL    $A,5,$Arot
169 ||      AND     $C,$B,$F
170 ||      ANDN    $D,$B,$F0
171 ||      ADD     $K,$E,$T                ; T=E+K
172 ||      ROTL    $TX1,1,$TX2             ; Xupdate output
173
174         XOR     $F0,$F,$F               ; F_00_19(B,C,D)
175 ||      MV      $D,$E                   ; E=D
176 ||      MV      $C,$D                   ; D=C
177
178         ADD     $F,$T,$T                ; T+=F_00_19(B,C,D)
179 ||      ROTL    $B,30,$C                ; C=ROL(B,30)
180 ||      XOR     $X0,$X2,$TX0
181 ||      LDW     *${XPA}++,$X0
182 ||      LDW     *${XPB}[4],$X2
183
184         ADD     $Arot,$T,$T             ; T+=ROL(A,5)
185 ||      MV      $A,$B                   ; B=A
186 ||      XOR     $X8,$X13,$TX1
187 ||      LDW     *${XPA}[7],$X8
188 ||      MV      $TX3,$X13               ; ||    LDW     *${XPB}[15],$X13
189 ||      MV      $TX2,$TX3
190
191         ADD     $TX2,$T,$A              ; A=T+Xi
192 ||      STW     $TX2,*${XPB}++
193 ||      XOR     $TX0,$TX1,$TX1
194         SPKERNEL
195
196         MVK     0xffffeba1,$K
197 ||      MVK     19,B0
198         MVKH    0x6ed90000,$K           ; K_20_39
199 ___
200 sub BODY_20_39 {
201 $code.=<<___;
202 ;;==================================================
203         SPLOOPD 5                       ; BODY_20_39
204 ||      MVC     B0,ILC
205
206         ROTL    $A,5,$Arot
207 ||      XOR     $B,$C,$F
208 ||      ADD     $K,$E,$T                ; T=E+K
209 ||      ROTL    $TX1,1,$TX2             ; Xupdate output
210
211         XOR     $D,$F,$F                ; F_20_39(B,C,D)
212 ||      MV      $D,$E                   ; E=D
213 ||      MV      $C,$D                   ; D=C
214
215         ADD     $F,$T,$T                ; T+=F_20_39(B,C,D)
216 ||      ROTL    $B,30,$C                ; C=ROL(B,30)
217 ||      XOR     $X0,$X2,$TX0
218 ||      LDW     *${XPA}++,$X0
219 ||      LDW     *${XPB}[4],$X2
220
221         ADD     $Arot,$T,$T             ; T+=ROL(A,5)
222 ||      MV      $A,$B                   ; B=A
223 ||      XOR     $X8,$X13,$TX1
224 ||      LDW     *${XPA}[7],$X8
225 ||      MV      $TX3,$X13               ; ||    LDW     *${XPB}[15],$X13
226 ||      MV      $TX2,$TX3
227
228         ADD     $TX2,$T,$A              ; A=T+Xi
229 ||      STW     $TX2,*${XPB}++          ; last one is redundant
230 ||      XOR     $TX0,$TX1,$TX1
231         SPKERNEL
232 ___
233 $code.=<<___ if (!shift);
234         MVK     0xffffbcdc,$K
235         MVKH    0x8f1b0000,$K           ; K_40_59
236 ___
237 }       &BODY_20_39();
238 $code.=<<___;
239 ;;==================================================
240         SPLOOPD 5                       ; BODY_40_59
241 ||      MVC     B0,ILC
242 ||      AND     $B,$C,$F
243 ||      AND     $B,$D,$F0
244
245         ROTL    $A,5,$Arot
246 ||      XOR     $F0,$F,$F
247 ||      AND     $C,$D,$F0
248 ||      ADD     $K,$E,$T                ; T=E+K
249 ||      ROTL    $TX1,1,$TX2             ; Xupdate output
250
251         XOR     $F0,$F,$F               ; F_40_59(B,C,D)
252 ||      MV      $D,$E                   ; E=D
253 ||      MV      $C,$D                   ; D=C
254
255         ADD     $F,$T,$T                ; T+=F_40_59(B,C,D)
256 ||      ROTL    $B,30,$C                ; C=ROL(B,30)
257 ||      XOR     $X0,$X2,$TX0
258 ||      LDW     *${XPA}++,$X0
259 ||      LDW     *${XPB}[4],$X2
260
261         ADD     $Arot,$T,$T             ; T+=ROL(A,5)
262 ||      MV      $A,$B                   ; B=A
263 ||      XOR     $X8,$X13,$TX1
264 ||      LDW     *${XPA}[7],$X8
265 ||      MV      $TX3,$X13               ; ||    LDW     *${XPB}[15],$X13
266 ||      MV      $TX2,$TX3
267
268         ADD     $TX2,$T,$A              ; A=T+Xi
269 ||      STW     $TX2,*${XPB}++
270 ||      XOR     $TX0,$TX1,$TX1
271 ||      AND     $B,$C,$F
272 ||      AND     $B,$D,$F0
273         SPKERNEL
274
275         MVK     0xffffc1d6,$K
276 ||      MVK     18,B0
277         MVKH    0xca620000,$K           ; K_60_79
278 ___
279         &BODY_20_39(-1);                # BODY_60_78
280 $code.=<<___;
281 ;;==================================================
282    [A0] B       loop?
283 ||      ROTL    $A,5,$Arot              ; BODY_79
284 ||      XOR     $B,$C,$F
285 ||      ROTL    $TX1,1,$TX2             ; Xupdate output
286
287    [A0] LDNW    *${INP}++,$TX1          ; pre-fetch input
288 ||      ADD     $K,$E,$T                ; T=E+K
289 ||      XOR     $D,$F,$F                ; F_20_39(B,C,D)
290
291         ADD     $F,$T,$T                ; T+=F_20_39(B,C,D)
292 ||      ADD     $Ectx,$D,$E             ; E=D,E+=Ectx
293 ||      ADD     $Dctx,$C,$D             ; D=C,D+=Dctx
294 ||      ROTL    $B,30,$C                ; C=ROL(B,30)
295
296         ADD     $Arot,$T,$T             ; T+=ROL(A,5)
297 ||      ADD     $Bctx,$A,$B             ; B=A,B+=Bctx
298
299         ADD     $TX2,$T,$A              ; A=T+Xi
300
301         ADD     $Actx,$A,$A             ; A+=Actx
302 ||      ADD     $Cctx,$C,$C             ; C+=Cctx
303 ;; end of loop?
304
305         BNOP    RA                      ; return
306 ||      MV      FP,SP                   ; restore stack pointer
307 ||      LDW     *FP[0],FP               ; restore frame pointer
308         STW     $A,*${CTX}[0]           ; emit A-E...
309 ||      MVK     0,B0
310         STW     $B,*${CTX}[1]
311 ||      MVC     B0,AMR                  ; clear AMR
312         STW     $C,*${CTX}[2]
313         STW     $D,*${CTX}[3]
314         STW     $E,*${CTX}[4]
315         .endasmfunc
316
317         .sect   .const
318         .cstring "SHA1 block transform for C64x+, CRYPTOGAMS by <appro\@openssl.org>"
319         .align  4
320 ___
321
322 print $code;
323 close STDOUT;