Cpuid modules updates.
[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         ldd     [%o0],%f0
38
39         subcc   %g0,1,%o0
40         ! Following is V9 "rd %ccr,%o0" instruction. However! V8
41         ! specification says that it ("rd %asr2,%o0" in V8 terms) does
42         ! not cause illegal_instruction trap. It therefore can be used
43         ! to determine if the CPU the code is executing on is V8- or
44         ! V9-compliant, as V9 returns a distinct value of 0x99,
45         ! "negative" and "borrow" bits set in both %icc and %xcc.
46         .word   0x91408000      !rd     %ccr,%o0
47         cmp     %o0,0x99
48         bne     .v8
49         nop
50                         ! Even though we do not use %fp register bank,
51                         ! we wipe it as memcpy might have used it...
52                         .word   0xbfa00040      !fmovd  %f0,%f62
53                         .word   0xbba00040      !...
54                         .word   0xb7a00040
55                         .word   0xb3a00040
56                         .word   0xafa00040
57                         .word   0xaba00040
58                         .word   0xa7a00040
59                         .word   0xa3a00040
60                         .word   0x9fa00040
61                         .word   0x9ba00040
62                         .word   0x97a00040
63                         .word   0x93a00040
64                         .word   0x8fa00040
65                         .word   0x8ba00040
66                         .word   0x87a00040
67                         .word   0x83a00040      !fmovd  %f0,%f32
68 .v8:                    fmovs   %f1,%f31
69         clr     %o0
70                         fmovs   %f0,%f30
71         clr     %o1
72                         fmovs   %f1,%f29
73         clr     %o2
74                         fmovs   %f0,%f28
75         clr     %o3
76                         fmovs   %f1,%f27
77         clr     %o4
78                         fmovs   %f0,%f26
79         clr     %o5
80                         fmovs   %f1,%f25
81         clr     %o7
82                         fmovs   %f0,%f24
83         clr     %l0
84                         fmovs   %f1,%f23
85         clr     %l1
86                         fmovs   %f0,%f22
87         clr     %l2
88                         fmovs   %f1,%f21
89         clr     %l3
90                         fmovs   %f0,%f20
91         clr     %l4
92                         fmovs   %f1,%f19
93         clr     %l5
94                         fmovs   %f0,%f18
95         clr     %l6
96                         fmovs   %f1,%f17
97         clr     %l7
98                         fmovs   %f0,%f16
99         clr     %i0
100                         fmovs   %f1,%f15
101         clr     %i1
102                         fmovs   %f0,%f14
103         clr     %i2
104                         fmovs   %f1,%f13
105         clr     %i3
106                         fmovs   %f0,%f12
107         clr     %i4
108                         fmovs   %f1,%f11
109         clr     %i5
110                         fmovs   %f0,%f10
111         clr     %g1
112                         fmovs   %f1,%f9
113         clr     %g2
114                         fmovs   %f0,%f8
115         clr     %g3
116                         fmovs   %f1,%f7
117         clr     %g4
118                         fmovs   %f0,%f6
119         clr     %g5
120                         fmovs   %f1,%f5
121                         fmovs   %f0,%f4
122                         fmovs   %f1,%f3
123                         fmovs   %f0,%f2
124
125         add     %fp,BIAS,%i0    ! return pointer to callerĀ“s top of stack
126
127         ret
128         restore
129
130 .zero:  .long   0x0,0x0
131 .PIC.zero.up:
132         retl
133         add     %o0,%o7,%o0
134 #ifdef DEBUG
135 .global walk_reg_wins
136 .type   walk_reg_wins,#function
137 walk_reg_wins:
138 #endif
139 .walk.reg.wins:
140         save    %sp,FRAME,%sp
141         cmp     %i7,%o7
142         be      2f
143         clr     %o0
144         cmp     %o7,0   ! compiler never cleans %o7...
145         be      1f      ! could have been a leaf function...
146         clr     %o1
147         call    .walk.reg.wins
148         nop
149 1:      clr     %o2
150         clr     %o3
151         clr     %o4
152         clr     %o5
153         clr     %o7
154         clr     %l0
155         clr     %l1
156         clr     %l2
157         clr     %l3
158         clr     %l4
159         clr     %l5
160         clr     %l6
161         clr     %l7
162         add     %o0,1,%i0       ! used for debugging
163 2:      ret
164         restore
165 .size   OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu
166
167 .global OPENSSL_atomic_add
168 .type   OPENSSL_atomic_add,#function
169 OPENSSL_atomic_add:
170 #ifndef ABI64
171         subcc   %g0,1,%o2
172         .word   0x95408000      !rd     %ccr,%o2, see comment above
173         cmp     %o2,0x99
174         be      .v9
175         nop
176         save    %sp,FRAME,%sp
177         ba      .enter
178         nop
179 #ifdef __sun
180 ! Note that you don't have to link with libthread to call thr_yield,
181 ! as libc provides a stub, which is overloaded the moment you link
182 ! with *either* libpthread or libthread...
183 #define YIELD_CPU       thr_yield
184 #else
185 ! applies at least to Linux and FreeBSD... Feedback expected...
186 #define YIELD_CPU       sched_yield
187 #endif
188 .spin:  call    YIELD_CPU
189         nop
190 .enter: ld      [%i0],%i2
191         cmp     %i2,-4096
192         be      .spin
193         mov     -1,%i2
194         swap    [%i0],%i2
195         cmp     %i2,-1
196         be      .spin
197         add     %i2,%i1,%i2
198         stbar
199         st      %i2,[%i0]
200         sra     %i2,%g0,%i0
201         ret
202         restore
203 .v9:
204 #endif
205         ld      [%o0],%o2
206 1:      add     %o1,%o2,%o3
207         .word   0xd7e2100a      !cas [%o0],%o2,%o3, compare [%o0] with %o2 and swap %o3
208         cmp     %o2,%o3
209         bne     1b
210         mov     %o3,%o2         ! cas is always fetching to dest. register
211         add     %o1,%o2,%o0     ! OpenSSL expects the new value
212         retl
213         sra     %o0,%g0,%o0     ! we return signed int, remember?
214 .size   OPENSSL_atomic_add,.-OPENSSL_atomic_add
215
216 .global OPENSSL_rdtsc
217         subcc   %g0,1,%o0
218         .word   0x91408000      !rd     %ccr,%o0
219         cmp     %o0,0x99
220         bne     .notsc
221         xor     %o0,%o0,%o0
222         save    %sp,FRAME-16,%sp
223         mov     513,%o0         !SI_PLATFORM
224         add     %sp,BIAS+16,%o1
225         call    sysinfo
226         mov     256,%o2
227
228         add     %sp,BIAS-16,%o1
229         ld      [%o1],%l0
230         ld      [%o1+4],%l1
231         ld      [%o1+8],%l2
232         mov     %lo('SUNW'),%l3
233         ret
234         restore
235 .notsc:
236         retl
237         nop
238 .type   OPENSSL_rdtsc,#function
239 .size   OPENSSL_rdtsc,.-OPENSSL_atomic_add