010-Add-PowerPC-soft-float-support.patch 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594
  1. From: Felix Fietkau <[email protected]>
  2. Date: Wed, 8 Jul 2015 13:56:37 +0200
  3. Subject: [PATCH] Add PowerPC soft-float support
  4. Some PowerPC CPUs (e.g. Freescale MPC85xx) have a completely different
  5. instruction set for floating point operations (SPE).
  6. Executing regular PowerPC floating point instructions results in
  7. "Illegal instruction" errors.
  8. Make it possible to run these devices in soft-float mode.
  9. Signed-off-by: Felix Fietkau <[email protected]>
  10. ---
  11. create mode 100644 src/fenv/powerpc/fenv-sf.c
  12. --- a/arch/powerpc/bits/fenv.h
  13. +++ b/arch/powerpc/bits/fenv.h
  14. @@ -1,3 +1,7 @@
  15. +#ifdef _SOFT_FLOAT
  16. +#define FE_ALL_EXCEPT 0
  17. +#define FE_TONEAREST 0
  18. +#else
  19. #define FE_TONEAREST 0
  20. #define FE_TOWARDZERO 1
  21. #define FE_UPWARD 2
  22. @@ -24,6 +28,7 @@
  23. #define FE_ALL_INVALID 0x01f80700
  24. #endif
  25. +#endif
  26. typedef unsigned fexcept_t;
  27. typedef double fenv_t;
  28. --- a/arch/powerpc/reloc.h
  29. +++ b/arch/powerpc/reloc.h
  30. @@ -1,4 +1,10 @@
  31. -#define LDSO_ARCH "powerpc"
  32. +#ifdef _SOFT_FLOAT
  33. +#define FP_SUFFIX "-sf"
  34. +#else
  35. +#define FP_SUFFIX ""
  36. +#endif
  37. +
  38. +#define LDSO_ARCH "powerpc" FP_SUFFIX
  39. #define TPOFF_K (-0x7000)
  40. --- a/configure
  41. +++ b/configure
  42. @@ -604,6 +604,10 @@ trycppif "_MIPSEL || __MIPSEL || __MIPSE
  43. trycppif __mips_soft_float "$t" && SUBARCH=${SUBARCH}-sf
  44. fi
  45. +if test "$ARCH" = "powerpc" ; then
  46. +trycppif _SOFT_FLOAT "$t" && SUBARCH=${SUBARCH}-sf
  47. +fi
  48. +
  49. test "$ARCH" = "microblaze" && trycppif __MICROBLAZEEL__ "$t" \
  50. && SUBARCH=${SUBARCH}el
  51. --- /dev/null
  52. +++ b/src/fenv/powerpc/fenv-sf.c
  53. @@ -0,0 +1,3 @@
  54. +#ifdef _SOFT_FLOAT
  55. +#include "../fenv.c"
  56. +#endif
  57. --- /dev/null
  58. +++ b/src/fenv/powerpc/fenv.S
  59. @@ -0,0 +1,129 @@
  60. +#ifndef _SOFT_FLOAT
  61. +.global feclearexcept
  62. +.type feclearexcept,@function
  63. +feclearexcept:
  64. + andis. 3,3,0x3e00
  65. + /* if (r3 & FE_INVALID) r3 |= all_invalid_flags */
  66. + andis. 0,3,0x2000
  67. + stwu 1,-16(1)
  68. + beq- 0,1f
  69. + oris 3,3,0x01f8
  70. + ori 3,3,0x0700
  71. +1:
  72. + /*
  73. + * note: fpscr contains various fpu status and control
  74. + * flags and we dont check if r3 may alter other flags
  75. + * than the exception related ones
  76. + * ufpscr &= ~r3
  77. + */
  78. + mffs 0
  79. + stfd 0,8(1)
  80. + lwz 9,12(1)
  81. + andc 9,9,3
  82. + stw 9,12(1)
  83. + lfd 0,8(1)
  84. + mtfsf 255,0
  85. +
  86. + /* return 0 */
  87. + li 3,0
  88. + addi 1,1,16
  89. + blr
  90. +
  91. +.global feraiseexcept
  92. +.type feraiseexcept,@function
  93. +feraiseexcept:
  94. + andis. 3,3,0x3e00
  95. + /* if (r3 & FE_INVALID) r3 |= software_invalid_flag */
  96. + andis. 0,3,0x2000
  97. + stwu 1,-16(1)
  98. + beq- 0,1f
  99. + ori 3,3,0x0400
  100. +1:
  101. + /* fpscr |= r3 */
  102. + mffs 0
  103. + stfd 0,8(1)
  104. + lwz 9,12(1)
  105. + or 9,9,3
  106. + stw 9,12(1)
  107. + lfd 0,8(1)
  108. + mtfsf 255,0
  109. +
  110. + /* return 0 */
  111. + li 3,0
  112. + addi 1,1,16
  113. + blr
  114. +
  115. +.global fetestexcept
  116. +.type fetestexcept,@function
  117. +fetestexcept:
  118. + andis. 3,3,0x3e00
  119. + /* return r3 & fpscr */
  120. + stwu 1,-16(1)
  121. + mffs 0
  122. + stfd 0,8(1)
  123. + lwz 9,12(1)
  124. + addi 1,1,16
  125. + and 3,3,9
  126. + blr
  127. +
  128. +.global fegetround
  129. +.type fegetround,@function
  130. +fegetround:
  131. + /* return fpscr & 3 */
  132. + stwu 1,-16(1)
  133. + mffs 0
  134. + stfd 0,8(1)
  135. + lwz 3,12(1)
  136. + addi 1,1,16
  137. + clrlwi 3,3,30
  138. + blr
  139. +
  140. +.global __fesetround
  141. +.type __fesetround,@function
  142. +__fesetround:
  143. + /*
  144. + * note: invalid input is not checked, r3 < 4 must hold
  145. + * fpscr = (fpscr & -4U) | r3
  146. + */
  147. + stwu 1,-16(1)
  148. + mffs 0
  149. + stfd 0,8(1)
  150. + lwz 9,12(1)
  151. + clrrwi 9,9,2
  152. + or 9,9,3
  153. + stw 9,12(1)
  154. + lfd 0,8(1)
  155. + mtfsf 255,0
  156. +
  157. + /* return 0 */
  158. + li 3,0
  159. + addi 1,1,16
  160. + blr
  161. +
  162. +.global fegetenv
  163. +.type fegetenv,@function
  164. +fegetenv:
  165. + /* *r3 = fpscr */
  166. + mffs 0
  167. + stfd 0,0(3)
  168. + /* return 0 */
  169. + li 3,0
  170. + blr
  171. +
  172. +.global fesetenv
  173. +.type fesetenv,@function
  174. +fesetenv:
  175. + cmpwi 3, -1
  176. + bne 1f
  177. + mflr 4
  178. + bl 2f
  179. + .zero 8
  180. +2: mflr 3
  181. + mtlr 4
  182. +1: /* fpscr = *r3 */
  183. + lfd 0,0(3)
  184. + mtfsf 255,0
  185. + /* return 0 */
  186. + li 3,0
  187. + blr
  188. +#endif
  189. --- a/src/fenv/powerpc/fenv.s
  190. +++ /dev/null
  191. @@ -1,123 +0,0 @@
  192. -.global feclearexcept
  193. -.type feclearexcept,@function
  194. -feclearexcept:
  195. - andis. 3,3,0x3e00
  196. - # if (r3 & FE_INVALID) r3 |= all_invalid_flags
  197. - andis. 0,3,0x2000
  198. - stwu 1,-16(1)
  199. - beq- 0,1f
  200. - oris 3,3,0x01f8
  201. - ori 3,3,0x0700
  202. -1:
  203. - # note: fpscr contains various fpu status and control
  204. - # flags and we dont check if r3 may alter other flags
  205. - # than the exception related ones
  206. - # fpscr &= ~r3
  207. - mffs 0
  208. - stfd 0,8(1)
  209. - lwz 9,12(1)
  210. - andc 9,9,3
  211. - stw 9,12(1)
  212. - lfd 0,8(1)
  213. - mtfsf 255,0
  214. -
  215. - # return 0
  216. - li 3,0
  217. - addi 1,1,16
  218. - blr
  219. -
  220. -.global feraiseexcept
  221. -.type feraiseexcept,@function
  222. -feraiseexcept:
  223. - andis. 3,3,0x3e00
  224. - # if (r3 & FE_INVALID) r3 |= software_invalid_flag
  225. - andis. 0,3,0x2000
  226. - stwu 1,-16(1)
  227. - beq- 0,1f
  228. - ori 3,3,0x0400
  229. -1:
  230. - # fpscr |= r3
  231. - mffs 0
  232. - stfd 0,8(1)
  233. - lwz 9,12(1)
  234. - or 9,9,3
  235. - stw 9,12(1)
  236. - lfd 0,8(1)
  237. - mtfsf 255,0
  238. -
  239. - # return 0
  240. - li 3,0
  241. - addi 1,1,16
  242. - blr
  243. -
  244. -.global fetestexcept
  245. -.type fetestexcept,@function
  246. -fetestexcept:
  247. - andis. 3,3,0x3e00
  248. - # return r3 & fpscr
  249. - stwu 1,-16(1)
  250. - mffs 0
  251. - stfd 0,8(1)
  252. - lwz 9,12(1)
  253. - addi 1,1,16
  254. - and 3,3,9
  255. - blr
  256. -
  257. -.global fegetround
  258. -.type fegetround,@function
  259. -fegetround:
  260. - # return fpscr & 3
  261. - stwu 1,-16(1)
  262. - mffs 0
  263. - stfd 0,8(1)
  264. - lwz 3,12(1)
  265. - addi 1,1,16
  266. - clrlwi 3,3,30
  267. - blr
  268. -
  269. -.global __fesetround
  270. -.type __fesetround,@function
  271. -__fesetround:
  272. - # note: invalid input is not checked, r3 < 4 must hold
  273. - # fpscr = (fpscr & -4U) | r3
  274. - stwu 1,-16(1)
  275. - mffs 0
  276. - stfd 0,8(1)
  277. - lwz 9,12(1)
  278. - clrrwi 9,9,2
  279. - or 9,9,3
  280. - stw 9,12(1)
  281. - lfd 0,8(1)
  282. - mtfsf 255,0
  283. -
  284. - # return 0
  285. - li 3,0
  286. - addi 1,1,16
  287. - blr
  288. -
  289. -.global fegetenv
  290. -.type fegetenv,@function
  291. -fegetenv:
  292. - # *r3 = fpscr
  293. - mffs 0
  294. - stfd 0,0(3)
  295. - # return 0
  296. - li 3,0
  297. - blr
  298. -
  299. -.global fesetenv
  300. -.type fesetenv,@function
  301. -fesetenv:
  302. - cmpwi 3, -1
  303. - bne 1f
  304. - mflr 4
  305. - bl 2f
  306. - .zero 8
  307. -2: mflr 3
  308. - mtlr 4
  309. -1: # fpscr = *r3
  310. - lfd 0,0(3)
  311. - mtfsf 255,0
  312. - # return 0
  313. - li 3,0
  314. - blr
  315. --- /dev/null
  316. +++ b/src/setjmp/powerpc/longjmp.S
  317. @@ -0,0 +1,69 @@
  318. + .global _longjmp
  319. + .global longjmp
  320. + .type _longjmp,@function
  321. + .type longjmp,@function
  322. +_longjmp:
  323. +longjmp:
  324. + /*
  325. + * void longjmp(jmp_buf env, int val);
  326. + * put val into return register and restore the env saved in setjmp
  327. + * if val(r4) is 0, put 1 there.
  328. + */
  329. + /* 0) move old return address into r0 */
  330. + lwz 0, 0(3)
  331. + /* 1) put it into link reg */
  332. + mtlr 0
  333. + /* 2 ) restore stack ptr */
  334. + lwz 1, 4(3)
  335. + /* 3) restore control reg */
  336. + lwz 0, 8(3)
  337. + mtcr 0
  338. + /* 4) restore r14-r31 */
  339. + lwz 14, 12(3)
  340. + lwz 15, 16(3)
  341. + lwz 16, 20(3)
  342. + lwz 17, 24(3)
  343. + lwz 18, 28(3)
  344. + lwz 19, 32(3)
  345. + lwz 20, 36(3)
  346. + lwz 21, 40(3)
  347. + lwz 22, 44(3)
  348. + lwz 23, 48(3)
  349. + lwz 24, 52(3)
  350. + lwz 25, 56(3)
  351. + lwz 26, 60(3)
  352. + lwz 27, 64(3)
  353. + lwz 28, 68(3)
  354. + lwz 29, 72(3)
  355. + lwz 30, 76(3)
  356. + lwz 31, 80(3)
  357. +#ifndef _SOFT_FLOAT
  358. + lfd 14,88(3)
  359. + lfd 15,96(3)
  360. + lfd 16,104(3)
  361. + lfd 17,112(3)
  362. + lfd 18,120(3)
  363. + lfd 19,128(3)
  364. + lfd 20,136(3)
  365. + lfd 21,144(3)
  366. + lfd 22,152(3)
  367. + lfd 23,160(3)
  368. + lfd 24,168(3)
  369. + lfd 25,176(3)
  370. + lfd 26,184(3)
  371. + lfd 27,192(3)
  372. + lfd 28,200(3)
  373. + lfd 29,208(3)
  374. + lfd 30,216(3)
  375. + lfd 31,224(3)
  376. +#endif
  377. + /* 5) put val into return reg r3 */
  378. + mr 3, 4
  379. +
  380. + /* 6) check if return value is 0, make it 1 in that case */
  381. + cmpwi cr7, 4, 0
  382. + bne cr7, 1f
  383. + li 3, 1
  384. +1:
  385. + blr
  386. +
  387. --- a/src/setjmp/powerpc/longjmp.s
  388. +++ /dev/null
  389. @@ -1,65 +0,0 @@
  390. - .global _longjmp
  391. - .global longjmp
  392. - .type _longjmp,@function
  393. - .type longjmp,@function
  394. -_longjmp:
  395. -longjmp:
  396. -# void longjmp(jmp_buf env, int val);
  397. -# put val into return register and restore the env saved in setjmp
  398. -# if val(r4) is 0, put 1 there.
  399. - # 0) move old return address into r0
  400. - lwz 0, 0(3)
  401. - # 1) put it into link reg
  402. - mtlr 0
  403. - #2 ) restore stack ptr
  404. - lwz 1, 4(3)
  405. - #3) restore control reg
  406. - lwz 0, 8(3)
  407. - mtcr 0
  408. - #4) restore r14-r31
  409. - lwz 14, 12(3)
  410. - lwz 15, 16(3)
  411. - lwz 16, 20(3)
  412. - lwz 17, 24(3)
  413. - lwz 18, 28(3)
  414. - lwz 19, 32(3)
  415. - lwz 20, 36(3)
  416. - lwz 21, 40(3)
  417. - lwz 22, 44(3)
  418. - lwz 23, 48(3)
  419. - lwz 24, 52(3)
  420. - lwz 25, 56(3)
  421. - lwz 26, 60(3)
  422. - lwz 27, 64(3)
  423. - lwz 28, 68(3)
  424. - lwz 29, 72(3)
  425. - lwz 30, 76(3)
  426. - lwz 31, 80(3)
  427. - lfd 14,88(3)
  428. - lfd 15,96(3)
  429. - lfd 16,104(3)
  430. - lfd 17,112(3)
  431. - lfd 18,120(3)
  432. - lfd 19,128(3)
  433. - lfd 20,136(3)
  434. - lfd 21,144(3)
  435. - lfd 22,152(3)
  436. - lfd 23,160(3)
  437. - lfd 24,168(3)
  438. - lfd 25,176(3)
  439. - lfd 26,184(3)
  440. - lfd 27,192(3)
  441. - lfd 28,200(3)
  442. - lfd 29,208(3)
  443. - lfd 30,216(3)
  444. - lfd 31,224(3)
  445. - #5) put val into return reg r3
  446. - mr 3, 4
  447. -
  448. - #6) check if return value is 0, make it 1 in that case
  449. - cmpwi cr7, 4, 0
  450. - bne cr7, 1f
  451. - li 3, 1
  452. -1:
  453. - blr
  454. -
  455. --- /dev/null
  456. +++ b/src/setjmp/powerpc/setjmp.S
  457. @@ -0,0 +1,63 @@
  458. + .global ___setjmp
  459. + .hidden ___setjmp
  460. + .global __setjmp
  461. + .global _setjmp
  462. + .global setjmp
  463. + .type __setjmp,@function
  464. + .type _setjmp,@function
  465. + .type setjmp,@function
  466. +___setjmp:
  467. +__setjmp:
  468. +_setjmp:
  469. +setjmp:
  470. + /* 0) store IP int 0, then into the jmpbuf pointed to by r3 (first arg) */
  471. + mflr 0
  472. + stw 0, 0(3)
  473. + /* 1) store reg1 (SP) */
  474. + stw 1, 4(3)
  475. + /* 2) store cr */
  476. + mfcr 0
  477. + stw 0, 8(3)
  478. + /* 3) store r14-31 */
  479. + stw 14, 12(3)
  480. + stw 15, 16(3)
  481. + stw 16, 20(3)
  482. + stw 17, 24(3)
  483. + stw 18, 28(3)
  484. + stw 19, 32(3)
  485. + stw 20, 36(3)
  486. + stw 21, 40(3)
  487. + stw 22, 44(3)
  488. + stw 23, 48(3)
  489. + stw 24, 52(3)
  490. + stw 25, 56(3)
  491. + stw 26, 60(3)
  492. + stw 27, 64(3)
  493. + stw 28, 68(3)
  494. + stw 29, 72(3)
  495. + stw 30, 76(3)
  496. + stw 31, 80(3)
  497. +#ifndef _SOFT_FLOAT
  498. + stfd 14,88(3)
  499. + stfd 15,96(3)
  500. + stfd 16,104(3)
  501. + stfd 17,112(3)
  502. + stfd 18,120(3)
  503. + stfd 19,128(3)
  504. + stfd 20,136(3)
  505. + stfd 21,144(3)
  506. + stfd 22,152(3)
  507. + stfd 23,160(3)
  508. + stfd 24,168(3)
  509. + stfd 25,176(3)
  510. + stfd 26,184(3)
  511. + stfd 27,192(3)
  512. + stfd 28,200(3)
  513. + stfd 29,208(3)
  514. + stfd 30,216(3)
  515. + stfd 31,224(3)
  516. +#endif
  517. + /* 4) set return value to 0 */
  518. + li 3, 0
  519. + /* 5) return */
  520. + blr
  521. --- a/src/setjmp/powerpc/setjmp.s
  522. +++ /dev/null
  523. @@ -1,61 +0,0 @@
  524. - .global ___setjmp
  525. - .hidden ___setjmp
  526. - .global __setjmp
  527. - .global _setjmp
  528. - .global setjmp
  529. - .type __setjmp,@function
  530. - .type _setjmp,@function
  531. - .type setjmp,@function
  532. -___setjmp:
  533. -__setjmp:
  534. -_setjmp:
  535. -setjmp:
  536. - # 0) store IP int 0, then into the jmpbuf pointed to by r3 (first arg)
  537. - mflr 0
  538. - stw 0, 0(3)
  539. - # 1) store reg1 (SP)
  540. - stw 1, 4(3)
  541. - # 2) store cr
  542. - mfcr 0
  543. - stw 0, 8(3)
  544. - # 3) store r14-31
  545. - stw 14, 12(3)
  546. - stw 15, 16(3)
  547. - stw 16, 20(3)
  548. - stw 17, 24(3)
  549. - stw 18, 28(3)
  550. - stw 19, 32(3)
  551. - stw 20, 36(3)
  552. - stw 21, 40(3)
  553. - stw 22, 44(3)
  554. - stw 23, 48(3)
  555. - stw 24, 52(3)
  556. - stw 25, 56(3)
  557. - stw 26, 60(3)
  558. - stw 27, 64(3)
  559. - stw 28, 68(3)
  560. - stw 29, 72(3)
  561. - stw 30, 76(3)
  562. - stw 31, 80(3)
  563. - stfd 14,88(3)
  564. - stfd 15,96(3)
  565. - stfd 16,104(3)
  566. - stfd 17,112(3)
  567. - stfd 18,120(3)
  568. - stfd 19,128(3)
  569. - stfd 20,136(3)
  570. - stfd 21,144(3)
  571. - stfd 22,152(3)
  572. - stfd 23,160(3)
  573. - stfd 24,168(3)
  574. - stfd 25,176(3)
  575. - stfd 26,184(3)
  576. - stfd 27,192(3)
  577. - stfd 28,200(3)
  578. - stfd 29,208(3)
  579. - stfd 30,216(3)
  580. - stfd 31,224(3)
  581. - # 4) set return value to 0
  582. - li 3, 0
  583. - # 5) return
  584. - blr