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