feat: make compatible with openperf
This commit is contained in:
parent
a7b830fedd
commit
5fee5aad38
79 changed files with 3943 additions and 274 deletions
|
@ -2,8 +2,8 @@
|
|||
#define KLIB_H__
|
||||
|
||||
#include <am.h>
|
||||
#include <stddef.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -12,43 +12,45 @@ extern "C" {
|
|||
//#define __NATIVE_USE_KLIB__
|
||||
|
||||
// string.h
|
||||
void *memset (void *s, int c, size_t n);
|
||||
void *memcpy (void *dst, const void *src, size_t n);
|
||||
void *memmove (void *dst, const void *src, size_t n);
|
||||
int memcmp (const void *s1, const void *s2, size_t n);
|
||||
size_t strlen (const char *s);
|
||||
char *strcat (char *dst, const char *src);
|
||||
char *strcpy (char *dst, const char *src);
|
||||
char *strncpy (char *dst, const char *src, size_t n);
|
||||
int strcmp (const char *s1, const char *s2);
|
||||
int strncmp (const char *s1, const char *s2, size_t n);
|
||||
char *stpcpy(char *dst, const char *src);
|
||||
char *stpncpy(char *dst, const char *src, size_t n);
|
||||
void *memset(void *s, int c, size_t n);
|
||||
void *memcpy(void *dst, const void *src, size_t n);
|
||||
void *memmove(void *dst, const void *src, size_t n);
|
||||
int memcmp(const void *s1, const void *s2, size_t n);
|
||||
size_t strlen(const char *s);
|
||||
char *strcat(char *dst, const char *src);
|
||||
char *strcpy(char *dst, const char *src);
|
||||
char *strncpy(char *dst, const char *src, size_t n);
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
int strncmp(const char *s1, const char *s2, size_t n);
|
||||
|
||||
// stdlib.h
|
||||
void srand (unsigned int seed);
|
||||
int rand (void);
|
||||
void *malloc (size_t size);
|
||||
void free (void *ptr);
|
||||
int abs (int x);
|
||||
int atoi (const char *nptr);
|
||||
|
||||
//stdlib.h
|
||||
void srand(unsigned int seed);
|
||||
int rand(void);
|
||||
void *malloc(size_t size);
|
||||
void free(void *ptr);
|
||||
int abs(int x);
|
||||
int atoi(const char *nptr);
|
||||
// stdio.h
|
||||
int printf (const char *format, ...);
|
||||
int sprintf (char *str, const char *format, ...);
|
||||
int snprintf (char *str, size_t size, const char *format, ...);
|
||||
int vsprintf (char *str, const char *format, va_list ap);
|
||||
int vsnprintf (char *str, size_t size, const char *format, va_list ap);
|
||||
int printf(const char *format, ...);
|
||||
int sprintf(char *str, const char *format, ...);
|
||||
int snprintf(char *str, size_t size, const char *format, ...);
|
||||
int vsprintf(char *str, const char *format, va_list ap);
|
||||
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
|
||||
|
||||
// assert.h
|
||||
#ifdef NDEBUG
|
||||
#define assert(ignore) ((void)0)
|
||||
#define assert(ignore) ((void)0)
|
||||
#else
|
||||
#define assert(cond) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
printf("Assertion fail at %s:%d\n", __FILE__, __LINE__); \
|
||||
halt(1); \
|
||||
} \
|
||||
} while (0)
|
||||
#define assert(cond) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
printf("Assertion fail at %s:%d\n", __FILE__, __LINE__); \
|
||||
halt(1); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
124
klib/src/stdio.c
124
klib/src/stdio.c
|
@ -1,28 +1,138 @@
|
|||
#include <am.h>
|
||||
#include <klib.h>
|
||||
|
||||
#include <klib-macros.h>
|
||||
#include <klib.h>
|
||||
#include <limits.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
|
||||
|
||||
|
||||
static int int2str(char *p, int v, size_t n) {
|
||||
if (n == 0 || p == NULL)
|
||||
return 0;
|
||||
if (v == 0) {
|
||||
*p = '0';
|
||||
return 1;
|
||||
}
|
||||
if (v == INT_MIN) {
|
||||
return stpncpy(p, "-2147483648", n) - p;
|
||||
}
|
||||
const char *const s = p;
|
||||
int idx = 0;
|
||||
char buf[16] = {0};
|
||||
|
||||
int tmp = abs(v);
|
||||
|
||||
while (tmp != 0) {
|
||||
buf[idx] = tmp % 10 + '0';
|
||||
tmp /= 10;
|
||||
idx++;
|
||||
}
|
||||
if(v < 0 && n > 0) {
|
||||
*p = '-';
|
||||
n--;
|
||||
p++;
|
||||
}
|
||||
idx--;
|
||||
while (idx >= 0 && n > 0) {
|
||||
*p = buf[idx];
|
||||
p++;
|
||||
idx--;
|
||||
n--;
|
||||
}
|
||||
return p - s;
|
||||
}
|
||||
int printf(const char *fmt, ...) {
|
||||
panic("Not implemented");
|
||||
|
||||
char buf[1024] = {0};
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int n = vsnprintf(buf, 1024, fmt, ap);
|
||||
va_end(ap);
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
putch(buf[i]);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
int vsprintf(char *out, const char *fmt, va_list ap) {
|
||||
panic("Not implemented");
|
||||
|
||||
return vsnprintf(out, -1, fmt, ap);
|
||||
}
|
||||
|
||||
int sprintf(char *out, const char *fmt, ...) {
|
||||
panic("Not implemented");
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int res = vsprintf(out, fmt, ap);
|
||||
va_end(ap);
|
||||
return res;
|
||||
}
|
||||
|
||||
int snprintf(char *out, size_t n, const char *fmt, ...) {
|
||||
panic("Not implemented");
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int res = vsnprintf(out, n, fmt, ap);
|
||||
va_end(ap);
|
||||
return res;
|
||||
}
|
||||
|
||||
int vsnprintf(char *out, size_t n, const char *fmt, va_list ap) {
|
||||
panic("Not implemented");
|
||||
int vsnprintf(char *out, size_t n, const char *fmt, va_list ap1) {
|
||||
|
||||
size_t count = 0;
|
||||
va_list ap;
|
||||
va_copy(ap, ap1);
|
||||
|
||||
while (count < n - 1 && *fmt != '\0') {
|
||||
switch (*fmt) {
|
||||
case '%': {
|
||||
fmt++;
|
||||
if (*fmt == '%') {
|
||||
*out = *fmt;
|
||||
out++;
|
||||
fmt++;
|
||||
count++;
|
||||
} else if (*fmt == 's') {
|
||||
char *p = va_arg(ap, char *);
|
||||
|
||||
while (count < n - 1 && *p) {
|
||||
*out = *p;
|
||||
out++;
|
||||
count++;
|
||||
p++;
|
||||
}
|
||||
fmt++;
|
||||
|
||||
} else if (*fmt == 'd') {
|
||||
int v = va_arg(ap, int);
|
||||
int int_num = int2str(out, v, n - 1 - count);
|
||||
count += int_num;
|
||||
out += int_num;
|
||||
fmt++;
|
||||
} else if(*fmt == 'c'){
|
||||
char c = (char)va_arg(ap, int);
|
||||
*out = c;
|
||||
out++;
|
||||
count++;
|
||||
fmt++;
|
||||
}
|
||||
else {
|
||||
//panic("not implemented");
|
||||
fmt++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
*out = *fmt;
|
||||
out++;
|
||||
fmt++;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
*out = '\0';
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
|
||||
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
|
||||
static unsigned long int next = 1;
|
||||
|
||||
#if defined(__ISA_RISCV32__) || defined (__ISA_RISCV32E__) || defined(__ISA_RISCV64__)
|
||||
void *heap_alloc_ptr = NULL;
|
||||
#endif
|
||||
int rand(void) {
|
||||
// RAND_MAX assumed to be 32767
|
||||
next = next * 1103515245 + 12345;
|
||||
|
@ -34,9 +36,19 @@ void *malloc(size_t size) {
|
|||
// Therefore do not call panic() here, else it will yield a dead recursion:
|
||||
// panic() -> putchar() -> (glibc) -> malloc() -> panic()
|
||||
#if !(defined(__ISA_NATIVE__) && defined(__NATIVE_USE_KLIB__))
|
||||
panic("Not implemented");
|
||||
|
||||
#if defined (__ISA_RISCV32__) || defined (__ISA_RISCV32E__)
|
||||
void *p = heap_alloc_ptr;
|
||||
heap_alloc_ptr = (void*)ROUNDUP(heap_alloc_ptr + size, 4);
|
||||
panic_on(!IN_RANGE(heap_alloc_ptr, heap), "Heap overflow");
|
||||
return p;
|
||||
#else
|
||||
panic("not implemented");
|
||||
#endif
|
||||
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void free(void *ptr) {
|
||||
|
|
|
@ -1,47 +1,155 @@
|
|||
#include <klib.h>
|
||||
#include <klib-macros.h>
|
||||
#include <klib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
|
||||
|
||||
size_t strlen(const char *s) {
|
||||
panic("Not implemented");
|
||||
if (s == NULL)
|
||||
return 0;
|
||||
size_t count = 0;
|
||||
while (*s != '\0') {
|
||||
count++;
|
||||
s++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
char *strcpy(char *dst, const char *src) {
|
||||
panic("Not implemented");
|
||||
}
|
||||
|
||||
size_t i = 0;
|
||||
while (src[i] != '\0') {
|
||||
dst[i] = src[i];
|
||||
i++;
|
||||
}
|
||||
|
||||
dst[i] = '\0';
|
||||
return dst;
|
||||
}
|
||||
char *stpncpy(char *dst, const char *src, size_t n) {
|
||||
|
||||
for (; n != 0 && (*dst = *src); src++, dst++, n--);
|
||||
return dst;
|
||||
}
|
||||
// copied from musl
|
||||
char *stpcpy(char *dst, const char *src) {
|
||||
|
||||
for (; (*dst = *src); src++, dst++)
|
||||
;
|
||||
return dst;
|
||||
}
|
||||
char *strncpy(char *dst, const char *src, size_t n) {
|
||||
panic("Not implemented");
|
||||
// If the specified size is less than or equal to the source string's length,
|
||||
// strncpy doesn't not append a null terminator to the destination buffer.
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
if (src[i] != '\0')
|
||||
dst[i] = src[i];
|
||||
else {
|
||||
while (i < n) {
|
||||
dst[i] = 0;
|
||||
i++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
char *strcat(char *dst, const char *src) {
|
||||
panic("Not implemented");
|
||||
|
||||
strcpy(dst + (strlen(dst)), src);
|
||||
return dst;
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2) {
|
||||
panic("Not implemented");
|
||||
}
|
||||
int strcmp(const char *s1, const char *s2) { return strncmp(s1, s2, -1); }
|
||||
|
||||
// refer to musl, more elegant than mine
|
||||
int strncmp(const char *s1, const char *s2, size_t n) {
|
||||
panic("Not implemented");
|
||||
|
||||
unsigned char *l = (void *)s1, *r = (void *)s2;
|
||||
if (!n--)
|
||||
return 0;
|
||||
|
||||
while (n && *l && *r && *l == *r) {
|
||||
l++;
|
||||
r++;
|
||||
n--;
|
||||
}
|
||||
return *l - *r;
|
||||
}
|
||||
|
||||
void *memset(void *s, int c, size_t n) {
|
||||
panic("Not implemented");
|
||||
if (n == 0)
|
||||
return s;
|
||||
for (size_t i = 0; i < n; i++)
|
||||
*((unsigned char *)s + i) = (unsigned char)c;
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void *memmove(void *dst, const void *src, size_t n) {
|
||||
panic("Not implemented");
|
||||
|
||||
if (dst == src)
|
||||
return dst;
|
||||
// A simple way to deal with overlap areas, improve in the future.
|
||||
// Can I use malloc here ? Will buf area and other areas overlap? try to find
|
||||
// a better way.
|
||||
size_t s = (size_t)src;
|
||||
size_t d = (size_t)dst;
|
||||
|
||||
if (s > d && (d + n - 1 >= s)) {
|
||||
size_t overlap_n = d + n - s;
|
||||
memcpy(dst, src, overlap_n);
|
||||
memcpy((void *)(s + overlap_n), (void *)(d + overlap_n), n - overlap_n);
|
||||
} else if (d > s && (s + n - 1 >= d)) {
|
||||
size_t overlap_n = s + n - d;
|
||||
memcpy((void *)(d + n - overlap_n), dst, overlap_n);
|
||||
memcpy(dst, src, n - overlap_n);
|
||||
} else {
|
||||
memcpy(dst, src, n);
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void *memcpy(void *out, const void *in, size_t n) {
|
||||
panic("Not implemented");
|
||||
}
|
||||
// Note that memcpy function require the memory areas do not overlap.
|
||||
// Panic directly when the input is invalid to debug. It seems to violate the
|
||||
// manual specifications.
|
||||
if (out == in)
|
||||
return out;
|
||||
size_t dest = (size_t)out;
|
||||
size_t src = (size_t)in;
|
||||
|
||||
int memcmp(const void *s1, const void *s2, size_t n) {
|
||||
panic("Not implemented");
|
||||
if ((dest > src && src + n - 1 < dest) ||
|
||||
(src > dest && dest + n - 1 < src)) {
|
||||
while (n != 0) {
|
||||
*(char *)(dest + n - 1) = *(char *)(src + n - 1);
|
||||
n--;
|
||||
}
|
||||
|
||||
}
|
||||
return out;
|
||||
|
||||
}
|
||||
int memcmp(const void *s1, const void *s2, size_t n) {
|
||||
if (n == 0)
|
||||
return 0;
|
||||
const unsigned char *a = s1;
|
||||
const unsigned char *b = s2;
|
||||
while (n != 0) {
|
||||
if (*a == *b) {
|
||||
a++;
|
||||
b++;
|
||||
n--;
|
||||
continue;
|
||||
} else {
|
||||
return *a - *b;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue