sparccpuid.S 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. ! Copyright 2005-2016 The OpenSSL Project Authors. All Rights Reserved.
  2. !
  3. ! Licensed under the OpenSSL license (the "License"). You may not use
  4. ! this file except in compliance with the License. You can obtain a copy
  5. ! in the file LICENSE in the source distribution or at
  6. ! https://www.openssl.org/source/license.html
  7. #if defined(__SUNPRO_C) && defined(__sparcv9)
  8. # define ABI64 /* They've said -xarch=v9 at command line */
  9. #elif defined(__GNUC__) && defined(__arch64__)
  10. # define ABI64 /* They've said -m64 at command line */
  11. #endif
  12. #ifdef ABI64
  13. .register %g2,#scratch
  14. .register %g3,#scratch
  15. # define FRAME -192
  16. # define BIAS 2047
  17. #else
  18. # define FRAME -96
  19. # define BIAS 0
  20. #endif
  21. .text
  22. .align 32
  23. .global OPENSSL_wipe_cpu
  24. .type OPENSSL_wipe_cpu,#function
  25. ! Keep in mind that this does not excuse us from wiping the stack!
  26. ! This routine wipes registers, but not the backing store [which
  27. ! resides on the stack, toward lower addresses]. To facilitate for
  28. ! stack wiping I return pointer to the top of stack of the *caller*.
  29. OPENSSL_wipe_cpu:
  30. save %sp,FRAME,%sp
  31. nop
  32. #ifdef __sun
  33. #include <sys/trap.h>
  34. ta ST_CLEAN_WINDOWS
  35. #else
  36. call .walk.reg.wins
  37. #endif
  38. nop
  39. call .PIC.zero.up
  40. mov .zero-(.-4),%o0
  41. ld [%o0],%f0
  42. ld [%o0],%f1
  43. subcc %g0,1,%o0
  44. ! Following is V9 "rd %ccr,%o0" instruction. However! V8
  45. ! specification says that it ("rd %asr2,%o0" in V8 terms) does
  46. ! not cause illegal_instruction trap. It therefore can be used
  47. ! to determine if the CPU the code is executing on is V8- or
  48. ! V9-compliant, as V9 returns a distinct value of 0x99,
  49. ! "negative" and "borrow" bits set in both %icc and %xcc.
  50. .word 0x91408000 !rd %ccr,%o0
  51. cmp %o0,0x99
  52. bne .v8
  53. nop
  54. ! Even though we do not use %fp register bank,
  55. ! we wipe it as memcpy might have used it...
  56. .word 0xbfa00040 !fmovd %f0,%f62
  57. .word 0xbba00040 !...
  58. .word 0xb7a00040
  59. .word 0xb3a00040
  60. .word 0xafa00040
  61. .word 0xaba00040
  62. .word 0xa7a00040
  63. .word 0xa3a00040
  64. .word 0x9fa00040
  65. .word 0x9ba00040
  66. .word 0x97a00040
  67. .word 0x93a00040
  68. .word 0x8fa00040
  69. .word 0x8ba00040
  70. .word 0x87a00040
  71. .word 0x83a00040 !fmovd %f0,%f32
  72. .v8: fmovs %f1,%f31
  73. clr %o0
  74. fmovs %f0,%f30
  75. clr %o1
  76. fmovs %f1,%f29
  77. clr %o2
  78. fmovs %f0,%f28
  79. clr %o3
  80. fmovs %f1,%f27
  81. clr %o4
  82. fmovs %f0,%f26
  83. clr %o5
  84. fmovs %f1,%f25
  85. clr %o7
  86. fmovs %f0,%f24
  87. clr %l0
  88. fmovs %f1,%f23
  89. clr %l1
  90. fmovs %f0,%f22
  91. clr %l2
  92. fmovs %f1,%f21
  93. clr %l3
  94. fmovs %f0,%f20
  95. clr %l4
  96. fmovs %f1,%f19
  97. clr %l5
  98. fmovs %f0,%f18
  99. clr %l6
  100. fmovs %f1,%f17
  101. clr %l7
  102. fmovs %f0,%f16
  103. clr %i0
  104. fmovs %f1,%f15
  105. clr %i1
  106. fmovs %f0,%f14
  107. clr %i2
  108. fmovs %f1,%f13
  109. clr %i3
  110. fmovs %f0,%f12
  111. clr %i4
  112. fmovs %f1,%f11
  113. clr %i5
  114. fmovs %f0,%f10
  115. clr %g1
  116. fmovs %f1,%f9
  117. clr %g2
  118. fmovs %f0,%f8
  119. clr %g3
  120. fmovs %f1,%f7
  121. clr %g4
  122. fmovs %f0,%f6
  123. clr %g5
  124. fmovs %f1,%f5
  125. fmovs %f0,%f4
  126. fmovs %f1,%f3
  127. fmovs %f0,%f2
  128. add %fp,BIAS,%i0 ! return pointer to caller´s top of stack
  129. ret
  130. restore
  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. .global OPENSSL_atomic_add
  168. .type OPENSSL_atomic_add,#function
  169. .align 32
  170. OPENSSL_atomic_add:
  171. #ifndef ABI64
  172. subcc %g0,1,%o2
  173. .word 0x95408000 !rd %ccr,%o2, see comment above
  174. cmp %o2,0x99
  175. be .v9
  176. nop
  177. save %sp,FRAME,%sp
  178. ba .enter
  179. nop
  180. #ifdef __sun
  181. ! Note that you do not have to link with libthread to call thr_yield,
  182. ! as libc provides a stub, which is overloaded the moment you link
  183. ! with *either* libpthread or libthread...
  184. #define YIELD_CPU thr_yield
  185. #else
  186. ! applies at least to Linux and FreeBSD... Feedback expected...
  187. #define YIELD_CPU sched_yield
  188. #endif
  189. .spin: call YIELD_CPU
  190. nop
  191. .enter: ld [%i0],%i2
  192. cmp %i2,-4096
  193. be .spin
  194. mov -1,%i2
  195. swap [%i0],%i2
  196. cmp %i2,-1
  197. be .spin
  198. add %i2,%i1,%i2
  199. stbar
  200. st %i2,[%i0]
  201. sra %i2,%g0,%i0
  202. ret
  203. restore
  204. .v9:
  205. #endif
  206. ld [%o0],%o2
  207. 1: add %o1,%o2,%o3
  208. .word 0xd7e2100a !cas [%o0],%o2,%o3, compare [%o0] with %o2 and swap %o3
  209. cmp %o2,%o3
  210. bne 1b
  211. mov %o3,%o2 ! cas is always fetching to dest. register
  212. add %o1,%o2,%o0 ! OpenSSL expects the new value
  213. retl
  214. sra %o0,%g0,%o0 ! we return signed int, remember?
  215. .size OPENSSL_atomic_add,.-OPENSSL_atomic_add
  216. .global _sparcv9_rdtick
  217. .align 32
  218. _sparcv9_rdtick:
  219. subcc %g0,1,%o0
  220. .word 0x91408000 !rd %ccr,%o0
  221. cmp %o0,0x99
  222. bne .notick
  223. xor %o0,%o0,%o0
  224. .word 0x91410000 !rd %tick,%o0
  225. retl
  226. .word 0x93323020 !srlx %o0,32,%o1
  227. .notick:
  228. retl
  229. xor %o1,%o1,%o1
  230. .type _sparcv9_rdtick,#function
  231. .size _sparcv9_rdtick,.-_sparcv9_rdtick
  232. .global _sparcv9_vis1_probe
  233. .align 8
  234. _sparcv9_vis1_probe:
  235. add %sp,BIAS+2,%o1
  236. .word 0xc19a5a40 !ldda [%o1]ASI_FP16_P,%f0
  237. retl
  238. .word 0x81b00d80 !fxor %f0,%f0,%f0
  239. .type _sparcv9_vis1_probe,#function
  240. .size _sparcv9_vis1_probe,.-_sparcv9_vis1_probe
  241. ! Probe and instrument VIS1 instruction. Output is number of cycles it
  242. ! takes to execute rdtick and pair of VIS1 instructions. US-Tx VIS unit
  243. ! is slow (documented to be 6 cycles on T2) and the core is in-order
  244. ! single-issue, it should be possible to distinguish Tx reliably...
  245. ! Observed return values are:
  246. !
  247. ! UltraSPARC IIe 7
  248. ! UltraSPARC III 7
  249. ! UltraSPARC T1 24
  250. ! SPARC T4 65(*)
  251. !
  252. ! (*) result has lesser to do with VIS instruction latencies, rdtick
  253. ! appears that slow, but it does the trick in sense that FP and
  254. ! VIS code paths are still slower than integer-only ones.
  255. !
  256. ! Numbers for T2 and SPARC64 V-VII are more than welcomed.
  257. !
  258. ! It would be possible to detect specifically US-T1 by instrumenting
  259. ! fmul8ulx16, which is emulated on T1 and as such accounts for quite
  260. ! a lot of %tick-s, couple of thousand on Linux...
  261. .global _sparcv9_vis1_instrument
  262. .align 8
  263. _sparcv9_vis1_instrument:
  264. .word 0x81b00d80 !fxor %f0,%f0,%f0
  265. .word 0x85b08d82 !fxor %f2,%f2,%f2
  266. .word 0x91410000 !rd %tick,%o0
  267. .word 0x81b00d80 !fxor %f0,%f0,%f0
  268. .word 0x85b08d82 !fxor %f2,%f2,%f2
  269. .word 0x93410000 !rd %tick,%o1
  270. .word 0x81b00d80 !fxor %f0,%f0,%f0
  271. .word 0x85b08d82 !fxor %f2,%f2,%f2
  272. .word 0x95410000 !rd %tick,%o2
  273. .word 0x81b00d80 !fxor %f0,%f0,%f0
  274. .word 0x85b08d82 !fxor %f2,%f2,%f2
  275. .word 0x97410000 !rd %tick,%o3
  276. .word 0x81b00d80 !fxor %f0,%f0,%f0
  277. .word 0x85b08d82 !fxor %f2,%f2,%f2
  278. .word 0x99410000 !rd %tick,%o4
  279. ! calculate intervals
  280. sub %o1,%o0,%o0
  281. sub %o2,%o1,%o1
  282. sub %o3,%o2,%o2
  283. sub %o4,%o3,%o3
  284. ! find minimum value
  285. cmp %o0,%o1
  286. .word 0x38680002 !bgu,a %xcc,.+8
  287. mov %o1,%o0
  288. cmp %o0,%o2
  289. .word 0x38680002 !bgu,a %xcc,.+8
  290. mov %o2,%o0
  291. cmp %o0,%o3
  292. .word 0x38680002 !bgu,a %xcc,.+8
  293. mov %o3,%o0
  294. retl
  295. nop
  296. .type _sparcv9_vis1_instrument,#function
  297. .size _sparcv9_vis1_instrument,.-_sparcv9_vis1_instrument
  298. .global _sparcv9_vis2_probe
  299. .align 8
  300. _sparcv9_vis2_probe:
  301. retl
  302. .word 0x81b00980 !bshuffle %f0,%f0,%f0
  303. .type _sparcv9_vis2_probe,#function
  304. .size _sparcv9_vis2_probe,.-_sparcv9_vis2_probe
  305. .global _sparcv9_fmadd_probe
  306. .align 8
  307. _sparcv9_fmadd_probe:
  308. .word 0x81b00d80 !fxor %f0,%f0,%f0
  309. .word 0x85b08d82 !fxor %f2,%f2,%f2
  310. retl
  311. .word 0x81b80440 !fmaddd %f0,%f0,%f2,%f0
  312. .type _sparcv9_fmadd_probe,#function
  313. .size _sparcv9_fmadd_probe,.-_sparcv9_fmadd_probe
  314. .global _sparcv9_rdcfr
  315. .align 8
  316. _sparcv9_rdcfr:
  317. retl
  318. .word 0x91468000 !rd %asr26,%o0
  319. .type _sparcv9_rdcfr,#function
  320. .size _sparcv9_rdcfr,.-_sparcv9_rdcfr
  321. .global _sparcv9_vis3_probe
  322. .align 8
  323. _sparcv9_vis3_probe:
  324. retl
  325. .word 0x81b022a0 !xmulx %g0,%g0,%g0
  326. .type _sparcv9_vis3_probe,#function
  327. .size _sparcv9_vis3_probe,.-_sparcv9_vis3_probe
  328. .global _sparcv9_random
  329. .align 8
  330. _sparcv9_random:
  331. retl
  332. .word 0x91b002a0 !random %o0
  333. .type _sparcv9_random,#function
  334. .size _sparcv9_random,.-_sparcv9_vis3_probe
  335. .global _sparcv9_fjaesx_probe
  336. .align 8
  337. _sparcv9_fjaesx_probe:
  338. .word 0x81b09206 !faesencx %f2,%f6,%f0
  339. retl
  340. nop
  341. .size _sparcv9_fjaesx_probe,.-_sparcv9_fjaesx_probe
  342. .global OPENSSL_cleanse
  343. .align 32
  344. OPENSSL_cleanse:
  345. cmp %o1,14
  346. nop
  347. #ifdef ABI64
  348. bgu %xcc,.Lot
  349. #else
  350. bgu .Lot
  351. #endif
  352. cmp %o1,0
  353. bne .Little
  354. nop
  355. retl
  356. nop
  357. .Little:
  358. stb %g0,[%o0]
  359. subcc %o1,1,%o1
  360. bnz .Little
  361. add %o0,1,%o0
  362. retl
  363. nop
  364. .align 32
  365. .Lot:
  366. #ifndef ABI64
  367. subcc %g0,1,%g1
  368. ! see above for explanation
  369. .word 0x83408000 !rd %ccr,%g1
  370. cmp %g1,0x99
  371. bne .v8lot
  372. nop
  373. #endif
  374. .v9lot: andcc %o0,7,%g0
  375. bz .v9aligned
  376. nop
  377. stb %g0,[%o0]
  378. sub %o1,1,%o1
  379. ba .v9lot
  380. add %o0,1,%o0
  381. .align 16,0x01000000
  382. .v9aligned:
  383. .word 0xc0720000 !stx %g0,[%o0]
  384. sub %o1,8,%o1
  385. andcc %o1,-8,%g0
  386. #ifdef ABI64
  387. .word 0x126ffffd !bnz %xcc,.v9aligned
  388. #else
  389. .word 0x124ffffd !bnz %icc,.v9aligned
  390. #endif
  391. add %o0,8,%o0
  392. cmp %o1,0
  393. bne .Little
  394. nop
  395. retl
  396. nop
  397. #ifndef ABI64
  398. .v8lot: andcc %o0,3,%g0
  399. bz .v8aligned
  400. nop
  401. stb %g0,[%o0]
  402. sub %o1,1,%o1
  403. ba .v8lot
  404. add %o0,1,%o0
  405. nop
  406. .v8aligned:
  407. st %g0,[%o0]
  408. sub %o1,4,%o1
  409. andcc %o1,-4,%g0
  410. bnz .v8aligned
  411. add %o0,4,%o0
  412. cmp %o1,0
  413. bne .Little
  414. nop
  415. retl
  416. nop
  417. #endif
  418. .type OPENSSL_cleanse,#function
  419. .size OPENSSL_cleanse,.-OPENSSL_cleanse
  420. .global CRYPTO_memcmp
  421. .align 16
  422. CRYPTO_memcmp:
  423. cmp %o2,0
  424. #ifdef ABI64
  425. beq,pn %xcc,.Lno_data
  426. #else
  427. beq .Lno_data
  428. #endif
  429. xor %g1,%g1,%g1
  430. nop
  431. .Loop_cmp:
  432. ldub [%o0],%o3
  433. add %o0,1,%o0
  434. ldub [%o1],%o4
  435. add %o1,1,%o1
  436. subcc %o2,1,%o2
  437. xor %o3,%o4,%o4
  438. #ifdef ABI64
  439. bnz %xcc,.Loop_cmp
  440. #else
  441. bnz .Loop_cmp
  442. #endif
  443. or %o4,%g1,%g1
  444. sub %g0,%g1,%g1
  445. srl %g1,31,%g1
  446. .Lno_data:
  447. retl
  448. mov %g1,%o0
  449. .type CRYPTO_memcmp,#function
  450. .size CRYPTO_memcmp,.-CRYPTO_memcmp
  451. .global _sparcv9_vis1_instrument_bus
  452. .align 8
  453. _sparcv9_vis1_instrument_bus:
  454. mov %o1,%o3 ! save cnt
  455. .word 0x99410000 !rd %tick,%o4 ! tick
  456. mov %o4,%o5 ! lasttick = tick
  457. set 0,%g4 ! diff
  458. andn %o0,63,%g1
  459. .word 0xc1985e00 !ldda [%g1]0xf0,%f0 ! block load
  460. .word 0x8143e040 !membar #Sync
  461. .word 0xc1b85c00 !stda %f0,[%g1]0xe0 ! block store and commit
  462. .word 0x8143e040 !membar #Sync
  463. ld [%o0],%o4
  464. add %o4,%g4,%g4
  465. .word 0xc9e2100c !cas [%o0],%o4,%g4
  466. .Loop: .word 0x99410000 !rd %tick,%o4
  467. sub %o4,%o5,%g4 ! diff=tick-lasttick
  468. mov %o4,%o5 ! lasttick=tick
  469. andn %o0,63,%g1
  470. .word 0xc1985e00 !ldda [%g1]0xf0,%f0 ! block load
  471. .word 0x8143e040 !membar #Sync
  472. .word 0xc1b85c00 !stda %f0,[%g1]0xe0 ! block store and commit
  473. .word 0x8143e040 !membar #Sync
  474. ld [%o0],%o4
  475. add %o4,%g4,%g4
  476. .word 0xc9e2100c !cas [%o0],%o4,%g4
  477. subcc %o1,1,%o1 ! --$cnt
  478. bnz .Loop
  479. add %o0,4,%o0 ! ++$out
  480. retl
  481. mov %o3,%o0
  482. .type _sparcv9_vis1_instrument_bus,#function
  483. .size _sparcv9_vis1_instrument_bus,.-_sparcv9_vis1_instrument_bus
  484. .global _sparcv9_vis1_instrument_bus2
  485. .align 8
  486. _sparcv9_vis1_instrument_bus2:
  487. mov %o1,%o3 ! save cnt
  488. sll %o1,2,%o1 ! cnt*=4
  489. .word 0x99410000 !rd %tick,%o4 ! tick
  490. mov %o4,%o5 ! lasttick = tick
  491. set 0,%g4 ! diff
  492. andn %o0,63,%g1
  493. .word 0xc1985e00 !ldda [%g1]0xf0,%f0 ! block load
  494. .word 0x8143e040 !membar #Sync
  495. .word 0xc1b85c00 !stda %f0,[%g1]0xe0 ! block store and commit
  496. .word 0x8143e040 !membar #Sync
  497. ld [%o0],%o4
  498. add %o4,%g4,%g4
  499. .word 0xc9e2100c !cas [%o0],%o4,%g4
  500. .word 0x99410000 !rd %tick,%o4 ! tick
  501. sub %o4,%o5,%g4 ! diff=tick-lasttick
  502. mov %o4,%o5 ! lasttick=tick
  503. mov %g4,%g5 ! lastdiff=diff
  504. .Loop2:
  505. andn %o0,63,%g1
  506. .word 0xc1985e00 !ldda [%g1]0xf0,%f0 ! block load
  507. .word 0x8143e040 !membar #Sync
  508. .word 0xc1b85c00 !stda %f0,[%g1]0xe0 ! block store and commit
  509. .word 0x8143e040 !membar #Sync
  510. ld [%o0],%o4
  511. add %o4,%g4,%g4
  512. .word 0xc9e2100c !cas [%o0],%o4,%g4
  513. subcc %o2,1,%o2 ! --max
  514. bz .Ldone2
  515. nop
  516. .word 0x99410000 !rd %tick,%o4 ! tick
  517. sub %o4,%o5,%g4 ! diff=tick-lasttick
  518. mov %o4,%o5 ! lasttick=tick
  519. cmp %g4,%g5
  520. mov %g4,%g5 ! lastdiff=diff
  521. .word 0x83408000 !rd %ccr,%g1
  522. and %g1,4,%g1 ! isolate zero flag
  523. xor %g1,4,%g1 ! flip zero flag
  524. subcc %o1,%g1,%o1 ! conditional --$cnt
  525. bnz .Loop2
  526. add %o0,%g1,%o0 ! conditional ++$out
  527. .Ldone2:
  528. srl %o1,2,%o1
  529. retl
  530. sub %o3,%o1,%o0
  531. .type _sparcv9_vis1_instrument_bus2,#function
  532. .size _sparcv9_vis1_instrument_bus2,.-_sparcv9_vis1_instrument_bus2
  533. .section ".init",#alloc,#execinstr
  534. call OPENSSL_cpuid_setup
  535. nop