diff --git a/abstract-machine/CMakeLists.txt b/abstract-machine/CMakeLists.txt index 6eb89d7..659bb84 100644 --- a/abstract-machine/CMakeLists.txt +++ b/abstract-machine/CMakeLists.txt @@ -6,7 +6,7 @@ set(CMAKE_C_STANDARD 11) set(CMAKE_CXX_STANDARD 11) include(CMakeDependentOption) -include(CMakePackageConfigHelpers) # Used to find libcheck +include(CMakePackageConfigHelpers) # Used to find libcheck include(CTest) include(GNUInstallDirs) @@ -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]*)__$") @@ -31,64 +27,96 @@ get_cmake_property(CACHE_VARS CACHE_VARIABLES) 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) - set(PLATFORM_UPPER ${CMAKE_MATCH_1}) - string(TOLOWER ${PLATFORM_UPPER} PLATFORM) - list(APPEND PLATFORMS ${PLATFORM}) - message(STATUS "Variable: ${VAR}=${VAR_VALUE}, Platform: ${PLATFORM}") - endif() + if(VAR MATCHES ${MATCH_PLATFORM_PATTERN}) + # Retrieve the value of the cache variable + get_property( + VAR_VALUE + CACHE ${VAR} + PROPERTY VALUE) + set(PLATFORM_UPPER ${CMAKE_MATCH_1}) + string(TOLOWER ${PLATFORM_UPPER} PLATFORM) + list(APPEND PLATFORMS ${PLATFORM}) + message(STATUS "Variable: ${VAR}=${VAR_VALUE}, Platform: ${PLATFORM}") + endif() endforeach() if((NOT PLATFORM) AND (NOT ISA MATCHES native)) - message(FATAL_ERROR "Platform not given!") + message(FATAL_ERROR "Platform not given!") endif() set(SUPPORTED_ARCH "riscv-nemu" "riscv-npc" "native") foreach(PLATFORM IN LISTS PLATFORMS) - if(${ISA} MATCHES "native") - set(ARCH "native") - else() - set(ARCH ${ISA}-${PLATFORM}) - endif() + if(${ISA} MATCHES "native") + set(ARCH "native") + else() + set(ARCH ${ISA}-${PLATFORM}) + 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}") - 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}" + ) + 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 - $ - $ - $) +target_include_directories( + am_interface + INTERFACE $ + $ + $) target_compile_definitions(am_interface INTERFACE ARCH_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 - $ - $) +target_include_directories( + klib_interface + INTERFACE $ + $) +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 - EXPORT interfaceTargets - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/abstract-machine) +install( + TARGETS am_interface klib_interface + EXPORT interfaceTargets + FILE_SET klib_headers FILE_SET am_headers + INCLUDES + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) -install(EXPORT interfaceTargets - FILE interfaceTargets.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) +install( + EXPORT interfaceTargets + FILE interfaceTargets.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake) add_subdirectory(klib) add_subdirectory(am) diff --git a/abstract-machine/CMakePresets.json b/abstract-machine/CMakePresets.json index 73dab56..fb5eb21 100644 --- a/abstract-machine/CMakePresets.json +++ b/abstract-machine/CMakePresets.json @@ -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,11 +19,11 @@ "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 } } ] -} \ No newline at end of file +} diff --git a/abstract-machine/am/CMakeLists.txt b/abstract-machine/am/CMakeLists.txt index 25895b7..f57d540 100644 --- a/abstract-machine/am/CMakeLists.txt +++ b/abstract-machine/am/CMakeLists.txt @@ -1,26 +1,26 @@ 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} - EXPORT amTargets-${ARCH} - LIBRARY DESTINATION lib) + if(ISA MATCHES "native") + set(ARCH "native") + else() + set(ARCH ${ISA}-${PLATFORM}) + endif() + install( + TARGETS am-${ARCH} + EXPORT amTargets-${ARCH} + LIBRARY DESTINATION lib) - install(EXPORT amTargets-${ARCH} - FILE amTargets.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH}) + install( + EXPORT amTargets-${ARCH} + FILE amTargets.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH}) - configure_package_config_file( - ${CMAKE_SOURCE_DIR}/cmake/am-config.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/am-${ARCH}-config.cmake - INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH}) + configure_package_config_file( + ${CMAKE_SOURCE_DIR}/cmake/am-config.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/am-${ARCH}-config.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH}) - install(FILES ${CMAKE_CURRENT_BINARY_DIR}/am-${ARCH}-config.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH}) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/am-${ARCH}-config.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/am-${ARCH}) endforeach() diff --git a/abstract-machine/am/src/native/CMakeLists.txt b/abstract-machine/am/src/native/CMakeLists.txt index 706aa80..d991825 100644 --- a/abstract-machine/am/src/native/CMakeLists.txt +++ b/abstract-machine/am/src/native/CMakeLists.txt @@ -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 - INTERFACE_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) diff --git a/abstract-machine/am/src/platform/nemu/ioe/timer.c b/abstract-machine/am/src/platform/nemu/ioe/timer.c index f173ed4..ce545de 100644 --- a/abstract-machine/am/src/platform/nemu/ioe/timer.c +++ b/abstract-machine/am/src/platform/nemu/ioe/timer.c @@ -1,18 +1,17 @@ #include #include -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) { rtc->second = 0; rtc->minute = 0; - rtc->hour = 0; - rtc->day = 0; - rtc->month = 0; - rtc->year = 1900; + rtc->hour = 0; + rtc->day = 0; + rtc->month = 0; + rtc->year = 1900; } diff --git a/abstract-machine/am/src/platform/nemu/trm.c b/abstract-machine/am/src/platform/nemu/trm.c index f1802aa..c4287c5 100644 --- a/abstract-machine/am/src/platform/nemu/trm.c +++ b/abstract-machine/am/src/platform/nemu/trm.c @@ -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() { diff --git a/abstract-machine/am/src/riscv/CMakeLists.txt b/abstract-machine/am/src/riscv/CMakeLists.txt index ced867e..0c876d0 100644 --- a/abstract-machine/am/src/riscv/CMakeLists.txt +++ b/abstract-machine/am/src/riscv/CMakeLists.txt @@ -1,12 +1,9 @@ foreach(PLATFORM IN LISTS PLATFORMS) - string(TOUPPER ${ARCH} ARCH_UPPER) - set(AM_COMMON_COMPILE_DEF - # -- Arch related - $ - __ISA_${ISA_UPPER}__ - __PLATFORM_${PLATFORM_UPPER}__ - - $<$:__NATIVE_USE_KLIB__> - ) - add_subdirectory(${PLATFORM}) + string(TOUPPER ${ARCH} ARCH_UPPER) + set(AM_COMMON_COMPILE_DEF + # -- Arch related + $ __ISA_${ISA_UPPER}__ + __PLATFORM_${PLATFORM_UPPER}__ + $<$:__NATIVE_USE_KLIB__>) + add_subdirectory(${PLATFORM}) endforeach() diff --git a/abstract-machine/am/src/riscv/nemu/CMakeLists.txt b/abstract-machine/am/src/riscv/nemu/CMakeLists.txt index 79db40f..0ec140f 100644 --- a/abstract-machine/am/src/riscv/nemu/CMakeLists.txt +++ b/abstract-machine/am/src/riscv/nemu/CMakeLists.txt @@ -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} - ${RISCV_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} - ${RISCV_LINK_OPTIONS}) +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 - LINKER:--defsym=_pmem_start=0x80000000 - LINKER:--defsym=_entry_offset=0x0 - LINKER:--gc-sections - LINKER:-e _start - -nostartfiles) +target_link_options( + am-riscv-nemu + INTERFACE + LINKER:--defsym=_pmem_start=0x80000000 + LINKER:--defsym=_entry_offset=0x0 + LINKER:--gc-sections + LINKER:-e + _start + -nostartfiles) -target_link_options(am-riscv-nemu INTERFACE - $ - $) +target_link_options( + am-riscv-nemu INTERFACE + $ + $) -target_include_directories(am-riscv-nemu - PUBLIC - $ - $) +target_link_libraries( + am-riscv-nemu + PUBLIC am_interface klib_interface + INTERFACE m) -target_link_libraries(am-riscv-nemu - PUBLIC am_interface klib_interface - INTERFACE m) +target_compile_definitions(am-riscv-nemu PRIVATE ISA_H=) -target_compile_definitions(am-riscv-nemu PRIVATE - ISA_H=) - -set_target_properties(am-riscv-nemu PROPERTIES - POSITION_INDEPENDENT_CODE OFF - INTERFACE_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}) - diff --git a/abstract-machine/am/src/riscv/npc/CMakeLists.txt b/abstract-machine/am/src/riscv/npc/CMakeLists.txt index 0859c11..fbcdd90 100644 --- a/abstract-machine/am/src/riscv/npc/CMakeLists.txt +++ b/abstract-machine/am/src/riscv/npc/CMakeLists.txt @@ -2,38 +2,45 @@ include(riscv-settings) add_subdirectory(libgcc) -add_library(am-riscv-npc - cte.c - input.c - ioe.c - mpe.c - start.S - timer.c - trap.S - trm.c - vme.c -) +add_library( + am-riscv-npc + cte.c + input.c + ioe.c + mpe.c + start.S + timer.c + trap.S + trm.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 + $ + $) -target_link_options(am-riscv-npc INTERFACE - LINKER:--defsym=_pmem_start=0x80000000 - LINKER:--defsym=_entry_offset=0x0 - LINKER:--gc-sections - LINKER:-e _start - -nostartfiles) +target_link_options( + am-riscv-npc + INTERFACE + LINKER:--defsym=_pmem_start=0x80000000 + LINKER:--defsym=_entry_offset=0x0 + LINKER:--gc-sections + LINKER:-e + _start + -nostartfiles) -target_link_options(am-riscv-npc INTERFACE - $ - $) +target_link_options( + am-riscv-npc INTERFACE + $ + $) -target_compile_definitions(am-riscv-npc - PUBLIC ${AM_COMMON_COMPILE_DEF} ARCH_H= -) +target_compile_definitions(am-riscv-npc PUBLIC ${AM_COMMON_COMPILE_DEF} + ARCH_H=) install(FILES ${CMAKE_SOURCE_DIR}/scripts/linker.ld DESTINATION ${CMAKE_INSTALL_DATADIR}) diff --git a/abstract-machine/am/src/riscv/npc/ioe.c b/abstract-machine/am/src/riscv/npc/ioe.c index 26bad0a..f794ce2 100644 --- a/abstract-machine/am/src/riscv/npc/ioe.c +++ b/abstract-machine/am/src/riscv/npc/ioe.c @@ -7,26 +7,32 @@ 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_input_config(AM_INPUT_CONFIG_T *cfg) { cfg->present = 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_TIMER_CONFIG] = __am_timer_config, - [AM_TIMER_RTC ] = __am_timer_rtc, - [AM_TIMER_UPTIME] = __am_timer_uptime, - [AM_INPUT_CONFIG] = __am_input_config, - [AM_INPUT_KEYBRD] = __am_input_keybrd, + [AM_UART_CONFIG] = __am_uart_config, + [AM_TIMER_CONFIG] = __am_timer_config, + [AM_TIMER_RTC] = __am_timer_rtc, + [AM_TIMER_UPTIME] = __am_timer_uptime, + [AM_INPUT_CONFIG] = __am_input_config, + [AM_INPUT_KEYBRD] = __am_input_keybrd, }; 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); } diff --git a/abstract-machine/am/src/riscv/npc/libgcc/CMakeLists.txt b/abstract-machine/am/src/riscv/npc/libgcc/CMakeLists.txt index 841adb6..feaec7e 100644 --- a/abstract-machine/am/src/riscv/npc/libgcc/CMakeLists.txt +++ b/abstract-machine/am/src/riscv/npc/libgcc/CMakeLists.txt @@ -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 - EXPORT amTargets-riscv-npc - LIBRARY DESTINATION lib) +install( + TARGETS npcgcc + EXPORT amTargets-riscv-npc + LIBRARY DESTINATION lib) diff --git a/abstract-machine/am/src/riscv/npc/timer.c b/abstract-machine/am/src/riscv/npc/timer.c index 6ea0ffa..844463d 100644 --- a/abstract-machine/am/src/riscv/npc/timer.c +++ b/abstract-machine/am/src/riscv/npc/timer.c @@ -1,17 +1,18 @@ +#include "npc.h" #include +#include -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) { rtc->second = 0; rtc->minute = 0; - rtc->hour = 0; - rtc->day = 0; - rtc->month = 0; - rtc->year = 1900; + rtc->hour = 0; + rtc->day = 0; + rtc->month = 0; + rtc->year = 1900; } diff --git a/abstract-machine/am/src/riscv/npc/trm.c b/abstract-machine/am/src/riscv/npc/trm.c index a5f4fac..ec9c965 100644 --- a/abstract-machine/am/src/riscv/npc/trm.c +++ b/abstract-machine/am/src/riscv/npc/trm.c @@ -1,5 +1,7 @@ +#include "npc.h" #include #include +#include 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)); diff --git a/abstract-machine/default.nix b/abstract-machine/default.nix index 2b614ac..ef21cf2 100644 --- a/abstract-machine/default.nix +++ b/abstract-machine/default.nix @@ -7,7 +7,7 @@ }: stdenv.mkDerivation { pname = "abstract-machine"; - version = "2024.02.18"; + version = "2024.06.01"; src = ./.; diff --git a/abstract-machine/klib/CMakeLists.txt b/abstract-machine/klib/CMakeLists.txt index febd4f0..4a7a3aa 100644 --- a/abstract-machine/klib/CMakeLists.txt +++ b/abstract-machine/klib/CMakeLists.txt @@ -1 +1,4 @@ +install(DIRECTORY include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/abstract-machine) + add_subdirectory(src) diff --git a/abstract-machine/klib/src/CMakeLists.txt b/abstract-machine/klib/src/CMakeLists.txt index b3a59fd..5d173b7 100644 --- a/abstract-machine/klib/src/CMakeLists.txt +++ b/abstract-machine/klib/src/CMakeLists.txt @@ -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 - # ${FLEX_fmt_scanner_OUTPUTS} +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 - EXPORT klibTargets - LIBRARY DESTINATION lib) +install( + TARGETS klib + EXPORT klibTargets + LIBRARY DESTINATION lib) -install(EXPORT klibTargets - FILE klibTargets.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/klib) +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) - diff --git a/abstract-machine/klib/src/stdio.c b/abstract-machine/klib/src/stdio.c index fec63bc..35f9f59 100644 --- a/abstract-machine/klib/src/stdio.c +++ b/abstract-machine/klib/src/stdio.c @@ -1,16 +1,91 @@ #include -#include #include +#include #include #if !defined(__ISA_NATIVE__) || defined(__NATIVE_USE_KLIB__) -int vprintf(const char *fmt, va_list ap) { - const char *p = fmt; - while(*p != '\0') { - putch(*p); +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); + } + p++; } - return 0; } 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, ...) { diff --git a/abstract-machine/klib/src/stdlib.c b/abstract-machine/klib/src/stdlib.c index 382635d..90432b6 100644 --- a/abstract-machine/klib/src/stdlib.c +++ b/abstract-machine/klib/src/stdlib.c @@ -1,6 +1,6 @@ #include -#include #include +#include #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 diff --git a/abstract-machine/klib/tests/CMakeLists.txt b/abstract-machine/klib/tests/CMakeLists.txt index 6cb0e40..6d1c225 100644 --- a/abstract-machine/klib/tests/CMakeLists.txt +++ b/abstract-machine/klib/tests/CMakeLists.txt @@ -1,14 +1,11 @@ -set(TEST_SOURCES - stdio - string -) +set(TEST_SOURCES stdio string) foreach(TEST IN LISTS TEST_SOURCES) - # TODO: Run tests in other configurations - if(__PLATFORM_NATIVE__) - add_executable(${TEST} ${TEST}.c) - target_link_libraries(${TEST} PRIVATE am_interface klib_interface klib m) - target_link_libraries(${TEST} PRIVATE am-native) - add_test(NAME ${TEST} COMMAND ${TEST}) - endif() + # TODO: Run tests in other configurations + if(__PLATFORM_NATIVE__) + add_executable(${TEST} ${TEST}.c) + target_link_libraries(${TEST} PRIVATE am_interface klib_interface klib m) + target_link_libraries(${TEST} PRIVATE am-native) + add_test(NAME ${TEST} COMMAND ${TEST}) + endif() endforeach()