blob: aa8b11efc97b2150a958b72f9d0b9d2b03976f6a [file] [log] [blame]
Kinson Chika8fa74c2011-07-29 11:33:41 -07001#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*.
25OPENSSL_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
138walk_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
1501: 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
1642: 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
171OPENSSL_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 do not 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
2081: 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
237OPENSSL_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