PR: 2149
[oweals/openssl.git] / crypto / sparccpuid.S
1 #if defined(__SUNPRO_C) && defined(__sparcv9)
2 # define ABI64  /* They've said -xarch=v9 at command line */
3 #elif defined(__GNUC__) && defined(__arch64__)
4 # define ABI64  /* They've said -m64 at command line */
5 #endif
6
7 #ifdef ABI64
8   .register     %g2,#scratch
9   .register     %g3,#scratch
10 # define        FRAME   -192
11 # define        BIAS    2047
12 #else
13 # define        FRAME   -96
14 # define        BIAS    0
15 #endif
16
17 .text
18 .align  32
19 .global OPENSSL_wipe_cpu
20 .type   OPENSSL_wipe_cpu,#function
21 ! Keep in mind that this does not excuse us from wiping the stack!
22 ! This routine wipes registers, but not the backing store [which
23 ! resides on the stack, toward lower addresses]. To facilitate for
24 ! stack wiping I return pointer to the top of stack of the *caller*.
25 OPENSSL_wipe_cpu:
26         save    %sp,FRAME,%sp
27         nop
28 #ifdef __sun
29 #include <sys/trap.h>
30         ta      ST_CLEAN_WINDOWS
31 #else
32         call    .walk.reg.wins
33 #endif
34         nop
35         call    .PIC.zero.up
36         mov     .zero-(.-4),%o0
37         ld      [%o0],%f0
38         ld      [%o0],%f1
39
40         subcc   %g0,1,%o0
41         ! Following is V9 "rd %ccr,%o0" instruction. However! V8
42         ! specification says that it ("rd %asr2,%o0" in V8 terms) does
43         ! not cause illegal_instruction trap. It therefore can be used
44         ! to determine if the CPU the code is executing on is V8- or
45         ! V9-compliant, as V9 returns a distinct value of 0x99,
46         ! "negative" and "borrow" bits set in both %icc and %xcc.
47         .word   0x91408000      !rd     %ccr,%o0
48         cmp     %o0,0x99
49         bne     .v8
50         nop
51                         ! Even though we do not use %fp register bank,
52                         ! we wipe it as memcpy might have used it...
53                         .word   0xbfa00040      !fmovd  %f0,%f62
54                         .word   0xbba00040      !...
55                         .word   0xb7a00040
56                         .word   0xb3a00040
57                         .word   0xafa00040
58                         .word   0xaba00040
59                         .word   0xa7a00040
60                         .word   0xa3a00040
61                         .word   0x9fa00040
62                         .word   0x9ba00040
63                         .word   0x97a00040
64                         .word   0x93a00040
65                         .word   0x8fa00040
66                         .word   0x8ba00040
67                         .word   0x87a00040
68                         .word   0x83a00040      !fmovd  %f0,%f32
69 .v8:                    fmovs   %f1,%f31
70         clr     %o0
71                         fmovs   %f0,%f30
72         clr     %o1
73                         fmovs   %f1,%f29
74         clr     %o2
75                         fmovs   %f0,%f28
76         clr     %o3
77                         fmovs   %f1,%f27
78         clr     %o4
79                         fmovs   %f0,%f26
80         clr     %o5
81                         fmovs   %f1,%f25
82         clr     %o7
83                         fmovs   %f0,%f24
84         clr     %l0
85                         fmovs   %f1,%f23
86         clr     %l1
87                         fmovs   %f0,%f22
88         clr     %l2
89                         fmovs   %f1,%f21
90         clr     %l3
91                         fmovs   %f0,%f20
92         clr     %l4
93                         fmovs   %f1,%f19
94         clr     %l5
95                         fmovs   %f0,%f18
96         clr     %l6
97                         fmovs   %f1,%f17
98         clr     %l7
99                         fmovs   %f0,%f16
100         clr     %i0
101                         fmovs   %f1,%f15
102         clr     %i1
103                         fmovs   %f0,%f14
104         clr     %i2
105                         fmovs   %f1,%f13
106         clr     %i3
107                         fmovs   %f0,%f12
108         clr     %i4
109                         fmovs   %f1,%f11
110         clr     %i5
111                         fmovs   %f0,%f10
112         clr     %g1
113                         fmovs   %f1,%f9
114         clr     %g2
115                         fmovs   %f0,%f8
116         clr     %g3
117                         fmovs   %f1,%f7
118         clr     %g4
119                         fmovs   %f0,%f6
120         clr     %g5
121                         fmovs   %f1,%f5
122                         fmovs   %f0,%f4
123                         fmovs   %f1,%f3
124                         fmovs   %f0,%f2
125
126         add     %fp,BIAS,%i0    ! return pointer to callerĀ“s top of stack
127
128         ret
129         restore
130
131 .zero:  .long   0x0,0x0
132 .PIC.zero.up:
133         retl
134         add     %o0,%o7,%o0
135 #ifdef DEBUG
136 .global walk_reg_wins
137 .type   walk_reg_wins,#function
138 walk_reg_wins:
139 #endif
140 .walk.reg.wins:
141         save    %sp,FRAME,%sp
142         cmp     %i7,%o7
143         be      2f
144         clr     %o0
145         cmp     %o7,0   ! compiler never cleans %o7...
146         be      1f      ! could have been a leaf function...
147         clr     %o1
148         call    .walk.reg.wins
149         nop
150 1:      clr     %o2
151         clr     %o3
152         clr     %o4
153         clr     %o5
154         clr     %o7
155         clr     %l0
156         clr     %l1
157         clr     %l2
158         clr     %l3
159         clr     %l4
160         clr     %l5
161         clr     %l6
162         clr     %l7
163         add     %o0,1,%i0       ! used for debugging
164 2:      ret
165         restore
166 .size   OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
167
168 .global OPENSSL_atomic_add
169 .type   OPENSSL_atomic_add,#function
170 .align  32
171 OPENSSL_atomic_add:
172 #ifndef ABI64
173         subcc   %g0,1,%o2
174         .word   0x95408000      !rd     %ccr,%o2, see comment above
175         cmp     %o2,0x99
176         be      .v9
177         nop
178         save    %sp,FRAME,%sp
179         ba      .enter
180         nop
181 #ifdef __sun
182 ! Note that you don't have to link with libthread to call thr_yield,
183 ! as libc provides a stub, which is overloaded the moment you link
184 ! with *either* libpthread or libthread...
185 #define YIELD_CPU       thr_yield
186 #else
187 ! applies at least to Linux and FreeBSD... Feedback expected...
188 #define YIELD_CPU       sched_yield
189 #endif
190 .spin:  call    YIELD_CPU
191         nop
192 .enter: ld      [%i0],%i2
193         cmp     %i2,-4096
194         be      .spin
195         mov     -1,%i2
196         swap    [%i0],%i2
197         cmp     %i2,-1
198         be      .spin
199         add     %i2,%i1,%i2
200         stbar
201         st      %i2,[%i0]
202         sra     %i2,%g0,%i0
203         ret
204         restore
205 .v9:
206 #endif
207         ld      [%o0],%o2
208 1:      add     %o1,%o2,%o3
209         .word   0xd7e2100a      !cas [%o0],%o2,%o3, compare [%o0] with %o2 and swap %o3
210         cmp     %o2,%o3
211         bne     1b
212         mov     %o3,%o2         ! cas is always fetching to dest. register
213         add     %o1,%o2,%o0     ! OpenSSL expects the new value
214         retl
215         sra     %o0,%g0,%o0     ! we return signed int, remember?
216 .size   OPENSSL_atomic_add,.-OPENSSL_atomic_add
217
218 .global _sparcv9_rdtick
219 .align  32
220 _sparcv9_rdtick:
221         subcc   %g0,1,%o0
222         .word   0x91408000      !rd     %ccr,%o0
223         cmp     %o0,0x99
224         bne     .notick
225         xor     %o0,%o0,%o0
226         .word   0x91410000      !rd     %tick,%o0
227         retl
228         .word   0x93323020      !srlx   %o2,32,%o1
229 .notick:
230         retl
231         xor     %o1,%o1,%o1
232 .type   _sparcv9_rdtick,#function
233 .size   _sparcv9_rdtick,.-_sparcv9_rdtick
234
235 .global OPENSSL_cleanse
236 .align  32
237 OPENSSL_cleanse:
238         cmp     %o1,14
239         nop
240 #ifdef ABI64
241         bgu     %xcc,.Lot
242 #else
243         bgu     .Lot
244 #endif
245         cmp     %o1,0
246         bne     .Little
247         nop
248         retl
249         nop
250
251 .Little:
252         stb     %g0,[%o0]
253         subcc   %o1,1,%o1
254         bnz     .Little
255         add     %o0,1,%o0
256         retl
257         nop
258 .align  32
259 .Lot:
260 #ifndef ABI64
261         subcc   %g0,1,%g1
262         ! see above for explanation
263         .word   0x83408000      !rd     %ccr,%g1
264         cmp     %g1,0x99
265         bne     .v8lot
266         nop
267 #endif
268
269 .v9lot: andcc   %o0,7,%g0
270         bz      .v9aligned
271         nop
272         stb     %g0,[%o0]
273         sub     %o1,1,%o1
274         ba      .v9lot
275         add     %o0,1,%o0
276 .align  16,0x01000000
277 .v9aligned:
278         .word   0xc0720000      !stx    %g0,[%o0]
279         sub     %o1,8,%o1
280         andcc   %o1,-8,%g0
281 #ifdef ABI64
282         .word   0x126ffffd      !bnz    %xcc,.v9aligned
283 #else
284         .word   0x124ffffd      !bnz    %icc,.v9aligned
285 #endif
286         add     %o0,8,%o0
287
288         cmp     %o1,0
289         bne     .Little
290         nop
291         retl
292         nop
293 #ifndef ABI64
294 .v8lot: andcc   %o0,3,%g0
295         bz      .v8aligned
296         nop
297         stb     %g0,[%o0]
298         sub     %o1,1,%o1
299         ba      .v8lot
300         add     %o0,1,%o0
301         nop
302 .v8aligned:
303         st      %g0,[%o0]
304         sub     %o1,4,%o1
305         andcc   %o1,-4,%g0
306         bnz     .v8aligned
307         add     %o0,4,%o0
308
309         cmp     %o1,0
310         bne     .Little
311         nop
312         retl
313         nop
314 #endif
315 .type   OPENSSL_cleanse,#function
316 .size   OPENSSL_cleanse,.-OPENSSL_cleanse
317
318 .section        ".init",#alloc,#execinstr
319         call    OPENSSL_cpuid_setup
320         nop