Since you asked about big-endian systems I also built your test program for the armeb architecture -- which involved hacking up the test harness fairly heavily to not require libc -- and ran the result in qemu.
Actually, it hasn't finished after 2 hours of (qemu) CPU time, but I can tell from the output that the first phase has completed successfully but the second hasn't finished (because it's printed 1 and 2 but not yet 3). I am pretty sure this is because it's just rather slow in emulation, and obviously performance figures are going to be useless. Anyway, I built this on my armhf machine with gcc-4.8 -O -o testeb linux32.c rv32.c verify.c -nostdlib -mbig-endian copied it to my fastest x86_64 desktop and ran it with qemu-armeb ./a.out || echo fail #include <stdio.h> #include <stdlib.h> #include <limits.h> #include <pthread.h> #include <string.h> #include "common.h" #define NTHR 1 #define LO_START 10ULL #define LO_STOP 10000000000ULL #define HI_START ULLONG_MAX #define HI_STOP ULLONG_MAX - LO_STOP static unsigned long long lenfreq[NTHR][32]; #include <unistd.h> #include <sys/syscall.h> __attribute__((noinline)) static void do_exit(int i) { register int i0 asm("r0") = i; register int ss asm("r7") = SYS_exit; __asm__ __volatile__("swi 0x0" : : "r"(ss), "r"(i0)); } __attribute__((noinline)) static void do_write(int fd, const char *buf, size_t n) { register int i0 asm("r0") = fd; register const char *i1 asm("r1") = buf; register size_t i2 asm("r2") = n; register int ss asm("r7") = SYS_write; __asm__ __volatile__("swi 0x0" : : "r"(ss), "r"(i0), "r"(i1), "r"(i2)); } int memcmp(const void * va, const void * vb, size_t sz) { unsigned char *a, *b, aa, bb; while(sz--) { int diff = *a++ - *b++; if(diff) return diff; } return 0; } static int do_check(unsigned long long n, unsigned idx) { char buf1[24]; char buf2[24]; int len1, len2; len1 = linux_put_dec(buf1, n) - buf1; len2 = rv_put_dec(buf2, n) - buf2; if (len1 != len2 || memcmp(buf1, buf2, len1)) { return -1; } lenfreq[idx][len1]++; return 0; } static void *check(void *arg) { unsigned long idx = (unsigned long)arg; unsigned long long n; do_write(1, "1\n", 2); for (n = LO_START; n % NTHR != idx; ++n) ; for (; n <= LO_STOP; n += NTHR) { if (do_check(n, idx)) return (void*) -1; } do_write(1, "2\n", 2); for (n = HI_START; n % NTHR != idx; --n) ; for (; n >= HI_STOP; n -= NTHR) { if (do_check(n, idx)) return (void*) -1; } /* * This will also visit a few one-digit numbers, but both the * old and new code actually handle that just fine for * non-zero n (it's just irrelevant because all callers of * put_dec take a shortcut for n < 10). */ do_write(1, "3\n", 2); n = 2*idx + 1; do { if (do_check(n, idx)) return (void*) -1; n *= 17179869185ull; } while (n != 2*idx + 1); return NULL; } int _start(void) { do_write(1, ".\n", 2); do_exit(!!check(0)); } -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/