udivsi3_i4i.S 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645
  1. /* SPDX-License-Identifier: GPL-2.0+ WITH GCC-exception-2.0
  2. Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
  3. 2004, 2005, 2006
  4. Free Software Foundation, Inc.
  5. */
  6. !! libgcc routines for the Renesas / SuperH SH CPUs.
  7. !! Contributed by Steve Chamberlain.
  8. !! sac@cygnus.com
  9. !! ashiftrt_r4_x, ___ashrsi3, ___ashlsi3, ___lshrsi3 routines
  10. !! recoded in assembly by Toshiyasu Morita
  11. !! tm@netcom.com
  12. /* SH2 optimizations for ___ashrsi3, ___ashlsi3, ___lshrsi3 and
  13. ELF local label prefixes by J"orn Rennecke
  14. amylaar@cygnus.com */
  15. /* This code used shld, thus is not suitable for SH1 / SH2. */
  16. /* Signed / unsigned division without use of FPU, optimized for SH4.
  17. Uses a lookup table for divisors in the range -128 .. +128, and
  18. div1 with case distinction for larger divisors in three more ranges.
  19. The code is lumped together with the table to allow the use of mova. */
  20. #ifdef CONFIG_CPU_LITTLE_ENDIAN
  21. #define L_LSB 0
  22. #define L_LSWMSB 1
  23. #define L_MSWLSB 2
  24. #else
  25. #define L_LSB 3
  26. #define L_LSWMSB 2
  27. #define L_MSWLSB 1
  28. #endif
  29. .balign 4
  30. .global __udivsi3_i4i
  31. .global __udivsi3_i4
  32. .set __udivsi3_i4, __udivsi3_i4i
  33. .type __udivsi3_i4i, @function
  34. __udivsi3_i4i:
  35. mov.w c128_w, r1
  36. div0u
  37. mov r4,r0
  38. shlr8 r0
  39. cmp/hi r1,r5
  40. extu.w r5,r1
  41. bf udiv_le128
  42. cmp/eq r5,r1
  43. bf udiv_ge64k
  44. shlr r0
  45. mov r5,r1
  46. shll16 r5
  47. mov.l r4,@-r15
  48. div1 r5,r0
  49. mov.l r1,@-r15
  50. div1 r5,r0
  51. div1 r5,r0
  52. bra udiv_25
  53. div1 r5,r0
  54. div_le128:
  55. mova div_table_ix,r0
  56. bra div_le128_2
  57. mov.b @(r0,r5),r1
  58. udiv_le128:
  59. mov.l r4,@-r15
  60. mova div_table_ix,r0
  61. mov.b @(r0,r5),r1
  62. mov.l r5,@-r15
  63. div_le128_2:
  64. mova div_table_inv,r0
  65. mov.l @(r0,r1),r1
  66. mov r5,r0
  67. tst #0xfe,r0
  68. mova div_table_clz,r0
  69. dmulu.l r1,r4
  70. mov.b @(r0,r5),r1
  71. bt/s div_by_1
  72. mov r4,r0
  73. mov.l @r15+,r5
  74. sts mach,r0
  75. /* clrt */
  76. addc r4,r0
  77. mov.l @r15+,r4
  78. rotcr r0
  79. rts
  80. shld r1,r0
  81. div_by_1_neg:
  82. neg r4,r0
  83. div_by_1:
  84. mov.l @r15+,r5
  85. rts
  86. mov.l @r15+,r4
  87. div_ge64k:
  88. bt/s div_r8
  89. div0u
  90. shll8 r5
  91. bra div_ge64k_2
  92. div1 r5,r0
  93. udiv_ge64k:
  94. cmp/hi r0,r5
  95. mov r5,r1
  96. bt udiv_r8
  97. shll8 r5
  98. mov.l r4,@-r15
  99. div1 r5,r0
  100. mov.l r1,@-r15
  101. div_ge64k_2:
  102. div1 r5,r0
  103. mov.l zero_l,r1
  104. .rept 4
  105. div1 r5,r0
  106. .endr
  107. mov.l r1,@-r15
  108. div1 r5,r0
  109. mov.w m256_w,r1
  110. div1 r5,r0
  111. mov.b r0,@(L_LSWMSB,r15)
  112. xor r4,r0
  113. and r1,r0
  114. bra div_ge64k_end
  115. xor r4,r0
  116. div_r8:
  117. shll16 r4
  118. bra div_r8_2
  119. shll8 r4
  120. udiv_r8:
  121. mov.l r4,@-r15
  122. shll16 r4
  123. clrt
  124. shll8 r4
  125. mov.l r5,@-r15
  126. div_r8_2:
  127. rotcl r4
  128. mov r0,r1
  129. div1 r5,r1
  130. mov r4,r0
  131. rotcl r0
  132. mov r5,r4
  133. div1 r5,r1
  134. .rept 5
  135. rotcl r0; div1 r5,r1
  136. .endr
  137. rotcl r0
  138. mov.l @r15+,r5
  139. div1 r4,r1
  140. mov.l @r15+,r4
  141. rts
  142. rotcl r0
  143. .global __sdivsi3_i4i
  144. .global __sdivsi3_i4
  145. .global __sdivsi3
  146. .set __sdivsi3_i4, __sdivsi3_i4i
  147. .set __sdivsi3, __sdivsi3_i4i
  148. .type __sdivsi3_i4i, @function
  149. /* This is link-compatible with a __sdivsi3 call,
  150. but we effectively clobber only r1. */
  151. __sdivsi3_i4i:
  152. mov.l r4,@-r15
  153. cmp/pz r5
  154. mov.w c128_w, r1
  155. bt/s pos_divisor
  156. cmp/pz r4
  157. mov.l r5,@-r15
  158. neg r5,r5
  159. bt/s neg_result
  160. cmp/hi r1,r5
  161. neg r4,r4
  162. pos_result:
  163. extu.w r5,r0
  164. bf div_le128
  165. cmp/eq r5,r0
  166. mov r4,r0
  167. shlr8 r0
  168. bf/s div_ge64k
  169. cmp/hi r0,r5
  170. div0u
  171. shll16 r5
  172. div1 r5,r0
  173. div1 r5,r0
  174. div1 r5,r0
  175. udiv_25:
  176. mov.l zero_l,r1
  177. div1 r5,r0
  178. div1 r5,r0
  179. mov.l r1,@-r15
  180. .rept 3
  181. div1 r5,r0
  182. .endr
  183. mov.b r0,@(L_MSWLSB,r15)
  184. xtrct r4,r0
  185. swap.w r0,r0
  186. .rept 8
  187. div1 r5,r0
  188. .endr
  189. mov.b r0,@(L_LSWMSB,r15)
  190. div_ge64k_end:
  191. .rept 8
  192. div1 r5,r0
  193. .endr
  194. mov.l @r15+,r4 ! zero-extension and swap using LS unit.
  195. extu.b r0,r0
  196. mov.l @r15+,r5
  197. or r4,r0
  198. mov.l @r15+,r4
  199. rts
  200. rotcl r0
  201. div_le128_neg:
  202. tst #0xfe,r0
  203. mova div_table_ix,r0
  204. mov.b @(r0,r5),r1
  205. mova div_table_inv,r0
  206. bt/s div_by_1_neg
  207. mov.l @(r0,r1),r1
  208. mova div_table_clz,r0
  209. dmulu.l r1,r4
  210. mov.b @(r0,r5),r1
  211. mov.l @r15+,r5
  212. sts mach,r0
  213. /* clrt */
  214. addc r4,r0
  215. mov.l @r15+,r4
  216. rotcr r0
  217. shld r1,r0
  218. rts
  219. neg r0,r0
  220. pos_divisor:
  221. mov.l r5,@-r15
  222. bt/s pos_result
  223. cmp/hi r1,r5
  224. neg r4,r4
  225. neg_result:
  226. extu.w r5,r0
  227. bf div_le128_neg
  228. cmp/eq r5,r0
  229. mov r4,r0
  230. shlr8 r0
  231. bf/s div_ge64k_neg
  232. cmp/hi r0,r5
  233. div0u
  234. mov.l zero_l,r1
  235. shll16 r5
  236. div1 r5,r0
  237. mov.l r1,@-r15
  238. .rept 7
  239. div1 r5,r0
  240. .endr
  241. mov.b r0,@(L_MSWLSB,r15)
  242. xtrct r4,r0
  243. swap.w r0,r0
  244. .rept 8
  245. div1 r5,r0
  246. .endr
  247. mov.b r0,@(L_LSWMSB,r15)
  248. div_ge64k_neg_end:
  249. .rept 8
  250. div1 r5,r0
  251. .endr
  252. mov.l @r15+,r4 ! zero-extension and swap using LS unit.
  253. extu.b r0,r1
  254. mov.l @r15+,r5
  255. or r4,r1
  256. div_r8_neg_end:
  257. mov.l @r15+,r4
  258. rotcl r1
  259. rts
  260. neg r1,r0
  261. div_ge64k_neg:
  262. bt/s div_r8_neg
  263. div0u
  264. shll8 r5
  265. mov.l zero_l,r1
  266. .rept 6
  267. div1 r5,r0
  268. .endr
  269. mov.l r1,@-r15
  270. div1 r5,r0
  271. mov.w m256_w,r1
  272. div1 r5,r0
  273. mov.b r0,@(L_LSWMSB,r15)
  274. xor r4,r0
  275. and r1,r0
  276. bra div_ge64k_neg_end
  277. xor r4,r0
  278. c128_w:
  279. .word 128
  280. div_r8_neg:
  281. clrt
  282. shll16 r4
  283. mov r4,r1
  284. shll8 r1
  285. mov r5,r4
  286. .rept 7
  287. rotcl r1; div1 r5,r0
  288. .endr
  289. mov.l @r15+,r5
  290. rotcl r1
  291. bra div_r8_neg_end
  292. div1 r4,r0
  293. m256_w:
  294. .word 0xff00
  295. /* This table has been generated by divtab-sh4.c. */
  296. .balign 4
  297. div_table_clz:
  298. .byte 0
  299. .byte 1
  300. .byte 0
  301. .byte -1
  302. .byte -1
  303. .byte -2
  304. .byte -2
  305. .byte -2
  306. .byte -2
  307. .byte -3
  308. .byte -3
  309. .byte -3
  310. .byte -3
  311. .byte -3
  312. .byte -3
  313. .byte -3
  314. .byte -3
  315. .byte -4
  316. .byte -4
  317. .byte -4
  318. .byte -4
  319. .byte -4
  320. .byte -4
  321. .byte -4
  322. .byte -4
  323. .byte -4
  324. .byte -4
  325. .byte -4
  326. .byte -4
  327. .byte -4
  328. .byte -4
  329. .byte -4
  330. .byte -4
  331. .byte -5
  332. .byte -5
  333. .byte -5
  334. .byte -5
  335. .byte -5
  336. .byte -5
  337. .byte -5
  338. .byte -5
  339. .byte -5
  340. .byte -5
  341. .byte -5
  342. .byte -5
  343. .byte -5
  344. .byte -5
  345. .byte -5
  346. .byte -5
  347. .byte -5
  348. .byte -5
  349. .byte -5
  350. .byte -5
  351. .byte -5
  352. .byte -5
  353. .byte -5
  354. .byte -5
  355. .byte -5
  356. .byte -5
  357. .byte -5
  358. .byte -5
  359. .byte -5
  360. .byte -5
  361. .byte -5
  362. .byte -5
  363. .byte -6
  364. .byte -6
  365. .byte -6
  366. .byte -6
  367. .byte -6
  368. .byte -6
  369. .byte -6
  370. .byte -6
  371. .byte -6
  372. .byte -6
  373. .byte -6
  374. .byte -6
  375. .byte -6
  376. .byte -6
  377. .byte -6
  378. .byte -6
  379. .byte -6
  380. .byte -6
  381. .byte -6
  382. .byte -6
  383. .byte -6
  384. .byte -6
  385. .byte -6
  386. .byte -6
  387. .byte -6
  388. .byte -6
  389. .byte -6
  390. .byte -6
  391. .byte -6
  392. .byte -6
  393. .byte -6
  394. .byte -6
  395. .byte -6
  396. .byte -6
  397. .byte -6
  398. .byte -6
  399. .byte -6
  400. .byte -6
  401. .byte -6
  402. .byte -6
  403. .byte -6
  404. .byte -6
  405. .byte -6
  406. .byte -6
  407. .byte -6
  408. .byte -6
  409. .byte -6
  410. .byte -6
  411. .byte -6
  412. .byte -6
  413. .byte -6
  414. .byte -6
  415. .byte -6
  416. .byte -6
  417. .byte -6
  418. .byte -6
  419. .byte -6
  420. .byte -6
  421. .byte -6
  422. .byte -6
  423. .byte -6
  424. .byte -6
  425. .byte -6
  426. /* Lookup table translating positive divisor to index into table of
  427. normalized inverse. N.B. the '0' entry is also the last entry of the
  428. previous table, and causes an unaligned access for division by zero. */
  429. div_table_ix:
  430. .byte -6
  431. .byte -128
  432. .byte -128
  433. .byte 0
  434. .byte -128
  435. .byte -64
  436. .byte 0
  437. .byte 64
  438. .byte -128
  439. .byte -96
  440. .byte -64
  441. .byte -32
  442. .byte 0
  443. .byte 32
  444. .byte 64
  445. .byte 96
  446. .byte -128
  447. .byte -112
  448. .byte -96
  449. .byte -80
  450. .byte -64
  451. .byte -48
  452. .byte -32
  453. .byte -16
  454. .byte 0
  455. .byte 16
  456. .byte 32
  457. .byte 48
  458. .byte 64
  459. .byte 80
  460. .byte 96
  461. .byte 112
  462. .byte -128
  463. .byte -120
  464. .byte -112
  465. .byte -104
  466. .byte -96
  467. .byte -88
  468. .byte -80
  469. .byte -72
  470. .byte -64
  471. .byte -56
  472. .byte -48
  473. .byte -40
  474. .byte -32
  475. .byte -24
  476. .byte -16
  477. .byte -8
  478. .byte 0
  479. .byte 8
  480. .byte 16
  481. .byte 24
  482. .byte 32
  483. .byte 40
  484. .byte 48
  485. .byte 56
  486. .byte 64
  487. .byte 72
  488. .byte 80
  489. .byte 88
  490. .byte 96
  491. .byte 104
  492. .byte 112
  493. .byte 120
  494. .byte -128
  495. .byte -124
  496. .byte -120
  497. .byte -116
  498. .byte -112
  499. .byte -108
  500. .byte -104
  501. .byte -100
  502. .byte -96
  503. .byte -92
  504. .byte -88
  505. .byte -84
  506. .byte -80
  507. .byte -76
  508. .byte -72
  509. .byte -68
  510. .byte -64
  511. .byte -60
  512. .byte -56
  513. .byte -52
  514. .byte -48
  515. .byte -44
  516. .byte -40
  517. .byte -36
  518. .byte -32
  519. .byte -28
  520. .byte -24
  521. .byte -20
  522. .byte -16
  523. .byte -12
  524. .byte -8
  525. .byte -4
  526. .byte 0
  527. .byte 4
  528. .byte 8
  529. .byte 12
  530. .byte 16
  531. .byte 20
  532. .byte 24
  533. .byte 28
  534. .byte 32
  535. .byte 36
  536. .byte 40
  537. .byte 44
  538. .byte 48
  539. .byte 52
  540. .byte 56
  541. .byte 60
  542. .byte 64
  543. .byte 68
  544. .byte 72
  545. .byte 76
  546. .byte 80
  547. .byte 84
  548. .byte 88
  549. .byte 92
  550. .byte 96
  551. .byte 100
  552. .byte 104
  553. .byte 108
  554. .byte 112
  555. .byte 116
  556. .byte 120
  557. .byte 124
  558. .byte -128
  559. /* 1/64 .. 1/127, normalized. There is an implicit leading 1 in bit 32. */
  560. .balign 4
  561. zero_l:
  562. .long 0x0
  563. .long 0xF81F81F9
  564. .long 0xF07C1F08
  565. .long 0xE9131AC0
  566. .long 0xE1E1E1E2
  567. .long 0xDAE6076C
  568. .long 0xD41D41D5
  569. .long 0xCD856891
  570. .long 0xC71C71C8
  571. .long 0xC0E07039
  572. .long 0xBACF914D
  573. .long 0xB4E81B4F
  574. .long 0xAF286BCB
  575. .long 0xA98EF607
  576. .long 0xA41A41A5
  577. .long 0x9EC8E952
  578. .long 0x9999999A
  579. .long 0x948B0FCE
  580. .long 0x8F9C18FA
  581. .long 0x8ACB90F7
  582. .long 0x86186187
  583. .long 0x81818182
  584. .long 0x7D05F418
  585. .long 0x78A4C818
  586. .long 0x745D1746
  587. .long 0x702E05C1
  588. .long 0x6C16C16D
  589. .long 0x68168169
  590. .long 0x642C8591
  591. .long 0x60581606
  592. .long 0x5C9882BA
  593. .long 0x58ED2309
  594. div_table_inv:
  595. .long 0x55555556
  596. .long 0x51D07EAF
  597. .long 0x4E5E0A73
  598. .long 0x4AFD6A06
  599. .long 0x47AE147B
  600. .long 0x446F8657
  601. .long 0x41414142
  602. .long 0x3E22CBCF
  603. .long 0x3B13B13C
  604. .long 0x38138139
  605. .long 0x3521CFB3
  606. .long 0x323E34A3
  607. .long 0x2F684BDB
  608. .long 0x2C9FB4D9
  609. .long 0x29E4129F
  610. .long 0x27350B89
  611. .long 0x24924925
  612. .long 0x21FB7813
  613. .long 0x1F7047DD
  614. .long 0x1CF06ADB
  615. .long 0x1A7B9612
  616. .long 0x18118119
  617. .long 0x15B1E5F8
  618. .long 0x135C8114
  619. .long 0x11111112
  620. .long 0xECF56BF
  621. .long 0xC9714FC
  622. .long 0xA6810A7
  623. .long 0x8421085
  624. .long 0x624DD30
  625. .long 0x4104105
  626. .long 0x2040811
  627. /* maximum error: 0.987342 scaled: 0.921875*/