sparccpuid.S 4.6 KB

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