
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