diff --git a/bare-metal-bsp b/bare-metal-bsp index f21ea46..f37242e 160000 --- a/bare-metal-bsp +++ b/bare-metal-bsp @@ -1 +1 @@ -Subproject commit f21ea46befe7401cc35205d3b64e3991504b6289 +Subproject commit f37242efa7f52fe8c2895a794d467d820c83b553 diff --git a/benchmarks/coremark/CMakeLists.txt b/benchmarks/coremark/CMakeLists.txt new file mode 100644 index 0000000..f9fda51 --- /dev/null +++ b/benchmarks/coremark/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.21) +project(coremark C) +set(TARGET coremark) +#set(CMAKE_BUILD_TYPE Release) + +option(HAVE_NO_INIT_FINI "Enable NO_INIT_FINI" OFF) + +if(HAVE_NO_INIT_FINI) + #if HAVE_NO_INIT_FINI is ON + add_definitions(-DHAVE_NO_INIT_FINI) +endif() + + +# Source files +set(SOURCES + core_portme.c + cvt.c + ee_printf.c + cm/core_list_join.c + cm/core_main.c + cm/core_matrix.c + cm/core_state.c + cm/core_util.c +) + + +# Create executable +add_executable(coremark ${SOURCES}) +target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_LIST_DIR} ${CMAKE_CURRENT_LIST_DIR}/cm) +target_compile_options(${TARGET} PRIVATE -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -fno-builtin-strnlen -fno-common -funroll-loops -finline-functions -falign-functions=16 -falign-jumps=4 -falign-loops=4 -finline-limit=1000 -fno-if-conversion2 -fselective-scheduling -fno-crossjumping -freorder-blocks-and-partition -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -fno-common -funroll-loops -finline-functions -falign-functions=16 -falign-jumps=4 -falign-loops=4 -finline-limit=1000 -fno-if-conversion2 -fselective-scheduling -fno-crossjumping -freorder-blocks-and-partition ) +target_compile_definitions(${TARGET} PRIVATE PERFORMANCE_RUN=1 CLOCKS_PER_SEC=10000000 FLAGS_STR="" PERFORMANCE_RUN=1 CLOCKS_PER_SEC=10000000 ITERATIONS=600) + +set(BOARD "iss" CACHE STRING "Target board") +add_subdirectory(../../bare-metal-bsp bsp) +target_link_libraries(${TARGET} PRIVATE bsp) +target_link_options(${TARGET} PRIVATE -Wl,-Map=${TARGET}.map) + +include(CMakePrintHelpers) +cmake_print_properties(TARGETS ${TARGET} PROPERTIES COMPILE_DEFINITIONS COMPILE_OPTIONS LINK_OPTIONS INTERFACE_LINK_OPTIONS) + +#message(STATUS "CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE}") +#message(STATUS "CMAKE_C_FLAGS = ${CMAKE_C_FLAGS}") + +add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND ${CMAKE_OBJDUMP} -S ${TARGET}.elf > ${TARGET}.dis + COMMENT "Creating disassembly for ${TARGET}") diff --git a/benchmarks/coremark/CMakePresets.json b/benchmarks/coremark/CMakePresets.json new file mode 100644 index 0000000..345cd99 --- /dev/null +++ b/benchmarks/coremark/CMakePresets.json @@ -0,0 +1,70 @@ +{ + "version": 3, + "vendor": { + "conan": {} + }, + "cmakeMinimumRequired": { + "major": 3, + "minor": 24, + "patch": 0 + }, + "configurePresets": [ + { + "name": "debug", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" + } + }, + { + "name": "debug_moon", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "BOARD": "moonlight", + "HAVE_NO_INIT_FINI": "ON", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" + } + }, + { + "name": "debug_tgc", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "BOARD": "tgc_vp", + "HAVE_NO_INIT_FINI": "ON", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" + } + }, + { + "name": "debug_64", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" + } + }, + { + "name": "debug_64_moon", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "BOARD": "moonlight", + "HAVE_NO_INIT_FINI": "ON", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" + } + }, + { + "name": "debug_64_tgc", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "BOARD": "tgc_vp", + "HAVE_NO_INIT_FINI": "ON", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" + } + }, + { + "name": "release", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" + } + } + ] +} \ No newline at end of file diff --git a/benchmarks/coremark/core_portme.c b/benchmarks/coremark/core_portme.c index e986425..41a7714 100644 --- a/benchmarks/coremark/core_portme.c +++ b/benchmarks/coremark/core_portme.c @@ -15,55 +15,58 @@ limitations under the License. Original Author: Shay Gal-on */ -#include "coremark.h" #include "core_portme.h" -//Read cycle CSR -unsigned long long _read_cycle() -{ - unsigned long long result; - unsigned long lower; - unsigned long upper1; - unsigned long upper2; +#include "coremark.h" +#include +// Read cycle CSR +unsigned long long _read_cycle() { + unsigned long long result; + unsigned long lower; + unsigned long upper1; + unsigned long upper2; - asm volatile ( - "repeat_cycle_%=: csrr %0, cycleh;\n" - " csrr %1, cycle;\n" - " csrr %2, cycleh;\n" - " bne %0, %2, repeat_cycle_%=;\n" - : "=r" (upper1),"=r" (lower),"=r" (upper2) // Outputs : temp variable for load result - : - : - ); - *(unsigned long *)(&result) = lower; - *((unsigned long *)(&result)+1) = upper1; + asm volatile("repeat_cycle_%=: csrr %0, cycleh;\n" + " csrr %1, cycle;\n" + " csrr %2, cycleh;\n" + " bne %0, %2, repeat_cycle_%=;\n" + : "=r"(upper1), "=r"(lower), + "=r"(upper2) // Outputs : temp variable for load result + : + :); + *(unsigned long *)(&result) = lower; + *((unsigned long *)(&result) + 1) = upper1; - return result; + return result; } -volatile int tohost; -volatile int fromhost; +// extern volatile int tohost; +// extern volatile int fromhost; -void exit(int n){ - tohost = 0x1; - for (;;); +void write_hex(int fd, uint32_t hex); + +void exit(int n) { + write_hex(STDERR_FILENO, 1); + // tohost = 0x1; + for (;;) + ; } -void __libc_init_array (void) { -/* - size_t count; - size_t i; - count = __preinit_array_end - __preinit_array_start; - for (i = 0; i < count; i++) - __preinit_array_start[i] (); +void __libc_init_array(void) { + /* + size_t count; + size_t i; + count = __preinit_array_end - __preinit_array_start; + for (i = 0; i < count; i++) + __preinit_array_start[i] (); -#ifdef HAVE_INIT_FINI - _init (); -#endif + #ifdef HAVE_INIT_FINI + _init (); + #endif - count = __init_array_end - __init_array_start; - for (i = 0; i < count; i++) - __init_array_start[i] (); -*/ + count = __init_array_end - __init_array_start; + for (i = 0; i < count; i++) + __init_array_start[i] (); + */ } #if VALIDATION_RUN volatile ee_s32 seed1_volatile = 0x3415; @@ -89,10 +92,7 @@ volatile ee_s32 seed5_volatile = 0; time.h and windows.h definitions included. */ CORETIMETYPE -barebones_clock() -{ - return (CORETIMETYPE)_read_cycle(); -} +barebones_clock() { return (CORETIMETYPE)_read_cycle(); } /* Define : TIMER_RES_DIVIDER Divider to trade off timer resolution and total time that can be measured. @@ -101,11 +101,11 @@ barebones_clock() does not occur. If there are issues with the return value overflowing, increase this value. */ -#define GETMYTIME(_t) (*_t = barebones_clock()) -#define MYTIMEDIFF(fin, ini) ((fin) - (ini)) -#define TIMER_RES_DIVIDER 1 +#define GETMYTIME(_t) (*_t = barebones_clock()) +#define MYTIMEDIFF(fin, ini) ((fin) - (ini)) +#define TIMER_RES_DIVIDER 1 #define SAMPLE_TIME_IMPLEMENTATION 1 -#define EE_TICKS_PER_SEC (CLOCKS_PER_SEC / TIMER_RES_DIVIDER) +#define EE_TICKS_PER_SEC (CLOCKS_PER_SEC / TIMER_RES_DIVIDER) /** Define Host specific (POSIX), or target specific global time variables. */ static CORETIMETYPE start_time_val, stop_time_val; @@ -118,11 +118,7 @@ static CORETIMETYPE start_time_val, stop_time_val; example code) or zeroing some system parameters - e.g. setting the cpu clocks cycles to 0. */ -void -start_time(void) -{ - GETMYTIME(&start_time_val); -} +void start_time(void) { GETMYTIME(&start_time_val); } /* Function : stop_time This function will be called right after ending the timed portion of the benchmark. @@ -131,11 +127,7 @@ start_time(void) example code) or other system parameters - e.g. reading the current value of cpu cycles counter. */ -void -stop_time(void) -{ - GETMYTIME(&stop_time_val); -} +void stop_time(void) { GETMYTIME(&stop_time_val); } /* Function : get_time Return an abstract "ticks" number that signifies time on the system. @@ -146,11 +138,9 @@ stop_time(void) controlled by */ CORE_TICKS -get_time(void) -{ - CORE_TICKS elapsed - = (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val)); - return elapsed; +get_time(void) { + CORE_TICKS elapsed = (CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val)); + return elapsed; } /* Function : time_in_secs Convert the value returned by get_time to seconds. @@ -159,11 +149,9 @@ get_time(void) floating point. Default implementation implemented by the EE_TICKS_PER_SEC macro above. */ -secs_ret -time_in_secs(CORE_TICKS ticks) -{ - secs_ret retval = ((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC; - return retval; +secs_ret time_in_secs(CORE_TICKS ticks) { + secs_ret retval = ((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC; + return retval; } ee_u32 default_num_contexts = 1; @@ -172,27 +160,18 @@ ee_u32 default_num_contexts = 1; Target specific initialization code Test for some common mistakes. */ -void -portable_init(core_portable *p, int *argc, char *argv[]) -{ - if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) - { - ee_printf( - "ERROR! Please define ee_ptr_int to a type that holds a " - "pointer!\n"); - } - if (sizeof(ee_u32) != 4) - { - ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n"); - } - p->portable_id = 1; - ee_printf("portable_init finished.\n"); +void portable_init(core_portable *p, int *argc, char *argv[]) { + if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) { + ee_printf("ERROR! Please define ee_ptr_int to a type that holds a " + "pointer!\n"); + } + if (sizeof(ee_u32) != 4) { + ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n"); + } + p->portable_id = 1; + ee_printf("portable_init finished.\n"); } /* Function : portable_fini Target specific final code */ -void -portable_fini(core_portable *p) -{ - p->portable_id = 0; -} +void portable_fini(core_portable *p) { p->portable_id = 0; } diff --git a/benchmarks/coremark/ee_printf.c b/benchmarks/coremark/ee_printf.c index d315f7d..6952ea6 100644 --- a/benchmarks/coremark/ee_printf.c +++ b/benchmarks/coremark/ee_printf.c @@ -16,690 +16,577 @@ limitations under the License. #include #include +#include -#define ZEROPAD (1 << 0) /* Pad with zero */ -#define SIGN (1 << 1) /* Unsigned/signed long */ -#define PLUS (1 << 2) /* Show plus */ -#define SPACE (1 << 3) /* Spacer */ -#define LEFT (1 << 4) /* Left justified */ -#define HEX_PREP (1 << 5) /* 0x */ +#define ZEROPAD (1 << 0) /* Pad with zero */ +#define SIGN (1 << 1) /* Unsigned/signed long */ +#define PLUS (1 << 2) /* Show plus */ +#define SPACE (1 << 3) /* Spacer */ +#define LEFT (1 << 4) /* Left justified */ +#define HEX_PREP (1 << 5) /* 0x */ #define UPPERCASE (1 << 6) /* 'ABCDEF' */ #define is_digit(c) ((c) >= '0' && (c) <= '9') -static char * digits = "0123456789abcdefghijklmnopqrstuvwxyz"; -static char * upper_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +static char *digits = "0123456789abcdefghijklmnopqrstuvwxyz"; +static char *upper_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; static ee_size_t strnlen(const char *s, ee_size_t count); -static ee_size_t -strnlen(const char *s, ee_size_t count) -{ - const char *sc; - for (sc = s; *sc != '\0' && count--; ++sc) - ; - return sc - s; +static ee_size_t strnlen(const char *s, ee_size_t count) { + const char *sc; + for (sc = s; *sc != '\0' && count--; ++sc) + ; + return sc - s; } -static int -skip_atoi(const char **s) -{ - int i = 0; - while (is_digit(**s)) - i = i * 10 + *((*s)++) - '0'; - return i; +static int skip_atoi(const char **s) { + int i = 0; + while (is_digit(**s)) + i = i * 10 + *((*s)++) - '0'; + return i; } -static char * -number(char *str, long num, int base, int size, int precision, int type) -{ - char c, sign, tmp[66]; - char *dig = digits; - int i; +static char *number(char *str, long num, int base, int size, int precision, + int type) { + char c, sign, tmp[66]; + char *dig = digits; + int i; - if (type & UPPERCASE) - dig = upper_digits; - if (type & LEFT) - type &= ~ZEROPAD; - if (base < 2 || base > 36) - return 0; + if (type & UPPERCASE) + dig = upper_digits; + if (type & LEFT) + type &= ~ZEROPAD; + if (base < 2 || base > 36) + return 0; - c = (type & ZEROPAD) ? '0' : ' '; - sign = 0; - if (type & SIGN) - { - if (num < 0) - { - sign = '-'; - num = -num; - size--; - } - else if (type & PLUS) - { - sign = '+'; - size--; - } - else if (type & SPACE) - { - sign = ' '; - size--; - } + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & SIGN) { + if (num < 0) { + sign = '-'; + num = -num; + size--; + } else if (type & PLUS) { + sign = '+'; + size--; + } else if (type & SPACE) { + sign = ' '; + size--; } + } - if (type & HEX_PREP) - { - if (base == 16) - size -= 2; - else if (base == 8) - size--; + if (type & HEX_PREP) { + if (base == 16) + size -= 2; + else if (base == 8) + size--; + } + + i = 0; + + if (num == 0) + tmp[i++] = '0'; + else { + while (num != 0) { + tmp[i++] = dig[((unsigned long)num) % (unsigned)base]; + num = ((unsigned long)num) / (unsigned)base; } + } - i = 0; - - if (num == 0) - tmp[i++] = '0'; - else - { - while (num != 0) - { - tmp[i++] = dig[((unsigned long)num) % (unsigned)base]; - num = ((unsigned long)num) / (unsigned)base; - } - } - - if (i > precision) - precision = i; - size -= precision; - if (!(type & (ZEROPAD | LEFT))) - while (size-- > 0) - *str++ = ' '; - if (sign) - *str++ = sign; - - if (type & HEX_PREP) - { - if (base == 8) - *str++ = '0'; - else if (base == 16) - { - *str++ = '0'; - *str++ = digits[33]; - } - } - - if (!(type & LEFT)) - while (size-- > 0) - *str++ = c; - while (i < precision--) - *str++ = '0'; - while (i-- > 0) - *str++ = tmp[i]; + if (i > precision) + precision = i; + size -= precision; + if (!(type & (ZEROPAD | LEFT))) while (size-- > 0) - *str++ = ' '; + *str++ = ' '; + if (sign) + *str++ = sign; - return str; + if (type & HEX_PREP) { + if (base == 8) + *str++ = '0'; + else if (base == 16) { + *str++ = '0'; + *str++ = digits[33]; + } + } + + if (!(type & LEFT)) + while (size-- > 0) + *str++ = c; + while (i < precision--) + *str++ = '0'; + while (i-- > 0) + *str++ = tmp[i]; + while (size-- > 0) + *str++ = ' '; + + return str; } -static char * -eaddr(char *str, unsigned char *addr, int size, int precision, int type) -{ - char tmp[24]; - char *dig = digits; - int i, len; +static char *eaddr(char *str, unsigned char *addr, int size, int precision, + int type) { + char tmp[24]; + char *dig = digits; + int i, len; - if (type & UPPERCASE) - dig = upper_digits; - len = 0; - for (i = 0; i < 6; i++) - { - if (i != 0) - tmp[len++] = ':'; - tmp[len++] = dig[addr[i] >> 4]; - tmp[len++] = dig[addr[i] & 0x0F]; - } + if (type & UPPERCASE) + dig = upper_digits; + len = 0; + for (i = 0; i < 6; i++) { + if (i != 0) + tmp[len++] = ':'; + tmp[len++] = dig[addr[i] >> 4]; + tmp[len++] = dig[addr[i] & 0x0F]; + } - if (!(type & LEFT)) - while (len < size--) - *str++ = ' '; - for (i = 0; i < len; ++i) - *str++ = tmp[i]; + if (!(type & LEFT)) while (len < size--) - *str++ = ' '; + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = tmp[i]; + while (len < size--) + *str++ = ' '; - return str; + return str; } -static char * -iaddr(char *str, unsigned char *addr, int size, int precision, int type) -{ - char tmp[24]; - int i, n, len; +static char *iaddr(char *str, unsigned char *addr, int size, int precision, + int type) { + char tmp[24]; + int i, n, len; - len = 0; - for (i = 0; i < 4; i++) - { - if (i != 0) - tmp[len++] = '.'; - n = addr[i]; + len = 0; + for (i = 0; i < 4; i++) { + if (i != 0) + tmp[len++] = '.'; + n = addr[i]; - if (n == 0) - tmp[len++] = digits[0]; - else - { - if (n >= 100) - { - tmp[len++] = digits[n / 100]; - n = n % 100; - tmp[len++] = digits[n / 10]; - n = n % 10; - } - else if (n >= 10) - { - tmp[len++] = digits[n / 10]; - n = n % 10; - } + if (n == 0) + tmp[len++] = digits[0]; + else { + if (n >= 100) { + tmp[len++] = digits[n / 100]; + n = n % 100; + tmp[len++] = digits[n / 10]; + n = n % 10; + } else if (n >= 10) { + tmp[len++] = digits[n / 10]; + n = n % 10; + } - tmp[len++] = digits[n]; - } + tmp[len++] = digits[n]; } + } - if (!(type & LEFT)) - while (len < size--) - *str++ = ' '; - for (i = 0; i < len; ++i) - *str++ = tmp[i]; + if (!(type & LEFT)) while (len < size--) - *str++ = ' '; + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = tmp[i]; + while (len < size--) + *str++ = ' '; - return str; + return str; } #if HAS_FLOAT -char * ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf); -char * fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf); +char *ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf); +char *fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf); static void ee_bufcpy(char *d, char *s, int count); -void -ee_bufcpy(char *pd, char *ps, int count) -{ - char *pe = ps + count; - while (ps != pe) - *pd++ = *ps++; +void ee_bufcpy(char *pd, char *ps, int count) { + char *pe = ps + count; + while (ps != pe) + *pd++ = *ps++; } -static void -parse_float(double value, char *buffer, char fmt, int precision) -{ - int decpt, sign, exp, pos; - char *digits = NULL; - char cvtbuf[80]; - int capexp = 0; - int magnitude; +static void parse_float(double value, char *buffer, char fmt, int precision) { + int decpt, sign, exp, pos; + char *digits = NULL; + char cvtbuf[80]; + int capexp = 0; + int magnitude; - if (fmt == 'G' || fmt == 'E') - { - capexp = 1; - fmt += 'a' - 'A'; + if (fmt == 'G' || fmt == 'E') { + capexp = 1; + fmt += 'a' - 'A'; + } + + if (fmt == 'g') { + digits = ecvtbuf(value, precision, &decpt, &sign, cvtbuf); + magnitude = decpt - 1; + if (magnitude < -4 || magnitude > precision - 1) { + fmt = 'e'; + precision -= 1; + } else { + fmt = 'f'; + precision -= decpt; } + } - if (fmt == 'g') - { - digits = ecvtbuf(value, precision, &decpt, &sign, cvtbuf); - magnitude = decpt - 1; - if (magnitude < -4 || magnitude > precision - 1) - { - fmt = 'e'; - precision -= 1; - } - else - { - fmt = 'f'; - precision -= decpt; - } - } + if (fmt == 'e') { + digits = ecvtbuf(value, precision + 1, &decpt, &sign, cvtbuf); - if (fmt == 'e') - { - digits = ecvtbuf(value, precision + 1, &decpt, &sign, cvtbuf); - - if (sign) - *buffer++ = '-'; - *buffer++ = *digits; - if (precision > 0) - *buffer++ = '.'; - ee_bufcpy(buffer, digits + 1, precision); - buffer += precision; - *buffer++ = capexp ? 'E' : 'e'; - - if (decpt == 0) - { - if (value == 0.0) - exp = 0; - else - exp = -1; - } - else - exp = decpt - 1; - - if (exp < 0) - { - *buffer++ = '-'; - exp = -exp; - } - else - *buffer++ = '+'; - - buffer[2] = (exp % 10) + '0'; - exp = exp / 10; - buffer[1] = (exp % 10) + '0'; - exp = exp / 10; - buffer[0] = (exp % 10) + '0'; - buffer += 3; - } - else if (fmt == 'f') - { - digits = fcvtbuf(value, precision, &decpt, &sign, cvtbuf); - if (sign) - *buffer++ = '-'; - if (*digits) - { - if (decpt <= 0) - { - *buffer++ = '0'; - *buffer++ = '.'; - for (pos = 0; pos < -decpt; pos++) - *buffer++ = '0'; - while (*digits) - *buffer++ = *digits++; - } - else - { - pos = 0; - while (*digits) - { - if (pos++ == decpt) - *buffer++ = '.'; - *buffer++ = *digits++; - } - } - } - else - { - *buffer++ = '0'; - if (precision > 0) - { - *buffer++ = '.'; - for (pos = 0; pos < precision; pos++) - *buffer++ = '0'; - } - } - } - - *buffer = '\0'; -} - -static void -decimal_point(char *buffer) -{ - while (*buffer) - { - if (*buffer == '.') - return; - if (*buffer == 'e' || *buffer == 'E') - break; - buffer++; - } - - if (*buffer) - { - int n = strnlen(buffer, 256); - while (n > 0) - { - buffer[n + 1] = buffer[n]; - n--; - } - - *buffer = '.'; - } - else - { - *buffer++ = '.'; - *buffer = '\0'; - } -} - -static void -cropzeros(char *buffer) -{ - char *stop; - - while (*buffer && *buffer != '.') - buffer++; - if (*buffer++) - { - while (*buffer && *buffer != 'e' && *buffer != 'E') - buffer++; - stop = buffer--; - while (*buffer == '0') - buffer--; - if (*buffer == '.') - buffer--; - while (buffer != stop) - *++buffer = 0; - } -} - -static char * -flt(char *str, double num, int size, int precision, char fmt, int flags) -{ - char tmp[80]; - char c, sign; - int n, i; - - // Left align means no zero padding - if (flags & LEFT) - flags &= ~ZEROPAD; - - // Determine padding and sign char - c = (flags & ZEROPAD) ? '0' : ' '; - sign = 0; - if (flags & SIGN) - { - if (num < 0.0) - { - sign = '-'; - num = -num; - size--; - } - else if (flags & PLUS) - { - sign = '+'; - size--; - } - else if (flags & SPACE) - { - sign = ' '; - size--; - } - } - - // Compute the precision value - if (precision < 0) - precision = 6; // Default precision: 6 - - // Convert floating point number to text - parse_float(num, tmp, fmt, precision); - - if ((flags & HEX_PREP) && precision == 0) - decimal_point(tmp); - if (fmt == 'g' && !(flags & HEX_PREP)) - cropzeros(tmp); - - n = strnlen(tmp, 256); - - // Output number with alignment and padding - size -= n; - if (!(flags & (ZEROPAD | LEFT))) - while (size-- > 0) - *str++ = ' '; if (sign) - *str++ = sign; - if (!(flags & LEFT)) - while (size-- > 0) - *str++ = c; - for (i = 0; i < n; i++) - *str++ = tmp[i]; - while (size-- > 0) - *str++ = ' '; + *buffer++ = '-'; + *buffer++ = *digits; + if (precision > 0) + *buffer++ = '.'; + ee_bufcpy(buffer, digits + 1, precision); + buffer += precision; + *buffer++ = capexp ? 'E' : 'e'; - return str; + if (decpt == 0) { + if (value == 0.0) + exp = 0; + else + exp = -1; + } else + exp = decpt - 1; + + if (exp < 0) { + *buffer++ = '-'; + exp = -exp; + } else + *buffer++ = '+'; + + buffer[2] = (exp % 10) + '0'; + exp = exp / 10; + buffer[1] = (exp % 10) + '0'; + exp = exp / 10; + buffer[0] = (exp % 10) + '0'; + buffer += 3; + } else if (fmt == 'f') { + digits = fcvtbuf(value, precision, &decpt, &sign, cvtbuf); + if (sign) + *buffer++ = '-'; + if (*digits) { + if (decpt <= 0) { + *buffer++ = '0'; + *buffer++ = '.'; + for (pos = 0; pos < -decpt; pos++) + *buffer++ = '0'; + while (*digits) + *buffer++ = *digits++; + } else { + pos = 0; + while (*digits) { + if (pos++ == decpt) + *buffer++ = '.'; + *buffer++ = *digits++; + } + } + } else { + *buffer++ = '0'; + if (precision > 0) { + *buffer++ = '.'; + for (pos = 0; pos < precision; pos++) + *buffer++ = '0'; + } + } + } + + *buffer = '\0'; +} + +static void decimal_point(char *buffer) { + while (*buffer) { + if (*buffer == '.') + return; + if (*buffer == 'e' || *buffer == 'E') + break; + buffer++; + } + + if (*buffer) { + int n = strnlen(buffer, 256); + while (n > 0) { + buffer[n + 1] = buffer[n]; + n--; + } + + *buffer = '.'; + } else { + *buffer++ = '.'; + *buffer = '\0'; + } +} + +static void cropzeros(char *buffer) { + char *stop; + + while (*buffer && *buffer != '.') + buffer++; + if (*buffer++) { + while (*buffer && *buffer != 'e' && *buffer != 'E') + buffer++; + stop = buffer--; + while (*buffer == '0') + buffer--; + if (*buffer == '.') + buffer--; + while (buffer != stop) + *++buffer = 0; + } +} + +static char *flt(char *str, double num, int size, int precision, char fmt, + int flags) { + char tmp[80]; + char c, sign; + int n, i; + + // Left align means no zero padding + if (flags & LEFT) + flags &= ~ZEROPAD; + + // Determine padding and sign char + c = (flags & ZEROPAD) ? '0' : ' '; + sign = 0; + if (flags & SIGN) { + if (num < 0.0) { + sign = '-'; + num = -num; + size--; + } else if (flags & PLUS) { + sign = '+'; + size--; + } else if (flags & SPACE) { + sign = ' '; + size--; + } + } + + // Compute the precision value + if (precision < 0) + precision = 6; // Default precision: 6 + + // Convert floating point number to text + parse_float(num, tmp, fmt, precision); + + if ((flags & HEX_PREP) && precision == 0) + decimal_point(tmp); + if (fmt == 'g' && !(flags & HEX_PREP)) + cropzeros(tmp); + + n = strnlen(tmp, 256); + + // Output number with alignment and padding + size -= n; + if (!(flags & (ZEROPAD | LEFT))) + while (size-- > 0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (!(flags & LEFT)) + while (size-- > 0) + *str++ = c; + for (i = 0; i < n; i++) + *str++ = tmp[i]; + while (size-- > 0) + *str++ = ' '; + + return str; } #endif -static int -ee_vsprintf(char *buf, const char *fmt, va_list args) -{ - int len; - unsigned long num; - int i, base; - char * str; - char * s; +static int ee_vsprintf(char *buf, const char *fmt, va_list args) { + int len; + unsigned long num; + int i, base; + char *str; + char *s; - int flags; // Flags to number() + int flags; // Flags to number() - int field_width; // Width of output field - int precision; // Min. # of digits for integers; max number of chars for - // from string - int qualifier; // 'h', 'l', or 'L' for integer fields + int field_width; // Width of output field + int precision; // Min. # of digits for integers; max number of chars for + // from string + int qualifier; // 'h', 'l', or 'L' for integer fields - for (str = buf; *fmt; fmt++) - { - if (*fmt != '%') - { - *str++ = *fmt; - continue; - } + for (str = buf; *fmt; fmt++) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } - // Process flags - flags = 0; - repeat: - fmt++; // This also skips first '%' - switch (*fmt) - { - case '-': - flags |= LEFT; - goto repeat; - case '+': - flags |= PLUS; - goto repeat; - case ' ': - flags |= SPACE; - goto repeat; - case '#': - flags |= HEX_PREP; - goto repeat; - case '0': - flags |= ZEROPAD; - goto repeat; - } + // Process flags + flags = 0; + repeat: + fmt++; // This also skips first '%' + switch (*fmt) { + case '-': + flags |= LEFT; + goto repeat; + case '+': + flags |= PLUS; + goto repeat; + case ' ': + flags |= SPACE; + goto repeat; + case '#': + flags |= HEX_PREP; + goto repeat; + case '0': + flags |= ZEROPAD; + goto repeat; + } - // Get field width - field_width = -1; - if (is_digit(*fmt)) - field_width = skip_atoi(&fmt); - else if (*fmt == '*') - { - fmt++; - field_width = va_arg(args, int); - if (field_width < 0) - { - field_width = -field_width; - flags |= LEFT; - } - } + // Get field width + field_width = -1; + if (is_digit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + fmt++; + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } - // Get the precision - precision = -1; - if (*fmt == '.') - { - ++fmt; - if (is_digit(*fmt)) - precision = skip_atoi(&fmt); - else if (*fmt == '*') - { - ++fmt; - precision = va_arg(args, int); - } - if (precision < 0) - precision = 0; - } + // Get the precision + precision = -1; + if (*fmt == '.') { + ++fmt; + if (is_digit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } - // Get the conversion qualifier - qualifier = -1; - if (*fmt == 'l' || *fmt == 'L') - { - qualifier = *fmt; - fmt++; - } + // Get the conversion qualifier + qualifier = -1; + if (*fmt == 'l' || *fmt == 'L') { + qualifier = *fmt; + fmt++; + } - // Default base - base = 10; + // Default base + base = 10; - switch (*fmt) - { - case 'c': - if (!(flags & LEFT)) - while (--field_width > 0) - *str++ = ' '; - *str++ = (unsigned char)va_arg(args, int); - while (--field_width > 0) - *str++ = ' '; - continue; + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char)va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + continue; - case 's': - s = va_arg(args, char *); - if (!s) - s = ""; - len = strnlen(s, precision); - if (!(flags & LEFT)) - while (len < field_width--) - *str++ = ' '; - for (i = 0; i < len; ++i) - *str++ = *s++; - while (len < field_width--) - *str++ = ' '; - continue; + case 's': + s = va_arg(args, char *); + if (!s) + s = ""; + len = strnlen(s, precision); + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + continue; - case 'p': - if (field_width == -1) - { - field_width = 2 * sizeof(void *); - flags |= ZEROPAD; - } - str = number(str, - (unsigned long)va_arg(args, void *), - 16, - field_width, - precision, - flags); - continue; + case 'p': + if (field_width == -1) { + field_width = 2 * sizeof(void *); + flags |= ZEROPAD; + } + str = number(str, (unsigned long)va_arg(args, void *), 16, field_width, + precision, flags); + continue; - case 'A': - flags |= UPPERCASE; + case 'A': + flags |= UPPERCASE; - case 'a': - if (qualifier == 'l') - str = eaddr(str, - va_arg(args, unsigned char *), - field_width, - precision, - flags); - else - str = iaddr(str, - va_arg(args, unsigned char *), - field_width, - precision, - flags); - continue; + case 'a': + if (qualifier == 'l') + str = eaddr(str, va_arg(args, unsigned char *), field_width, precision, + flags); + else + str = iaddr(str, va_arg(args, unsigned char *), field_width, precision, + flags); + continue; - // Integer number formats - set up the flags and "break" - case 'o': - base = 8; - break; + // Integer number formats - set up the flags and "break" + case 'o': + base = 8; + break; - case 'X': - flags |= UPPERCASE; + case 'X': + flags |= UPPERCASE; - case 'x': - base = 16; - break; + case 'x': + base = 16; + break; - case 'd': - case 'i': - flags |= SIGN; + case 'd': + case 'i': + flags |= SIGN; - case 'u': - break; + case 'u': + break; #if HAS_FLOAT - case 'f': - str = flt(str, - va_arg(args, double), - field_width, - precision, - *fmt, - flags | SIGN); - continue; + case 'f': + str = flt(str, va_arg(args, double), field_width, precision, *fmt, + flags | SIGN); + continue; #endif - default: - if (*fmt != '%') - *str++ = '%'; - if (*fmt) - *str++ = *fmt; - else - --fmt; - continue; - } - - if (qualifier == 'l') - num = va_arg(args, unsigned long); - else if (flags & SIGN) - num = va_arg(args, int); - else - num = va_arg(args, unsigned int); - - str = number(str, num, base, field_width, precision, flags); + default: + if (*fmt != '%') + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + continue; } - *str = '\0'; - return str - buf; + if (qualifier == 'l') + num = va_arg(args, unsigned long); + else if (flags & SIGN) + num = va_arg(args, int); + else + num = va_arg(args, unsigned int); + + str = number(str, num, base, field_width, precision, flags); + } + + *str = '\0'; + return str - buf; } #include -void -uart_send_char(char c) -{ -#if defined(BOARD_ehrenberg) || defined(BOARD_tgc_vp) - while (get_uart_rx_tx_reg_tx_free(uart)==0) ; - uart_write(uart, c); - if (c == '\n') { - while (get_uart_rx_tx_reg_tx_free(uart)==0) ; - uart_write(uart, '\r'); - } -#elif defined(BOARD_iss) - *((uint32_t*) 0xFFFF0000) = c; -#else - while (UART0_REG(UART_REG_TXFIFO) & 0x80000000) ; - UART0_REG(UART_REG_TXFIFO) = c; - if (c == '\n') { - while (UART0_REG(UART_REG_TXFIFO) & 0x80000000) ; - UART0_REG(UART_REG_TXFIFO) = '\r'; - } -#endif -} - -int -ee_printf(const char *fmt, ...) -{ - char buf[1024], *p; - va_list args; - int n = 0; - - va_start(args, fmt); - ee_vsprintf(buf, fmt, args); - va_end(args); - p = buf; - while (*p) - { - uart_send_char(*p); - n++; - p++; - } - - return n; +void uart_send_char(char c) { write(STDOUT_FILENO, &c, 1); } + +int ee_printf(const char *fmt, ...) { + char buf[1024], *p; + va_list args; + int n = 0; + + va_start(args, fmt); + ee_vsprintf(buf, fmt, args); + va_end(args); + p = buf; + while (*p) { + uart_send_char(*p); + n++; + p++; + } + + return n; } diff --git a/benchmarks/dhrystone/.gitignore b/benchmarks/dhrystone/.gitignore index f8028c7..a3f9bbf 100644 --- a/benchmarks/dhrystone/.gitignore +++ b/benchmarks/dhrystone/.gitignore @@ -1,2 +1,3 @@ dhrystone /dhrystone.dis +build/ \ No newline at end of file diff --git a/benchmarks/dhrystone/CMakeLists.txt b/benchmarks/dhrystone/CMakeLists.txt new file mode 100644 index 0000000..47294cd --- /dev/null +++ b/benchmarks/dhrystone/CMakeLists.txt @@ -0,0 +1,31 @@ +cmake_minimum_required(VERSION 3.21) +project(dhrystone C) +set(TARGET dhrystone) + +option(HAVE_NO_INIT_FINI "Enable NO_INIT_FINI" OFF) + +if(HAVE_NO_INIT_FINI) + #if HAVE_NO_INIT_FINI is ON + add_definitions(-DHAVE_NO_INIT_FINI) +endif() + +set(ITERATIONS 50000) # 20000 for TGC + +add_executable(${TARGET} dhry_1.c dhry_2.c dhry_stubs.c) +target_include_directories(${TARGET} PRIVATE ${CMAKE_CURRENT_LIST_DIR}) +target_compile_options(${TARGET} PRIVATE -fno-inline -fno-builtin-printf -fno-common -Wno-implicit -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las) +target_compile_definitions(${TARGET} PRIVATE ITERATIONS=${ITERATIONS} HZ=32768 TIME NO_INIT) + +set(BOARD "iss" CACHE STRING "Target board") +add_subdirectory(../../bare-metal-bsp bsp) +target_link_libraries(${TARGET} PRIVATE bsp) +target_link_options(${TARGET} PRIVATE LINKER:--wrap=scanf) +#target_link_options(${TARGET} PRIVATE LINKER:--wrap=scanf -Wl,--no-gc-sections) + +target_link_options(${TARGET} PRIVATE -Wl,-Map=${TARGET}.map) +include(CMakePrintHelpers) +cmake_print_properties(TARGETS ${TARGET} PROPERTIES COMPILE_DEFINITIONS COMPILE_OPTIONS LINK_OPTIONS INTERFACE_LINK_OPTIONS) + +add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND ${CMAKE_OBJDUMP} -S ${TARGET}.elf > ${TARGET}.dis + COMMENT "Creating disassembly for ${TARGET}") diff --git a/benchmarks/dhrystone/CMakePresets.json b/benchmarks/dhrystone/CMakePresets.json new file mode 100644 index 0000000..345cd99 --- /dev/null +++ b/benchmarks/dhrystone/CMakePresets.json @@ -0,0 +1,70 @@ +{ + "version": 3, + "vendor": { + "conan": {} + }, + "cmakeMinimumRequired": { + "major": 3, + "minor": 24, + "patch": 0 + }, + "configurePresets": [ + { + "name": "debug", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" + } + }, + { + "name": "debug_moon", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "BOARD": "moonlight", + "HAVE_NO_INIT_FINI": "ON", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" + } + }, + { + "name": "debug_tgc", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "BOARD": "tgc_vp", + "HAVE_NO_INIT_FINI": "ON", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" + } + }, + { + "name": "debug_64", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" + } + }, + { + "name": "debug_64_moon", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "BOARD": "moonlight", + "HAVE_NO_INIT_FINI": "ON", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" + } + }, + { + "name": "debug_64_tgc", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "BOARD": "tgc_vp", + "HAVE_NO_INIT_FINI": "ON", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" + } + }, + { + "name": "release", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" + } + } + ] +} \ No newline at end of file diff --git a/benchmarks/dhrystone/dhry_stubs.c b/benchmarks/dhrystone/dhry_stubs.c index a3e7b7c..3a327e2 100644 --- a/benchmarks/dhrystone/dhry_stubs.c +++ b/benchmarks/dhrystone/dhry_stubs.c @@ -1,4 +1,5 @@ #include "platform.h" +#include #ifndef ITERATIONS #define ITERATIONS 20000 #endif @@ -6,20 +7,16 @@ /* The functions in this file are only meant to support Dhrystone on an * embedded RV32 system and are obviously incorrect in general. */ -long time(void) -{ - return get_timer_value(); -} +long time(void) { return get_timer_value(); } // set the number of dhrystone iterations -void __wrap_scanf(const char* fmt, int* n) -{ - *n = ITERATIONS; -} +void __wrap_scanf(const char *fmt, int *n) { *n = ITERATIONS; } -extern volatile uint32_t tohost; +// extern volatile uint64_t tohost; -void exit(int n){ - tohost = 0x1; - for (;;); +void exit(int n) { + // tohost = 0x1; + write_hex(STDERR_FILENO, 1); + for (;;) + ; } diff --git a/hello-world/.gitignore b/hello-world/.gitignore index 35be72e..c3f0253 100644 --- a/hello-world/.gitignore +++ b/hello-world/.gitignore @@ -1,2 +1,3 @@ /hello /hello.dis +build/ \ No newline at end of file diff --git a/hello-world/CMakeLists.txt b/hello-world/CMakeLists.txt new file mode 100644 index 0000000..83f3883 --- /dev/null +++ b/hello-world/CMakeLists.txt @@ -0,0 +1,23 @@ +cmake_minimum_required(VERSION 3.21) +project(hello-world C) +set(TARGET hello) +option(HAVE_NO_INIT_FINI "Enable NO_INIT_FINI" OFF) + +if(HAVE_NO_INIT_FINI) + #if HAVE_NO_INIT_FINI is ON + add_definitions(-DHAVE_NO_INIT_FINI) +endif() + +add_executable(${TARGET} hello.c) + + + +set(BOARD "iss" CACHE STRING "Target board") +message(" BOARD = ${BOARD}") +add_subdirectory(../bare-metal-bsp bsp) +target_link_libraries(${TARGET} PRIVATE bsp) +target_link_options(${TARGET} PRIVATE -Wl,-Map=${TARGET}.map) + +add_custom_command(TARGET ${TARGET} POST_BUILD + COMMAND ${CMAKE_OBJDUMP} -S ${TARGET}.elf > ${TARGET}.dis + COMMENT "Creating disassembly for ${TARGET}") diff --git a/hello-world/CMakePresets.json b/hello-world/CMakePresets.json new file mode 100644 index 0000000..345cd99 --- /dev/null +++ b/hello-world/CMakePresets.json @@ -0,0 +1,70 @@ +{ + "version": 3, + "vendor": { + "conan": {} + }, + "cmakeMinimumRequired": { + "major": 3, + "minor": 24, + "patch": 0 + }, + "configurePresets": [ + { + "name": "debug", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" + } + }, + { + "name": "debug_moon", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "BOARD": "moonlight", + "HAVE_NO_INIT_FINI": "ON", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" + } + }, + { + "name": "debug_tgc", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "BOARD": "tgc_vp", + "HAVE_NO_INIT_FINI": "ON", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" + } + }, + { + "name": "debug_64", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" + } + }, + { + "name": "debug_64_moon", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "BOARD": "moonlight", + "HAVE_NO_INIT_FINI": "ON", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" + } + }, + { + "name": "debug_64_tgc", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Debug", + "BOARD": "tgc_vp", + "HAVE_NO_INIT_FINI": "ON", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv64gc.cmake" + } + }, + { + "name": "release", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_TOOLCHAIN_FILE": "../../bare-metal-bsp/cmake/rv32imc.cmake" + } + } + ] +} \ No newline at end of file diff --git a/hello-world/hello.c b/hello-world/hello.c index 219ed8a..090d3bd 100644 --- a/hello-world/hello.c +++ b/hello-world/hello.c @@ -1,24 +1,37 @@ #include #include +#include #include -#include "platform.h" #include "encoding.h" +#include "platform.h" +#include -int factorial(int i){ +int factorial(int i) { - volatile int result = 1; - for (int ii = 1; ii <= i; ii++) { - result = result * ii; - } - return result; + volatile int result = 1; + for (int ii = 1; ii <= i; ii++) { + result = result * ii; + } + return result; +} +extern volatile uintptr_t tohost; +void write_tohost(char *string) { + volatile uint64_t payload[4] = {64, 0, (uintptr_t)string, + (strlen(string) + 1)}; + tohost = (uintptr_t)payload; } -int main() -{ - volatile int result = factorial (10); - printf("Factorial is %d\n", result); - printf("End of execution"); - return 0; +int main() { + char string[] = "hello world with write in hello"; + + write_tohost(string); + + write(STDOUT_FILENO, string, sizeof(string)); + + int result = factorial(10); + printf("Factorial is %d", result); + + return 0; }