Constify s2i_ASN1_IA5STRING
[openssl.git] / crypto / sparccpuid.S
1 ! Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
2 !
3 ! Licensed under the OpenSSL license (the "License").  You may not use
4 ! this file except in compliance with the License.  You can obtain a copy
5 ! in the file LICENSE in the source distribution or at
6 ! https://www.openssl.org/source/license.html
7
8 #ifdef OPENSSL_FIPSCANISTER
9 #include <openssl/fipssyms.h>
10 #endif
11
12 #if defined(__SUNPRO_C) && defined(__sparcv9)
13 # define ABI64  /* They've said -xarch=v9 at command line */
14 #elif defined(__GNUC__) && defined(__arch64__)
15 # define ABI64  /* They've said -m64 at command line */
16 #endif
17
18 #ifdef ABI64
19   .register     %g2,#scratch
20   .register     %g3,#scratch
21 # define        FRAME   -192
22 # define        BIAS    2047
23 #else
24 # define        FRAME   -96
25 # define        BIAS    0
26 #endif
27
28 .text
29 .align  32
30 .global OPENSSL_wipe_cpu
31 .type   OPENSSL_wipe_cpu,#function
32 ! Keep in mind that this does not excuse us from wiping the stack!
33 ! This routine wipes registers, but not the backing store [which
34 ! resides on the stack, toward lower addresses]. To facilitate for
35 ! stack wiping I return pointer to the top of stack of the *caller*.
36 OPENSSL_wipe_cpu:
37         save    %sp,FRAME,%sp
38         nop
39 #ifdef __sun
40 #include <sys/trap.h>
41         ta      ST_CLEAN_WINDOWS
42 #else
43         call    .walk.reg.wins
44 #endif
45         nop
46         call    .PIC.zero.up
47         mov     .zero-(.-4),%o0
48         ld      [%o0],%f0
49         ld      [%o0],%f1
50
51         subcc   %g0,1,%o0
52         ! Following is V9 "rd %ccr,%o0" instruction. However! V8
53         ! specification says that it ("rd %asr2,%o0" in V8 terms) does
54         ! not cause illegal_instruction trap. It therefore can be used
55         ! to determine if the CPU the code is executing on is V8- or
56         ! V9-compliant, as V9 returns a distinct value of 0x99,
57         ! "negative" and "borrow" bits set in both %icc and %xcc.
58         .word   0x91408000      !rd     %ccr,%o0
59         cmp     %o0,0x99
60         bne     .v8
61         nop
62                         ! Even though we do not use %fp register bank,
63                         ! we wipe it as memcpy might have used it...
64                         .word   0xbfa00040      !fmovd  %f0,%f62
65                         .word   0xbba00040      !...
66                         .word   0xb7a00040
67                         .word   0xb3a00040
68                         .word   0xafa00040
69                         .word   0xaba00040
70                         .word   0xa7a00040
71                         .word   0xa3a00040
72                         .word   0x9fa00040
73                         .word   0x9ba00040
74                         .word   0x97a00040
75                         .word   0x93a00040
76                         .word   0x8fa00040
77                         .word   0x8ba00040
78                         .word   0x87a00040
79                         .word   0x83a00040      !fmovd  %f0,%f32
80 .v8:                    fmovs   %f1,%f31
81         clr     %o0
82                         fmovs   %f0,%f30
83         clr     %o1
84                         fmovs   %f1,%f29
85         clr     %o2
86                         fmovs   %f0,%f28
87         clr     %o3
88                         fmovs   %f1,%f27
89         clr     %o4
90                         fmovs   %f0,%f26
91         clr     %o5
92                         fmovs   %f1,%f25
93         clr     %o7
94                         fmovs   %f0,%f24
95         clr     %l0
96                         fmovs   %f1,%f23
97         clr     %l1
98                         fmovs   %f0,%f22
99         clr     %l2
100                         fmovs   %f1,%f21
101         clr     %l3
102                         fmovs   %f0,%f20
103         clr     %l4
104                         fmovs   %f1,%f19
105         clr     %l5
106                         fmovs   %f0,%f18
107         clr     %l6
108                         fmovs   %f1,%f17
109         clr     %l7
110                         fmovs   %f0,%f16
111         clr     %i0
112                         fmovs   %f1,%f15
113         clr     %i1
114                         fmovs   %f0,%f14
115         clr     %i2
116                         fmovs   %f1,%f13
117         clr     %i3
118                         fmovs   %f0,%f12
119         clr     %i4
120                         fmovs   %f1,%f11
121         clr     %i5
122                         fmovs   %f0,%f10
123         clr     %g1
124                         fmovs   %f1,%f9
125         clr     %g2
126                         fmovs   %f0,%f8
127         clr     %g3
128                         fmovs   %f1,%f7
129         clr     %g4
130                         fmovs   %f0,%f6
131         clr     %g5
132                         fmovs   %f1,%f5
133                         fmovs   %f0,%f4
134                         fmovs   %f1,%f3
135                         fmovs   %f0,%f2
136
137         add     %fp,BIAS,%i0    ! return pointer to callerĀ“s top of stack
138
139         ret
140         restore
141
142 .zero:  .long   0x0,0x0
143 .PIC.zero.up:
144         retl
145         add     %o0,%o7,%o0
146 #ifdef DEBUG
147 .global walk_reg_wins
148 .type   walk_reg_wins,#function
149 walk_reg_wins:
150 #endif
151 .walk.reg.wins:
152         save    %sp,FRAME,%sp
153         cmp     %i7,%o7
154         be      2f
155         clr     %o0
156         cmp     %o7,0   ! compiler never cleans %o7...
157         be      1f      ! could have been a leaf function...
158         clr     %o1
159         call    .walk.reg.wins
160         nop
161 1:      clr     %o2
162         clr     %o3
163         clr     %o4
164         clr     %o5
165         clr     %o7
166         clr     %l0
167         clr     %l1
168         clr     %l2
169         clr     %l3
170         clr     %l4
171         clr     %l5
172         clr     %l6
173         clr     %l7
174         add     %o0,1,%i0       ! used for debugging
175 2:      ret
176         restore
177 .size   OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
178
179 .global OPENSSL_atomic_add
180 .type   OPENSSL_atomic_add,#function
181 .align  32
182 OPENSSL_atomic_add:
183 #ifndef ABI64
184         subcc   %g0,1,%o2
185         .word   0x95408000      !rd     %ccr,%o2, see comment above
186         cmp     %o2,0x99
187         be      .v9
188         nop
189         save    %sp,FRAME,%sp
190         ba      .enter
191         nop
192 #ifdef __sun
193 ! Note that you do not have to link with libthread to call thr_yield,
194 ! as libc provides a stub, which is overloaded the moment you link
195 ! with *either* libpthread or libthread...
196 #define YIELD_CPU       thr_yield
197 #else
198 ! applies at least to Linux and FreeBSD... Feedback expected...
199 #define YIELD_CPU       sched_yield
200 #endif
201 .spin:  call    YIELD_CPU
202         nop
203 .enter: ld      [%i0],%i2
204         cmp     %i2,-4096
205         be      .spin
206         mov     -1,%i2
207         swap    [%i0],%i2
208         cmp     %i2,-1
209         be      .spin
210         add     %i2,%i1,%i2
211         stbar
212         st      %i2,[%i0]
213         sra     %i2,%g0,%i0
214         ret
215         restore
216 .v9:
217 #endif
218         ld      [%o0],%o2
219 1:      add     %o1,%o2,%o3
220         .word   0xd7e2100a      !cas [%o0],%o2,%o3, compare [%o0] with %o2 and swap %o3
221         cmp     %o2,%o3
222         bne     1b
223         mov     %o3,%o2         ! cas is always fetching to dest. register
224         add     %o1,%o2,%o0     ! OpenSSL expects the new value
225         retl
226         sra     %o0,%g0,%o0     ! we return signed int, remember?
227 .size   OPENSSL_atomic_add,.-OPENSSL_atomic_add
228
229 .global _sparcv9_rdtick
230 .align  32
231 _sparcv9_rdtick:
232         subcc   %g0,1,%o0
233         .word   0x91408000      !rd     %ccr,%o0
234         cmp     %o0,0x99
235         bne     .notick
236         xor     %o0,%o0,%o0
237         .word   0x91410000      !rd     %tick,%o0
238         retl
239         .word   0x93323020      !srlx   %o0,32,%o1
240 .notick:
241         retl
242         xor     %o1,%o1,%o1
243 .type   _sparcv9_rdtick,#function
244 .size   _sparcv9_rdtick,.-_sparcv9_rdtick
245
246 .global _sparcv9_vis1_probe
247 .align  8
248 _sparcv9_vis1_probe:
249         add     %sp,BIAS+2,%o1
250         .word   0xc19a5a40      !ldda   [%o1]ASI_FP16_P,%f0
251         retl
252         .word   0x81b00d80      !fxor   %f0,%f0,%f0
253 .type   _sparcv9_vis1_probe,#function
254 .size   _sparcv9_vis1_probe,.-_sparcv9_vis1_probe
255
256 ! Probe and instrument VIS1 instruction. Output is number of cycles it
257 ! takes to execute rdtick and pair of VIS1 instructions. US-Tx VIS unit
258 ! is slow (documented to be 6 cycles on T2) and the core is in-order
259 ! single-issue, it should be possible to distinguish Tx reliably...
260 ! Observed return values are:
261 !
262 !       UltraSPARC IIe          7
263 !       UltraSPARC III          7
264 !       UltraSPARC T1           24
265 !       SPARC T4                65(*)
266 !
267 ! (*)   result has lesser to do with VIS instruction latencies, rdtick
268 !       appears that slow, but it does the trick in sense that FP and
269 !       VIS code paths are still slower than integer-only ones.
270 !
271 ! Numbers for T2 and SPARC64 V-VII are more than welcomed.
272 !
273 ! It would be possible to detect specifically US-T1 by instrumenting
274 ! fmul8ulx16, which is emulated on T1 and as such accounts for quite
275 ! a lot of %tick-s, couple of thousand on Linux...
276 .global _sparcv9_vis1_instrument
277 .align  8
278 _sparcv9_vis1_instrument:
279         .word   0x81b00d80      !fxor   %f0,%f0,%f0
280         .word   0x85b08d82      !fxor   %f2,%f2,%f2
281         .word   0x91410000      !rd     %tick,%o0
282         .word   0x81b00d80      !fxor   %f0,%f0,%f0
283         .word   0x85b08d82      !fxor   %f2,%f2,%f2
284         .word   0x93410000      !rd     %tick,%o1
285         .word   0x81b00d80      !fxor   %f0,%f0,%f0
286         .word   0x85b08d82      !fxor   %f2,%f2,%f2
287         .word   0x95410000      !rd     %tick,%o2
288         .word   0x81b00d80      !fxor   %f0,%f0,%f0
289         .word   0x85b08d82      !fxor   %f2,%f2,%f2
290         .word   0x97410000      !rd     %tick,%o3
291         .word   0x81b00d80      !fxor   %f0,%f0,%f0
292         .word   0x85b08d82      !fxor   %f2,%f2,%f2
293         .word   0x99410000      !rd     %tick,%o4
294
295         ! calculate intervals
296         sub     %o1,%o0,%o0
297         sub     %o2,%o1,%o1
298         sub     %o3,%o2,%o2
299         sub     %o4,%o3,%o3
300
301         ! find minumum value
302         cmp     %o0,%o1
303         .word   0x38680002      !bgu,a  %xcc,.+8
304         mov     %o1,%o0
305         cmp     %o0,%o2
306         .word   0x38680002      !bgu,a  %xcc,.+8
307         mov     %o2,%o0
308         cmp     %o0,%o3
309         .word   0x38680002      !bgu,a  %xcc,.+8
310         mov     %o3,%o0
311
312         retl
313         nop
314 .type   _sparcv9_vis1_instrument,#function
315 .size   _sparcv9_vis1_instrument,.-_sparcv9_vis1_instrument
316
317 .global _sparcv9_vis2_probe
318 .align  8
319 _sparcv9_vis2_probe:
320         retl
321         .word   0x81b00980      !bshuffle       %f0,%f0,%f0
322 .type   _sparcv9_vis2_probe,#function
323 .size   _sparcv9_vis2_probe,.-_sparcv9_vis2_probe
324
325 .global _sparcv9_fmadd_probe
326 .align  8
327 _sparcv9_fmadd_probe:
328         .word   0x81b00d80      !fxor   %f0,%f0,%f0
329         .word   0x85b08d82      !fxor   %f2,%f2,%f2
330         retl
331         .word   0x81b80440      !fmaddd %f0,%f0,%f2,%f0
332 .type   _sparcv9_fmadd_probe,#function
333 .size   _sparcv9_fmadd_probe,.-_sparcv9_fmadd_probe
334
335 .global _sparcv9_rdcfr
336 .align  8
337 _sparcv9_rdcfr:
338         retl
339         .word   0x91468000      !rd     %asr26,%o0
340 .type   _sparcv9_rdcfr,#function
341 .size   _sparcv9_rdcfr,.-_sparcv9_rdcfr
342
343 .global _sparcv9_vis3_probe
344 .align  8
345 _sparcv9_vis3_probe:
346         retl
347         .word   0x81b022a0      !xmulx  %g0,%g0,%g0
348 .type   _sparcv9_vis3_probe,#function
349 .size   _sparcv9_vis3_probe,.-_sparcv9_vis3_probe
350
351 .global _sparcv9_random
352 .align  8
353 _sparcv9_random:
354         retl
355         .word   0x91b002a0      !random %o0
356 .type   _sparcv9_random,#function
357 .size   _sparcv9_random,.-_sparcv9_vis3_probe
358
359 .global _sparcv9_fjaesx_probe
360 .align  8
361 _sparcv9_fjaesx_probe:
362         .word   0x81b09206      !faesencx %f2,%f6,%f0
363         retl
364         nop
365 .size   _sparcv9_fjaesx_probe,.-_sparcv9_fjaesx_probe
366
367 .global OPENSSL_cleanse
368 .align  32
369 OPENSSL_cleanse:
370         cmp     %o1,14
371         nop
372 #ifdef ABI64
373         bgu     %xcc,.Lot
374 #else
375         bgu     .Lot
376 #endif
377         cmp     %o1,0
378         bne     .Little
379         nop
380         retl
381         nop
382
383 .Little:
384         stb     %g0,[%o0]
385         subcc   %o1,1,%o1
386         bnz     .Little
387         add     %o0,1,%o0
388         retl
389         nop
390 .align  32
391 .Lot:
392 #ifndef ABI64
393         subcc   %g0,1,%g1
394         ! see above for explanation
395         .word   0x83408000      !rd     %ccr,%g1
396         cmp     %g1,0x99
397         bne     .v8lot
398         nop
399 #endif
400
401 .v9lot: andcc   %o0,7,%g0
402         bz      .v9aligned
403         nop
404         stb     %g0,[%o0]
405         sub     %o1,1,%o1
406         ba      .v9lot
407         add     %o0,1,%o0
408 .align  16,0x01000000
409 .v9aligned:
410         .word   0xc0720000      !stx    %g0,[%o0]
411         sub     %o1,8,%o1
412         andcc   %o1,-8,%g0
413 #ifdef ABI64
414         .word   0x126ffffd      !bnz    %xcc,.v9aligned
415 #else
416         .word   0x124ffffd      !bnz    %icc,.v9aligned
417 #endif
418         add     %o0,8,%o0
419
420         cmp     %o1,0
421         bne     .Little
422         nop
423         retl
424         nop
425 #ifndef ABI64
426 .v8lot: andcc   %o0,3,%g0
427         bz      .v8aligned
428         nop
429         stb     %g0,[%o0]
430         sub     %o1,1,%o1
431         ba      .v8lot
432         add     %o0,1,%o0
433         nop
434 .v8aligned:
435         st      %g0,[%o0]
436         sub     %o1,4,%o1
437         andcc   %o1,-4,%g0
438         bnz     .v8aligned
439         add     %o0,4,%o0
440
441         cmp     %o1,0
442         bne     .Little
443         nop
444         retl
445         nop
446 #endif
447 .type   OPENSSL_cleanse,#function
448 .size   OPENSSL_cleanse,.-OPENSSL_cleanse
449
450 .global CRYPTO_memcmp
451 .align  16
452 CRYPTO_memcmp:
453         cmp     %o2,0
454 #ifdef ABI64
455         beq,pn  %xcc,.Lno_data
456 #else
457         beq     .Lno_data
458 #endif
459         xor     %g1,%g1,%g1
460         nop
461
462 .Loop_cmp:
463         ldub    [%o0],%o3
464         add     %o0,1,%o0
465         ldub    [%o1],%o4
466         add     %o1,1,%o1
467         subcc   %o2,1,%o2
468         xor     %o3,%o4,%o4
469 #ifdef ABI64
470         bnz     %xcc,.Loop_cmp
471 #else
472         bnz     .Loop_cmp
473 #endif
474         or      %o4,%g1,%g1
475
476         sub     %g0,%g1,%g1
477         srl     %g1,31,%g1
478 .Lno_data:
479         retl
480         mov     %g1,%o0
481 .type   CRYPTO_memcmp,#function
482 .size   CRYPTO_memcmp,.-CRYPTO_memcmp
483
484 .global _sparcv9_vis1_instrument_bus
485 .align  8
486 _sparcv9_vis1_instrument_bus:
487         mov     %o1,%o3                                 ! save cnt
488         .word   0x99410000      !rd     %tick,%o4       ! tick
489         mov     %o4,%o5                                 ! lasttick = tick
490         set     0,%g4                                   ! diff
491
492         andn    %o0,63,%g1
493         .word   0xc1985e00      !ldda   [%g1]0xf0,%f0   ! block load
494         .word   0x8143e040      !membar #Sync
495         .word   0xc1b85c00      !stda   %f0,[%g1]0xe0   ! block store and commit
496         .word   0x8143e040      !membar #Sync
497         ld      [%o0],%o4
498         add     %o4,%g4,%g4
499         .word   0xc9e2100c      !cas    [%o0],%o4,%g4
500
501 .Loop:  .word   0x99410000      !rd     %tick,%o4
502         sub     %o4,%o5,%g4                             ! diff=tick-lasttick
503         mov     %o4,%o5                                 ! lasttick=tick
504
505         andn    %o0,63,%g1
506         .word   0xc1985e00      !ldda   [%g1]0xf0,%f0   ! block load
507         .word   0x8143e040      !membar #Sync
508         .word   0xc1b85c00      !stda   %f0,[%g1]0xe0   ! block store and commit
509         .word   0x8143e040      !membar #Sync
510         ld      [%o0],%o4
511         add     %o4,%g4,%g4
512         .word   0xc9e2100c      !cas    [%o0],%o4,%g4
513         subcc   %o1,1,%o1                               ! --$cnt
514         bnz     .Loop
515         add     %o0,4,%o0                               ! ++$out
516
517         retl
518         mov     %o3,%o0
519 .type   _sparcv9_vis1_instrument_bus,#function
520 .size   _sparcv9_vis1_instrument_bus,.-_sparcv9_vis1_instrument_bus
521
522 .global _sparcv9_vis1_instrument_bus2
523 .align  8
524 _sparcv9_vis1_instrument_bus2:
525         mov     %o1,%o3                                 ! save cnt
526         sll     %o1,2,%o1                               ! cnt*=4
527
528         .word   0x99410000      !rd     %tick,%o4       ! tick
529         mov     %o4,%o5                                 ! lasttick = tick
530         set     0,%g4                                   ! diff
531
532         andn    %o0,63,%g1
533         .word   0xc1985e00      !ldda   [%g1]0xf0,%f0   ! block load
534         .word   0x8143e040      !membar #Sync
535         .word   0xc1b85c00      !stda   %f0,[%g1]0xe0   ! block store and commit
536         .word   0x8143e040      !membar #Sync
537         ld      [%o0],%o4
538         add     %o4,%g4,%g4
539         .word   0xc9e2100c      !cas    [%o0],%o4,%g4
540
541         .word   0x99410000      !rd     %tick,%o4       ! tick
542         sub     %o4,%o5,%g4                             ! diff=tick-lasttick
543         mov     %o4,%o5                                 ! lasttick=tick
544         mov     %g4,%g5                                 ! lastdiff=diff
545 .Loop2:
546         andn    %o0,63,%g1
547         .word   0xc1985e00      !ldda   [%g1]0xf0,%f0   ! block load
548         .word   0x8143e040      !membar #Sync
549         .word   0xc1b85c00      !stda   %f0,[%g1]0xe0   ! block store and commit
550         .word   0x8143e040      !membar #Sync
551         ld      [%o0],%o4
552         add     %o4,%g4,%g4
553         .word   0xc9e2100c      !cas    [%o0],%o4,%g4
554
555         subcc   %o2,1,%o2                               ! --max
556         bz      .Ldone2
557         nop
558
559         .word   0x99410000      !rd     %tick,%o4       ! tick
560         sub     %o4,%o5,%g4                             ! diff=tick-lasttick
561         mov     %o4,%o5                                 ! lasttick=tick
562         cmp     %g4,%g5
563         mov     %g4,%g5                                 ! lastdiff=diff
564
565         .word   0x83408000      !rd     %ccr,%g1
566         and     %g1,4,%g1                               ! isolate zero flag
567         xor     %g1,4,%g1                               ! flip zero flag
568
569         subcc   %o1,%g1,%o1                             ! conditional --$cnt
570         bnz     .Loop2
571         add     %o0,%g1,%o0                             ! conditional ++$out
572
573 .Ldone2:
574         srl     %o1,2,%o1
575         retl
576         sub     %o3,%o1,%o0
577 .type   _sparcv9_vis1_instrument_bus2,#function
578 .size   _sparcv9_vis1_instrument_bus2,.-_sparcv9_vis1_instrument_bus2
579
580 .section        ".init",#alloc,#execinstr
581         call    OPENSSL_cpuid_setup
582         nop