feat: make compatible with openperf

This commit is contained in:
xinyangli 2024-11-09 10:56:27 +08:00
parent a7b830fedd
commit 5fee5aad38
Signed by: xin
SSH key fingerprint: SHA256:UU5pRTl7NiLFJbWJZa+snLylZSXIz5rgHmwjzv8v4oE
79 changed files with 3943 additions and 274 deletions

View file

@ -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

View file

@ -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

View file

@ -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) {

View file

@ -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