sparccpuid.S revision bdfb8ad83da0647e9b9a32792598e8ce7ba3ef4d
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*. 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 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 137walk_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 1491: 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 1632: ret 164 restore 165.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu 166 167.global OPENSSL_atomic_add 168.type OPENSSL_atomic_add,#function 169OPENSSL_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 2061: 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 240