aboutsummaryrefslogtreecommitdiff
path: root/tests/tcg/cris/libc
diff options
context:
space:
mode:
Diffstat (limited to 'tests/tcg/cris/libc')
-rw-r--r--tests/tcg/cris/libc/check_abs.c40
-rw-r--r--tests/tcg/cris/libc/check_addc.c58
-rw-r--r--tests/tcg/cris/libc/check_addcm.c85
-rw-r--r--tests/tcg/cris/libc/check_addo.c125
-rw-r--r--tests/tcg/cris/libc/check_addoq.c44
-rw-r--r--tests/tcg/cris/libc/check_bound.c142
-rw-r--r--tests/tcg/cris/libc/check_ftag.c37
-rw-r--r--tests/tcg/cris/libc/check_gcctorture_pr28634-1.c15
-rw-r--r--tests/tcg/cris/libc/check_gcctorture_pr28634.c15
-rw-r--r--tests/tcg/cris/libc/check_glibc_kernelversion.c116
-rw-r--r--tests/tcg/cris/libc/check_hello.c7
-rw-r--r--tests/tcg/cris/libc/check_int64.c47
-rw-r--r--tests/tcg/cris/libc/check_lz.c49
-rw-r--r--tests/tcg/cris/libc/check_mapbrk.c39
-rw-r--r--tests/tcg/cris/libc/check_mmap1.c48
-rw-r--r--tests/tcg/cris/libc/check_mmap2.c48
-rw-r--r--tests/tcg/cris/libc/check_mmap3.c33
-rw-r--r--tests/tcg/cris/libc/check_moveq.c51
-rw-r--r--tests/tcg/cris/libc/check_openpf1.c38
-rw-r--r--tests/tcg/cris/libc/check_openpf2.c16
-rw-r--r--tests/tcg/cris/libc/check_openpf3.c49
-rw-r--r--tests/tcg/cris/libc/check_openpf5.c56
-rw-r--r--tests/tcg/cris/libc/check_settls1.c45
-rw-r--r--tests/tcg/cris/libc/check_sigalrm.c26
-rw-r--r--tests/tcg/cris/libc/check_stat1.c16
-rw-r--r--tests/tcg/cris/libc/check_stat2.c20
-rw-r--r--tests/tcg/cris/libc/check_stat3.c25
-rw-r--r--tests/tcg/cris/libc/check_stat4.c27
-rw-r--r--tests/tcg/cris/libc/check_swap.c76
-rw-r--r--tests/tcg/cris/libc/check_time2.c18
-rw-r--r--tests/tcg/cris/libc/crisutils.h76
-rw-r--r--tests/tcg/cris/libc/sys.h18
32 files changed, 1505 insertions, 0 deletions
diff --git a/tests/tcg/cris/libc/check_abs.c b/tests/tcg/cris/libc/check_abs.c
new file mode 100644
index 0000000..08b67b6
--- /dev/null
+++ b/tests/tcg/cris/libc/check_abs.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "sys.h"
+#include "crisutils.h"
+
+static always_inline int cris_abs(int n)
+{
+ int r;
+ asm ("abs\t%1, %0\n" : "=r" (r) : "r" (n));
+ return r;
+}
+
+static always_inline void
+verify_abs(int val, int res,
+ const int n, const int z, const int v, const int c)
+{
+ int r;
+
+ cris_tst_cc_init();
+ r = cris_abs(val);
+ cris_tst_cc(n, z, v, c);
+ if (r != res)
+ err();
+}
+
+int main(void)
+{
+ verify_abs(-1, 1, 0, 0, 0, 0);
+ verify_abs(0x80000000, 0x80000000, 1, 0, 0, 0);
+ verify_abs(0x7fffffff, 0x7fffffff, 0, 0, 0, 0);
+ verify_abs(42, 42, 0, 0, 0, 0);
+ verify_abs(1, 1, 0, 0, 0, 0);
+ verify_abs(0xffff, 0xffff, 0, 0, 0, 0);
+ verify_abs(0xffff, 0xffff, 0, 0, 0, 0);
+ verify_abs(-31, 0x1f, 0, 0, 0, 0);
+ verify_abs(0, 0, 0, 1, 0, 0);
+ pass();
+ return 0;
+}
diff --git a/tests/tcg/cris/libc/check_addc.c b/tests/tcg/cris/libc/check_addc.c
new file mode 100644
index 0000000..fc3fb1f
--- /dev/null
+++ b/tests/tcg/cris/libc/check_addc.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "sys.h"
+#include "crisutils.h"
+
+static always_inline int cris_addc(int a, const int b)
+{
+ asm ("addc\t%1, %0\n" : "+r" (a) : "r" (b));
+ return a;
+}
+
+#define verify_addc(a, b, res, n, z, v, c) \
+{ \
+ int r; \
+ r = cris_addc((a), (b)); \
+ cris_tst_cc((n), (z), (v), (c)); \
+ if (r != (res)) \
+ err(); \
+}
+
+int main(void)
+{
+ cris_tst_cc_init();
+ asm volatile ("clearf cz");
+ verify_addc(0, 0, 0, 0, 0, 0, 0);
+
+ cris_tst_cc_init();
+ asm volatile ("setf z");
+ verify_addc(0, 0, 0, 0, 1, 0, 0);
+
+ cris_tst_cc_init();
+ asm volatile ("setf cz");
+ verify_addc(0, 0, 1, 0, 0, 0, 0);
+ cris_tst_cc_init();
+ asm volatile ("clearf c");
+ verify_addc(-1, 2, 1, 0, 0, 0, 1);
+
+ cris_tst_cc_init();
+ asm volatile ("clearf nzv");
+ asm volatile ("setf c");
+ verify_addc(-1, 2, 2, 0, 0, 0, 1);
+
+ cris_tst_cc_init();
+ asm volatile ("setf c");
+ verify_addc(0xffff, 0xffff, 0x1ffff, 0, 0, 0, 0);
+
+ cris_tst_cc_init();
+ asm volatile ("clearf nzvc");
+ verify_addc(-1, -1, 0xfffffffe, 1, 0, 0, 1);
+
+ cris_tst_cc_init();
+ asm volatile ("setf c");
+ verify_addc(0x78134452, 0x5432f789, 0xcc463bdc, 1, 0, 1, 0);
+
+ pass();
+ return 0;
+}
diff --git a/tests/tcg/cris/libc/check_addcm.c b/tests/tcg/cris/libc/check_addcm.c
new file mode 100644
index 0000000..b355ba1
--- /dev/null
+++ b/tests/tcg/cris/libc/check_addcm.c
@@ -0,0 +1,85 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "sys.h"
+#include "crisutils.h"
+
+/* need to avoid acr as source here. */
+static always_inline int cris_addc_m(int a, const int *b)
+{
+ asm volatile ("addc [%1], %0\n" : "+r" (a) : "r" (b));
+ return a;
+}
+
+/* 'b' is a crisv32 constrain to avoid postinc with $acr. */
+static always_inline int cris_addc_pi_m(int a, int **b)
+{
+ asm volatile ("addc [%1+], %0\n" : "+r" (a), "+b" (*b));
+ return a;
+}
+
+#define verify_addc_m(a, b, res, n, z, v, c) \
+{ \
+ int r; \
+ r = cris_addc_m((a), (b)); \
+ cris_tst_cc((n), (z), (v), (c)); \
+ if (r != (res)) \
+ err(); \
+}
+
+#define verify_addc_pi_m(a, b, res, n, z, v, c) \
+{ \
+ int r; \
+ r = cris_addc_pi_m((a), (b)); \
+ cris_tst_cc((n), (z), (v), (c)); \
+ if (r != (res)) \
+ err(); \
+}
+
+int x[] = { 0, 0, 2, -1, 0xffff, -1, 0x5432f789};
+
+int main(void)
+{
+ int *p = (void *)&x[0];
+#if 1
+ cris_tst_cc_init();
+ asm volatile ("clearf cz");
+ verify_addc_m(0, p, 0, 0, 0, 0, 0);
+
+ cris_tst_cc_init();
+ asm volatile ("setf z");
+ verify_addc_m(0, p, 0, 0, 1, 0, 0);
+
+ cris_tst_cc_init();
+ asm volatile ("setf c");
+ verify_addc_m(0, p, 1, 0, 0, 0, 0);
+
+ cris_tst_cc_init();
+ asm volatile ("clearf c");
+ verify_addc_pi_m(0, &p, 0, 0, 1, 0, 0);
+
+ p = &x[1];
+ cris_tst_cc_init();
+ asm volatile ("setf c");
+ verify_addc_pi_m(0, &p, 1, 0, 0, 0, 0);
+
+ if (p != &x[2])
+ err();
+
+ cris_tst_cc_init();
+ asm volatile ("clearf c");
+ verify_addc_pi_m(-1, &p, 1, 0, 0, 0, 1);
+
+ if (p != &x[3])
+ err();
+#endif
+ p = &x[3];
+ /* TODO: investigate why this one fails. */
+ cris_tst_cc_init();
+ asm volatile ("setf c");
+ verify_addc_m(2, p, 2, 0, 0, 0, 1);
+ p += 4;
+
+ pass();
+ return 0;
+}
diff --git a/tests/tcg/cris/libc/check_addo.c b/tests/tcg/cris/libc/check_addo.c
new file mode 100644
index 0000000..4235e5f
--- /dev/null
+++ b/tests/tcg/cris/libc/check_addo.c
@@ -0,0 +1,125 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "sys.h"
+#include "crisutils.h"
+
+/* this would be better to do in asm, it's an orgy in GCC inline asm now. */
+
+#define cris_addo_b(o, v) \
+ asm volatile ("addo.b\t[%0], %1, $acr\n" : : "r" (o), "r" (v) : "acr");
+#define cris_addo_w(o, v) \
+ asm volatile ("addo.w\t[%0], %1, $acr\n" : : "r" (o), "r" (v) : "acr");
+#define cris_addo_d(o, v) \
+ asm volatile ("addo.d\t[%0], %1, $acr\n" : : "r" (o), "r" (v) : "acr");
+#define cris_addo_pi_b(o, v) \
+ asm volatile ("addo.b\t[%0+], %1, $acr\n" \
+ : "+b" (o): "r" (v) : "acr");
+#define cris_addo_pi_w(o, v) \
+ asm volatile ("addo.w\t[%0+], %1, $acr\n" \
+ : "+b" (o): "r" (v) : "acr");
+#define cris_addo_pi_d(o, v) \
+ asm volatile ("addo.d\t[%0+], %1, $acr\n" \
+ : "+b" (o): "r" (v) : "acr");
+
+struct {
+ uint32_t v1;
+ uint16_t v2;
+ uint32_t v3;
+ uint8_t v4;
+ uint8_t v5;
+ uint16_t v6;
+ uint32_t v7;
+} y = {
+ 32769,
+ -1,
+ 5,
+ 3, -4,
+ 2,
+ -76789887
+};
+
+static int x[3] = {0x55aa77ff, 0xccff2244, 0x88ccee19};
+
+int main(void)
+{
+ int *r;
+ unsigned char *t, *p;
+
+ /* Note, this test-case will trig an unaligned access, partly
+ to x[0] and to [x1]. */
+ t = (unsigned char *)x;
+ t -= 32768;
+ p = (unsigned char *) &y.v1;
+ mb(); /* don't reorder anything beyond here. */
+ cris_tst_cc_init();
+ asm volatile ("setf\tzvnc\n");
+ cris_addo_pi_d(p, t);
+ cris_tst_cc(1, 1, 1, 1);
+ asm volatile ("move.d\t$acr, %0\n" : "=r" (r));
+ if (*r != 0x4455aa77)
+ err();
+
+
+ t += 32770;
+ mb(); /* don't reorder anything beyond here. */
+ cris_tst_cc_init();
+ asm volatile ("setf\tzvnc\n");
+ cris_addo_pi_w(p, t);
+ cris_tst_cc(1, 1, 1, 1);
+ asm volatile ("move.d\t$acr, %0\n" : "=r" (r));
+ if (*r != 0x4455aa77)
+ err();
+
+ mb(); /* don't reorder anything beyond here. */
+ cris_tst_cc_init();
+ asm volatile ("setf\tzvnc\n");
+ cris_addo_d(p, r);
+ cris_tst_cc(1, 1, 1, 1);
+ p += 4;
+ asm volatile ("move.d\t$acr, %0\n" : "=r" (r));
+ if (*r != 0xee19ccff)
+ err();
+
+ mb(); /* don't reorder anything beyond here. */
+ cris_tst_cc_init();
+ asm volatile ("setf\tzvnc\n");
+ cris_addo_pi_b(p, t);
+ cris_tst_cc(0, 0, 0, 0);
+ asm volatile ("move.d\t$acr, %0\n" : "=r" (r));
+ if (*(uint16_t*)r != 0xff22)
+ err();
+
+ mb(); /* don't reorder anything beyond here. */
+ cris_tst_cc_init();
+ asm volatile ("setf\tzvnc\n");
+ cris_addo_b(p, r);
+ cris_tst_cc(1, 1, 1, 1);
+ p += 1;
+ asm volatile ("move.d\t$acr, %0\n" : "=r" (r));
+ if (*r != 0x4455aa77)
+ err();
+
+ mb(); /* don't reorder anything beyond here. */
+ cris_tst_cc_init();
+ asm volatile ("setf\tzvnc\n");
+ cris_addo_w(p, r);
+ cris_tst_cc(1, 1, 1, 1);
+ p += 2;
+ asm volatile ("move.d\t$acr, %0\n" : "=r" (r));
+ if (*r != 0xff224455)
+ err();
+
+ mb(); /* don't reorder anything beyond here. */
+ cris_tst_cc_init();
+ asm volatile ("setf\tzvnc\n");
+ cris_addo_pi_d(p, t);
+ cris_tst_cc(0, 0, 0, 0);
+ asm volatile ("move.d\t$acr, %0\n" : "=r" (r));
+ r = (void*)(((char *)r) + 76789885);
+ if (*r != 0x55aa77ff)
+ err();
+
+ pass();
+ return 0;
+}
diff --git a/tests/tcg/cris/libc/check_addoq.c b/tests/tcg/cris/libc/check_addoq.c
new file mode 100644
index 0000000..ed509e2
--- /dev/null
+++ b/tests/tcg/cris/libc/check_addoq.c
@@ -0,0 +1,44 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "sys.h"
+#include "crisutils.h"
+
+/* this would be better to do in asm, it's an orgy in GCC inline asm now. */
+
+/* ACR will be clobbered. */
+#define cris_addoq(o, v) \
+ asm volatile ("addoq\t%1, %0, $acr\n" : : "r" (v), "i" (o) : "acr");
+
+
+int main(void)
+{
+ int x[3] = {0x55aa77ff, 0xccff2244, 0x88ccee19};
+ int *p, *t = x + 1;
+
+ cris_tst_cc_init();
+ asm volatile ("setf\tzvnc\n");
+ cris_addoq(0, t);
+ cris_tst_cc(1, 1, 1, 1);
+ asm volatile ("move.d\t$acr, %0\n" : "=r" (p));
+ if (*p != 0xccff2244)
+ err();
+
+ cris_tst_cc_init();
+ asm volatile ("setf\tzvnc\n");
+ cris_addoq(4, t);
+ cris_tst_cc(0, 0, 0, 0);
+ asm volatile ("move.d\t$acr, %0\n" : "=r" (p));
+ if (*p != 0x88ccee19)
+ err();
+
+ cris_tst_cc_init();
+ asm volatile ("clearf\tzvnc\n");
+ cris_addoq(-8, t + 1);
+ cris_tst_cc(0, 0, 0, 0);
+ asm volatile ("move.d\t$acr, %0\n" : "=r" (p));
+ if (*p != 0x55aa77ff)
+ err();
+ pass();
+ return 0;
+}
diff --git a/tests/tcg/cris/libc/check_bound.c b/tests/tcg/cris/libc/check_bound.c
new file mode 100644
index 0000000..d956ab9
--- /dev/null
+++ b/tests/tcg/cris/libc/check_bound.c
@@ -0,0 +1,142 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "sys.h"
+#include "crisutils.h"
+
+static always_inline int cris_bound_b(int v, int b)
+{
+ int r = v;
+ asm ("bound.b\t%1, %0\n" : "+r" (r) : "ri" (b));
+ return r;
+}
+
+static always_inline int cris_bound_w(int v, int b)
+{
+ int r = v;
+ asm ("bound.w\t%1, %0\n" : "+r" (r) : "ri" (b));
+ return r;
+}
+
+static always_inline int cris_bound_d(int v, int b)
+{
+ int r = v;
+ asm ("bound.d\t%1, %0\n" : "+r" (r) : "ri" (b));
+ return r;
+}
+
+int main(void)
+{
+ int r;
+
+ cris_tst_cc_init();
+ r = cris_bound_d(-1, 2);
+ cris_tst_cc(0, 0, 0, 0);
+ if (r != 2)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_d(2, 0xffffffff);
+ cris_tst_cc(0, 0, 0, 0);
+ if (r != 2)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_d(0xffff, 0xffff);
+ cris_tst_cc(0, 0, 0, 0);
+ if (r != 0xffff)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_d(-1, 0xffffffff);
+ cris_tst_cc(1, 0, 0, 0);
+ if (r != 0xffffffff)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_d(0x78134452, 0x5432f789);
+ cris_tst_cc(0, 0, 0, 0);
+ if (r != 0x5432f789)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_w(-1, 2);
+ cris_tst_cc(0, 0, 0, 0);
+ if (r != 2)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_w(-1, 0xffff);
+ cris_tst_cc(0, 0, 0, 0);
+ if (r != 0xffff)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_w(2, 0xffff);
+ cris_tst_cc(0, 0, 0, 0);
+ if (r != 2)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_w(0xfedaffff, 0xffff);
+ cris_tst_cc(0, 0, 0, 0);
+ if (r != 0xffff)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_w(0x78134452, 0xf789);
+ cris_tst_cc(0, 0, 0, 0);
+ if (r != 0xf789)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_b(-1, 2);
+ cris_tst_cc(0, 0, 0, 0);
+ if (r != 2)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_b(2, 0xff);
+ cris_tst_cc(0, 0, 0, 0);
+ if (r != 2)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_b(-1, 0xff);
+ cris_tst_cc(0, 0, 0, 0);
+ if (r != 0xff)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_b(0xff, 0xff);
+ cris_tst_cc(0, 0, 0, 0);
+ if (r != 0xff)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_b(0xfeda49ff, 0xff);
+ cris_tst_cc(0, 0, 0, 0);
+ if (r != 0xff)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_b(0x78134452, 0x89);
+ cris_tst_cc(0, 0, 0, 0);
+ if (r != 0x89)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_w(0x78134452, 0);
+ cris_tst_cc(0, 1, 0, 0);
+ if (r != 0)
+ err();
+
+ cris_tst_cc_init();
+ r = cris_bound_b(0xffff, -1);
+ cris_tst_cc(0, 0, 0, 0);
+ if (r != 0xff)
+ err();
+
+ pass();
+ return 0;
+}
diff --git a/tests/tcg/cris/libc/check_ftag.c b/tests/tcg/cris/libc/check_ftag.c
new file mode 100644
index 0000000..aaa5c97
--- /dev/null
+++ b/tests/tcg/cris/libc/check_ftag.c
@@ -0,0 +1,37 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "sys.h"
+#include "crisutils.h"
+
+static always_inline void cris_ftag_i(unsigned int x)
+{
+ register unsigned int v asm("$r10") = x;
+ asm ("ftagi\t[%0]\n" : : "r" (v) );
+}
+static always_inline void cris_ftag_d(unsigned int x)
+{
+ register unsigned int v asm("$r10") = x;
+ asm ("ftagd\t[%0]\n" : : "r" (v) );
+}
+static always_inline void cris_fidx_i(unsigned int x)
+{
+ register unsigned int v asm("$r10") = x;
+ asm ("fidxi\t[%0]\n" : : "r" (v) );
+}
+static always_inline void cris_fidx_d(unsigned int x)
+{
+ register unsigned int v asm("$r10") = x;
+ asm ("fidxd\t[%0]\n" : : "r" (v) );
+}
+
+
+int main(void)
+{
+ cris_ftag_i(0);
+ cris_ftag_d(0);
+ cris_fidx_i(0);
+ cris_fidx_d(0);
+ pass();
+ return 0;
+}
diff --git a/tests/tcg/cris/libc/check_gcctorture_pr28634-1.c b/tests/tcg/cris/libc/check_gcctorture_pr28634-1.c
new file mode 100644
index 0000000..45ecd15
--- /dev/null
+++ b/tests/tcg/cris/libc/check_gcctorture_pr28634-1.c
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/28634. On targets with delayed branches,
+ dbr_schedule could do the next iteration's addition in the
+ branch delay slot, then subtract the value again if the branch
+ wasn't taken. This can lead to rounding errors. */
+int x = -1;
+int y = 1;
+int
+main (void)
+{
+ while (y > 0)
+ y += x;
+ if (y != x + 1)
+ abort ();
+ exit (0);
+}
diff --git a/tests/tcg/cris/libc/check_gcctorture_pr28634.c b/tests/tcg/cris/libc/check_gcctorture_pr28634.c
new file mode 100644
index 0000000..a0c5254
--- /dev/null
+++ b/tests/tcg/cris/libc/check_gcctorture_pr28634.c
@@ -0,0 +1,15 @@
+/* PR rtl-optimization/28634. On targets with delayed branches,
+ dbr_schedule could do the next iteration's addition in the
+ branch delay slot, then subtract the value again if the branch
+ wasn't taken. This can lead to rounding errors. */
+double x = -0x1.0p53;
+double y = 1;
+int
+main (void)
+{
+ while (y > 0)
+ y += x;
+ if (y != x + 1)
+ abort ();
+ exit (0);
+}
diff --git a/tests/tcg/cris/libc/check_glibc_kernelversion.c b/tests/tcg/cris/libc/check_glibc_kernelversion.c
new file mode 100644
index 0000000..7aada89
--- /dev/null
+++ b/tests/tcg/cris/libc/check_glibc_kernelversion.c
@@ -0,0 +1,116 @@
+/*
+ * Check the lz insn.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "sys.h"
+
+#define __LINUX_KERNEL_VERSION 131584
+
+#define DL_SYSDEP_OSCHECK(FATAL) \
+ do { \
+ /* Test whether the kernel is new enough. This test is only \
+ performed if the library is not compiled to run on all \
+ kernels. */ \
+ if (__LINUX_KERNEL_VERSION > 0) \
+ { \
+ char bufmem[64]; \
+ char *buf = bufmem; \
+ unsigned int version; \
+ int parts; \
+ char *cp; \
+ struct utsname uts; \
+ \
+ /* Try the uname syscall */ \
+ if (__uname (&uts)) \
+ { \
+ /* This was not successful. Now try reading the /proc \
+ filesystem. */ \
+ ssize_t reslen; \
+ int fd = __open ("/proc/sys/kernel/osrelease", O_RDONLY); \
+ if (fd == -1 \
+ || (reslen = __read (fd, bufmem, sizeof (bufmem))) <= 0) \
+ /* This also didn't work. We give up since we cannot \
+ make sure the library can actually work. */ \
+ FATAL ("FATAL: cannot determine library version\n"); \
+ __close (fd); \
+ buf[MIN (reslen, (ssize_t) sizeof (bufmem) - 1)] = '\0'; \
+ } \
+ else \
+ buf = uts.release; \
+ \
+ /* Now convert it into a number. The string consists of at most \
+ three parts. */ \
+ version = 0; \
+ parts = 0; \
+ cp = buf; \
+ while ((*cp >= '0') && (*cp <= '9')) \
+ { \
+ unsigned int here = *cp++ - '0'; \
+ \
+ while ((*cp >= '0') && (*cp <= '9')) \
+ { \
+ here *= 10; \
+ here += *cp++ - '0'; \
+ } \
+ \
+ ++parts; \
+ version <<= 8; \
+ version |= here; \
+ \
+ if (*cp++ != '.') \
+ /* Another part following? */ \
+ break; \
+ } \
+ \
+ if (parts < 3) \
+ version <<= 8 * (3 - parts); \
+ \
+ /* Now we can test with the required version. */ \
+ if (version < __LINUX_KERNEL_VERSION) \
+ /* Not sufficient. */ \
+ FATAL ("FATAL: kernel too old\n"); \
+ \
+ _dl_osversion = version; \
+ } \
+ } while (0)
+
+int main(void)
+{
+ char bufmem[64] = "2.6.22";
+ char *buf = bufmem;
+ unsigned int version;
+ int parts;
+ char *cp;
+
+ version = 0;
+ parts = 0;
+ cp = buf;
+ while ((*cp >= '0') && (*cp <= '9'))
+ {
+ unsigned int here = *cp++ - '0';
+
+ while ((*cp >= '0') && (*cp <= '9'))
+ {
+ here *= 10;
+ here += *cp++ - '0';
+ }
+
+ ++parts;
+ version <<= 8;
+ version |= here;
+
+ if (*cp++ != '.')
+ /* Another part following? */
+ break;
+ }
+
+ if (parts < 3)
+ version <<= 8 * (3 - parts);
+ if (version < __LINUX_KERNEL_VERSION)
+ err();
+ pass();
+ exit(0);
+}
diff --git a/tests/tcg/cris/libc/check_hello.c b/tests/tcg/cris/libc/check_hello.c
new file mode 100644
index 0000000..fb403ba
--- /dev/null
+++ b/tests/tcg/cris/libc/check_hello.c
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include <stdlib.h>
+int main ()
+{
+ printf ("pass\n");
+ exit (0);
+}
diff --git a/tests/tcg/cris/libc/check_int64.c b/tests/tcg/cris/libc/check_int64.c
new file mode 100644
index 0000000..69caec1
--- /dev/null
+++ b/tests/tcg/cris/libc/check_int64.c
@@ -0,0 +1,47 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "sys.h"
+#include "crisutils.h"
+
+
+static always_inline int64_t add64(const int64_t a, const int64_t b)
+{
+ return a + b;
+}
+
+static always_inline int64_t sub64(const int64_t a, const int64_t b)
+{
+ return a - b;
+}
+
+int main(void)
+{
+ int64_t a = 1;
+ int64_t b = 2;
+
+ /* FIXME: add some tests. */
+ a = add64(a, b);
+ if (a != 3)
+ err();
+
+ a = sub64(a, b);
+ if (a != 1)
+ err();
+
+ a = add64(a, -4);
+ if (a != -3)
+ err();
+
+ a = add64(a, 3);
+ if (a != 0)
+ err();
+
+ a = 0;
+ a = sub64(a, 1);
+ if (a != -1)
+ err();
+
+ pass();
+ return 0;
+}
diff --git a/tests/tcg/cris/libc/check_lz.c b/tests/tcg/cris/libc/check_lz.c
new file mode 100644
index 0000000..bf051a6
--- /dev/null
+++ b/tests/tcg/cris/libc/check_lz.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "sys.h"
+
+static always_inline int cris_lz(int x)
+{
+ int r;
+ asm ("lz\t%1, %0\n" : "=r" (r) : "r" (x));
+ return r;
+}
+
+void check_lz(void)
+{
+ int i;
+
+ if (cris_lz(0) != 32)
+ err();
+ if (cris_lz(1) != 31)
+ err();
+ if (cris_lz(2) != 30)
+ err();
+ if (cris_lz(4) != 29)
+ err();
+ if (cris_lz(8) != 28)
+ err();
+
+ /* try all positions with a single bit. */
+ for (i = 1; i < 32; i++) {
+ if (cris_lz(1 << (i-1)) != (32 - i))
+ err();
+ }
+
+ /* try all positions with all bits. */
+ for (i = 1; i < 32; i++) {
+ /* split up this computation to clarify it. */
+ uint32_t val;
+ val = (unsigned int)-1 >> (32 - i);
+ if (cris_lz(val) != (32 - i))
+ err();
+ }
+}
+
+int main(void)
+{
+ check_lz();
+ pass();
+ exit(0);
+}
diff --git a/tests/tcg/cris/libc/check_mapbrk.c b/tests/tcg/cris/libc/check_mapbrk.c
new file mode 100644
index 0000000..1aff762
--- /dev/null
+++ b/tests/tcg/cris/libc/check_mapbrk.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Basic sanity check that syscalls to implement malloc (brk, mmap2,
+ munmap) are trivially functional. */
+
+int main ()
+{
+ void *p1, *p2, *p3, *p4, *p5, *p6;
+
+ if ((p1 = malloc (8100)) == NULL
+ || (p2 = malloc (16300)) == NULL
+ || (p3 = malloc (4000)) == NULL
+ || (p4 = malloc (500)) == NULL
+ || (p5 = malloc (1023*1024)) == NULL
+ || (p6 = malloc (8191*1024)) == NULL)
+ {
+ printf ("fail\n");
+ exit (1);
+ }
+
+ free (p1);
+ free (p2);
+ free (p3);
+ free (p4);
+ free (p5);
+ free (p6);
+
+ p1 = malloc (64000);
+ if (p1 == NULL)
+ {
+ printf ("fail\n");
+ exit (1);
+ }
+ free (p1);
+
+ printf ("pass\n");
+ exit (0);
+}
diff --git a/tests/tcg/cris/libc/check_mmap1.c b/tests/tcg/cris/libc/check_mmap1.c
new file mode 100644
index 0000000..b803f0c
--- /dev/null
+++ b/tests/tcg/cris/libc/check_mmap1.c
@@ -0,0 +1,48 @@
+/*
+#notarget: cris*-*-elf
+*/
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+int main (int argc, char *argv[])
+{
+ int fd = open (argv[0], O_RDONLY);
+ struct stat sb;
+ int size;
+ void *a;
+ const char *str = "a string you'll only find in the program";
+
+ if (fd == -1)
+ {
+ perror ("open");
+ abort ();
+ }
+
+ if (fstat (fd, &sb) < 0)
+ {
+ perror ("fstat");
+ abort ();
+ }
+
+ size = sb.st_size;
+
+ /* We want to test mmapping a size that isn't exactly a page. */
+ if ((size & 8191) == 0)
+ size--;
+
+ a = mmap (NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
+
+ if (memmem (a, size, str, strlen (str) + 1) == NULL)
+ abort ();
+
+ printf ("pass\n");
+ exit (0);
+}
diff --git a/tests/tcg/cris/libc/check_mmap2.c b/tests/tcg/cris/libc/check_mmap2.c
new file mode 100644
index 0000000..35139a0
--- /dev/null
+++ b/tests/tcg/cris/libc/check_mmap2.c
@@ -0,0 +1,48 @@
+/*
+#notarget: cris*-*-elf
+*/
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+int main (int argc, char *argv[])
+{
+ int fd = open (argv[0], O_RDONLY);
+ struct stat sb;
+ int size;
+ void *a;
+ const char *str = "a string you'll only find in the program";
+
+ if (fd == -1)
+ {
+ perror ("open");
+ abort ();
+ }
+
+ if (fstat (fd, &sb) < 0)
+ {
+ perror ("fstat");
+ abort ();
+ }
+
+ size = sb.st_size;
+
+ /* We want to test mmapping a size that isn't exactly a page. */
+ if ((size & 8191) == 0)
+ size--;
+
+ a = mmap (NULL, size, PROT_READ, MAP_SHARED, fd, 0);
+
+ if (memmem (a, size, str, strlen (str) + 1) == NULL)
+ abort ();
+
+ printf ("pass\n");
+ exit (0);
+}
diff --git a/tests/tcg/cris/libc/check_mmap3.c b/tests/tcg/cris/libc/check_mmap3.c
new file mode 100644
index 0000000..cb890ef
--- /dev/null
+++ b/tests/tcg/cris/libc/check_mmap3.c
@@ -0,0 +1,33 @@
+/*
+#notarget: cris*-*-elf
+*/
+
+#define _GNU_SOURCE
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/mman.h>
+
+int main (int argc, char *argv[])
+{
+ volatile unsigned char *a;
+
+ /* Check that we can map a non-multiple of a page and still get a full page. */
+ a = mmap (NULL, 0x4c, PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (a == NULL || a == (unsigned char *) -1)
+ abort ();
+
+ a[0] = 0xbe;
+ a[8191] = 0xef;
+ memset ((char *) a + 1, 0, 8190);
+
+ if (a[0] != 0xbe || a[8191] != 0xef)
+ abort ();
+
+ printf ("pass\n");
+ exit (0);
+}
diff --git a/tests/tcg/cris/libc/check_moveq.c b/tests/tcg/cris/libc/check_moveq.c
new file mode 100644
index 0000000..80f2dff
--- /dev/null
+++ b/tests/tcg/cris/libc/check_moveq.c
@@ -0,0 +1,51 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "sys.h"
+#include "crisutils.h"
+
+#define cris_moveq(dst, src) \
+ asm volatile ("moveq %1, %0\n" : "=r" (dst) : "i" (src));
+
+
+
+int main(void)
+{
+ int t;
+
+ cris_tst_cc_init();
+ asm volatile ("setf\tzvnc\n");
+ cris_moveq(t, 10);
+ cris_tst_cc(1, 1, 1, 1);
+ if (t != 10)
+ err();
+
+ /* make sure moveq doesn't clobber the zflag. */
+ cris_tst_cc_init();
+ asm volatile ("setf vnc\n");
+ asm volatile ("clearf z\n");
+ cris_moveq(t, 0);
+ cris_tst_cc(1, 0, 1, 1);
+ if (t != 0)
+ err();
+
+ /* make sure moveq doesn't clobber the nflag.
+ Also check large immediates */
+ cris_tst_cc_init();
+ asm volatile ("setf zvc\n");
+ asm volatile ("clearf n\n");
+ cris_moveq(t, -31);
+ cris_tst_cc(0, 1, 1, 1);
+ if (t != -31)
+ err();
+
+ cris_tst_cc_init();
+ asm volatile ("setf nzvc\n");
+ cris_moveq(t, 31);
+ cris_tst_cc(1, 1, 1, 1);
+ if (t != 31)
+ err();
+
+ pass();
+ return 0;
+}
diff --git a/tests/tcg/cris/libc/check_openpf1.c b/tests/tcg/cris/libc/check_openpf1.c
new file mode 100644
index 0000000..251d26e
--- /dev/null
+++ b/tests/tcg/cris/libc/check_openpf1.c
@@ -0,0 +1,38 @@
+/* Check that --sysroot is applied to open(2).
+#sim: --sysroot=@exedir@
+
+ We assume, with EXE being the name of the executable:
+ - The simulator executes with cwd the same directory where the executable
+ is located (so argv[0] contains a plain filename without directory
+ components).
+ - There's no /EXE on the host file system. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+int main (int argc, char *argv[])
+{
+ char *fnam = argv[0];
+ FILE *f;
+ if (argv[0][0] != '/')
+ {
+ fnam = malloc (strlen (argv[0]) + 2);
+ if (fnam == NULL)
+ abort ();
+ strcpy (fnam, "/");
+ strcat (fnam, argv[0]);
+ }
+
+ f = fopen (fnam, "rb");
+ if (f == NULL)
+ abort ();
+ fclose(f);
+
+ /* Cover another execution path. */
+ if (fopen ("/nonexistent", "rb") != NULL
+ || errno != ENOENT)
+ abort ();
+ printf ("pass\n");
+ return 0;
+}
diff --git a/tests/tcg/cris/libc/check_openpf2.c b/tests/tcg/cris/libc/check_openpf2.c
new file mode 100644
index 0000000..5d56189
--- /dev/null
+++ b/tests/tcg/cris/libc/check_openpf2.c
@@ -0,0 +1,16 @@
+/* Check that the simulator has chdir:ed to the --sysroot argument
+#sim: --sysroot=@srcdir@
+ (or that --sysroot is applied to relative file paths). */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+int main (int argc, char *argv[])
+{
+ FILE *f = fopen ("check_openpf2.c", "rb");
+ if (f == NULL)
+ abort ();
+ fclose(f);
+ printf ("pass\n");
+ return 0;
+}
diff --git a/tests/tcg/cris/libc/check_openpf3.c b/tests/tcg/cris/libc/check_openpf3.c
new file mode 100644
index 0000000..557adee
--- /dev/null
+++ b/tests/tcg/cris/libc/check_openpf3.c
@@ -0,0 +1,49 @@
+/* Basic file operations (rename, unlink); once without sysroot. We
+ also test that the simulator has chdir:ed to PREFIX, when defined. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#ifndef PREFIX
+#define PREFIX
+#endif
+
+void err (const char *s)
+{
+ perror (s);
+ abort ();
+}
+
+int main (int argc, char *argv[])
+{
+ FILE *f;
+ struct stat buf;
+
+ unlink (PREFIX "testfoo2.tmp");
+
+ f = fopen ("testfoo1.tmp", "w");
+ if (f == NULL)
+ err ("open");
+ fclose (f);
+
+ if (rename (PREFIX "testfoo1.tmp", PREFIX "testfoo2.tmp") != 0)
+ err ("rename");
+
+ if (stat (PREFIX "testfoo2.tmp", &buf) != 0
+ || !S_ISREG (buf.st_mode))
+ err ("stat 1");
+
+ if (stat ("testfoo2.tmp", &buf) != 0
+ || !S_ISREG (buf.st_mode))
+ err ("stat 2");
+
+ if (unlink (PREFIX "testfoo2.tmp") != 0)
+ err ("unlink");
+
+ printf ("pass\n");
+ return 0;
+}
diff --git a/tests/tcg/cris/libc/check_openpf5.c b/tests/tcg/cris/libc/check_openpf5.c
new file mode 100644
index 0000000..1f86ea2
--- /dev/null
+++ b/tests/tcg/cris/libc/check_openpf5.c
@@ -0,0 +1,56 @@
+/* Check that TRT happens when error on too many opened files.
+#notarget: cris*-*-elf
+#sim: --sysroot=@exedir@
+*/
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+
+int main (int argc, char *argv[])
+{
+ int i;
+ int filemax;
+
+#ifdef OPEN_MAX
+ filemax = OPEN_MAX;
+#else
+ filemax = sysconf (_SC_OPEN_MAX);
+#endif
+
+ char *fn = malloc (strlen (argv[0]) + 2);
+ if (fn == NULL)
+ abort ();
+ strcpy (fn, "/");
+ strcat (fn, argv[0]);
+
+ for (i = 0; i < filemax + 1; i++)
+ {
+ if (open (fn, O_RDONLY) < 0)
+ {
+ /* Shouldn't happen too early. */
+ if (i < filemax - 3 - 1)
+ {
+ fprintf (stderr, "i: %d\n", i);
+ abort ();
+ }
+ if (errno != EMFILE)
+ {
+ perror ("open");
+ abort ();
+ }
+ goto ok;
+ }
+ }
+ abort ();
+
+ok:
+ printf ("pass\n");
+ exit (0);
+}
diff --git a/tests/tcg/cris/libc/check_settls1.c b/tests/tcg/cris/libc/check_settls1.c
new file mode 100644
index 0000000..3abc3a9
--- /dev/null
+++ b/tests/tcg/cris/libc/check_settls1.c
@@ -0,0 +1,45 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <sys/syscall.h>
+
+#ifndef SYS_set_thread_area
+#define SYS_set_thread_area 243
+#endif
+
+int main (void)
+{
+ unsigned long tp, old_tp;
+ int ret;
+
+ asm volatile ("move $pid,%0" : "=r" (old_tp));
+ old_tp &= ~0xff;
+
+ ret = syscall (SYS_set_thread_area, 0xf0);
+ if (ret != -1 || errno != EINVAL) {
+ syscall (SYS_set_thread_area, old_tp);
+ perror ("Invalid thread area accepted:");
+ abort();
+ }
+
+ ret = syscall (SYS_set_thread_area, 0xeddeed00);
+ if (ret != 0) {
+ perror ("Valid thread area not accepted: ");
+ abort ();
+ }
+
+ asm volatile ("move $pid,%0" : "=r" (tp));
+ tp &= ~0xff;
+ syscall (SYS_set_thread_area, old_tp);
+
+ if (tp != 0xeddeed00) {
+ * (volatile int *) 0 = 0;
+ perror ("tls2");
+ abort ();
+ }
+
+ printf ("pass\n");
+ return EXIT_SUCCESS;
+}
diff --git a/tests/tcg/cris/libc/check_sigalrm.c b/tests/tcg/cris/libc/check_sigalrm.c
new file mode 100644
index 0000000..39fa8d9
--- /dev/null
+++ b/tests/tcg/cris/libc/check_sigalrm.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+#include <unistd.h>
+
+#define MAGIC (0xdeadbeef)
+
+int s = 0;
+void sighandler(int sig)
+{
+ s = MAGIC;
+}
+
+int main(int argc, char **argv)
+{
+ int p;
+
+ p = getpid();
+ signal(SIGALRM, sighandler);
+ kill(p, SIGALRM);
+ if (s != MAGIC)
+ return EXIT_FAILURE;
+
+ printf ("passed\n");
+ return EXIT_SUCCESS;
+}
diff --git a/tests/tcg/cris/libc/check_stat1.c b/tests/tcg/cris/libc/check_stat1.c
new file mode 100644
index 0000000..2e2cae5
--- /dev/null
+++ b/tests/tcg/cris/libc/check_stat1.c
@@ -0,0 +1,16 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main (void)
+{
+ struct stat buf;
+
+ if (stat (".", &buf) != 0
+ || !S_ISDIR (buf.st_mode))
+ abort ();
+ printf ("pass\n");
+ exit (0);
+}
diff --git a/tests/tcg/cris/libc/check_stat2.c b/tests/tcg/cris/libc/check_stat2.c
new file mode 100644
index 0000000..e36172e
--- /dev/null
+++ b/tests/tcg/cris/libc/check_stat2.c
@@ -0,0 +1,20 @@
+/*
+#notarget: cris*-*-elf
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int main (void)
+{
+ struct stat buf;
+
+ if (lstat (".", &buf) != 0
+ || !S_ISDIR (buf.st_mode))
+ abort ();
+ printf ("pass\n");
+ exit (0);
+}
diff --git a/tests/tcg/cris/libc/check_stat3.c b/tests/tcg/cris/libc/check_stat3.c
new file mode 100644
index 0000000..36a9d5d
--- /dev/null
+++ b/tests/tcg/cris/libc/check_stat3.c
@@ -0,0 +1,25 @@
+/* Simulator options:
+#sim: --sysroot=@exedir@
+*/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int main (int argc, char *argv[])
+{
+ char path[1024] = "/";
+ struct stat buf;
+
+ strncat(path, argv[0], sizeof(path) - 2);
+ if (stat (".", &buf) != 0
+ || !S_ISDIR (buf.st_mode))
+ abort ();
+ if (stat (path, &buf) != 0
+ || !S_ISREG (buf.st_mode))
+ abort ();
+ printf ("pass\n");
+ exit (0);
+}
diff --git a/tests/tcg/cris/libc/check_stat4.c b/tests/tcg/cris/libc/check_stat4.c
new file mode 100644
index 0000000..04f21fe
--- /dev/null
+++ b/tests/tcg/cris/libc/check_stat4.c
@@ -0,0 +1,27 @@
+/* Simulator options:
+#notarget: cris*-*-elf
+#sim: --sysroot=@exedir@
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int main (int argc, char *argv[])
+{
+ char path[1024] = "/";
+ struct stat buf;
+
+ strncat(path, argv[0], sizeof(path) - 2);
+ if (lstat (".", &buf) != 0
+ || !S_ISDIR (buf.st_mode))
+ abort ();
+ if (lstat (path, &buf) != 0
+ || !S_ISREG (buf.st_mode))
+ abort ();
+ printf ("pass\n");
+ exit (0);
+}
diff --git a/tests/tcg/cris/libc/check_swap.c b/tests/tcg/cris/libc/check_swap.c
new file mode 100644
index 0000000..9a68c1e
--- /dev/null
+++ b/tests/tcg/cris/libc/check_swap.c
@@ -0,0 +1,76 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include "sys.h"
+#include "crisutils.h"
+
+#define N 8
+#define W 4
+#define B 2
+#define R 1
+
+static always_inline int cris_swap(const int mode, int x)
+{
+ switch (mode)
+ {
+ case N: asm ("swapn\t%0\n" : "+r" (x) : "0" (x)); break;
+ case W: asm ("swapw\t%0\n" : "+r" (x) : "0" (x)); break;
+ case B: asm ("swapb\t%0\n" : "+r" (x) : "0" (x)); break;
+ case R: asm ("swapr\t%0\n" : "+r" (x) : "0" (x)); break;
+ case B|R: asm ("swapbr\t%0\n" : "+r" (x) : "0" (x)); break;
+ case W|R: asm ("swapwr\t%0\n" : "+r" (x) : "0" (x)); break;
+ case W|B: asm ("swapwb\t%0\n" : "+r" (x) : "0" (x)); break;
+ case W|B|R: asm ("swapwbr\t%0\n" : "+r" (x) : "0" (x)); break;
+ case N|R: asm ("swapnr\t%0\n" : "+r" (x) : "0" (x)); break;
+ case N|B: asm ("swapnb\t%0\n" : "+r" (x) : "0" (x)); break;
+ case N|B|R: asm ("swapnbr\t%0\n" : "+r" (x) : "0" (x)); break;
+ case N|W: asm ("swapnw\t%0\n" : "+r" (x) : "0" (x)); break;
+ default:
+ err();
+ break;
+ }
+ return x;
+}
+
+/* Made this a macro to be able to pick up the location of the errors. */
+#define verify_swap(mode, val, expected, n, z) \
+do { \
+ int r; \
+ cris_tst_cc_init(); \
+ r = cris_swap(mode, val); \
+ cris_tst_mov_cc(n, z); \
+ if (r != expected) \
+ err(); \
+} while(0)
+
+void check_swap(void)
+{
+ /* Some of these numbers are borrowed from GDB's cris sim
+ testsuite. */
+ if (cris_swap(N, 0) != 0xffffffff)
+ err();
+ if (cris_swap(W, 0x12345678) != 0x56781234)
+ err();
+ if (cris_swap(B, 0x12345678) != 0x34127856)
+ err();
+
+ verify_swap(R, 0x78134452, 0x1ec8224a, 0, 0);
+ verify_swap(B, 0x78134452, 0x13785244, 0, 0);
+ verify_swap(B|R, 0x78134452, 0xc81e4a22, 1, 0);
+ verify_swap(W, 0x78134452, 0x44527813, 0, 0);
+ verify_swap(W|R, 0x78134452, 0x224a1ec8, 0, 0);
+ verify_swap(W|B|R, 0x78134452, 0x4a22c81e, 0, 0);
+ verify_swap(N, 0x78134452, 0x87ecbbad, 1, 0);
+ verify_swap(N|R, 0x78134452, 0xe137ddb5, 1, 0);
+ verify_swap(N|B, 0x78134452, 0xec87adbb, 1, 0);
+ verify_swap(N|B|R, 0x78134452, 0x37e1b5dd, 0, 0);
+ verify_swap(N|W, 0x78134452, 0xbbad87ec, 1, 0);
+ verify_swap(N|B|R, 0xffffffff, 0, 0, 1);
+}
+
+int main(void)
+{
+ check_swap();
+ pass();
+ return 0;
+}
diff --git a/tests/tcg/cris/libc/check_time2.c b/tests/tcg/cris/libc/check_time2.c
new file mode 100644
index 0000000..20b69b4
--- /dev/null
+++ b/tests/tcg/cris/libc/check_time2.c
@@ -0,0 +1,18 @@
+/* CB_SYS_time doesn't implement the Linux time syscall; the return
+ value isn't written to the argument. */
+
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main (void)
+{
+ time_t x = (time_t) -1;
+ time_t t = time (&x);
+
+ if (t == (time_t) -1 || t != x)
+ abort ();
+ printf ("pass\n");
+ exit (0);
+}
diff --git a/tests/tcg/cris/libc/crisutils.h b/tests/tcg/cris/libc/crisutils.h
new file mode 100644
index 0000000..bbbe6c5
--- /dev/null
+++ b/tests/tcg/cris/libc/crisutils.h
@@ -0,0 +1,76 @@
+#ifndef CRISUTILS_H
+#define CRISUTILS_H 1
+
+static char *tst_cc_loc = NULL;
+
+#define cris_tst_cc_init() \
+do { tst_cc_loc = "test_cc failed at " CURRENT_LOCATION; } while(0)
+
+/* We need a real symbol to signal error. */
+void _err(void) {
+ if (!tst_cc_loc)
+ tst_cc_loc = "tst_cc_failed\n";
+ _fail(tst_cc_loc);
+}
+
+static always_inline void cris_tst_cc_n1(void)
+{
+ asm volatile ("bpl _err\n"
+ "nop\n");
+}
+static always_inline void cris_tst_cc_n0(void)
+{
+ asm volatile ("bmi _err\n"
+ "nop\n");
+}
+
+static always_inline void cris_tst_cc_z1(void)
+{
+ asm volatile ("bne _err\n"
+ "nop\n");
+}
+static always_inline void cris_tst_cc_z0(void)
+{
+ asm volatile ("beq _err\n"
+ "nop\n");
+}
+static always_inline void cris_tst_cc_v1(void)
+{
+ asm volatile ("bvc _err\n"
+ "nop\n");
+}
+static always_inline void cris_tst_cc_v0(void)
+{
+ asm volatile ("bvs _err\n"
+ "nop\n");
+}
+
+static always_inline void cris_tst_cc_c1(void)
+{
+ asm volatile ("bcc _err\n"
+ "nop\n");
+}
+static always_inline void cris_tst_cc_c0(void)
+{
+ asm volatile ("bcs _err\n"
+ "nop\n");
+}
+
+static always_inline void cris_tst_mov_cc(int n, int z)
+{
+ if (n) cris_tst_cc_n1(); else cris_tst_cc_n0();
+ if (z) cris_tst_cc_z1(); else cris_tst_cc_z0();
+ asm volatile ("" : : "g" (_err));
+}
+
+static always_inline void cris_tst_cc(const int n, const int z,
+ const int v, const int c)
+{
+ if (n) cris_tst_cc_n1(); else cris_tst_cc_n0();
+ if (z) cris_tst_cc_z1(); else cris_tst_cc_z0();
+ if (v) cris_tst_cc_v1(); else cris_tst_cc_v0();
+ if (c) cris_tst_cc_c1(); else cris_tst_cc_c0();
+ asm volatile ("" : : "g" (_err));
+}
+
+#endif
diff --git a/tests/tcg/cris/libc/sys.h b/tests/tcg/cris/libc/sys.h
new file mode 100644
index 0000000..3dd47bb
--- /dev/null
+++ b/tests/tcg/cris/libc/sys.h
@@ -0,0 +1,18 @@
+#include <unistd.h>
+
+#define STRINGIFY(x) #x
+#define TOSTRING(x) STRINGIFY(x)
+
+#define always_inline inline __attribute__((always_inline))
+
+#define CURRENT_LOCATION __FILE__ ":" TOSTRING(__LINE__)
+
+#define err() \
+{ \
+ _fail("at " CURRENT_LOCATION " "); \
+}
+
+#define mb() asm volatile ("" : : : "memory")
+
+void pass(void);
+void _fail(char *reason);