summaryrefslogtreecommitdiff
path: root/lib/libsetjmp/mips
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-08-24 12:38:42 +0000
committerThomas Martitz <kugel@rockbox.org>2010-08-24 12:38:42 +0000
commit46454ac2a8a7d693ac135f0d4a9461bbcf24eea9 (patch)
tree86488784b36537f382ccd448c6684d60f1540527 /lib/libsetjmp/mips
parent20de4c55a2ddfa802a01cc353884d73a934bf7ba (diff)
Move setjmp to lib and add setjmp for sh (imported from newlib) and compile it as separate library.
It's used by both, plugins and codecs, and sh/hwcodec doesn't compile codecs so it doesn't fit into sources. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27869 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'lib/libsetjmp/mips')
-rw-r--r--lib/libsetjmp/mips/setjmp.S101
1 files changed, 101 insertions, 0 deletions
diff --git a/lib/libsetjmp/mips/setjmp.S b/lib/libsetjmp/mips/setjmp.S
new file mode 100644
index 0000000000..7fa127a7a4
--- /dev/null
+++ b/lib/libsetjmp/mips/setjmp.S
@@ -0,0 +1,101 @@
+#include "config.h"
+#include "mips.h"
+
+/* This is a simple version of setjmp and longjmp for MIPS 32 and 64.
+
+ Ian Lance Taylor, Cygnus Support, 13 May 1993. */
+
+#ifdef __mips16
+/* This file contains 32 bit assembly code. */
+ .set nomips16
+#endif
+
+#define GPR_LAYOUT \
+ GPR_OFFSET ($16, 0); \
+ GPR_OFFSET ($17, 1); \
+ GPR_OFFSET ($18, 2); \
+ GPR_OFFSET ($19, 3); \
+ GPR_OFFSET ($20, 4); \
+ GPR_OFFSET ($21, 5); \
+ GPR_OFFSET ($22, 6); \
+ GPR_OFFSET ($23, 7); \
+ GPR_OFFSET ($29, 8); \
+ GPR_OFFSET ($30, 9); \
+ GPR_OFFSET ($31, 10)
+
+#define NUM_GPRS_SAVED 11
+
+#ifdef __mips_hard_float
+#define FPR_LAYOUT \
+ FPR_OFFSET ($f20, 0); \
+ FPR_OFFSET ($f21, 1); \
+ FPR_OFFSET ($f22, 2); \
+ FPR_OFFSET ($f23, 3); \
+ FPR_OFFSET ($f24, 4); \
+ FPR_OFFSET ($f25, 5); \
+ FPR_OFFSET ($f26, 6); \
+ FPR_OFFSET ($f27, 7); \
+ FPR_OFFSET ($f28, 8); \
+ FPR_OFFSET ($f29, 9); \
+ FPR_OFFSET ($f30, 10); \
+ FPR_OFFSET ($f31, 11)
+#else
+#define FPR_LAYOUT
+#endif
+
+#if CPU_MIPS == 64
+#define BYTES_PER_WORD 8
+#define LOAD_GPR ld
+#define LOAD_FPR ldc1
+#define STORE_GPR sd
+#define STORE_FPR sdc1
+#else
+#define BYTES_PER_WORD 4
+#define LOAD_GPR lw
+#define LOAD_FPR lwc1
+#define STORE_GPR sw
+#define STORE_FPR swc1
+#endif
+
+#define GPOFF(INDEX) (INDEX * BYTES_PER_WORD)
+#define FPOFF(INDEX) ((INDEX + NUM_GPRS_SAVED) * BYTES_PER_WORD)
+
+/* int setjmp (jmp_buf); */
+ .globl setjmp
+ .ent setjmp
+setjmp:
+ .frame sp, 0, ra
+
+#define GPR_OFFSET(REG, INDEX) STORE_GPR REG,GPOFF(INDEX)(a0)
+#define FPR_OFFSET(REG, INDEX) STORE_FPR REG,FPOFF(INDEX)(a0)
+ GPR_LAYOUT
+ FPR_LAYOUT
+#undef GPR_OFFSET
+#undef FPR_OFFSET
+
+ move v0, $0
+ j ra
+
+ .end setjmp
+
+/* volatile void longjmp (jmp_buf, int); */
+ .globl longjmp
+ .ent longjmp
+longjmp:
+ .frame sp, 0, ra
+
+#define GPR_OFFSET(REG, INDEX) LOAD_GPR REG,GPOFF(INDEX)(a0)
+#define FPR_OFFSET(REG, INDEX) LOAD_FPR REG,FPOFF(INDEX)(a0)
+ GPR_LAYOUT
+ FPR_LAYOUT
+#undef GPR_OFFSET
+#undef FPR_OFFSET
+
+ bne a1, $0, 1f
+ li a1, 1
+1:
+ move v0, a1
+ j ra
+
+ .end longjmp
+