diff options
Diffstat (limited to 'tests/tcg/cris/libc')
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); |