CPDO.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:12k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2. The FP structure has 4 words reserved for each register, the first is used just
  3. for the sign in bit 31, the second and third are for the mantissa (unsigned
  4. integer, high 32 bit first) and the fourth is the exponent (signed integer).
  5. The mantissa is always normalized.
  6. If the exponent is 0x80000000, that is the most negative value, the number
  7. represented is 0 and both mantissa words are also 0.
  8. If the exponent is 0x7fffffff, that is the biggest positive value, the number
  9. represented is infinity if the high 32 mantissa bit are also 0, otherwise it is
  10. a NaN. The low 32 mantissa bit are 0 if the number represented is infinity.
  11. Decimal and packed decimal numbers are not supported yet.
  12. The parameters to these functions are r0=destination pointer, r1 and r2
  13. source pointers. r4 is the instruction. They may use r0-r8 and r14. They return
  14. to fastfpe_next, except CPDO_rnf_core which expects the return address in r14.
  15. */
  16. /*---------------------------------------------------------------------------*/
  17. .globl CPDO_adf
  18. CPDO_adf:
  19. ldmia r1,{r1,r3,r5,r7}
  20. ldmia r2,{r2,r4,r6,r8}
  21. cmp r7,#0x7fffffff
  22. cmpne r8,#0x7fffffff
  23. beq CPDO_adf_extra
  24. cmp r1,r2
  25. bne CPDO_suf_s
  26. CPDO_adf_s:
  27. subs r2,r7,r8
  28. bge CPDO_adf_2nd
  29. mov r7,r8
  30. rsb r2,r2,#0
  31. cmp r2,#32
  32. ble CPDO_adf_1st2
  33. sub r2,r2,#32
  34. cmp r2,#32
  35. movgt r2,#32
  36. mov r5,r3,lsr r2
  37. mov r3,#0
  38. b CPDO_adf_add
  39. CPDO_adf_1st2:
  40. rsb r8,r2,#32
  41. mov r5,r5,lsr r2
  42. orr r5,r5,r3,lsl r8
  43. mov r3,r3,lsr r2 @ 1. op normalized
  44. b CPDO_adf_add
  45. CPDO_adf_2nd:
  46. cmp r2,#32
  47. ble CPDO_adf_2nd2
  48. sub r2,r2,#32
  49. cmp r2,#32
  50. movgt r2,#32
  51. mov r6,r4,lsr r2
  52. mov r4,#0
  53. b CPDO_adf_add
  54. CPDO_adf_2nd2:
  55. rsb r8,r2,#32
  56. mov r6,r6,lsr r2
  57. orr r6,r6,r4,lsl r8
  58. mov r4,r4,lsr r2 @ 2. op normalized
  59. CPDO_adf_add:
  60. adds r5,r5,r6
  61. adcs r3,r3,r4 @ do addition
  62. bcc CPDO_adf_end
  63. add r7,r7,#1
  64. movs r3,r3,rrx
  65. mov r5,r5,rrx @ correct for overflow
  66. CPDO_adf_end:
  67. cmp r7,#0x20000000
  68. bge CPDO_inf
  69. stmia r0,{r1,r3,r5,r7}
  70. b fastfpe_next
  71. CPDO_adf_extra:
  72. cmp r7,#0x7fffffff @ was it the 1st ?
  73. bne CPDO_infnan_2 @ no it was the 2nd
  74. cmp r8,#0x7fffffff @ if 1st, 2nd too ?
  75. bne CPDO_infnan_1 @ no only 1st
  76. cmp r3,#0
  77. cmpeq r4,#0
  78. bne CPDO_nan_12
  79. b CPDO_inf
  80. /*---------------------------------------------------------------------------*/
  81. CPDO_infnan_1:
  82. stmia r0,{r1,r3,r5,r7}
  83. b fastfpe_next
  84. CPDO_infnan_2:
  85. stmia r0,{r2,r4,r6,r8}
  86. b fastfpe_next
  87. CPDO_nan_12:
  88. orr r2,r3,r4
  89. b CPDO_inf_1
  90. CPDO_nan:
  91. mov r2,#0x40000000 @ create non signalling NaN
  92. b CPDO_inf_1
  93. CPDO_inf:
  94. mov r2,#0
  95. CPDO_inf_1:
  96. mov r3,#0
  97. mov r4,#0x7fffffff
  98. CPDO_store_1234:
  99. stmia r0,{r1,r2,r3,r4}
  100. b fastfpe_next
  101. CPDO_zero:
  102. mov r1,#0
  103. CPDO_zero_1:
  104. mov r2,#0
  105. mov r3,#0
  106. mov r4,#0x80000000
  107. stmia r0,{r1,r2,r3,r4}
  108. b fastfpe_next
  109. /*---------------------------------------------------------------------------*/
  110. .globl CPDO_suf
  111. CPDO_suf:
  112. ldmia r1,{r1,r3,r5,r7}
  113. ldmia r2,{r2,r4,r6,r8}
  114. CPDO_suf_l:
  115. cmp r7,#0x7fffffff
  116. cmpne r8,#0x7fffffff
  117. beq CPDO_suf_extra
  118. cmp r1,r2
  119. bne CPDO_adf_s
  120. CPDO_suf_s:
  121. subs r2,r7,r8 @ determine greater number
  122. bgt CPDO_suf_2nd @ first number is greater
  123. blt CPDO_suf_1st @ second number is greater
  124. cmp r3,r4 @ also mantissa is important
  125. cmpeq r5,r6
  126. bhi CPDO_suf_2nd @ first number is greater
  127. beq CPDO_zero
  128. CPDO_suf_1st:
  129. eor r1,r1,#0x80000000 @ second number is greater, invert sign
  130. mov r7,r8
  131. rsb r2,r2,#0
  132. cmp r2,#32
  133. ble CPDO_suf_1st2
  134. sub r2,r2,#32
  135. cmp r2,#32
  136. movgt r2,#32
  137. mov r5,r3,lsr r2
  138. mov r3,#0
  139. b CPDO_suf_1st_sub
  140. CPDO_suf_1st2:
  141. rsb r8,r2,#32
  142. mov r5,r5,lsr r2
  143. orr r5,r5,r3,lsl r8
  144. mov r3,r3,lsr r2 @ 1. op normalized
  145. CPDO_suf_1st_sub:
  146. subs r5,r6,r5 @ do subtraction
  147. sbc r3,r4,r3
  148. b CPDO_suf_norm
  149. CPDO_suf_2nd:
  150. cmp r2,#32
  151. ble CPDO_suf_2nd2
  152. sub r2,r2,#32
  153. cmp r2,#32
  154. movgt r2,#32
  155. mov r6,r4,lsr r2
  156. mov r4,#0
  157. b CPDO_suf_2nd_sub
  158. CPDO_suf_2nd2:
  159. rsb r8,r2,#32
  160. mov r6,r6,lsr r2
  161. orr r6,r6,r4,lsl r8
  162. mov r4,r4,lsr r2 @ 2. op normalized
  163. CPDO_suf_2nd_sub:
  164. subs r5,r5,r6
  165. sbc r3,r3,r4 @ do subtraction
  166. CPDO_suf_norm:
  167. teq r3,#0 @ normalize 32bit
  168. moveq r3,r5
  169. moveq r5,#0
  170. subeq r7,r7,#32
  171. cmp r3,#0x00010000 @ 16bit
  172. movcc r3,r3,lsl#16
  173. orrcc r3,r3,r5,lsr#16
  174. movcc r5,r5,lsl#16
  175. subcc r7,r7,#16
  176. cmp r3,#0x01000000 @ 8bit
  177. movcc r3,r3,lsl#8
  178. orrcc r3,r3,r5,lsr#24
  179. movcc r5,r5,lsl#8
  180. subcc r7,r7,#8
  181. cmp r3,#0x10000000 @ 4bit
  182. movcc r3,r3,lsl#4
  183. orrcc r3,r3,r5,lsr#28
  184. movcc r5,r5,lsl#4
  185. subcc r7,r7,#4
  186. cmp r3,#0x40000000 @ 2bit
  187. movcc r3,r3,lsl#2
  188. orrcc r3,r3,r5,lsr#30
  189. movcc r5,r5,lsl#2
  190. subcc r7,r7,#2
  191. cmp r3,#0x80000000 @ 1bit
  192. movcc r3,r3,lsl#1
  193. orrcc r3,r3,r5,lsr#31
  194. movcc r5,r5,lsl#1
  195. subcc r7,r7,#1
  196. cmp r7,#0xe0000000
  197. ble CPDO_zero_1
  198. stmia r0,{r1,r3,r5,r7}
  199. b fastfpe_next
  200. CPDO_suf_extra:
  201. cmp r7,#0x7fffffff @ was it the 1st ?
  202. eorne r2,r2,#0x80000000 @ change sign, might have been INF
  203. bne CPDO_infnan_2 @ no it was the 2nd
  204. cmp r8,#0x7fffffff @ if 1st, 2nd too ?
  205. bne CPDO_infnan_1 @ no only 1st
  206. cmp r3,#0
  207. cmpeq r4,#0
  208. bne CPDO_nan_12
  209. b CPDO_nan @ here is difference with adf !
  210. /*---------------------------------------------------------------------------*/
  211. .globl CPDO_rsf
  212. CPDO_rsf:
  213. mov r3,r2
  214. ldmia r1,{r2,r4,r6,r8}
  215. ldmia r3,{r1,r3,r5,r7}
  216. b CPDO_suf_l
  217. /*---------------------------------------------------------------------------*/
  218. .globl CPDO_muf
  219. CPDO_muf:
  220. ldmia r1,{r1,r3,r5,r7}
  221. ldmia r2,{r2,r4,r6,r8}
  222. cmp r7,#0x7fffffff
  223. cmpne r8,#0x7fffffff
  224. beq CPDO_muf_extra
  225. eor r1,r1,r2
  226. adds r8,r7,r8
  227. bvs CPDO_zero_1
  228. umull r7,r2,r3,r4
  229. umull r14,r3,r6,r3
  230. adds r7,r7,r3 @ r2|r7|r14 = r2|r7|#0 + #0|r3|r14
  231. adc r2,r2,#0
  232. umull r4,r3,r5,r4
  233. adds r14,r14,r4 @ r2|r7|r14 += #0|r3|r4
  234. adcs r7,r7,r3
  235. adc r2,r2,#0
  236. umull r4,r3,r5,r6
  237. adds r14,r14,r3 @ r2|r7|r14 += #0|#0|r3
  238. adcs r7,r7,#0
  239. adcs r2,r2,#0
  240. bpl CPDO_muf_norm
  241. add r8,r8,#1
  242. b CPDO_muf_end
  243. CPDO_muf_norm:
  244. adds r14,r14,r14
  245. adcs r7,r7,r7
  246. adcs r2,r2,r2
  247. CPDO_muf_end:
  248. cmp r8,#0x20000000
  249. bge CPDO_inf
  250. cmp r8,#0xe0000000
  251. ble CPDO_zero_1
  252. stmia r0,{r1,r2,r7,r8}
  253. b fastfpe_next
  254. CPDO_muf_extra:
  255. cmp r7,#0x7fffffff @ was it the first?
  256. bne CPDO_muf_extra_2nd @ no, so it was the second
  257. cmp r8,#0x7fffffff @ yes, second too?
  258. bne CPDO_muf_extra_1st @ no, only first
  259. orr r3,r3,r4 @ if both inf -> inf, otherwise nan
  260. eor r1,r1,r2 @ sign for the inf case
  261. b CPDO_infnan_1
  262. CPDO_muf_extra_1st:
  263. cmp r3,#0 @ is it a nan?
  264. bne CPDO_infnan_1
  265. cmp r8,#0x80000000 @ is the second 0?
  266. beq CPDO_nan
  267. eor r1,r1,r2 @ correct sign for inf
  268. b CPDO_inf
  269. CPDO_muf_extra_2nd:
  270. cmp r4,#0 @ is it a nan?
  271. bne CPDO_infnan_2
  272. cmp r7,#0x80000000 @ is the first 0?
  273. beq CPDO_nan
  274. eor r1,r1,r2 @ correct sign for inf
  275. b CPDO_inf
  276. /*---------------------------------------------------------------------------*/
  277. .globl CPDO_dvf
  278. CPDO_dvf:
  279. ldmia r1,{r1,r3,r5,r7}
  280. ldmia r2,{r2,r4,r6,r8}
  281. CPDO_dvf_l:
  282. cmp r7,#0x7fffffff
  283. cmpne r8,#0x7fffffff
  284. beq CPDO_dvf_extra
  285. cmp r8,#0x80000000
  286. beq CPDO_dvf_by0
  287. eor r1,r1,r2
  288. cmp r7,#0x80000000
  289. beq CPDO_zero_1
  290. sub r8,r7,r8
  291. mov r2,#0
  292. mov r7,#1
  293. cmp r3,r4
  294. cmpeq r5,r6
  295. bcs CPDO_dvf_loop_
  296. sub r8,r8,#1
  297. CPDO_dvf_loop:
  298. adds r5,r5,r5
  299. adcs r3,r3,r3
  300. bcs CPDO_dvf_anyway
  301. CPDO_dvf_loop_:
  302. subs r5,r5,r6
  303. sbcs r3,r3,r4
  304. bcs CPDO_dvf_okay
  305. adds r5,r5,r6
  306. adc r3,r3,r4
  307. adds r7,r7,r7
  308. adcs r2,r2,r2
  309. bcc CPDO_dvf_loop
  310. b CPDO_dvf_end
  311. CPDO_dvf_anyway:
  312. adcs r7,r7,r7
  313. adcs r2,r2,r2
  314. bcs CPDO_dvf_end
  315. subs r5,r5,r6
  316. sbc r3,r3,r4
  317. b CPDO_dvf_loop
  318. CPDO_dvf_okay:
  319. adcs r7,r7,r7
  320. adcs r2,r2,r2
  321. bcc CPDO_dvf_loop
  322. CPDO_dvf_end:
  323. b CPDO_muf_end
  324. CPDO_dvf_by0:
  325. cmp R7,#0x80000000
  326. beq CPDO_nan @ first also 0 -> nan
  327. eor r1,r1,r2 @ otherwise calculatesign for inf
  328. b CPDO_inf
  329. CPDO_dvf_extra:
  330. cmp r7,#0x7fffffff @ was it the first?
  331. bne CPDO_dvf_extra_2nd @ no, so it was the second
  332. cmp r8,#0x7fffffff @ yes, second too?
  333. bne CPDO_dvf_extra_1st @ no, only first
  334. orrs r3,r3,r4
  335. beq CPDO_nan @ if both inf -> create nan
  336. b CPDO_nan_12 @ otherwise keep nan
  337. CPDO_dvf_extra_1st:
  338. eor r1,r1,r2 @ correct sign for inf
  339. b CPDO_infnan_1
  340. CPDO_dvf_extra_2nd:
  341. cmp r4,#0 @ is it a nan?
  342. bne CPDO_infnan_2
  343. eor r1,r1,r2 @ correct sign for zero
  344. b CPDO_zero_1
  345. /*---------------------------------------------------------------------------*/
  346. .globl CPDO_rdf
  347. CPDO_rdf:
  348. mov r3,r2
  349. ldmia r1,{r2,r4,r6,r8}
  350. ldmia r3,{r1,r3,r5,r7}
  351. b CPDO_dvf_l
  352. /*---------------------------------------------------------------------------*/
  353. .globl CPDO_rmf
  354. CPDO_rmf:
  355. b fastfpe_next
  356. /*---------------------------------------------------------------------------*/
  357. /*---------------------------------------------------------------------------*/
  358. .globl CPDO_mvf
  359. CPDO_mvf:
  360. ldmia r2,{r1,r2,r3,r4}
  361. stmia r0,{r1,r2,r3,r4}
  362. b fastfpe_next
  363. /*---------------------------------------------------------------------------*/
  364. .globl CPDO_mnf
  365. CPDO_mnf:
  366. ldmia r2,{r1,r2,r3,r4}
  367. eor r1,r1,#0x80000000
  368. stmia r0,{r1,r2,r3,r4}
  369. b fastfpe_next
  370. /*---------------------------------------------------------------------------*/
  371. .globl CPDO_abs
  372. CPDO_abs:
  373. ldmia r2,{r1,r2,r3,r4}
  374. bic r1,r1,#0x80000000
  375. stmia r0,{r1,r2,r3,r4}
  376. b fastfpe_next
  377. /*---------------------------------------------------------------------------*/
  378. .globl CPDO_sqt
  379. CPDO_sqt:
  380. ldmia r2,{r1,r2,r3,r4}
  381. cmp r1,#0
  382. bne CPDO_nan
  383. cmp r4,#0x7fffffff
  384. beq CPDO_store_1234
  385. tst r4,r4,lsr#1 @carry=exponent bit 0
  386. bcc CPDO_sqt_exponenteven
  387. adds r3,r3,r3
  388. adcs r2,r2,r2 @carry is needed in loop!
  389. CPDO_sqt_exponenteven:
  390. mov r4,r4,asr #1
  391. str r4,[r0,#12]
  392. mov r4,#0x80000000
  393. mov r5,#0
  394. sub r2,r2,#0x80000000
  395. mov r8,#0x40000000
  396. mov r14,#0x80000000
  397. mov r1,#1
  398. b CPDO_sqt_loop1_first
  399. CPDO_sqt_loop1:
  400. adds r3,r3,r3
  401. adcs r2,r2,r2
  402. CPDO_sqt_loop1_first:
  403. add r6,r4,r8,lsr r1 @r7 const = r5
  404. bcs CPDO_sqt_loop1_1
  405. cmp r2,r6
  406. cmpeq r3,r5 @r5 for r7
  407. bcc CPDO_sqt_loop1_0
  408. CPDO_sqt_loop1_1:
  409. orr r4,r4,r14,lsr r1
  410. subs r3,r3,r5 @r5 for r7
  411. sbc r2,r2,r6
  412. CPDO_sqt_loop1_0:
  413. add r1,r1,#1
  414. cmp r1,#30
  415. ble CPDO_sqt_loop1
  416. adds r3,r3,r3
  417. adcs r2,r2,r2
  418. bcs CPDO_sqt_between_1
  419. adds r7,r5,#0x80000000
  420. adc r6,r4,#0
  421. cmp r2,r6
  422. cmpeq r3,r7
  423. bcc CPDO_sqt_between_0
  424. CPDO_sqt_between_1:
  425. orr r4,r4,#0x00000001
  426. subs r3,r3,r5
  427. sbc r2,r2,r4
  428. subs r3,r3,#0x80000000
  429. sbc r2,r2,#0
  430. CPDO_sqt_between_0:
  431. mov r1,#0
  432. CPDO_sqt_loop2:
  433. adds r3,r3,r3
  434. adcs r2,r2,r2
  435. bcs CPDO_sqt_loop2_1
  436. adds r7,r5,r8,lsr r1
  437. adc r6,r4,#0
  438. cmp r2,r6
  439. cmpeq r3,r7
  440. bcc CPDO_sqt_loop2_0
  441. CPDO_sqt_loop2_1:
  442. orr r5,r5,r14,lsr r1
  443. subs r3,r3,r5
  444. sbc r2,r2,r4
  445. subs r3,r3,r8,lsr r1
  446. sbc r2,r2,#0
  447. CPDO_sqt_loop2_0:
  448. add r1,r1,#1
  449. cmp r1,#30
  450. ble CPDO_sqt_loop2
  451. adds r3,r3,r3
  452. adcs r2,r2,r2
  453. bcs CPDO_sqt_after_1
  454. cmp r2,r6
  455. cmpeq r3,r7
  456. bcc CPDO_sqt_after_0
  457. CPDO_sqt_after_1:
  458. orr r5,r5,#0x00000001
  459. CPDO_sqt_after_0:
  460. mov r1,#0
  461. stmia r0,{r1,r4,r5}
  462. b fastfpe_next
  463. /*---------------------------------------------------------------------------*/
  464. .globl CPDO_rnd
  465. CPDO_rnd:
  466. ldmia r2,{r1,r2,r3,r5}
  467.         bl      CPDO_rnd_core
  468. CPDO_rnd_store:
  469. stmia r0,{r1,r2,r3,r5}
  470.      b fastfpe_next
  471. /*---------------------------------------------------------------------------*/
  472. .globl CPDO_rnd_core
  473. CPDO_rnd_core:
  474. and r4,r4,#0x00000060
  475. add pc,pc,r4,lsr#3
  476. mov r0,r0
  477. b CPDO_rnd_N
  478. b CPDO_rnd_P
  479. b CPDO_rnd_M
  480. b CPDO_rnd_Z
  481. CPDO_rnd_N:
  482. cmp r5,#-1
  483. blt CPDO_rnd_zero
  484. cmp r5,#63
  485. movge pc,r14
  486. mov r4,#0x40000000
  487. cmp r5,#31
  488. bge CPDO_rnd_N_2
  489. adds r2,r2,r4,lsr r5
  490. bcc CPDO_rnd_end
  491. b CPDO_rnd_end_norm
  492. CPDO_rnd_N_2:
  493. CPDO_rnd_P_2:
  494. sub r6,r5,#32
  495. adds r3,r3,r4,ror r6 @ror ist needed to handle a -1 correctly
  496. adcs r2,r2,#0
  497. bcc CPDO_rnd_end
  498. b CPDO_rnd_end_norm
  499. CPDO_rnd_P:
  500. tst r1,#0x80000000
  501. bne CPDO_rnd_M_entry
  502. CPDO_rnd_P_entry:
  503. cmp r5,#0
  504. blt CPDO_rnd_P_small
  505. cmp r5,#63
  506. movge pc,r14
  507. mov r4,#0x7fffffff
  508. cmp r5,#32
  509. bge CPDO_rnd_P_2
  510. adds r3,r3,#0xffffffff
  511. adcs r2,r2,r4,lsr r5
  512. bcc CPDO_rnd_end
  513. b CPDO_rnd_end_norm
  514. CPDO_rnd_P_small:
  515. cmp r5,#0x80000000
  516. moveq pc,r14
  517. b CPDO_rnd_one
  518. CPDO_rnd_M:
  519. tst r1,#0x80000000
  520. bne CPDO_rnd_P_entry
  521. CPDO_rnd_M_entry:
  522. cmp r5,#0
  523. blt CPDO_rnd_zero
  524. cmp r5,#63
  525. movge pc,r14
  526. b CPDO_rnd_end
  527. CPDO_rnd_Z:
  528. cmp r5,#0
  529. blt CPDO_rnd_zero
  530. cmp r5,#63
  531. movge pc,r14
  532. b CPDO_rnd_end
  533. CPDO_rnd_end_norm:
  534. add r5,r5,#1
  535. movs r2,r2,rrx
  536. mov r3,r3,rrx
  537. CPDO_rnd_end:
  538. rsbs r4,r5,#31
  539. bmi CPDO_rnd_end_2
  540. mov     r3,#0
  541. mov     r2,r2,lsr r4
  542. mov r2,r2,lsl r4
  543. mov pc,r14
  544. CPDO_rnd_end_2:
  545. rsb r4,r5,#63
  546. mov r3,r3,lsr r4
  547. mov r3,r3,lsl r4
  548. mov pc,r14
  549. CPDO_rnd_one:
  550. mov r2,#0x80000000
  551. mov r3,#0
  552. mov r5,#0
  553. mov pc,r14
  554. CPDO_rnd_zero:
  555. mov r1,#0
  556. mov r2,#0
  557. mov r3,#0
  558. mov r5,#0x80000000
  559. mov pc,r14
  560. /*---------------------------------------------------------------------------*/