sparccpuid.S 4.6 KB

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