summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2014-12-15 13:32:17 +0000
committerCorinna Vinschen <corinna@vinschen.de>2014-12-15 13:32:17 +0000
commitf5ce72dffc738d43213e566d8ae082d7428f8be9 (patch)
tree62536bdf369ea8fbb6cbb59bef5348e414e8fab2
parentd4ef8a6368e8e5b22808e3df64306418f1971ba9 (diff)
downloadcygnal-f5ce72dffc738d43213e566d8ae082d7428f8be9.tar.gz
cygnal-f5ce72dffc738d43213e566d8ae082d7428f8be9.tar.bz2
cygnal-f5ce72dffc738d43213e566d8ae082d7428f8be9.zip
* newlib/libc/include/machine/setjmp.h: Add FPU support.
* newlib/libc/machine/nds32/setjmp.S: Add FPU support.
-rw-r--r--newlib/ChangeLog5
-rw-r--r--newlib/libc/include/machine/setjmp.h13
-rw-r--r--newlib/libc/machine/nds32/setjmp.S82
3 files changed, 95 insertions, 5 deletions
diff --git a/newlib/ChangeLog b/newlib/ChangeLog
index 802945ba9..526a66de2 100644
--- a/newlib/ChangeLog
+++ b/newlib/ChangeLog
@@ -1,5 +1,10 @@
2014-12-15 Nick Hung <nick@andestech.com>
+ * newlib/libc/include/machine/setjmp.h: Add FPU support.
+ * newlib/libc/machine/nds32/setjmp.S: Add FPU support.
+
+2014-12-15 Nick Hung <nick@andestech.com>
+
* configure.host: Add libm nds32 machine directory.
* libm/machine/configure: Regenerated.
* libm/machine/configure.in: Add nds32 AC_CONFIG.
diff --git a/newlib/libc/include/machine/setjmp.h b/newlib/libc/include/machine/setjmp.h
index a9e0d7141..f7e5865ab 100644
--- a/newlib/libc/include/machine/setjmp.h
+++ b/newlib/libc/include/machine/setjmp.h
@@ -61,11 +61,18 @@ _BEGIN_STD_C
#endif
#ifdef __nds32__
-/* Only 17 words are currently needed.
- Preserve one word slot if we need to expand.
- Check newlib/libc/machine/nds32/setjmp.S for more information. */
+/* 17 words for GPRs,
+ 1 word for $fpcfg.freg and 30 words for FPUs
+ Reserved 2 words for aligement-adjustment. When storeing double-precision
+ floating-point register into memory, the address has to be
+ double-word-aligned.
+ Check libc/machine/nds32/setjmp.S for more information. */
+#if __NDS32_EXT_FPU_SP__ || __NDS32_EXT_FPU_DP__
+#define _JBLEN 50
+#else
#define _JBLEN 18
#endif
+#endif
#if defined(__Z8001__) || defined(__Z8002__)
/* 16 regs + pc */
diff --git a/newlib/libc/machine/nds32/setjmp.S b/newlib/libc/machine/nds32/setjmp.S
index e5d8531bc..7197c86f3 100644
--- a/newlib/libc/machine/nds32/setjmp.S
+++ b/newlib/libc/machine/nds32/setjmp.S
@@ -51,7 +51,7 @@ The $r16 ~ $r19 are used to store D0/D1, keep them for backward-compatible.
.global setjmp
.type setjmp, @function
setjmp:
-#ifdef __NDS32_REDUCED_REGS__
+#if __NDS32_REDUCED_REGS__
smw.bim $r6, [$r0], $r10, #0b0000
addi $r0, $r0, #32 /* Leave room to keep jum_buf all the same. */
smw.bim $r31, [$r0], $r31, #0b1111
@@ -60,6 +60,46 @@ setjmp:
smw.bim $r16, [$r0], $r19, #0b1111
#endif
+#if __NDS32_EXT_FPU_SP__ || __NDS32_EXT_FPU_DP__
+
+ /* Extract $fpcfg.freg (b[3:2]), then save into jmp_buf. */
+ fmfcfg $r2
+ slli $r2, $r2, #28
+ srli $r2, $r2, #30
+ swi.bi $r2, [$r0], #4
+
+ /* Make sure $r0 is double-word-aligned. */
+ addi $r0, $r0, #7
+ bitci $r0, $r0, #7
+
+ /* Case switch according to $fpcfg.freg */
+ beqz $r2, .LCFG0_save /* Branch if $fpcfg.freg = 0b00. */
+ xori $r15, $r2, #0b10
+ beqz $r15, .LCFG2_save /* Branch $fpcfg.freg = 0b10. */
+ srli $r2, $r2, #0b01
+ beqz $r2, .LCFG1_save /* Branch if $fpcfg.freg = 0b01. */
+ /* Fall-through if $fpcfg.freg = 0b11. */
+.LCFG3_save:
+ fsdi.bi $fd31, [$r0], #8
+ fsdi.bi $fd29, [$r0], #8
+ fsdi.bi $fd27, [$r0], #8
+ fsdi.bi $fd25, [$r0], #8
+ fsdi.bi $fd23, [$r0], #8
+ fsdi.bi $fd21, [$r0], #8
+ fsdi.bi $fd19, [$r0], #8
+ fsdi.bi $fd17, [$r0], #8
+.LCFG2_save:
+ fsdi.bi $fd15, [$r0], #8
+ fsdi.bi $fd13, [$r0], #8
+ fsdi.bi $fd11, [$r0], #8
+ fsdi.bi $fd9, [$r0], #8
+.LCFG1_save:
+ fsdi.bi $fd7, [$r0], #8
+ fsdi.bi $fd5, [$r0], #8
+.LCFG0_save:
+ fsdi.bi $fd3, [$r0], #8
+#endif
+
/* Set return value to zero. */
movi $r0, 0
ret
@@ -72,7 +112,7 @@ setjmp:
.global longjmp
.type longjmp, @function
longjmp:
-#ifdef __NDS32_REDUCED_REGS__
+#if __NDS32_REDUCED_REGS__
lmw.bim $r6, [$r0], $r10, #0b0000
addi $r0, $r0, #32
lmw.bim $r31, [$r0], $r31, #0b1111
@@ -80,6 +120,44 @@ longjmp:
lmw.bim $r6, [$r0], $r14, #0b0000
lmw.bim $r16, [$r0], $r19, #0b1111
#endif
+
+#if __NDS32_EXT_FPU_SP__ || __NDS32_EXT_FPU_DP__
+
+ /* Restore value of $fpcfg.freg (b[3:2]). */
+ lwi.bi $r2, [$r0], #4
+
+ /* Make sure $r0 is double-word-aligned. */
+ addi $r0, $r0, #7
+ bitci $r0, $r0, #7
+
+ /* Case switch according to $fpcfg.freg */
+ beqz $r2, .LCFG0_restore /* Branch if $fpcfg.freg = 0b00. */
+ xori $r15, $r2, #0b10
+ beqz $r15, .LCFG2_restore /* Branch $fpcfg.freg = 0b10. */
+ srli $r2, $r2, #0b01
+ beqz $r2, .LCFG1_restore /* Branch if $fpcfg.freg = 0b01. */
+ /* Fall-through if $fpcfg.freg = 0b11. */
+.LCFG3_restore:
+ fldi.bi $fd31, [$r0], #8
+ fldi.bi $fd29, [$r0], #8
+ fldi.bi $fd27, [$r0], #8
+ fldi.bi $fd25, [$r0], #8
+ fldi.bi $fd23, [$r0], #8
+ fldi.bi $fd21, [$r0], #8
+ fldi.bi $fd19, [$r0], #8
+ fldi.bi $fd17, [$r0], #8
+.LCFG2_restore:
+ fldi.bi $fd15, [$r0], #8
+ fldi.bi $fd13, [$r0], #8
+ fldi.bi $fd11, [$r0], #8
+ fldi.bi $fd9, [$r0], #8
+.LCFG1_restore:
+ fldi.bi $fd7, [$r0], #8
+ fldi.bi $fd5, [$r0], #8
+.LCFG0_restore:
+ fldi.bi $fd3, [$r0], #8
+#endif
+
/* Set val as return value. If the value val is 0, 1 will be returned
instead. */
movi $r0, 1