sha512-ppc.pl: add PPC32 code, >2x improvement on in-order cores.
[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         .if     __TI_EABI__
42         .asg    sha1_block_data_order,_sha1_block_data_order
43         .endif
44
45         .asg    B3,RA
46         .asg    A15,FP
47         .asg    B15,SP
48
49         .if     .BIG_ENDIAN
50         .asg    MV,SWAP2
51         .asg    MV,SWAP4
52         .endif
53
54         .global _sha1_block_data_order
55 _sha1_block_data_order:
56         .asmfunc stack_usage(64)
57         MV      $NUM,A0                 ; reassign $NUM
58 ||      MVK     -64,B0
59   [!A0] BNOP    RA                      ; if ($NUM==0) return;
60 || [A0] STW     FP,*SP--[16]            ; save frame pointer and alloca(64)
61 || [A0] MV      SP,FP
62    [A0] LDW     *${CTX}[0],$A           ; load A-E...
63 || [A0] AND     B0,SP,SP                ; align stack at 64 bytes
64    [A0] LDW     *${CTX}[1],$B
65 || [A0] SUBAW   SP,2,SP                 ; reserve two words above buffer
66    [A0] LDW     *${CTX}[2],$C
67 || [A0] MVK     0x00404,B0
68    [A0] LDW     *${CTX}[3],$D
69 || [A0] MVKH    0x50000,B0              ; 0x050404, 64 bytes for $XP[AB]
70    [A0] LDW     *${CTX}[4],$E
71 || [A0] MVC     B0,AMR                  ; setup circular addressing
72         LDNW    *${INP}++,$TX1          ; pre-fetch input
73         NOP     1
74
75 loop?:
76         MVK     0x00007999,$K
77 ||      ADDAW   SP,2,$XPA
78 ||      SUB     A0,1,A0
79 ||      MVK     13,B0
80         MVKH    0x5a820000,$K           ; K_00_19
81 ||      ADDAW   SP,2,$XPB
82 ||      MV      $A,$Actx
83 ||      MV      $B,$Bctx
84 ;;==================================================
85         SPLOOPD 5                       ; BODY_00_13
86 ||      MV      $C,$Cctx
87 ||      MV      $D,$Dctx
88 ||      MV      $E,$Ectx
89 ||      MVC     B0,ILC
90
91         ROTL    $A,5,$Arot
92 ||      AND     $C,$B,$F
93 ||      ANDN    $D,$B,$F0
94 ||      ADD     $K,$E,$T                ; T=E+K
95
96         XOR     $F0,$F,$F               ; F_00_19(B,C,D)
97 ||      MV      $D,$E                   ; E=D
98 ||      MV      $C,$D                   ; D=C
99 ||      SWAP2   $TX1,$TX2
100 ||      LDNW    *${INP}++,$TX1
101
102         ADD     $F,$T,$T                ; T+=F_00_19(B,C,D)
103 ||      ROTL    $B,30,$C                ; C=ROL(B,30)
104 ||      SWAP4   $TX2,$TX3               ; byte swap
105
106         ADD     $Arot,$T,$T             ; T+=ROL(A,5)
107 ||      MV      $A,$B                   ; B=A
108
109         ADD     $TX3,$T,$A              ; A=T+Xi
110 ||      STW     $TX3,*${XPB}++
111         SPKERNEL
112 ;;==================================================
113         ROTL    $A,5,$Arot              ; BODY_14
114 ||      AND     $C,$B,$F
115 ||      ANDN    $D,$B,$F0
116 ||      ADD     $K,$E,$T                ; T=E+K
117
118         XOR     $F0,$F,$F               ; F_00_19(B,C,D)
119 ||      MV      $D,$E                   ; E=D
120 ||      MV      $C,$D                   ; D=C
121 ||      SWAP2   $TX1,$TX2
122 ||      LDNW    *${INP}++,$TX1
123
124         ADD     $F,$T,$T                ; T+=F_00_19(B,C,D)
125 ||      ROTL    $B,30,$C                ; C=ROL(B,30)
126 ||      SWAP4   $TX2,$TX2               ; byte swap
127 ||      LDW     *${XPA}++,$X0           ; fetches from X ring buffer are
128 ||      LDW     *${XPB}[4],$X2          ; 2 iterations ahead
129
130         ADD     $Arot,$T,$T             ; T+=ROL(A,5)
131 ||      MV      $A,$B                   ; B=A
132 ||      LDW     *${XPA}[7],$X8
133 ||      MV      $TX3,$X13               ; ||    LDW     *${XPB}[15],$X13
134 ||      MV      $TX2,$TX3
135
136         ADD     $TX2,$T,$A              ; A=T+Xi
137 ||      STW     $TX2,*${XPB}++
138 ;;==================================================
139         ROTL    $A,5,$Arot              ; BODY_15
140 ||      AND     $C,$B,$F
141 ||      ANDN    $D,$B,$F0
142 ||      ADD     $K,$E,$T                ; T=E+K
143
144         XOR     $F0,$F,$F               ; F_00_19(B,C,D)
145 ||      MV      $D,$E                   ; E=D
146 ||      MV      $C,$D                   ; D=C
147 ||      SWAP2   $TX1,$TX2
148
149         ADD     $F,$T,$T                ; T+=F_00_19(B,C,D)
150 ||      ROTL    $B,30,$C                ; C=ROL(B,30)
151 ||      SWAP4   $TX2,$TX2               ; byte swap
152 ||      XOR     $X0,$X2,$TX0            ; Xupdate XORs are 1 iteration ahead
153 ||      LDW     *${XPA}++,$X0
154 ||      LDW     *${XPB}[4],$X2
155
156         ADD     $Arot,$T,$T             ; T+=ROL(A,5)
157 ||      MV      $A,$B                   ; B=A
158 ||      XOR     $X8,$X13,$TX1
159 ||      LDW     *${XPA}[7],$X8
160 ||      MV      $TX3,$X13               ; ||    LDW     *${XPB}[15],$X13
161 ||      MV      $TX2,$TX3
162
163         ADD     $TX2,$T,$A              ; A=T+Xi
164 ||      STW     $TX2,*${XPB}++
165 ||      XOR     $TX0,$TX1,$TX1
166 ||      MVK     3,B0
167 ;;==================================================
168         SPLOOPD 5                       ; BODY_16_19
169 ||      MVC     B0,ILC
170
171         ROTL    $A,5,$Arot
172 ||      AND     $C,$B,$F
173 ||      ANDN    $D,$B,$F0
174 ||      ADD     $K,$E,$T                ; T=E+K
175 ||      ROTL    $TX1,1,$TX2             ; Xupdate output
176
177         XOR     $F0,$F,$F               ; F_00_19(B,C,D)
178 ||      MV      $D,$E                   ; E=D
179 ||      MV      $C,$D                   ; D=C
180
181         ADD     $F,$T,$T                ; T+=F_00_19(B,C,D)
182 ||      ROTL    $B,30,$C                ; C=ROL(B,30)
183 ||      XOR     $X0,$X2,$TX0
184 ||      LDW     *${XPA}++,$X0
185 ||      LDW     *${XPB}[4],$X2
186
187         ADD     $Arot,$T,$T             ; T+=ROL(A,5)
188 ||      MV      $A,$B                   ; B=A
189 ||      XOR     $X8,$X13,$TX1
190 ||      LDW     *${XPA}[7],$X8
191 ||      MV      $TX3,$X13               ; ||    LDW     *${XPB}[15],$X13
192 ||      MV      $TX2,$TX3
193
194         ADD     $TX2,$T,$A              ; A=T+Xi
195 ||      STW     $TX2,*${XPB}++
196 ||      XOR     $TX0,$TX1,$TX1
197         SPKERNEL
198
199         MVK     0xffffeba1,$K
200 ||      MVK     19,B0
201         MVKH    0x6ed90000,$K           ; K_20_39
202 ___
203 sub BODY_20_39 {
204 $code.=<<___;
205 ;;==================================================
206         SPLOOPD 5                       ; BODY_20_39
207 ||      MVC     B0,ILC
208
209         ROTL    $A,5,$Arot
210 ||      XOR     $B,$C,$F
211 ||      ADD     $K,$E,$T                ; T=E+K
212 ||      ROTL    $TX1,1,$TX2             ; Xupdate output
213
214         XOR     $D,$F,$F                ; F_20_39(B,C,D)
215 ||      MV      $D,$E                   ; E=D
216 ||      MV      $C,$D                   ; D=C
217
218         ADD     $F,$T,$T                ; T+=F_20_39(B,C,D)
219 ||      ROTL    $B,30,$C                ; C=ROL(B,30)
220 ||      XOR     $X0,$X2,$TX0
221 ||      LDW     *${XPA}++,$X0
222 ||      LDW     *${XPB}[4],$X2
223
224         ADD     $Arot,$T,$T             ; T+=ROL(A,5)
225 ||      MV      $A,$B                   ; B=A
226 ||      XOR     $X8,$X13,$TX1
227 ||      LDW     *${XPA}[7],$X8
228 ||      MV      $TX3,$X13               ; ||    LDW     *${XPB}[15],$X13
229 ||      MV      $TX2,$TX3
230
231         ADD     $TX2,$T,$A              ; A=T+Xi
232 ||      STW     $TX2,*${XPB}++          ; last one is redundant
233 ||      XOR     $TX0,$TX1,$TX1
234         SPKERNEL
235 ___
236 $code.=<<___ if (!shift);
237         MVK     0xffffbcdc,$K
238         MVKH    0x8f1b0000,$K           ; K_40_59
239 ___
240 }       &BODY_20_39();
241 $code.=<<___;
242 ;;==================================================
243         SPLOOPD 5                       ; BODY_40_59
244 ||      MVC     B0,ILC
245 ||      AND     $B,$C,$F
246 ||      AND     $B,$D,$F0
247
248         ROTL    $A,5,$Arot
249 ||      XOR     $F0,$F,$F
250 ||      AND     $C,$D,$F0
251 ||      ADD     $K,$E,$T                ; T=E+K
252 ||      ROTL    $TX1,1,$TX2             ; Xupdate output
253
254         XOR     $F0,$F,$F               ; F_40_59(B,C,D)
255 ||      MV      $D,$E                   ; E=D
256 ||      MV      $C,$D                   ; D=C
257
258         ADD     $F,$T,$T                ; T+=F_40_59(B,C,D)
259 ||      ROTL    $B,30,$C                ; C=ROL(B,30)
260 ||      XOR     $X0,$X2,$TX0
261 ||      LDW     *${XPA}++,$X0
262 ||      LDW     *${XPB}[4],$X2
263
264         ADD     $Arot,$T,$T             ; T+=ROL(A,5)
265 ||      MV      $A,$B                   ; B=A
266 ||      XOR     $X8,$X13,$TX1
267 ||      LDW     *${XPA}[7],$X8
268 ||      MV      $TX3,$X13               ; ||    LDW     *${XPB}[15],$X13
269 ||      MV      $TX2,$TX3
270
271         ADD     $TX2,$T,$A              ; A=T+Xi
272 ||      STW     $TX2,*${XPB}++
273 ||      XOR     $TX0,$TX1,$TX1
274 ||      AND     $B,$C,$F
275 ||      AND     $B,$D,$F0
276         SPKERNEL
277
278         MVK     0xffffc1d6,$K
279 ||      MVK     18,B0
280         MVKH    0xca620000,$K           ; K_60_79
281 ___
282         &BODY_20_39(-1);                # BODY_60_78
283 $code.=<<___;
284 ;;==================================================
285    [A0] B       loop?
286 ||      ROTL    $A,5,$Arot              ; BODY_79
287 ||      XOR     $B,$C,$F
288 ||      ROTL    $TX1,1,$TX2             ; Xupdate output
289
290    [A0] LDNW    *${INP}++,$TX1          ; pre-fetch input
291 ||      ADD     $K,$E,$T                ; T=E+K
292 ||      XOR     $D,$F,$F                ; F_20_39(B,C,D)
293
294         ADD     $F,$T,$T                ; T+=F_20_39(B,C,D)
295 ||      ADD     $Ectx,$D,$E             ; E=D,E+=Ectx
296 ||      ADD     $Dctx,$C,$D             ; D=C,D+=Dctx
297 ||      ROTL    $B,30,$C                ; C=ROL(B,30)
298
299         ADD     $Arot,$T,$T             ; T+=ROL(A,5)
300 ||      ADD     $Bctx,$A,$B             ; B=A,B+=Bctx
301
302         ADD     $TX2,$T,$A              ; A=T+Xi
303
304         ADD     $Actx,$A,$A             ; A+=Actx
305 ||      ADD     $Cctx,$C,$C             ; C+=Cctx
306 ;; end of loop?
307
308         BNOP    RA                      ; return
309 ||      MV      FP,SP                   ; restore stack pointer
310 ||      LDW     *FP[0],FP               ; restore frame pointer
311         STW     $A,*${CTX}[0]           ; emit A-E...
312 ||      MVK     0,B0
313         STW     $B,*${CTX}[1]
314 ||      MVC     B0,AMR                  ; clear AMR
315         STW     $C,*${CTX}[2]
316         STW     $D,*${CTX}[3]
317         STW     $E,*${CTX}[4]
318         .endasmfunc
319
320         .sect   .const
321         .cstring "SHA1 block transform for C64x+, CRYPTOGAMS by <appro\@openssl.org>"
322         .align  4
323 ___
324
325 print $code;
326 close STDOUT;