diff options
Diffstat (limited to 'riscv/picorv32/dhrystone/stdlib.c')
-rw-r--r-- | riscv/picorv32/dhrystone/stdlib.c | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/riscv/picorv32/dhrystone/stdlib.c b/riscv/picorv32/dhrystone/stdlib.c new file mode 100644 index 0000000..f88023b --- /dev/null +++ b/riscv/picorv32/dhrystone/stdlib.c @@ -0,0 +1,210 @@ +// This is free and unencumbered software released into the public domain. +// +// Anyone is free to copy, modify, publish, use, compile, sell, or +// distribute this software, either in source code form or as a compiled +// binary, for any purpose, commercial or non-commercial, and by any +// means. + +#include <stdarg.h> +#include <stdint.h> + +extern long time(); +extern long insn(); + +#ifdef USE_MYSTDLIB +extern char *malloc(); +extern int printf(const char *format, ...); + +extern void *memcpy(void *dest, const void *src, long n); +extern char *strcpy(char *dest, const char *src); +extern int strcmp(const char *s1, const char *s2); + +char heap_memory[1024]; +int heap_memory_used = 0; +#endif + +long time() +{ + int cycles; + asm volatile ("rdcycle %0" : "=r"(cycles)); + // printf("[time() -> %d]", cycles); + return cycles; +} + +long insn() +{ + int insns; + asm volatile ("rdinstret %0" : "=r"(insns)); + // printf("[insn() -> %d]", insns); + return insns; +} + +#ifdef USE_MYSTDLIB +char *malloc(int size) +{ + char *p = heap_memory + heap_memory_used; + // printf("[malloc(%d) -> %d (%d..%d)]", size, (int)p, heap_memory_used, heap_memory_used + size); + heap_memory_used += size; + if (heap_memory_used > 1024) + asm volatile ("ebreak"); + return p; +} + +static void printf_c(int c) +{ + *((volatile int*)0x10000000) = c; +} + +static void printf_s(char *p) +{ + while (*p) + *((volatile int*)0x10000000) = *(p++); +} + +static void printf_d(int val) +{ + char buffer[32]; + char *p = buffer; + if (val < 0) { + printf_c('-'); + val = -val; + } + while (val || p == buffer) { + *(p++) = '0' + val % 10; + val = val / 10; + } + while (p != buffer) + printf_c(*(--p)); +} + +int printf(const char *format, ...) +{ + int i; + va_list ap; + + va_start(ap, format); + + for (i = 0; format[i]; i++) + if (format[i] == '%') { + while (format[++i]) { + if (format[i] == 'c') { + printf_c(va_arg(ap,int)); + break; + } + if (format[i] == 's') { + printf_s(va_arg(ap,char*)); + break; + } + if (format[i] == 'd') { + printf_d(va_arg(ap,int)); + break; + } + } + } else + printf_c(format[i]); + + va_end(ap); +} + +void *memcpy(void *aa, const void *bb, long n) +{ + // printf("**MEMCPY**\n"); + char *a = aa; + const char *b = bb; + while (n--) *(a++) = *(b++); + return aa; +} + +char *strcpy(char* dst, const char* src) +{ + char *r = dst; + + while ((((uint32_t)dst | (uint32_t)src) & 3) != 0) + { + char c = *(src++); + *(dst++) = c; + if (!c) return r; + } + + while (1) + { + uint32_t v = *(uint32_t*)src; + + if (__builtin_expect((((v) - 0x01010101UL) & ~(v) & 0x80808080UL), 0)) + { + dst[0] = v & 0xff; + if ((v & 0xff) == 0) + return r; + v = v >> 8; + + dst[1] = v & 0xff; + if ((v & 0xff) == 0) + return r; + v = v >> 8; + + dst[2] = v & 0xff; + if ((v & 0xff) == 0) + return r; + v = v >> 8; + + dst[3] = v & 0xff; + return r; + } + + *(uint32_t*)dst = v; + src += 4; + dst += 4; + } +} + +int strcmp(const char *s1, const char *s2) +{ + while ((((uint32_t)s1 | (uint32_t)s2) & 3) != 0) + { + char c1 = *(s1++); + char c2 = *(s2++); + + if (c1 != c2) + return c1 < c2 ? -1 : +1; + else if (!c1) + return 0; + } + + while (1) + { + uint32_t v1 = *(uint32_t*)s1; + uint32_t v2 = *(uint32_t*)s2; + + if (__builtin_expect(v1 != v2, 0)) + { + char c1, c2; + + c1 = v1 & 0xff, c2 = v2 & 0xff; + if (c1 != c2) return c1 < c2 ? -1 : +1; + if (!c1) return 0; + v1 = v1 >> 8, v2 = v2 >> 8; + + c1 = v1 & 0xff, c2 = v2 & 0xff; + if (c1 != c2) return c1 < c2 ? -1 : +1; + if (!c1) return 0; + v1 = v1 >> 8, v2 = v2 >> 8; + + c1 = v1 & 0xff, c2 = v2 & 0xff; + if (c1 != c2) return c1 < c2 ? -1 : +1; + if (!c1) return 0; + v1 = v1 >> 8, v2 = v2 >> 8; + + c1 = v1 & 0xff, c2 = v2 & 0xff; + if (c1 != c2) return c1 < c2 ? -1 : +1; + return 0; + } + + if (__builtin_expect((((v1) - 0x01010101UL) & ~(v1) & 0x80808080UL), 0)) + return 0; + + s1 += 4; + s2 += 4; + } +} +#endif + |