summaryrefslogtreecommitdiffstats
path: root/newlib/libc/machine/cris/setjmp.c
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2005-01-27 23:54:46 +0000
committerJeff Johnston <jjohnstn@redhat.com>2005-01-27 23:54:46 +0000
commit1815fdeab41b5dab9d6ab70824aef3a4c2574bdb (patch)
tree2ade0065b704c8ee1d8574d89eea42f06ce0f386 /newlib/libc/machine/cris/setjmp.c
parent3a267038039b75580454dca90aac591363e98c31 (diff)
downloadcygnal-1815fdeab41b5dab9d6ab70824aef3a4c2574bdb.tar.gz
cygnal-1815fdeab41b5dab9d6ab70824aef3a4c2574bdb.tar.bz2
cygnal-1815fdeab41b5dab9d6ab70824aef3a4c2574bdb.zip
2005-01-27 Hans-Peter Nilsson <hp@axis.com>
* configure.host: Add support for cris-*-* and crisv32-*-*. * libc/include/machine/ieeefp.h: Ditto. * libc/include/machine/setjmp.h: Ditto. * libc/machine/cris/configure.in, libc/machine/cris/Makefile.am, libc/machine/cris/libcdtor.c, libc/machine/cris/setjmp.c, libc/machine/cris/memmove.c, libc/machine/cris/memcpy.c, libc/machine/cris/memset.c, libc/machine/cris/include/pthread.h, libc/machine/cris/sys/signal.h, libc/machine/cris/sys/fcntl.h, libc/machine/cris/sys/errno.h, libc/machine/cris/aclocal.m4, libc/machine/cris/configure, libc/machine/cris/Makefile.in: New files.
Diffstat (limited to 'newlib/libc/machine/cris/setjmp.c')
-rw-r--r--newlib/libc/machine/cris/setjmp.c212
1 files changed, 212 insertions, 0 deletions
diff --git a/newlib/libc/machine/cris/setjmp.c b/newlib/libc/machine/cris/setjmp.c
new file mode 100644
index 000000000..ca544942f
--- /dev/null
+++ b/newlib/libc/machine/cris/setjmp.c
@@ -0,0 +1,212 @@
+/* A setjmp.c for CRIS
+ Copyright (C) 1993-2005 Axis Communications.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Neither the name of Axis Communications nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY AXIS COMMUNICATIONS AND ITS CONTRIBUTORS
+ ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL AXIS
+ COMMUNICATIONS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE. */
+
+/* For benefit of CRIS v0..v3, we save and restore CCR to be able to
+ correctly handle DI/EI; otherwise there would be no reason to save it.
+ Note also that the "move x,ccr" does NOT affect
+ the DMA enable bits (E and D) of v0..v3.
+
+ We do not save mof; it is call-clobbered. It also does not exist in
+ v0..v8; it should be safe to read or write to it there, but better not.
+
+ jmp_buf[0] - PC
+ jmp_buf[1] - SP (R14)
+ jmp_buf[2] - R13
+ jmp_buf[3] - R12
+ jmp_buf[4] - R11
+ jmp_buf[5] - R10
+ jmp_buf[6] - R9
+ jmp_buf[7] - R8
+ jmp_buf[8] - R7
+ jmp_buf[9] - R6
+ jmp_buf[10] - R5
+ jmp_buf[11] - R4
+ jmp_buf[12] - R3
+ jmp_buf[13] - R2
+ jmp_buf[14] - R1
+ jmp_buf[15] - R0
+ jmp_buf[16] - SRP
+ jmp_buf[17] - CCR
+ */
+
+#include <setjmp.h>
+
+int
+setjmp (jmp_buf buf)
+{
+ int ret;
+#if defined (__arch_common_v10_v32) || defined (__arch_v32)
+ /* No offsets in the compatibility mode. Also, movem saves in
+ different order on v10 than on v32, so we use single move
+ instructions instead, this not being a speed-prioritized operation.
+ And we don't save CCR or CCS; since long unuseful. */
+ __asm__ __volatile__
+ ("move.d %1,$r13 \n\
+ move 0f,$mof \n\
+ move $mof,[$r13+] \n\
+ move.d $sp,[$r13+] \n\
+ clear.d [$r13+] \n\
+ move.d $r12,[$r13+] \n\
+ move.d $r11,[$r13+] \n\
+ move.d $r10,[$r13+] \n\
+ moveq 1,$r9 \n\
+ move.d $r9,[$r13+] \n\
+ move.d $r8,[$r13+] \n\
+ move.d $r7,[$r13+] \n\
+ move.d $r6,[$r13+] \n\
+ move.d $r5,[$r13+] \n\
+ move.d $r4,[$r13+] \n\
+ move.d $r3,[$r13+] \n\
+ move.d $r2,[$r13+] \n\
+ move.d $r1,[$r13+] \n\
+ move.d $r0,[$r13+] \n\
+ move $srp,[$r13+] \n\
+ clear.d [$r13+] \n\
+ clear.d $r9 \n\
+0: \n\
+ move.d $r9,%0"
+
+ /* Output. */
+ : "=&r" (ret)
+
+ /* Input. */
+ : "r" (buf)
+
+ /* Clobber. */
+ : "r9", "r13", "memory");
+#else /* not __arch_common_v10_v32 or __arch_v32 */
+#ifdef __PIC__
+ __asm__ __volatile__
+ ("moveq 1,$r9 \n\
+ movem $sp,[%1+1*4] \n\
+ move.d $pc,$r9 \n\
+ addq 0f-.,$r9 \n\
+ move.d $r9,[%1] \n\
+ move $srp,[%1+16*4] \n\
+ move $ccr,[%1+17*4] \n\
+ clear.d $r9 \n\
+0: \n\
+ move.d $r9,%0"
+
+ /* Output. */
+ : "=&r" (ret)
+
+ /* Input. */
+ : "r" (buf)
+
+ /* Clobber. */
+ : "r9", "memory");
+#else /* not PIC */
+ __asm__ __volatile__
+ ("moveq 1,$r9 \n\
+ movem $sp,[%1+1*4] \n\
+ move.d 0f,$r9 \n\
+ move.d $r9,[%1] \n\
+ move $srp,[%1+16*4] \n\
+ move $ccr,[%1+17*4] \n\
+ clear.d $r9 \n\
+0: \n\
+ move.d $r9,%0"
+
+ /* Output. */
+ : "=&r" (ret)
+
+ /* Input. */
+ : "r" (buf)
+
+ /* Clobber. */
+ : "r9");
+#endif /* not PIC */
+#endif /* not __arch_common_v10_v32 or __arch_v32 */
+ return ret;
+}
+
+void
+longjmp(jmp_buf buf, int val)
+{
+#if defined (__arch_common_v10_v32) || defined (__arch_v32)
+ __asm__ __volatile__
+ ("cmpq 0,%1 \n\
+ beq 0f \n\
+ move.d %0,$r13 ; In delay-slot. \n\
+ addq 6*4,$r13 \n\
+ move.d %1,[$r13] \n\
+ subq 6*4,$r13 \n\
+0:\n"
+#ifdef __arch_common_v10_v32
+ /* Cater to branch offset difference between v32 and v10. We
+ assume the branch above is 8-bit. */
+" setf\n"
+#endif
+" move [$r13+],$mof \n\
+ move.d [$r13+],$sp \n\
+ addq 4,$r13 \n\
+ move.d [$r13+],$r12 \n\
+ move.d [$r13+],$r11 \n\
+ move.d [$r13+],$r10 \n\
+ move.d [$r13+],$r9 \n\
+ move.d [$r13+],$r8 \n\
+ move.d [$r13+],$r7 \n\
+ move.d [$r13+],$r6 \n\
+ move.d [$r13+],$r5 \n\
+ move.d [$r13+],$r4 \n\
+ move.d [$r13+],$r3 \n\
+ move.d [$r13+],$r2 \n\
+ move.d [$r13+],$r1 \n\
+ move.d [$r13+],$r0 \n\
+ move [$r13+],$srp \n\
+ move $mof,$r13 \n\
+ jump $r13 \n\
+ setf"
+
+ /* No outputs. */
+ :
+
+ /* Inputs. */
+ : "r" (buf), "r" (val)
+ : "r13", "memory");
+
+#else /* not __arch_common_v10_v32 or __arch_v32 */
+ __asm__ __volatile__
+ ("move [%0+17*4],$ccr \n\
+ move [%0+16*4],$srp \n\
+ test.d %1 \n\
+ beq 0f \n\
+ nop \n\
+ move.d %1,[%0+6*4] ; Offset for r9. \n\
+0: \n\
+ movem [%0],$pc"
+
+ /* No outputs. */
+ :
+
+ /* Inputs. */
+ : "r" (buf), "r" (val)
+ : "memory");
+#endif /* not __arch_common_v10_v32 or __arch_v32 */
+}