klib: printf support

This commit is contained in:
xinyangli 2024-07-09 17:26:11 +08:00
parent f38674ce79
commit 955f1f2d79
Signed by: xin
SSH key fingerprint: SHA256:qZ/tzd8lYRtUFSrfBDBMcUqV4GHKxqeqRA3huItgvbk
19 changed files with 438 additions and 245 deletions

View file

@ -15,15 +15,11 @@ set(ISA CACHE STRING "Target ISA")
set_property(CACHE ISA PROPERTY STRINGS "riscv" "x86" "x86_64" "native")
string(TOUPPER ${ISA} ISA_UPPER)
cmake_dependent_option(
__PLATFORM_NEMU__ "Run on NEMU"
ON "ISA MATCHES \"(riscv | x86)\"" OFF)
cmake_dependent_option(
__PLATFORM_NPC__ "Run on NPC"
ON "ISA MATCHES riscv" OFF)
cmake_dependent_option(
__PLATFORM_NATIVE__ "Run on native"
ON "ISA MATCHES native" OFF)
cmake_dependent_option(__PLATFORM_NEMU__ "Run on NEMU" ON
"ISA MATCHES \"(riscv | x86)\"" OFF)
cmake_dependent_option(__PLATFORM_NPC__ "Run on NPC" ON "ISA MATCHES riscv" OFF)
cmake_dependent_option(__PLATFORM_NATIVE__ "Run on native" ON
"ISA MATCHES native" OFF)
# -- Set PLATFORM according to options
set(MATCH_PLATFORM_PATTERN "^__PLATFORM_([A-Z]*)__$")
@ -33,7 +29,10 @@ message(STATUS "ISA: ${ISA}")
foreach(VAR IN LISTS CACHE_VARS)
if(VAR MATCHES ${MATCH_PLATFORM_PATTERN})
# Retrieve the value of the cache variable
get_property(VAR_VALUE CACHE ${VAR} PROPERTY VALUE)
get_property(
VAR_VALUE
CACHE ${VAR}
PROPERTY VALUE)
set(PLATFORM_UPPER ${CMAKE_MATCH_1})
string(TOLOWER ${PLATFORM_UPPER} PLATFORM)
list(APPEND PLATFORMS ${PLATFORM})
@ -54,39 +53,68 @@ foreach(PLATFORM IN LISTS PLATFORMS)
endif()
if(NOT ARCH IN_LIST SUPPORTED_ARCH)
message(FATAL_ERROR "Given ISA-PLATFORM (${ISA}-${PLATFORM}) does not match one of the following: ${SUPPORTED_ARCH}")
message(
FATAL_ERROR
"Given ISA-PLATFORM (${ISA}-${PLATFORM}) does not match one of the following: ${SUPPORTED_ARCH}"
)
endif()
endforeach()
# -- Target specific options
cmake_dependent_option(
NATIVE_USE_KLIB "Use Klib even if on native"
ON "NOT __ISA_NATIVE__" OFF)
cmake_dependent_option(NATIVE_USE_KLIB "Use Klib even if on native" ON
"NOT __ISA_NATIVE__" OFF)
# -- Add compile definitions based on options
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
# NOTE: klib and am include header files in each other,
# so we need to create interface libraries for correct dependency
# NOTE: klib and am include header files in each other, so we need to create
# interface libraries for correct dependency
add_library(am_interface INTERFACE)
target_include_directories(am_interface INTERFACE
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/am/include>
target_include_directories(
am_interface
INTERFACE $<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/am/include>
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/am/src>
$<INSTALL_INTERFACE:include/abstract-machine>)
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
target_compile_definitions(am_interface INTERFACE ARCH_H=<arch/${ISA}.h>)
file(GLOB_RECURSE AM_HEADERS "${CMAKE_SOURCE_DIR}/am/include/*.h")
target_sources(
am_interface
PUBLIC FILE_SET
am_headers
TYPE
HEADERS
BASE_DIRS
${CMAKE_SOURCE_DIR}/am/include
FILES
${AM_HEADERS})
add_library(klib_interface INTERFACE)
target_include_directories(klib_interface
INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/klib/include>
$<INSTALL_INTERFACE:include/abstract-machine>)
target_include_directories(
klib_interface
INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/klib/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
file(GLOB_RECURSE KLIB_HEADERS "${CMAKE_SOURCE_DIR}/klib/include/*.h")
target_sources(
klib_interface
PUBLIC FILE_SET
klib_headers
TYPE
HEADERS
BASE_DIRS
${CMAKE_SOURCE_DIR}/klib/include
FILES
${KLIB_HEADERS})
install(TARGETS am_interface klib_interface
install(
TARGETS am_interface klib_interface
EXPORT interfaceTargets
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/abstract-machine)
FILE_SET klib_headers FILE_SET am_headers
INCLUDES
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
install(EXPORT interfaceTargets
install(
EXPORT interfaceTargets
FILE interfaceTargets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake)

View file

@ -7,7 +7,7 @@
"generator": "Unix Makefiles",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
"ISA": "native",
"__PLATFORM_NATIVE__": true,
"NATIVE_USE_KLIB": true
@ -19,7 +19,7 @@
"generator": "Unix Makefiles",
"binaryDir": "${sourceDir}/out/build/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
"ISA": "riscv",
"__PLATFORM_NPC__": true,
"__PLATFORM_NEMU__": true

View file

@ -1,18 +1,18 @@
add_subdirectory(src)
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/abstract-machine)
foreach(PLATFORM IN LISTS PLATFORMS)
if(ISA MATCHES "native")
set(ARCH "native")
else()
set(ARCH ${ISA}-${PLATFORM})
endif()
install(TARGETS am-${ARCH}
install(
TARGETS am-${ARCH}
EXPORT amTargets-${ARCH}
LIBRARY DESTINATION lib)
install(EXPORT amTargets-${ARCH}
install(
EXPORT amTargets-${ARCH}
FILE amTargets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH})

View file

@ -10,14 +10,16 @@ set(SOURCES
ioe/disk.c
ioe/gpu.c
ioe/input.c
ioe/timer.c
)
ioe/timer.c)
add_library(am-native ${SOURCES})
# FIXME: get free(): invalid address when user program compiled without pie
set_target_properties(am-native PROPERTIES
POSITION_INDEPENDENT_CODE TRUE
set_target_properties(
am-native PROPERTIES POSITION_INDEPENDENT_CODE TRUE
INTERFACE_POSITION_INDEPENDENT_CODE TRUE)
find_package(SDL2 REQUIRED)
target_link_libraries(am-native PUBLIC SDL2::SDL2 PRIVATE klib_interface am_interface)
target_link_libraries(
am-native
PUBLIC SDL2::SDL2
PRIVATE klib_interface am_interface)

View file

@ -1,11 +1,10 @@
#include <am.h>
#include <nemu.h>
void __am_timer_init() {
}
void __am_timer_init() {}
void __am_timer_uptime(AM_TIMER_UPTIME_T *uptime) {
uptime->us = 0;
uptime->us = ((uint64_t)inl(RTC_ADDR + 4) << 32) + inl(RTC_ADDR);
}
void __am_timer_rtc(AM_TIMER_RTC_T *rtc) {

View file

@ -6,19 +6,18 @@ int main(const char *args);
Area heap = RANGE(&_heap_start, PMEM_END);
#ifndef MAINARGS
#define MAINARGS ""
#define MAINARGS "5"
#endif
static const char mainargs[] = MAINARGS;
void putch(char ch) {
outb(SERIAL_PORT, ch);
}
void putch(char ch) { outb(SERIAL_PORT, ch); }
void halt(int code) {
nemu_trap(code);
// should not reach here
while (1);
while (1)
;
}
void _trm_init() {

View file

@ -2,11 +2,8 @@ foreach(PLATFORM IN LISTS PLATFORMS)
string(TOUPPER ${ARCH} ARCH_UPPER)
set(AM_COMMON_COMPILE_DEF
# -- Arch related
$<MAKE_C_IDENTIFIER:__ARCH_${ARCH_UPPER}__>
__ISA_${ISA_UPPER}__
$<MAKE_C_IDENTIFIER:__ARCH_${ARCH_UPPER}__> __ISA_${ISA_UPPER}__
__PLATFORM_${PLATFORM_UPPER}__
$<$<BOOL:${NATIVE_USE_KLIB}>:__NATIVE_USE_KLIB__>
)
$<$<BOOL:${NATIVE_USE_KLIB}>:__NATIVE_USE_KLIB__>)
add_subdirectory(${PLATFORM})
endforeach()

View file

@ -1,52 +1,41 @@
include(nemu-settings)
include(riscv-settings)
add_library(am-riscv-nemu
cte.c
start.S
trap.S
vme.c
${NEMU_SOURCES}
)
add_library(am-riscv-nemu cte.c start.S trap.S vme.c ${NEMU_SOURCES})
target_compile_options(am-riscv-nemu PRIVATE
${NEMU_COMPILE_OPTIONS}
target_compile_options(am-riscv-nemu PRIVATE ${NEMU_COMPILE_OPTIONS}
${RISCV_COMPILE_OPTIONS})
target_link_options(am-riscv-nemu PRIVATE
${NEMU_LINK_OPITIONS}
target_link_options(am-riscv-nemu PRIVATE ${NEMU_LINK_OPITIONS}
${RISCV_LINK_OPTIONS})
target_include_directories(am-riscv-nemu PRIVATE
${NEMU_INCLUDE_DIRECTORIES})
target_include_directories(am-riscv-nemu PRIVATE ${NEMU_INCLUDE_DIRECTORIES})
target_link_options(am-riscv-nemu INTERFACE
target_link_options(
am-riscv-nemu
INTERFACE
LINKER:--defsym=_pmem_start=0x80000000
LINKER:--defsym=_entry_offset=0x0
LINKER:--gc-sections
LINKER:-e _start
LINKER:-e
_start
-nostartfiles)
target_link_options(am-riscv-nemu INTERFACE
target_link_options(
am-riscv-nemu INTERFACE
$<BUILD_INTERFACE:-T${CMAKE_SOURCE_DIR}/scripts/linker.ld>
$<INSTALL_INTERFACE:-T${CMAKE_INSTALL_FULL_DATADIR}/linker.ld>)
target_include_directories(am-riscv-nemu
PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/am/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/abstract-machine>)
target_link_libraries(am-riscv-nemu
target_link_libraries(
am-riscv-nemu
PUBLIC am_interface klib_interface
INTERFACE m)
target_compile_definitions(am-riscv-nemu PRIVATE
ISA_H=<riscv/riscv.h>)
target_compile_definitions(am-riscv-nemu PRIVATE ISA_H=<riscv/riscv.h>)
set_target_properties(am-riscv-nemu PROPERTIES
POSITION_INDEPENDENT_CODE OFF
set_target_properties(
am-riscv-nemu PROPERTIES POSITION_INDEPENDENT_CODE OFF
INTERFACE_POSITION_INDEPENDENT_CODE OFF)
install(FILES ${CMAKE_SOURCE_DIR}/scripts/linker.ld
DESTINATION ${CMAKE_INSTALL_DATADIR})

View file

@ -2,7 +2,8 @@ include(riscv-settings)
add_subdirectory(libgcc)
add_library(am-riscv-npc
add_library(
am-riscv-npc
cte.c
input.c
ioe.c
@ -11,29 +12,35 @@ add_library(am-riscv-npc
timer.c
trap.S
trm.c
vme.c
)
vme.c)
target_link_libraries(am-riscv-npc PRIVATE npcgcc PUBLIC am_interface klib_interface)
target_link_libraries(
am-riscv-npc
PRIVATE npcgcc
PUBLIC am_interface klib_interface)
target_link_options(am-riscv-npc INTERFACE
target_link_options(
am-riscv-npc INTERFACE
$<BUILD_INTERFACE:-T${CMAKE_SOURCE_DIR}/scripts/linker.ld>
$<INSTALL_INTERFACE:-T${CMAKE_INSTALL_FULL_DATADIR}/linker.ld>)
target_link_options(am-riscv-npc INTERFACE
target_link_options(
am-riscv-npc
INTERFACE
LINKER:--defsym=_pmem_start=0x80000000
LINKER:--defsym=_entry_offset=0x0
LINKER:--gc-sections
LINKER:-e _start
LINKER:-e
_start
-nostartfiles)
target_link_options(am-riscv-npc INTERFACE
target_link_options(
am-riscv-npc INTERFACE
$<BUILD_INTERFACE:-T${CMAKE_SOURCE_DIR}/scripts/linker.ld>
$<INSTALL_INTERFACE:-T${CMAKE_INSTALL_FULL_DATADIR}/linker.ld>)
target_compile_definitions(am-riscv-npc
PUBLIC ${AM_COMMON_COMPILE_DEF} ARCH_H=<arch/riscv.h>
)
target_compile_definitions(am-riscv-npc PUBLIC ${AM_COMMON_COMPILE_DEF}
ARCH_H=<arch/riscv.h>)
install(FILES ${CMAKE_SOURCE_DIR}/scripts/linker.ld
DESTINATION ${CMAKE_INSTALL_DATADIR})

View file

@ -7,13 +7,18 @@ void __am_timer_rtc(AM_TIMER_RTC_T *);
void __am_timer_uptime(AM_TIMER_UPTIME_T *);
void __am_input_keybrd(AM_INPUT_KEYBRD_T *);
static void __am_timer_config(AM_TIMER_CONFIG_T *cfg) { cfg->present = true; cfg->has_rtc = true; }
static void __am_timer_config(AM_TIMER_CONFIG_T *cfg) {
cfg->present = true;
cfg->has_rtc = true;
}
static void __am_input_config(AM_INPUT_CONFIG_T *cfg) { cfg->present = true; }
static void __am_uart_config(AM_UART_CONFIG_T *cfg) { cfg->present = false; }
typedef void (*handler_t)(void *buf);
static void *lut[128] = {
[AM_UART_CONFIG] = __am_uart_config,
[AM_TIMER_CONFIG] = __am_timer_config,
[AM_TIMER_RTC ] = __am_timer_rtc,
[AM_TIMER_RTC] = __am_timer_rtc,
[AM_TIMER_UPTIME] = __am_timer_uptime,
[AM_INPUT_CONFIG] = __am_input_config,
[AM_INPUT_KEYBRD] = __am_input_keybrd,
@ -23,10 +28,11 @@ static void fail(void *buf) { panic("access nonexist register"); }
bool ioe_init() {
for (int i = 0; i < LENGTH(lut); i++)
if (!lut[i]) lut[i] = fail;
if (!lut[i])
lut[i] = fail;
__am_timer_init();
return true;
}
void ioe_read (int reg, void *buf) { ((handler_t)lut[reg])(buf); }
void ioe_read(int reg, void *buf) { ((handler_t)lut[reg])(buf); }
void ioe_write(int reg, void *buf) { ((handler_t)lut[reg])(buf); }

View file

@ -1,14 +1,9 @@
add_library(npcgcc
ashldi3.c
div.S
muldi3.S
multi3.c
unused.c
)
add_library(npcgcc ashldi3.c div.S muldi3.S multi3.c unused.c)
target_link_libraries(npcgcc PRIVATE klib_interface am_interface)
target_link_options(npcgcc INTERFACE -nolibc -nostdlib)
install(TARGETS npcgcc
install(
TARGETS npcgcc
EXPORT amTargets-riscv-npc
LIBRARY DESTINATION lib)

View file

@ -1,10 +1,11 @@
#include "npc.h"
#include <am.h>
#include <riscv/riscv.h>
void __am_timer_init() {
}
void __am_timer_init() {}
void __am_timer_uptime(AM_TIMER_UPTIME_T *uptime) {
uptime->us = 0;
uptime->us = ((uint64_t)inl(RTC_ADDR + 4) << 32) + inl(RTC_ADDR);
}
void __am_timer_rtc(AM_TIMER_RTC_T *rtc) {

View file

@ -1,5 +1,7 @@
#include "npc.h"
#include <am.h>
#include <klib-macros.h>
#include <riscv/riscv.h>
extern char _heap_start;
int main(const char *args);
@ -10,11 +12,11 @@ extern char _pmem_start;
Area heap = RANGE(&_heap_start, PMEM_END);
#ifndef MAINARGS
#define MAINARGS ""
#define MAINARGS "3"
#endif
static const char mainargs[] = MAINARGS;
void putch(char ch) {}
void putch(char ch) { outb(SERIAL_PORT, ch); }
void halt(int code) {
asm volatile("mv a0, %0; ebreak" : : "r"(code));

View file

@ -7,7 +7,7 @@
}:
stdenv.mkDerivation {
pname = "abstract-machine";
version = "2024.02.18";
version = "2024.06.01";
src = ./.;

View file

@ -1 +1,4 @@
install(DIRECTORY include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/abstract-machine)
add_subdirectory(src)

View file

@ -1,32 +1,30 @@
# find_package(FLEX)
# find_package(BISON)
# find_package(FLEX) find_package(BISON)
# FLEX_TARGET(fmt_scanner fmt_scanner.l fmt_scanner.c)
set(SOURCES
cpp.c
int64.c
stdio.c
stdlib.c
string.c
set(SOURCES cpp.c int64.c stdio.c stdlib.c string.c
# ${FLEX_fmt_scanner_OUTPUTS}
)
add_library(klib ${SOURCES})
target_link_libraries(klib PRIVATE am_interface klib_interface)
target_link_libraries(klib PUBLIC am_interface klib_interface)
target_compile_options(klib PUBLIC -fno-builtin)
target_link_options(klib PUBLIC -nostartfiles -nolibc)
install(TARGETS klib
install(
TARGETS klib
EXPORT klibTargets
LIBRARY DESTINATION lib)
install(EXPORT klibTargets
install(
EXPORT klibTargets
FILE klibTargets.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib)
configure_package_config_file(${CMAKE_SOURCE_DIR}/cmake/klib-config.cmake.in
configure_package_config_file(
${CMAKE_SOURCE_DIR}/cmake/klib-config.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/klib-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/klib-config.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib)

View file

@ -1,16 +1,91 @@
#include <am.h>
#include <klib.h>
#include <klib-macros.h>
#include <klib.h>
#include <stdarg.h>
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
int vprintf(const char *fmt, va_list ap) {
const char *p = fmt;
while(*p != '\0') {
void print_int(int num, int width, char pad) {
int reverse = 0;
int count = 0;
if (num == 0) {
reverse = 0;
count = 1;
} else {
if (num < 0) {
putch('-');
num = -num;
}
while (num != 0) {
reverse = reverse * 10 + (num % 10);
num /= 10;
count++;
}
}
while (width > count) {
putch(pad);
width--;
}
if (reverse == 0) {
putch('0');
} else {
while (reverse != 0) {
putch('0' + (reverse % 10));
reverse /= 10;
}
}
}
int vprintf(const char *format, va_list args) {
const char *p = format;
while (*p) {
if (*p == '%') {
p++; // Skip the '%'
char pad = ' ';
int width = 0;
if (*p == '0') {
pad = '0';
p++;
}
while (*p >= '0' && *p <= '9') {
width = width * 10 + (*p - '0');
p++;
}
switch (*p) {
case 'd': { // Integer
int ival = va_arg(args, int);
print_int(ival, width, pad);
break;
}
case 'c': { // Character
char c = (char)va_arg(args, int);
putch(c);
break;
}
case 's': { // String
char *s = va_arg(args, char *);
putstr(s);
break;
}
case '%': {
putch('%');
break;
}
default:
panic("Wrong formatter provided to printf");
}
} else {
putch(*p);
}
return 0;
p++;
}
}
int printf(const char *fmt, ...) {
@ -21,12 +96,103 @@ int printf(const char *fmt, ...) {
return 0;
}
int vsprintf(char *out, const char *fmt, va_list ap) {
panic("Not implemented");
void append_to_buffer(char **buf, int *pos, char c) { (*buf)[(*pos)++] = c; }
void print_int_to_buf(char **buf, int *pos, int num, int width, char pad) {
int reverse = 0, count = 0, neg = 0;
if (num == 0) {
reverse = 0;
count = 1;
} else {
if (num < 0) {
append_to_buffer(buf, pos, '-');
num = -num;
neg = 1;
}
while (num != 0) {
reverse = reverse * 10 + (num % 10);
num /= 10;
count++;
}
}
width -= neg;
while (width > count) {
append_to_buffer(buf, pos, pad);
width--;
}
if (reverse == 0) {
append_to_buffer(buf, pos, '0');
} else {
while (reverse != 0) {
append_to_buffer(buf, pos, '0' + (reverse % 10));
reverse /= 10;
}
}
}
int vsprintf(char *buf, const char *format, va_list args) {
const char *p = format;
int pos = 0; // Position in buf
while (*p) {
if (*p == '%') {
p++; // Skip the '%'
char pad = ' ';
int width = 0;
if (*p == '0') {
pad = '0';
p++;
}
while (*p >= '0' && *p <= '9') {
width = width * 10 + (*p - '0');
p++;
}
switch (*p) {
case 'd': { // Integer
int ival = va_arg(args, int);
print_int_to_buf(&buf, &pos, ival, width, pad);
break;
}
case 'c': { // Character
char c = (char)va_arg(args, int);
append_to_buffer(&buf, &pos, c);
break;
}
case 's': { // String
char *s = va_arg(args, char *);
while (*s) {
append_to_buffer(&buf, &pos, *s++);
}
break;
}
case '%': {
append_to_buffer(&buf, &pos, '%');
break;
}
default:
panic("Unsupported format specifier");
}
} else {
append_to_buffer(&buf, &pos, *p);
}
p++;
}
buf[pos] = '\0'; // Null-terminate the string
return pos;
}
int sprintf(char *out, const char *fmt, ...) {
panic("Not implemented");
va_list args;
va_start(args, fmt);
vsprintf(out, fmt, args);
va_end(args);
return 0;
}
int snprintf(char *out, size_t n, const char *fmt, ...) {

View file

@ -1,6 +1,6 @@
#include <am.h>
#include <klib.h>
#include <klib-macros.h>
#include <klib.h>
#if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__)
static unsigned long int next = 1;
@ -8,23 +8,21 @@ static unsigned long int next = 1;
int rand(void) {
// RAND_MAX assumed to be 32767
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
return (unsigned int)(next / 65536) % 32768;
}
void srand(unsigned int seed) {
next = seed;
}
void srand(unsigned int seed) { next = seed; }
int abs(int x) {
return (x < 0 ? -x : x);
}
int abs(int x) { return (x < 0 ? -x : x); }
int atoi(const char* nptr) {
int atoi(const char *nptr) {
int x = 0;
while (*nptr == ' ') { nptr ++; }
while (*nptr == ' ') {
nptr++;
}
while (*nptr >= '0' && *nptr <= '9') {
x = x * 10 + *nptr - '0';
nptr ++;
nptr++;
}
return x;
}
@ -33,13 +31,19 @@ void *malloc(size_t size) {
// On native, malloc() will be called during initializaion of C runtime.
// 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");
#endif
return NULL;
static void *addr = NULL;
void *ret = NULL;
if (addr == 0) {
addr = heap.start;
ret = addr;
} else {
panic_on(addr + size > heap.end, "Memory space not enough");
ret = addr;
addr += size;
}
return ret;
}
void free(void *ptr) {
}
void free(void *ptr) {}
#endif

View file

@ -1,7 +1,4 @@
set(TEST_SOURCES
stdio
string
)
set(TEST_SOURCES stdio string)
foreach(TEST IN LISTS TEST_SOURCES)
# TODO: Run tests in other configurations