divsi3.S 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. /* $NetBSD: divsi3.S,v 1.5 2005/02/26 22:58:56 perry Exp $ */
  2. /*
  3. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  4. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  5. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  6. * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  7. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  8. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  9. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  10. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  11. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  12. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  13. * SUCH DAMAGE.
  14. */
  15. /*
  16. * stack is aligned as there's a possibility of branching to L_overflow
  17. * which makes a C call
  18. */
  19. .text
  20. .align 0
  21. .globl __umodsi3
  22. .type __umodsi3 , function
  23. __umodsi3:
  24. stmfd sp!, {lr}
  25. sub sp, sp, #4 /* align stack */
  26. bl .L_udivide
  27. add sp, sp, #4 /* unalign stack */
  28. mov r0, r1
  29. ldmfd sp!, {pc}
  30. .text
  31. .align 0
  32. .globl __modsi3
  33. .type __modsi3 , function
  34. __modsi3:
  35. stmfd sp!, {lr}
  36. sub sp, sp, #4 /* align stack */
  37. bl .L_divide
  38. add sp, sp, #4 /* unalign stack */
  39. mov r0, r1
  40. ldmfd sp!, {pc}
  41. .L_overflow:
  42. /* XXX should cause a fatal error */
  43. mvn r0, #0
  44. mov pc, lr
  45. .text
  46. .align 0
  47. .globl __udivsi3
  48. .type __udivsi3 , function
  49. __udivsi3:
  50. .L_udivide: /* r0 = r0 / r1; r1 = r0 % r1 */
  51. eor r0, r1, r0
  52. eor r1, r0, r1
  53. eor r0, r1, r0
  54. /* r0 = r1 / r0; r1 = r1 % r0 */
  55. cmp r0, #1
  56. bcc .L_overflow
  57. beq .L_divide_l0
  58. mov ip, #0
  59. movs r1, r1
  60. bpl .L_divide_l1
  61. orr ip, ip, #0x20000000 /* ip bit 0x20000000 = -ve r1 */
  62. movs r1, r1, lsr #1
  63. orrcs ip, ip, #0x10000000 /* ip bit 0x10000000 = bit 0 of r1 */
  64. b .L_divide_l1
  65. .L_divide_l0: /* r0 == 1 */
  66. mov r0, r1
  67. mov r1, #0
  68. mov pc, lr
  69. .text
  70. .align 0
  71. .globl __divsi3
  72. .type __divsi3 , function
  73. __divsi3:
  74. .L_divide: /* r0 = r0 / r1; r1 = r0 % r1 */
  75. eor r0, r1, r0
  76. eor r1, r0, r1
  77. eor r0, r1, r0
  78. /* r0 = r1 / r0; r1 = r1 % r0 */
  79. cmp r0, #1
  80. bcc .L_overflow
  81. beq .L_divide_l0
  82. ands ip, r0, #0x80000000
  83. rsbmi r0, r0, #0
  84. ands r2, r1, #0x80000000
  85. eor ip, ip, r2
  86. rsbmi r1, r1, #0
  87. orr ip, r2, ip, lsr #1 /* ip bit 0x40000000 = -ve division */
  88. /* ip bit 0x80000000 = -ve remainder */
  89. .L_divide_l1:
  90. mov r2, #1
  91. mov r3, #0
  92. /*
  93. * If the highest bit of the dividend is set, we have to be
  94. * careful when shifting the divisor. Test this.
  95. */
  96. movs r1,r1
  97. bpl .L_old_code
  98. /*
  99. * At this point, the highest bit of r1 is known to be set.
  100. * We abuse this below in the tst instructions.
  101. */
  102. tst r1, r0 /*, lsl #0 */
  103. bmi .L_divide_b1
  104. tst r1, r0, lsl #1
  105. bmi .L_divide_b2
  106. tst r1, r0, lsl #2
  107. bmi .L_divide_b3
  108. tst r1, r0, lsl #3
  109. bmi .L_divide_b4
  110. tst r1, r0, lsl #4
  111. bmi .L_divide_b5
  112. tst r1, r0, lsl #5
  113. bmi .L_divide_b6
  114. tst r1, r0, lsl #6
  115. bmi .L_divide_b7
  116. tst r1, r0, lsl #7
  117. bmi .L_divide_b8
  118. tst r1, r0, lsl #8
  119. bmi .L_divide_b9
  120. tst r1, r0, lsl #9
  121. bmi .L_divide_b10
  122. tst r1, r0, lsl #10
  123. bmi .L_divide_b11
  124. tst r1, r0, lsl #11
  125. bmi .L_divide_b12
  126. tst r1, r0, lsl #12
  127. bmi .L_divide_b13
  128. tst r1, r0, lsl #13
  129. bmi .L_divide_b14
  130. tst r1, r0, lsl #14
  131. bmi .L_divide_b15
  132. tst r1, r0, lsl #15
  133. bmi .L_divide_b16
  134. tst r1, r0, lsl #16
  135. bmi .L_divide_b17
  136. tst r1, r0, lsl #17
  137. bmi .L_divide_b18
  138. tst r1, r0, lsl #18
  139. bmi .L_divide_b19
  140. tst r1, r0, lsl #19
  141. bmi .L_divide_b20
  142. tst r1, r0, lsl #20
  143. bmi .L_divide_b21
  144. tst r1, r0, lsl #21
  145. bmi .L_divide_b22
  146. tst r1, r0, lsl #22
  147. bmi .L_divide_b23
  148. tst r1, r0, lsl #23
  149. bmi .L_divide_b24
  150. tst r1, r0, lsl #24
  151. bmi .L_divide_b25
  152. tst r1, r0, lsl #25
  153. bmi .L_divide_b26
  154. tst r1, r0, lsl #26
  155. bmi .L_divide_b27
  156. tst r1, r0, lsl #27
  157. bmi .L_divide_b28
  158. tst r1, r0, lsl #28
  159. bmi .L_divide_b29
  160. tst r1, r0, lsl #29
  161. bmi .L_divide_b30
  162. tst r1, r0, lsl #30
  163. bmi .L_divide_b31
  164. /*
  165. * instead of:
  166. * tst r1, r0, lsl #31
  167. * bmi .L_divide_b32
  168. */
  169. b .L_divide_b32
  170. .L_old_code:
  171. cmp r1, r0
  172. bcc .L_divide_b0
  173. cmp r1, r0, lsl #1
  174. bcc .L_divide_b1
  175. cmp r1, r0, lsl #2
  176. bcc .L_divide_b2
  177. cmp r1, r0, lsl #3
  178. bcc .L_divide_b3
  179. cmp r1, r0, lsl #4
  180. bcc .L_divide_b4
  181. cmp r1, r0, lsl #5
  182. bcc .L_divide_b5
  183. cmp r1, r0, lsl #6
  184. bcc .L_divide_b6
  185. cmp r1, r0, lsl #7
  186. bcc .L_divide_b7
  187. cmp r1, r0, lsl #8
  188. bcc .L_divide_b8
  189. cmp r1, r0, lsl #9
  190. bcc .L_divide_b9
  191. cmp r1, r0, lsl #10
  192. bcc .L_divide_b10
  193. cmp r1, r0, lsl #11
  194. bcc .L_divide_b11
  195. cmp r1, r0, lsl #12
  196. bcc .L_divide_b12
  197. cmp r1, r0, lsl #13
  198. bcc .L_divide_b13
  199. cmp r1, r0, lsl #14
  200. bcc .L_divide_b14
  201. cmp r1, r0, lsl #15
  202. bcc .L_divide_b15
  203. cmp r1, r0, lsl #16
  204. bcc .L_divide_b16
  205. cmp r1, r0, lsl #17
  206. bcc .L_divide_b17
  207. cmp r1, r0, lsl #18
  208. bcc .L_divide_b18
  209. cmp r1, r0, lsl #19
  210. bcc .L_divide_b19
  211. cmp r1, r0, lsl #20
  212. bcc .L_divide_b20
  213. cmp r1, r0, lsl #21
  214. bcc .L_divide_b21
  215. cmp r1, r0, lsl #22
  216. bcc .L_divide_b22
  217. cmp r1, r0, lsl #23
  218. bcc .L_divide_b23
  219. cmp r1, r0, lsl #24
  220. bcc .L_divide_b24
  221. cmp r1, r0, lsl #25
  222. bcc .L_divide_b25
  223. cmp r1, r0, lsl #26
  224. bcc .L_divide_b26
  225. cmp r1, r0, lsl #27
  226. bcc .L_divide_b27
  227. cmp r1, r0, lsl #28
  228. bcc .L_divide_b28
  229. cmp r1, r0, lsl #29
  230. bcc .L_divide_b29
  231. cmp r1, r0, lsl #30
  232. bcc .L_divide_b30
  233. .L_divide_b32:
  234. cmp r1, r0, lsl #31
  235. subhs r1, r1,r0, lsl #31
  236. addhs r3, r3,r2, lsl #31
  237. .L_divide_b31:
  238. cmp r1, r0, lsl #30
  239. subhs r1, r1,r0, lsl #30
  240. addhs r3, r3,r2, lsl #30
  241. .L_divide_b30:
  242. cmp r1, r0, lsl #29
  243. subhs r1, r1,r0, lsl #29
  244. addhs r3, r3,r2, lsl #29
  245. .L_divide_b29:
  246. cmp r1, r0, lsl #28
  247. subhs r1, r1,r0, lsl #28
  248. addhs r3, r3,r2, lsl #28
  249. .L_divide_b28:
  250. cmp r1, r0, lsl #27
  251. subhs r1, r1,r0, lsl #27
  252. addhs r3, r3,r2, lsl #27
  253. .L_divide_b27:
  254. cmp r1, r0, lsl #26
  255. subhs r1, r1,r0, lsl #26
  256. addhs r3, r3,r2, lsl #26
  257. .L_divide_b26:
  258. cmp r1, r0, lsl #25
  259. subhs r1, r1,r0, lsl #25
  260. addhs r3, r3,r2, lsl #25
  261. .L_divide_b25:
  262. cmp r1, r0, lsl #24
  263. subhs r1, r1,r0, lsl #24
  264. addhs r3, r3,r2, lsl #24
  265. .L_divide_b24:
  266. cmp r1, r0, lsl #23
  267. subhs r1, r1,r0, lsl #23
  268. addhs r3, r3,r2, lsl #23
  269. .L_divide_b23:
  270. cmp r1, r0, lsl #22
  271. subhs r1, r1,r0, lsl #22
  272. addhs r3, r3,r2, lsl #22
  273. .L_divide_b22:
  274. cmp r1, r0, lsl #21
  275. subhs r1, r1,r0, lsl #21
  276. addhs r3, r3,r2, lsl #21
  277. .L_divide_b21:
  278. cmp r1, r0, lsl #20
  279. subhs r1, r1,r0, lsl #20
  280. addhs r3, r3,r2, lsl #20
  281. .L_divide_b20:
  282. cmp r1, r0, lsl #19
  283. subhs r1, r1,r0, lsl #19
  284. addhs r3, r3,r2, lsl #19
  285. .L_divide_b19:
  286. cmp r1, r0, lsl #18
  287. subhs r1, r1,r0, lsl #18
  288. addhs r3, r3,r2, lsl #18
  289. .L_divide_b18:
  290. cmp r1, r0, lsl #17
  291. subhs r1, r1,r0, lsl #17
  292. addhs r3, r3,r2, lsl #17
  293. .L_divide_b17:
  294. cmp r1, r0, lsl #16
  295. subhs r1, r1,r0, lsl #16
  296. addhs r3, r3,r2, lsl #16
  297. .L_divide_b16:
  298. cmp r1, r0, lsl #15
  299. subhs r1, r1,r0, lsl #15
  300. addhs r3, r3,r2, lsl #15
  301. .L_divide_b15:
  302. cmp r1, r0, lsl #14
  303. subhs r1, r1,r0, lsl #14
  304. addhs r3, r3,r2, lsl #14
  305. .L_divide_b14:
  306. cmp r1, r0, lsl #13
  307. subhs r1, r1,r0, lsl #13
  308. addhs r3, r3,r2, lsl #13
  309. .L_divide_b13:
  310. cmp r1, r0, lsl #12
  311. subhs r1, r1,r0, lsl #12
  312. addhs r3, r3,r2, lsl #12
  313. .L_divide_b12:
  314. cmp r1, r0, lsl #11
  315. subhs r1, r1,r0, lsl #11
  316. addhs r3, r3,r2, lsl #11
  317. .L_divide_b11:
  318. cmp r1, r0, lsl #10
  319. subhs r1, r1,r0, lsl #10
  320. addhs r3, r3,r2, lsl #10
  321. .L_divide_b10:
  322. cmp r1, r0, lsl #9
  323. subhs r1, r1,r0, lsl #9
  324. addhs r3, r3,r2, lsl #9
  325. .L_divide_b9:
  326. cmp r1, r0, lsl #8
  327. subhs r1, r1,r0, lsl #8
  328. addhs r3, r3,r2, lsl #8
  329. .L_divide_b8:
  330. cmp r1, r0, lsl #7
  331. subhs r1, r1,r0, lsl #7
  332. addhs r3, r3,r2, lsl #7
  333. .L_divide_b7:
  334. cmp r1, r0, lsl #6
  335. subhs r1, r1,r0, lsl #6
  336. addhs r3, r3,r2, lsl #6
  337. .L_divide_b6:
  338. cmp r1, r0, lsl #5
  339. subhs r1, r1,r0, lsl #5
  340. addhs r3, r3,r2, lsl #5
  341. .L_divide_b5:
  342. cmp r1, r0, lsl #4
  343. subhs r1, r1,r0, lsl #4
  344. addhs r3, r3,r2, lsl #4
  345. .L_divide_b4:
  346. cmp r1, r0, lsl #3
  347. subhs r1, r1,r0, lsl #3
  348. addhs r3, r3,r2, lsl #3
  349. .L_divide_b3:
  350. cmp r1, r0, lsl #2
  351. subhs r1, r1,r0, lsl #2
  352. addhs r3, r3,r2, lsl #2
  353. .L_divide_b2:
  354. cmp r1, r0, lsl #1
  355. subhs r1, r1,r0, lsl #1
  356. addhs r3, r3,r2, lsl #1
  357. .L_divide_b1:
  358. cmp r1, r0
  359. subhs r1, r1, r0
  360. addhs r3, r3, r2
  361. .L_divide_b0:
  362. tst ip, #0x20000000
  363. bne .L_udivide_l1
  364. mov r0, r3
  365. cmp ip, #0
  366. rsbmi r1, r1, #0
  367. movs ip, ip, lsl #1
  368. bicmi r0, r0, #0x80000000 /* Fix incase we divided 0x80000000 */
  369. rsbmi r0, r0, #0
  370. mov pc, lr
  371. .L_udivide_l1:
  372. tst ip, #0x10000000
  373. mov r1, r1, lsl #1
  374. orrne r1, r1, #1
  375. mov r3, r3, lsl #1
  376. cmp r1, r0
  377. subhs r1, r1, r0
  378. addhs r3, r3, r2
  379. mov r0, r3
  380. mov pc, lr