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 callers 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 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 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 321