diff --git a/riscv-coremark/coremark/README.md b/riscv-coremark/coremark/README.md index 26636f486..16b54b7b3 100644 --- a/riscv-coremark/coremark/README.md +++ b/riscv-coremark/coremark/README.md @@ -3,6 +3,8 @@ CoreMark's primary goals are simplicity and providing a method for testing only a processor's core features. For more information about EEMBC's comprehensive embedded benchmark suites, please see www.eembc.org. +For a more compute-intensive version of CoreMark that uses larger datasets and execution loops taken from common applications, please check out EEMBC's [CoreMark-PRO](https://www.github.com/eembc/coremark-pro) benchmark, also on GitHub. + # Building and Running To build and run the benchmark, type @@ -83,7 +85,9 @@ Use `XCFLAGS=-DMULTITHREAD=N` where N is number of threads to run in parallel. S % make XCFLAGS="-DMULTITHREAD=4 -DUSE_PTHREAD" ~~~ -Above will compile the benchmark for execution on 4 cores, using POSIX Threads API. +The above will compile the benchmark for execution on 4 cores, using POSIX Threads API. + +Note: linking may fail on the previous command if your linker does not automatically add the `pthread` library. If you encounter `undefined reference` errors, please modify the `core_portme.mak` file for your platform, (e.g. `linux/core_portme.mak`) and add `-lpthread` to the `LFLAGS_END` parameter. # Run Parameters for the Benchmark Executable CoreMark's executable takes several parameters as follows (but only if `main()` accepts arguments): @@ -109,7 +113,7 @@ The default for such a target when testing different configurations could be: # Submitting Results -CoreMark results can be submitted on the web. Open a web browser and go to https://www.eembc.org/coremark/login.php?url=enter_score.php. After registering an account you may enter a score. +CoreMark results can be submitted on the web. Open a web browser and go to the [submission page](https://www.eembc.org/coremark/submit.php). After registering an account you may enter a score. # Run Rules What is and is not allowed. diff --git a/riscv-coremark/coremark/barebones/core_portme.c b/riscv-coremark/coremark/barebones/core_portme.c old mode 100755 new mode 100644 index 336468191..18967676b --- a/riscv-coremark/coremark/barebones/core_portme.c +++ b/riscv-coremark/coremark/barebones/core_portme.c @@ -19,110 +19,135 @@ Original Author: Shay Gal-on #include "core_portme.h" #if VALIDATION_RUN - volatile ee_s32 seed1_volatile=0x3415; - volatile ee_s32 seed2_volatile=0x3415; - volatile ee_s32 seed3_volatile=0x66; +volatile ee_s32 seed1_volatile = 0x3415; +volatile ee_s32 seed2_volatile = 0x3415; +volatile ee_s32 seed3_volatile = 0x66; #endif #if PERFORMANCE_RUN - volatile ee_s32 seed1_volatile=0x0; - volatile ee_s32 seed2_volatile=0x0; - volatile ee_s32 seed3_volatile=0x66; +volatile ee_s32 seed1_volatile = 0x0; +volatile ee_s32 seed2_volatile = 0x0; +volatile ee_s32 seed3_volatile = 0x66; #endif #if PROFILE_RUN - volatile ee_s32 seed1_volatile=0x8; - volatile ee_s32 seed2_volatile=0x8; - volatile ee_s32 seed3_volatile=0x8; +volatile ee_s32 seed1_volatile = 0x8; +volatile ee_s32 seed2_volatile = 0x8; +volatile ee_s32 seed3_volatile = 0x8; #endif - volatile ee_s32 seed4_volatile=ITERATIONS; - volatile ee_s32 seed5_volatile=0; +volatile ee_s32 seed4_volatile = ITERATIONS; +volatile ee_s32 seed5_volatile = 0; /* Porting : Timing functions - How to capture time and convert to seconds must be ported to whatever is supported by the platform. - e.g. Read value from on board RTC, read value from cpu clock cycles performance counter etc. - Sample implementation for standard time.h and windows.h definitions included. + How to capture time and convert to seconds must be ported to whatever is + supported by the platform. e.g. Read value from on board RTC, read value from + cpu clock cycles performance counter etc. Sample implementation for standard + time.h and windows.h definitions included. */ -CORETIMETYPE barebones_clock() { - #error "You must implement a method to measure time in barebones_clock()! This function should return current time.\n" +CORETIMETYPE +barebones_clock() +{ +#error \ + "You must implement a method to measure time in barebones_clock()! This function should return current time.\n" } /* Define : TIMER_RES_DIVIDER - Divider to trade off timer resolution and total time that can be measured. + Divider to trade off timer resolution and total time that can be + measured. - Use lower values to increase resolution, but make sure that overflow 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 + Use lower values to increase resolution, but make sure that overflow + 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 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; /* Function : start_time - This function will be called right before starting the timed portion of the benchmark. + This function will be called right before starting the timed portion of + the benchmark. - Implementation may be capturing a system timer (as implemented in the example code) - or zeroing some system parameters - e.g. setting the cpu clocks cycles to 0. + Implementation may be capturing a system timer (as implemented in the + 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. + This function will be called right after ending the timed portion of the + benchmark. - Implementation may be capturing a system timer (as implemented in the example code) - or other system parameters - e.g. reading the current value of cpu cycles counter. + Implementation may be capturing a system timer (as implemented in the + 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. - - Actual value returned may be cpu cycles, milliseconds or any other value, - as long as it can be converted to seconds by . - This methodology is taken to accomodate any hardware or simulated platform. - The sample implementation returns millisecs by default, - and the resolution is controlled by + Return an abstract "ticks" number that signifies time on the system. + + Actual value returned may be cpu cycles, milliseconds or any other + value, as long as it can be converted to seconds by . This + methodology is taken to accomodate any hardware or simulated platform. The + sample implementation returns millisecs by default, and the resolution is + controlled by */ -CORE_TICKS get_time(void) { - CORE_TICKS elapsed=(CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val)); - return elapsed; +CORE_TICKS +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. + Convert the value returned by get_time to seconds. - The type is used to accomodate systems with no support for floating point. - Default implementation implemented by the EE_TICKS_PER_SEC macro above. + The type is used to accomodate systems with no support for + 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; +ee_u32 default_num_contexts = 1; /* Function : portable_init - Target specific initialization code - Test for some common mistakes. + Target specific initialization code + Test for some common mistakes. */ -void portable_init(core_portable *p, int *argc, char *argv[]) +void +portable_init(core_portable *p, int *argc, char *argv[]) { - #error "Call board initialization routines in portable init (if needed), in particular initialize UART!\n" - 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; +#error \ + "Call board initialization routines in portable init (if needed), in particular initialize UART!\n" + 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; } /* Function : portable_fini - Target specific final code + Target specific final code */ -void portable_fini(core_portable *p) +void +portable_fini(core_portable *p) { - p->portable_id=0; + p->portable_id = 0; } - - diff --git a/riscv-coremark/coremark/barebones/core_portme.h b/riscv-coremark/coremark/barebones/core_portme.h old mode 100755 new mode 100644 index 23a155888..55f643bf3 --- a/riscv-coremark/coremark/barebones/core_portme.h +++ b/riscv-coremark/coremark/barebones/core_portme.h @@ -16,178 +16,189 @@ limitations under the License. Original Author: Shay Gal-on */ /* Topic : Description - This file contains configuration constants required to execute on different platforms + This file contains configuration constants required to execute on + different platforms */ #ifndef CORE_PORTME_H #define CORE_PORTME_H /************************/ /* Data types and settings */ /************************/ -/* Configuration : HAS_FLOAT - Define to 1 if the platform supports floating point. +/* Configuration : HAS_FLOAT + Define to 1 if the platform supports floating point. */ -#ifndef HAS_FLOAT +#ifndef HAS_FLOAT #define HAS_FLOAT 1 #endif /* Configuration : HAS_TIME_H - Define to 1 if platform has the time.h header file, - and implementation of functions thereof. + Define to 1 if platform has the time.h header file, + and implementation of functions thereof. */ #ifndef HAS_TIME_H #define HAS_TIME_H 1 #endif /* Configuration : USE_CLOCK - Define to 1 if platform has the time.h header file, - and implementation of functions thereof. + Define to 1 if platform has the time.h header file, + and implementation of functions thereof. */ #ifndef USE_CLOCK #define USE_CLOCK 1 #endif /* Configuration : HAS_STDIO - Define to 1 if the platform has stdio.h. + Define to 1 if the platform has stdio.h. */ #ifndef HAS_STDIO #define HAS_STDIO 0 #endif /* Configuration : HAS_PRINTF - Define to 1 if the platform has stdio.h and implements the printf function. + Define to 1 if the platform has stdio.h and implements the printf + function. */ #ifndef HAS_PRINTF #define HAS_PRINTF 0 #endif - /* Definitions : COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION - Initialize these strings per platform + Initialize these strings per platform */ -#ifndef COMPILER_VERSION - #ifdef __GNUC__ - #define COMPILER_VERSION "GCC"__VERSION__ - #else - #define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)" - #endif +#ifndef COMPILER_VERSION +#ifdef __GNUC__ +#define COMPILER_VERSION "GCC"__VERSION__ +#else +#define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)" #endif -#ifndef COMPILER_FLAGS - #define COMPILER_FLAGS FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */ #endif -#ifndef MEM_LOCATION - #define MEM_LOCATION "STACK" +#ifndef COMPILER_FLAGS +#define COMPILER_FLAGS \ + FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */ +#endif +#ifndef MEM_LOCATION +#define MEM_LOCATION "STACK" #endif /* Data Types : - To avoid compiler issues, define the data types that need ot be used for 8b, 16b and 32b in . - - *Imprtant* : - ee_ptr_int needs to be the data type used to hold pointers, otherwise coremark may fail!!! + To avoid compiler issues, define the data types that need ot be used for + 8b, 16b and 32b in . + + *Imprtant* : + ee_ptr_int needs to be the data type used to hold pointers, otherwise + coremark may fail!!! */ -typedef signed short ee_s16; +typedef signed short ee_s16; typedef unsigned short ee_u16; -typedef signed int ee_s32; -typedef double ee_f32; -typedef unsigned char ee_u8; -typedef unsigned int ee_u32; -typedef ee_u32 ee_ptr_int; -typedef size_t ee_size_t; +typedef signed int ee_s32; +typedef double ee_f32; +typedef unsigned char ee_u8; +typedef unsigned int ee_u32; +typedef ee_u32 ee_ptr_int; +typedef size_t ee_size_t; #define NULL ((void *)0) /* align_mem : - This macro is used to align an offset to point to a 32b value. It is used in the Matrix algorithm to initialize the input memory blocks. + This macro is used to align an offset to point to a 32b value. It is + used in the Matrix algorithm to initialize the input memory blocks. */ -#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x) - 1) & ~3)) +#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x)-1) & ~3)) /* Configuration : CORE_TICKS - Define type of return from the timing functions. + Define type of return from the timing functions. */ -#define CORETIMETYPE ee_u32 +#define CORETIMETYPE ee_u32 typedef ee_u32 CORE_TICKS; /* Configuration : SEED_METHOD - Defines method to get seed values that cannot be computed at compile time. - - Valid values : - SEED_ARG - from command line. - SEED_FUNC - from a system function. - SEED_VOLATILE - from volatile variables. + Defines method to get seed values that cannot be computed at compile + time. + + Valid values : + SEED_ARG - from command line. + SEED_FUNC - from a system function. + SEED_VOLATILE - from volatile variables. */ #ifndef SEED_METHOD #define SEED_METHOD SEED_VOLATILE #endif /* Configuration : MEM_METHOD - Defines method to get a block of memry. - - Valid values : - MEM_MALLOC - for platforms that implement malloc and have malloc.h. - MEM_STATIC - to use a static memory array. - MEM_STACK - to allocate the data block on the stack (NYI). + Defines method to get a block of memry. + + Valid values : + MEM_MALLOC - for platforms that implement malloc and have malloc.h. + MEM_STATIC - to use a static memory array. + MEM_STACK - to allocate the data block on the stack (NYI). */ #ifndef MEM_METHOD #define MEM_METHOD MEM_STACK #endif /* Configuration : MULTITHREAD - Define for parallel execution - - Valid values : - 1 - only one context (default). - N>1 - will execute N copies in parallel. - - Note : - If this flag is defined to more then 1, an implementation for launching parallel contexts must be defined. - - Two sample implementations are provided. Use or to enable them. - - It is valid to have a different implementation of and in , - to fit a particular architecture. + Define for parallel execution + + Valid values : + 1 - only one context (default). + N>1 - will execute N copies in parallel. + + Note : + If this flag is defined to more then 1, an implementation for launching + parallel contexts must be defined. + + Two sample implementations are provided. Use or + to enable them. + + It is valid to have a different implementation of + and in , to fit a particular architecture. */ #ifndef MULTITHREAD #define MULTITHREAD 1 #define USE_PTHREAD 0 -#define USE_FORK 0 -#define USE_SOCKET 0 +#define USE_FORK 0 +#define USE_SOCKET 0 #endif /* Configuration : MAIN_HAS_NOARGC - Needed if platform does not support getting arguments to main. - - Valid values : - 0 - argc/argv to main is supported - 1 - argc/argv to main is not supported - - Note : - This flag only matters if MULTITHREAD has been defined to a value greater then 1. + Needed if platform does not support getting arguments to main. + + Valid values : + 0 - argc/argv to main is supported + 1 - argc/argv to main is not supported + + Note : + This flag only matters if MULTITHREAD has been defined to a value + greater then 1. */ -#ifndef MAIN_HAS_NOARGC +#ifndef MAIN_HAS_NOARGC #define MAIN_HAS_NOARGC 0 #endif /* Configuration : MAIN_HAS_NORETURN - Needed if platform does not support returning a value from main. - - Valid values : - 0 - main returns an int, and return value will be 0. - 1 - platform does not support returning a value from main + Needed if platform does not support returning a value from main. + + Valid values : + 0 - main returns an int, and return value will be 0. + 1 - platform does not support returning a value from main */ #ifndef MAIN_HAS_NORETURN #define MAIN_HAS_NORETURN 0 #endif /* Variable : default_num_contexts - Not used for this simple port, must cintain the value 1. + Not used for this simple port, must cintain the value 1. */ extern ee_u32 default_num_contexts; -typedef struct CORE_PORTABLE_S { - ee_u8 portable_id; +typedef struct CORE_PORTABLE_S +{ + ee_u8 portable_id; } core_portable; /* target specific init/fini */ void portable_init(core_portable *p, int *argc, char *argv[]); void portable_fini(core_portable *p); -#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) && !defined(VALIDATION_RUN) -#if (TOTAL_DATA_SIZE==1200) +#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) \ + && !defined(VALIDATION_RUN) +#if (TOTAL_DATA_SIZE == 1200) #define PROFILE_RUN 1 -#elif (TOTAL_DATA_SIZE==2000) +#elif (TOTAL_DATA_SIZE == 2000) #define PERFORMANCE_RUN 1 #else #define VALIDATION_RUN 1 diff --git a/riscv-coremark/coremark/barebones/cvt.c b/riscv-coremark/coremark/barebones/cvt.c old mode 100755 new mode 100644 index ee0506d54..333e8ead2 --- a/riscv-coremark/coremark/barebones/cvt.c +++ b/riscv-coremark/coremark/barebones/cvt.c @@ -17,101 +17,111 @@ limitations under the License. #define CVTBUFSIZE 80 static char CVTBUF[CVTBUFSIZE]; -static char *cvt(double arg, int ndigits, int *decpt, int *sign, char *buf, int eflag) +static char * +cvt(double arg, int ndigits, int *decpt, int *sign, char *buf, int eflag) { - int r2; - double fi, fj; - char *p, *p1; + int r2; + double fi, fj; + char * p, *p1; - if (ndigits < 0) ndigits = 0; - if (ndigits >= CVTBUFSIZE - 1) ndigits = CVTBUFSIZE - 2; - r2 = 0; - *sign = 0; - p = &buf[0]; - if (arg < 0) - { - *sign = 1; - arg = -arg; - } - arg = modf(arg, &fi); - p1 = &buf[CVTBUFSIZE]; + if (ndigits < 0) + ndigits = 0; + if (ndigits >= CVTBUFSIZE - 1) + ndigits = CVTBUFSIZE - 2; + r2 = 0; + *sign = 0; + p = &buf[0]; + if (arg < 0) + { + *sign = 1; + arg = -arg; + } + arg = modf(arg, &fi); + p1 = &buf[CVTBUFSIZE]; - if (fi != 0) - { - p1 = &buf[CVTBUFSIZE]; - while (fi != 0) + if (fi != 0) { - fj = modf(fi / 10, &fi); - *--p1 = (int)((fj + .03) * 10) + '0'; - r2++; + p1 = &buf[CVTBUFSIZE]; + while (fi != 0) + { + fj = modf(fi / 10, &fi); + *--p1 = (int)((fj + .03) * 10) + '0'; + r2++; + } + while (p1 < &buf[CVTBUFSIZE]) + *p++ = *p1++; } - while (p1 < &buf[CVTBUFSIZE]) *p++ = *p1++; - } - else if (arg > 0) - { - while ((fj = arg * 10) < 1) + else if (arg > 0) { - arg = fj; - r2--; + while ((fj = arg * 10) < 1) + { + arg = fj; + r2--; + } } - } - p1 = &buf[ndigits]; - if (eflag == 0) p1 += r2; - *decpt = r2; - if (p1 < &buf[0]) - { - buf[0] = '\0'; + p1 = &buf[ndigits]; + if (eflag == 0) + p1 += r2; + *decpt = r2; + if (p1 < &buf[0]) + { + buf[0] = '\0'; + return buf; + } + while (p <= p1 && p < &buf[CVTBUFSIZE]) + { + arg *= 10; + arg = modf(arg, &fj); + *p++ = (int)fj + '0'; + } + if (p1 >= &buf[CVTBUFSIZE]) + { + buf[CVTBUFSIZE - 1] = '\0'; + return buf; + } + p = p1; + *p1 += 5; + while (*p1 > '9') + { + *p1 = '0'; + if (p1 > buf) + ++*--p1; + else + { + *p1 = '1'; + (*decpt)++; + if (eflag == 0) + { + if (p > buf) + *p = '0'; + p++; + } + } + } + *p = '\0'; return buf; - } - while (p <= p1 && p < &buf[CVTBUFSIZE]) - { - arg *= 10; - arg = modf(arg, &fj); - *p++ = (int) fj + '0'; - } - if (p1 >= &buf[CVTBUFSIZE]) - { - buf[CVTBUFSIZE - 1] = '\0'; - return buf; - } - p = p1; - *p1 += 5; - while (*p1 > '9') - { - *p1 = '0'; - if (p1 > buf) - ++*--p1; - else - { - *p1 = '1'; - (*decpt)++; - if (eflag == 0) - { - if (p > buf) *p = '0'; - p++; - } - } - } - *p = '\0'; - return buf; } -char *ecvt(double arg, int ndigits, int *decpt, int *sign) +char * +ecvt(double arg, int ndigits, int *decpt, int *sign) { - return cvt(arg, ndigits, decpt, sign, CVTBUF, 1); + return cvt(arg, ndigits, decpt, sign, CVTBUF, 1); } -char *ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf) +char * +ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf) { - return cvt(arg, ndigits, decpt, sign, buf, 1); + return cvt(arg, ndigits, decpt, sign, buf, 1); } -char *fcvt(double arg, int ndigits, int *decpt, int *sign) +char * +fcvt(double arg, int ndigits, int *decpt, int *sign) { - return cvt(arg, ndigits, decpt, sign, CVTBUF, 0); + return cvt(arg, ndigits, decpt, sign, CVTBUF, 0); } -char *fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf) +char * +fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf) { - return cvt(arg, ndigits, decpt, sign, buf, 0); + return cvt(arg, ndigits, decpt, sign, buf, 0); } diff --git a/riscv-coremark/coremark/barebones/ee_printf.c b/riscv-coremark/coremark/barebones/ee_printf.c old mode 100755 new mode 100644 index b08f59dbe..f2d362dc0 --- a/riscv-coremark/coremark/barebones/ee_printf.c +++ b/riscv-coremark/coremark/barebones/ee_printf.c @@ -17,581 +17,684 @@ limitations under the License. #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 UPPERCASE (1<<6) /* 'ABCDEF' */ +#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) +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; + const char *sc; + for (sc = s; *sc != '\0' && count--; ++sc) + ; + return sc - s; } -static int skip_atoi(const char **s) +static int +skip_atoi(const char **s) { - int i = 0; - while (is_digit(**s)) i = i*10 + *((*s)++) - '0'; - return i; + 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) +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; + 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; - - c = (type & ZEROPAD) ? '0' : ' '; - sign = 0; - if (type & SIGN) - { - if (num < 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) { - sign = '-'; - num = -num; - size--; + if (num < 0) + { + sign = '-'; + num = -num; + size--; + } + else if (type & PLUS) + { + sign = '+'; + size--; + } + else if (type & SPACE) + { + sign = ' '; + size--; + } } - else if (type & PLUS) + + if (type & HEX_PREP) { - sign = '+'; - size--; + if (base == 16) + size -= 2; + else if (base == 8) + size--; } - else if (type & SPACE) - { - sign = ' '; - size--; - } - } - if (type & HEX_PREP) - { - if (base == 16) - size -= 2; - else if (base == 8) - size--; - } + i = 0; - 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]; - 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; - - 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]; - while (len < size--) *str++ = ' '; - - return str; -} - -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]; - - if (n == 0) - tmp[len++] = digits[0]; + if (num == 0) + tmp[i++] = '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]; + while (num != 0) + { + tmp[i++] = dig[((unsigned long)num) % (unsigned)base]; + num = ((unsigned long)num) / (unsigned)base; + } } - } - if (!(type & LEFT)) while (len < size--) *str++ = ' '; - for (i = 0; i < len; ++i) *str++ = tmp[i]; - while (len < size--) *str++ = ' '; + if (i > precision) + precision = i; + size -= precision; + if (!(type & (ZEROPAD | LEFT))) + while (size-- > 0) + *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; + + 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]; + while (len < size--) + *str++ = ' '; + + return str; +} + +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]; + + 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]; + } + } + + if (!(type & LEFT)) + while (len < size--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = tmp[i]; + while (len < size--) + *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); -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++; +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++; } -static void parse_float(double value, char *buffer, char fmt, int precision) +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; + 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') - { - digits = ecvtbuf(value, precision, &decpt, &sign, cvtbuf); - magnitude = decpt - 1; - if (magnitude < -4 || magnitude > precision - 1) + if (fmt == 'G' || fmt == 'E') { - fmt = 'e'; - precision -= 1; + capexp = 1; + fmt += 'a' - 'A'; } - else + + if (fmt == 'g') { - fmt = 'f'; - precision -= decpt; - } - } - - 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) + digits = ecvtbuf(value, precision, &decpt, &sign, cvtbuf); + magnitude = decpt - 1; + if (magnitude < -4 || magnitude > precision - 1) { - if (pos++ == decpt) *buffer++ = '.'; - *buffer++ = *digits++; + fmt = 'e'; + precision -= 1; + } + else + { + fmt = 'f'; + precision -= decpt; } - } } - else + + if (fmt == 'e') { - *buffer++ = '0'; - if (precision > 0) - { - *buffer++ = '.'; - for (pos = 0; pos < precision; pos++) *buffer++ = '0'; - } + 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; } - } - - *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) + else if (fmt == 'f') { - buffer[n + 1] = buffer[n]; - n--; + 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 = '.'; - } - else - { - *buffer++ = '.'; *buffer = '\0'; - } } -static void cropzeros(char *buffer) +static void +decimal_point(char *buffer) { - char *stop; + while (*buffer) + { + if (*buffer == '.') + return; + if (*buffer == 'e' || *buffer == 'E') + break; + buffer++; + } - 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; - } + if (*buffer) + { + int n = strnlen(buffer, 256); + while (n > 0) + { + buffer[n + 1] = buffer[n]; + n--; + } + + *buffer = '.'; + } + else + { + *buffer++ = '.'; + *buffer = '\0'; + } } -static char *flt(char *str, double num, int size, int precision, char fmt, int flags) +static void +cropzeros(char *buffer) { - char tmp[80]; - char c, sign; - int n, i; + char *stop; - // 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) + while (*buffer && *buffer != '.') + buffer++; + if (*buffer++) { - sign = '-'; - num = -num; - size--; + while (*buffer && *buffer != 'e' && *buffer != 'E') + buffer++; + stop = buffer--; + while (*buffer == '0') + buffer--; + if (*buffer == '.') + buffer--; + while (buffer != stop) + *++buffer = 0; } - else if (flags & PLUS) +} + +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) { - sign = '+'; - size--; + if (num < 0.0) + { + sign = '-'; + num = -num; + size--; + } + else if (flags & PLUS) + { + sign = '+'; + size--; + } + else if (flags & SPACE) + { + sign = ' '; + size--; + } } - else if (flags & SPACE) - { - sign = ' '; - size--; - } - } - // Compute the precision value - if (precision < 0) - precision = 6; // Default precision: 6 + // Compute the precision value + if (precision < 0) + precision = 6; // Default precision: 6 - // Convert floating point number to text - parse_float(num, tmp, fmt, precision); + // 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); + if ((flags & HEX_PREP) && precision == 0) + decimal_point(tmp); + if (fmt == 'g' && !(flags & HEX_PREP)) + cropzeros(tmp); - n = strnlen(tmp,256); + 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++ = ' '; + // 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; + return str; } #endif -static int ee_vsprintf(char *buf, const char *fmt, va_list args) +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 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 != '%') + for (str = buf; *fmt; 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; - } - - // 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 conversion qualifier - qualifier = -1; - if (*fmt == 'l' || *fmt == 'L') - { - qualifier = *fmt; - fmt++; - } - - // 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; - - 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) + if (*fmt != '%') { - field_width = 2 * sizeof(void *); - flags |= ZEROPAD; + *str++ = *fmt; + continue; } - str = number(str, (unsigned long) va_arg(args, void *), 16, field_width, precision, flags); - continue; - case 'A': - flags |= UPPERCASE; + // 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; + } - 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; + // 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; + } + } - // Integer number formats - set up the flags and "break" - case 'o': - base = 8; - break; + // 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; + } - case 'X': - flags |= UPPERCASE; + // Get the conversion qualifier + qualifier = -1; + if (*fmt == 'l' || *fmt == 'L') + { + qualifier = *fmt; + fmt++; + } - case 'x': - base = 16; - break; + // Default base + base = 10; - case 'd': - case 'i': - flags |= SIGN; + 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 'u': - break; + 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 '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; + + // Integer number formats - set up the flags and "break" + case 'o': + base = 8; + break; + + case 'X': + flags |= UPPERCASE; + + case 'x': + base = 16; + break; + + case 'd': + case 'i': + flags |= SIGN; + + 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; + 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 - --fmt; - continue; + num = va_arg(args, unsigned int); + + str = number(str, num, base, field_width, precision, flags); } - 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; + *str = '\0'; + return str - buf; } -void uart_send_char(char c) { -#error "You must implement the method uart_send_char to use this file!\n"; -/* Output of a char to a UART usually follows the following model: - Wait until UART is ready - Write char to UART - Wait until UART is done - - Or in code: - while (*UART_CONTROL_ADDRESS != UART_READY); - *UART_DATA_ADDRESS = c; - while (*UART_CONTROL_ADDRESS != UART_READY); - - Check the UART sample code on your platform or the board documentation. -*/ -} - -int ee_printf(const char *fmt, ...) +void +uart_send_char(char c) { - char buf[256],*p; - va_list args; - int n=0; +#error "You must implement the method uart_send_char to use this file!\n"; + /* Output of a char to a UART usually follows the following model: + Wait until UART is ready + Write char to UART + Wait until UART is done - va_start(args, fmt); - ee_vsprintf(buf, fmt, args); - va_end(args); - p=buf; - while (*p) { - uart_send_char(*p); - n++; - p++; - } + Or in code: + while (*UART_CONTROL_ADDRESS != UART_READY); + *UART_DATA_ADDRESS = c; + while (*UART_CONTROL_ADDRESS != UART_READY); - return n; + Check the UART sample code on your platform or the board + documentation. + */ } +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/riscv-coremark/coremark/core_list_join.c b/riscv-coremark/coremark/core_list_join.c index e5dba39e3..d9c256d4b 100644 --- a/riscv-coremark/coremark/core_list_join.c +++ b/riscv-coremark/coremark/core_list_join.c @@ -17,562 +17,579 @@ Original Author: Shay Gal-on */ #include "coremark.h" -#include -#include /* Topic: Description - Benchmark using a linked list. + Benchmark using a linked list. + + Linked list is a common data structure used in many applications. + + For our purposes, this will excercise the memory units of the processor. + In particular, usage of the list pointers to find and alter data. + + We are not using Malloc since some platforms do not support this +library. + + Instead, the memory block being passed in is used to create a list, + and the benchmark takes care not to add more items then can be + accomodated by the memory block. The porting layer will make sure + that we have a valid memory block. + + All operations are done in place, without using any extra memory. + + The list itself contains list pointers and pointers to data items. + Data items contain the following: + + idx - An index that captures the initial order of the list. + data - Variable data initialized based on the input parameters. The 16b +are divided as follows: o Upper 8b are backup of original data. o Bit 7 +indicates if the lower 7 bits are to be used as is or calculated. o Bits 0-2 +indicate type of operation to perform to get a 7b value. o Bits 3-6 provide +input for the operation. - Linked list is a common data structure used in many applications. - - For our purposes, this will excercise the memory units of the processor. - In particular, usage of the list pointers to find and alter data. - - We are not using Malloc since some platforms do not support this library. - - Instead, the memory block being passed in is used to create a list, - and the benchmark takes care not to add more items then can be - accomodated by the memory block. The porting layer will make sure - that we have a valid memory block. - - All operations are done in place, without using any extra memory. - - The list itself contains list pointers and pointers to data items. - Data items contain the following: - - idx - An index that captures the initial order of the list. - data - Variable data initialized based on the input parameters. The 16b are divided as follows: - o Upper 8b are backup of original data. - o Bit 7 indicates if the lower 7 bits are to be used as is or calculated. - o Bits 0-2 indicate type of operation to perform to get a 7b value. - o Bits 3-6 provide input for the operation. - */ /* local functions */ -list_head *core_list_find(list_head *list,list_data *info); +list_head *core_list_find(list_head *list, list_data *info); list_head *core_list_reverse(list_head *list); list_head *core_list_remove(list_head *item); -list_head *core_list_undo_remove(list_head *item_removed, list_head *item_modified); -list_head *core_list_insert_new(list_head *insert_point - , list_data *info, list_head **memblock, list_data **datablock - , list_head *memblock_end, list_data *datablock_end); -typedef ee_s32(*list_cmp)(list_data *a, list_data *b, core_results *res); -list_head *core_list_mergesort(list_head *list, list_cmp cmp, core_results *res); +list_head *core_list_undo_remove(list_head *item_removed, + list_head *item_modified); +list_head *core_list_insert_new(list_head * insert_point, + list_data * info, + list_head **memblock, + list_data **datablock, + list_head * memblock_end, + list_data * datablock_end); +typedef ee_s32 (*list_cmp)(list_data *a, list_data *b, core_results *res); +list_head *core_list_mergesort(list_head * list, + list_cmp cmp, + core_results *res); -ee_s16 calc_func(ee_s16 *pdata, core_results *res) { - ee_s16 data=*pdata; - ee_s16 retval; - ee_u8 optype=(data>>7) & 1; /* bit 7 indicates if the function result has been cached */ - if (optype) /* if cached, use cache */ - return (data & 0x007f); - else { /* otherwise calculate and cache the result */ - ee_s16 flag=data & 0x7; /* bits 0-2 is type of function to perform */ - ee_s16 dtype=((data>>3) & 0xf); /* bits 3-6 is specific data for the operation */ - dtype |= dtype << 4; /* replicate the lower 4 bits to get an 8b value */ - switch (flag) { - case 0: - if (dtype<0x22) /* set min period for bit corruption */ - dtype=0x22; - retval=core_bench_state(res->size,res->memblock[3],res->seed1,res->seed2,dtype,res->crc); - if (res->crcstate==0) - res->crcstate=retval; - break; - case 1: - retval=core_bench_matrix(&(res->mat),dtype,res->crc); - if (res->crcmatrix==0) - res->crcmatrix=retval; - break; - default: - retval=data; - break; - } - res->crc=crcu16(retval,res->crc); - retval &= 0x007f; - *pdata = (data & 0xff00) | 0x0080 | retval; /* cache the result */ - return retval; - } +ee_s16 +calc_func(ee_s16 *pdata, core_results *res) +{ + ee_s16 data = *pdata; + ee_s16 retval; + ee_u8 optype + = (data >> 7) + & 1; /* bit 7 indicates if the function result has been cached */ + if (optype) /* if cached, use cache */ + return (data & 0x007f); + else + { /* otherwise calculate and cache the result */ + ee_s16 flag = data & 0x7; /* bits 0-2 is type of function to perform */ + ee_s16 dtype + = ((data >> 3) + & 0xf); /* bits 3-6 is specific data for the operation */ + dtype |= dtype << 4; /* replicate the lower 4 bits to get an 8b value */ + switch (flag) + { + case 0: + if (dtype < 0x22) /* set min period for bit corruption */ + dtype = 0x22; + retval = core_bench_state(res->size, + res->memblock[3], + res->seed1, + res->seed2, + dtype, + res->crc); + if (res->crcstate == 0) + res->crcstate = retval; + break; + case 1: + retval = core_bench_matrix(&(res->mat), dtype, res->crc); + if (res->crcmatrix == 0) + res->crcmatrix = retval; + break; + default: + retval = data; + break; + } + res->crc = crcu16(retval, res->crc); + retval &= 0x007f; + *pdata = (data & 0xff00) | 0x0080 | retval; /* cache the result */ + return retval; + } } /* Function: cmp_complex - Compare the data item in a list cell. + Compare the data item in a list cell. - Can be used by mergesort. + Can be used by mergesort. */ -ee_s32 cmp_complex(list_data *a, list_data *b, core_results *res) { - ee_s16 val1=calc_func(&(a->data16),res); - ee_s16 val2=calc_func(&(b->data16),res); - return val1 - val2; +ee_s32 +cmp_complex(list_data *a, list_data *b, core_results *res) +{ + ee_s16 val1 = calc_func(&(a->data16), res); + ee_s16 val2 = calc_func(&(b->data16), res); + return val1 - val2; } /* Function: cmp_idx - Compare the idx item in a list cell, and regen the data. + Compare the idx item in a list cell, and regen the data. - Can be used by mergesort. + Can be used by mergesort. */ -ee_s32 cmp_idx(list_data *a, list_data *b, core_results *res) { - if (res==NULL) { - a->data16 = (a->data16 & 0xff00) | (0x00ff & (a->data16>>8)); - b->data16 = (b->data16 & 0xff00) | (0x00ff & (b->data16>>8)); - } - return a->idx - b->idx; +ee_s32 +cmp_idx(list_data *a, list_data *b, core_results *res) +{ + if (res == NULL) + { + a->data16 = (a->data16 & 0xff00) | (0x00ff & (a->data16 >> 8)); + b->data16 = (b->data16 & 0xff00) | (0x00ff & (b->data16 >> 8)); + } + return a->idx - b->idx; } -void ehitoa(int value, char *str, int base){ - if (value>100000) strcpy(str,"too big"); - else{ - int places[6] = {100000, 10000, 1000, 100, 10, 1}; - int col; - int pv; - for(col = 0; col<6; col++){ - pv = 0; - while (value >= places[col]){ - value=value -places[col]; - pv++; - - } - str[col]=pv+'0'; - } - str[6]=0; - } -} - -void copy_info(list_data *to,list_data *from) { - to->data16=from->data16; - to->idx=from->idx; +void +copy_info(list_data *to, list_data *from) +{ + to->data16 = from->data16; + to->idx = from->idx; } /* Benchmark for linked list: - - Try to find multiple data items. - - List sort - - Operate on data from list (crc) - - Single remove/reinsert - * At the end of this function, the list is back to original state + - Try to find multiple data items. + - List sort + - Operate on data from list (crc) + - Single remove/reinsert + * At the end of this function, the list is back to original state */ -ee_u16 core_bench_list(core_results *res, ee_s16 finder_idx) { - ee_u16 retval=0; - ee_u16 found=0,missed=0; - list_head *list=res->list; - ee_s16 find_num=res->seed3; - list_head *this_find; - list_head *finder, *remover; - list_data info; - ee_s16 i; - ee_printf("entered corebenchlist \n"); - info.idx=finder_idx; - /* find values in the list, and change the list each time (reverse and cache if value found) */ - for (i=0; inext->info->data16 >> 8) & 1; - ee_printf("if statement \n"); - } - else { - found++; - ee_printf("else statement \n"); - if (this_find->info->data16 & 0x1) /* use found value */ - retval+=(this_find->info->data16 >> 9) & 1; - /* and cache next item at the head of the list (if any) */ - if (this_find->next != NULL) { - finder = this_find->next; - this_find->next = finder->next; - finder->next=list->next; - list->next=finder; - } - } - if (info.idx>=0) - info.idx++; +ee_u16 +core_bench_list(core_results *res, ee_s16 finder_idx) +{ + ee_u16 retval = 0; + ee_u16 found = 0, missed = 0; + list_head *list = res->list; + ee_s16 find_num = res->seed3; + list_head *this_find; + list_head *finder, *remover; + list_data info; + ee_s16 i; + + info.idx = finder_idx; + /* find values in the list, and change the list each time + * (reverse and cache if value found) */ + for (i = 0; i < find_num; i++) + { + info.data16 = (i & 0xff); + this_find = core_list_find(list, &info); + list = core_list_reverse(list); + if (this_find == NULL) + { + missed++; + retval += (list->next->info->data16 >> 8) & 1; + } + else + { + found++; + if (this_find->info->data16 & 0x1) /* use found value */ + retval += (this_find->info->data16 >> 9) & 1; + /* and cache next item at the head of the list (if any) */ + if (this_find->next != NULL) + { + finder = this_find->next; + this_find->next = finder->next; + finder->next = list->next; + list->next = finder; + } + } + if (info.idx >= 0) + info.idx++; #if CORE_DEBUG - ee_printf("List find %d: [%d,%d,%d]\n",i,retval,missed,found); + ee_printf("List find %d: [%d,%d,%d]\n", i, retval, missed, found); #endif - } - retval+=found*4-missed; - /* sort the list by data content and remove one item*/ - if (finder_idx>0) - list=core_list_mergesort(list,cmp_complex,res); - remover=core_list_remove(list->next); - /* CRC data content of list from location of index N forward, and then undo remove */ - finder=core_list_find(list,&info); - if (!finder) - finder=list->next; - while (finder) { - retval=crc16(list->info->data16,retval); - finder=finder->next; - } + } + retval += found * 4 - missed; + /* sort the list by data content and remove one item*/ + if (finder_idx > 0) + list = core_list_mergesort(list, cmp_complex, res); + remover = core_list_remove(list->next); + /* CRC data content of list from location of index N forward, and then undo + * remove */ + finder = core_list_find(list, &info); + if (!finder) + finder = list->next; + while (finder) + { + retval = crc16(list->info->data16, retval); + finder = finder->next; + } #if CORE_DEBUG - ee_printf("List sort 1: %04x\n",retval); + ee_printf("List sort 1: %04x\n", retval); #endif - remover=core_list_undo_remove(remover,list->next); - /* sort the list by index, in effect returning the list to original state */ - list=core_list_mergesort(list,cmp_idx,NULL); - /* CRC data content of list */ - finder=list->next; - while (finder) { - retval=crc16(list->info->data16,retval); - finder=finder->next; - } + remover = core_list_undo_remove(remover, list->next); + /* sort the list by index, in effect returning the list to original state */ + list = core_list_mergesort(list, cmp_idx, NULL); + /* CRC data content of list */ + finder = list->next; + while (finder) + { + retval = crc16(list->info->data16, retval); + finder = finder->next; + } #if CORE_DEBUG - ee_printf("List sort 2: %04x\n",retval); + ee_printf("List sort 2: %04x\n", retval); #endif - return retval; + return retval; } /* Function: core_list_init - Initialize list with data. + Initialize list with data. - Parameters: - blksize - Size of memory to be initialized. - memblock - Pointer to memory block. - seed - Actual values chosen depend on the seed parameter. - The seed parameter MUST be supplied from a source that cannot be determined at compile time + Parameters: + blksize - Size of memory to be initialized. + memblock - Pointer to memory block. + seed - Actual values chosen depend on the seed parameter. + The seed parameter MUST be supplied from a source that cannot be + determined at compile time - Returns: - Pointer to the head of the list. + Returns: + Pointer to the head of the list. */ -list_head *core_list_init(ee_u32 blksize, list_head *memblock, ee_s16 seed) { - /* calculated pointers for the list */ - ee_printf("%d \n blksize", blksize); - ee_u32 per_item=16+sizeof(struct list_data_s); - ee_printf("%d \n sizeof", sizeof(struct list_data_s)); - ee_printf("%d \n per_item", per_item); - ee_u32 size=(blksize/per_item)-2; - char bufftwo[200]; - ehitoa(size, bufftwo, 10); - ee_printf(" size = %s done \n", bufftwo); - ee_printf("%d", size);/* to accomodate systems with 64b pointers, and make sure same code is executed, set max list elements */ - list_head *memblock_end=memblock+size; +list_head * +core_list_init(ee_u32 blksize, list_head *memblock, ee_s16 seed) +{ + /* calculated pointers for the list */ + ee_u32 per_item = 16 + sizeof(struct list_data_s); + ee_u32 size = (blksize / per_item) + - 2; /* to accomodate systems with 64b pointers, and make sure + same code is executed, set max list elements */ + list_head *memblock_end = memblock + size; + list_data *datablock = (list_data *)(memblock_end); + list_data *datablock_end = datablock + size; + /* some useful variables */ + ee_u32 i; + list_head *finder, *list = memblock; + list_data info; - list_data *datablock=(list_data *)(memblock_end); - list_data *datablock_end=datablock+size; - ee_printf("datablock_end"); - /* some useful variables */ - ee_u32 i; - list_head *finder,*list=memblock; - list_data info; - ehitoa(size, bufftwo, 10); - ee_printf(" size2 = %s done \n", bufftwo); + /* create a fake items for the list head and tail */ + list->next = NULL; + list->info = datablock; + list->info->idx = 0x0000; + list->info->data16 = (ee_s16)0x8080; + memblock++; + datablock++; + info.idx = 0x7fff; + info.data16 = (ee_s16)0xffff; + core_list_insert_new( + list, &info, &memblock, &datablock, memblock_end, datablock_end); - /* create a fake items for the list head and tail */ - list->next=NULL; - list->info=datablock; - list->info->idx=0x0000; - list->info->data16=(ee_s16)0x8080; - memblock++; - datablock++; - info.idx=0x7fff; - info.data16=(ee_s16)0xffff; - ehitoa(size, bufftwo, 10); - ee_printf(" size3 = %s done \n", bufftwo); - core_list_insert_new(list,&info,&memblock,&datablock,memblock_end,datablock_end); - ehitoa(size, bufftwo, 10); - ee_printf(" size4 = %s done \n", bufftwo);; - /* then insert size items */ - for (i=0; inext; - i=1; - ehitoa(i, bufftwo, 10); - ee_printf(" i = %s done \n", bufftwo); - while (finder->next!=NULL) { - ee_printf("enter while statement \n"); - if (iinfo->idx=i++; - ehitoa(i, bufftwo, 10); - ee_printf(" if i = %s done \n", bufftwo); - } - - else { - ee_u16 pat=(ee_u16)(i++ ^ seed); /* get a pseudo random number */ - finder->info->idx=0x3fff & (((i & 0x07) << 8) | pat); /* make sure the mixed items end up after the ones in sequence */ - ehitoa(i, bufftwo, 10); - ee_printf(" else i = %s done \n", bufftwo); - } - finder=finder->next; - } - ehitoa(i, bufftwo, 10); - ee_printf(" i2 = %s done \n", bufftwo); - list = core_list_mergesort(list,cmp_idx,NULL); + /* then insert size items */ + for (i = 0; i < size; i++) + { + ee_u16 datpat = ((ee_u16)(seed ^ i) & 0xf); + ee_u16 dat + = (datpat << 3) | (i & 0x7); /* alternate between algorithms */ + info.data16 = (dat << 8) | dat; /* fill the data with actual data and + upper bits with rebuild value */ + core_list_insert_new( + list, &info, &memblock, &datablock, memblock_end, datablock_end); + } + /* and now index the list so we know initial seed order of the list */ + finder = list->next; + i = 1; + while (finder->next != NULL) + { + if (i < size / 5) /* first 20% of the list in order */ + finder->info->idx = i++; + else + { + ee_u16 pat = (ee_u16)(i++ ^ seed); /* get a pseudo random number */ + finder->info->idx = 0x3fff + & (((i & 0x07) << 8) + | pat); /* make sure the mixed items end up + after the ones in sequence */ + } + finder = finder->next; + } + list = core_list_mergesort(list, cmp_idx, NULL); #if CORE_DEBUG - ee_printf("Initialized list:\n"); - finder=list; - while (finder) { - ee_printf("[%04x,%04x]",finder->info->idx,(ee_u16)finder->info->data16); - finder=finder->next; - } - ee_printf("\n"); + ee_printf("Initialized list:\n"); + finder = list; + while (finder) + { + ee_printf( + "[%04x,%04x]", finder->info->idx, (ee_u16)finder->info->data16); + finder = finder->next; + } + ee_printf("\n"); #endif - return list; + return list; } /* Function: core_list_insert - Insert an item to the list + Insert an item to the list - Parameters: - insert_point - where to insert the item. - info - data for the cell. - memblock - pointer for the list header - datablock - pointer for the list data - memblock_end - end of region for list headers - datablock_end - end of region for list data + Parameters: + insert_point - where to insert the item. + info - data for the cell. + memblock - pointer for the list header + datablock - pointer for the list data + memblock_end - end of region for list headers + datablock_end - end of region for list data - Returns: - Pointer to new item. + Returns: + Pointer to new item. */ -list_head *core_list_insert_new(list_head *insert_point, list_data *info, list_head **memblock, list_data **datablock - , list_head *memblock_end, list_data *datablock_end) { - list_head *newitem; - - if ((*memblock+1) >= memblock_end) - return NULL; - if ((*datablock+1) >= datablock_end) - return NULL; - - newitem=*memblock; - (*memblock)++; - newitem->next=insert_point->next; - insert_point->next=newitem; - - newitem->info=*datablock; - (*datablock)++; - copy_info(newitem->info,info); - - return newitem; +list_head * +core_list_insert_new(list_head * insert_point, + list_data * info, + list_head **memblock, + list_data **datablock, + list_head * memblock_end, + list_data * datablock_end) +{ + list_head *newitem; + + if ((*memblock + 1) >= memblock_end) + return NULL; + if ((*datablock + 1) >= datablock_end) + return NULL; + + newitem = *memblock; + (*memblock)++; + newitem->next = insert_point->next; + insert_point->next = newitem; + + newitem->info = *datablock; + (*datablock)++; + copy_info(newitem->info, info); + + return newitem; } /* Function: core_list_remove - Remove an item from the list. + Remove an item from the list. - Operation: - For a singly linked list, remove by copying the data from the next item - over to the current cell, and unlinking the next item. + Operation: + For a singly linked list, remove by copying the data from the next item + over to the current cell, and unlinking the next item. - Note: - since there is always a fake item at the end of the list, no need to check for NULL. + Note: + since there is always a fake item at the end of the list, no need to + check for NULL. - Returns: - Removed item. + Returns: + Removed item. */ -list_head *core_list_remove(list_head *item) { - list_data *tmp; - list_head *ret=item->next; - /* swap data pointers */ - tmp=item->info; - item->info=ret->info; - ret->info=tmp; - /* and eliminate item */ - item->next=item->next->next; - ret->next=NULL; - return ret; +list_head * +core_list_remove(list_head *item) +{ + list_data *tmp; + list_head *ret = item->next; + /* swap data pointers */ + tmp = item->info; + item->info = ret->info; + ret->info = tmp; + /* and eliminate item */ + item->next = item->next->next; + ret->next = NULL; + return ret; } /* Function: core_list_undo_remove - Undo a remove operation. + Undo a remove operation. - Operation: - Since we want each iteration of the benchmark to be exactly the same, - we need to be able to undo a remove. - Link the removed item back into the list, and switch the info items. + Operation: + Since we want each iteration of the benchmark to be exactly the same, + we need to be able to undo a remove. + Link the removed item back into the list, and switch the info items. - Parameters: - item_removed - Return value from the - item_modified - List item that was modified during + Parameters: + item_removed - Return value from the + item_modified - List item that was modified during + + Returns: + The item that was linked back to the list. - Returns: - The item that was linked back to the list. - */ -list_head *core_list_undo_remove(list_head *item_removed, list_head *item_modified) { - list_data *tmp; - /* swap data pointers */ - tmp=item_removed->info; - item_removed->info=item_modified->info; - item_modified->info=tmp; - /* and insert item */ - item_removed->next=item_modified->next; - item_modified->next=item_removed; - return item_removed; +list_head * +core_list_undo_remove(list_head *item_removed, list_head *item_modified) +{ + list_data *tmp; + /* swap data pointers */ + tmp = item_removed->info; + item_removed->info = item_modified->info; + item_modified->info = tmp; + /* and insert item */ + item_removed->next = item_modified->next; + item_modified->next = item_removed; + return item_removed; } /* Function: core_list_find - Find an item in the list + Find an item in the list - Operation: - Find an item by idx (if not 0) or specific data value + Operation: + Find an item by idx (if not 0) or specific data value - Parameters: - list - list head - info - idx or data to find + Parameters: + list - list head + info - idx or data to find - Returns: - Found item, or NULL if not found. + Returns: + Found item, or NULL if not found. */ -list_head *core_list_find(list_head *list,list_data *info) { - ee_printf("entered core_list_find \n"); - if (info->idx>=0) { - ee_printf("find if \n"); - while (list && (list->info->idx != info->idx)){ - list=list->next; - ee_printf("find while if \n");} - ee_printf("core_list_find end \n"); - return list; - } else { - ee_printf("find else"); - while (list && ((list->info->data16 & 0xff) != info->data16)){ - list=list->next; - ee_printf("find while else \n");} - ee_printf("core list find end \n"); - return list; - } +list_head * +core_list_find(list_head *list, list_data *info) +{ + if (info->idx >= 0) + { + while (list && (list->info->idx != info->idx)) + list = list->next; + return list; + } + else + { + while (list && ((list->info->data16 & 0xff) != info->data16)) + list = list->next; + return list; + } } /* Function: core_list_reverse - Reverse a list + Reverse a list - Operation: - Rearrange the pointers so the list is reversed. + Operation: + Rearrange the pointers so the list is reversed. - Parameters: - list - list head - info - idx or data to find + Parameters: + list - list head + info - idx or data to find - Returns: - Found item, or NULL if not found. + Returns: + Found item, or NULL if not found. */ -list_head *core_list_reverse(list_head *list) { - ee_printf("entered core_list_reverse"); - list_head *next=NULL, *tmp; - while (list) { - tmp=list->next; - list->next=next; - next=list; - list=tmp; - } - ee_printf("core_list_reverse done"); - return next; +list_head * +core_list_reverse(list_head *list) +{ + list_head *next = NULL, *tmp; + while (list) + { + tmp = list->next; + list->next = next; + next = list; + list = tmp; + } + return next; } /* Function: core_list_mergesort - Sort the list in place without recursion. + Sort the list in place without recursion. - Description: - Use mergesort, as for linked list this is a realistic solution. - Also, since this is aimed at embedded, care was taken to use iterative rather then recursive algorithm. - The sort can either return the list to original order (by idx) , - or use the data item to invoke other other algorithms and change the order of the list. + Description: + Use mergesort, as for linked list this is a realistic solution. + Also, since this is aimed at embedded, care was taken to use iterative + rather then recursive algorithm. The sort can either return the list to + original order (by idx) , or use the data item to invoke other other + algorithms and change the order of the list. - Parameters: - list - list to be sorted. - cmp - cmp function to use + Parameters: + list - list to be sorted. + cmp - cmp function to use - Returns: - New head of the list. + Returns: + New head of the list. - Note: - We have a special header for the list that will always be first, - but the algorithm could theoretically modify where the list starts. + Note: + We have a special header for the list that will always be first, + but the algorithm could theoretically modify where the list starts. */ -list_head *core_list_mergesort(list_head *list, list_cmp cmp, core_results *res) { +list_head * +core_list_mergesort(list_head *list, list_cmp cmp, core_results *res) +{ list_head *p, *q, *e, *tail; - ee_s32 insize, nmerges, psize, qsize, i; + ee_s32 insize, nmerges, psize, qsize, i; insize = 1; - char bufftwo[200]; - while (1) { - p = list; + + while (1) + { + p = list; list = NULL; tail = NULL; - nmerges = 0; /* count number of merges we do in this pass */ - ehitoa(nmerges, bufftwo, 10); - ee_printf(" nmerges default value = %s done \n", bufftwo); - while (p) { - nmerges++; /* there exists a merge to be done */ - ehitoa(nmerges, bufftwo, 10); - ee_printf(" current nmerges = %s done \n", bufftwo); + nmerges = 0; /* count number of merges we do in this pass */ + + while (p) + { + nmerges++; /* there exists a merge to be done */ /* step `insize' places along from p */ - q = p; + q = p; psize = 0; - ehitoa(insize, bufftwo, 10); - ee_printf(" insize = %s done \n", bufftwo); - for (i = 0; i < insize; i++) { - ehitoa(i, bufftwo, 10); - ee_printf(" i = %s done \n", bufftwo); + for (i = 0; i < insize; i++) + { psize++; - q = q->next; - if (!q) break; + q = q->next; + if (!q) + break; } /* if q hasn't fallen off end, we have two lists to merge */ qsize = insize; - ehitoa(qsize, bufftwo, 10); - ee_printf(" qsize = %s done \n", bufftwo); /* now we have two lists; merge them */ - while (psize > 0 || (qsize > 0 && q)) { + while (psize > 0 || (qsize > 0 && q)) + { - /* decide whether next element of merge comes from p or q */ - if (psize == 0) { - ee_printf("if \n"); - /* p is empty; e must come from q. */ - e = q; q = q->next; qsize--; - } else if (qsize == 0 || !q) { - ee_printf("else if \n"); - /* q is empty; e must come from p. */ - e = p; p = p->next; psize--; - } else if (cmp(p->info,q->info,res) <= 0) { - ee_printf("else if 2 \n"); - /* First element of p is lower (or same); e must come from p. */ - e = p; p = p->next; psize--; - } else { - ee_printf("else \n"); - /* First element of q is lower; e must come from q. */ - e = q; q = q->next; qsize--; - } + /* decide whether next element of merge comes from p or q */ + if (psize == 0) + { + /* p is empty; e must come from q. */ + e = q; + q = q->next; + qsize--; + } + else if (qsize == 0 || !q) + { + /* q is empty; e must come from p. */ + e = p; + p = p->next; + psize--; + } + else if (cmp(p->info, q->info, res) <= 0) + { + /* First element of p is lower (or same); e must come from + * p. */ + e = p; + p = p->next; + psize--; + } + else + { + /* First element of q is lower; e must come from q. */ + e = q; + q = q->next; + qsize--; + } - /* add the next element to the merged list */ - if (tail) { - ee_printf("tail if \n"); - tail->next = e; - } else { - ee_printf("tail else \n"); - list = e; - } - tail = e; - } + /* add the next element to the merged list */ + if (tail) + { + tail->next = e; + } + else + { + list = e; + } + tail = e; + } - /* now p has stepped `insize' places along, and q has too */ - p = q; + /* now p has stepped `insize' places along, and q has too */ + p = q; } - - tail->next = NULL; + + tail->next = NULL; /* If we have done only one merge, we're finished. */ - if (nmerges <= 1) /* allow for nmerges==0, the empty list case */ + if (nmerges <= 1) /* allow for nmerges==0, the empty list case */ return list; /* Otherwise repeat, merging lists twice the size */ insize *= 2; - ehitoa(insize, bufftwo, 10); - ee_printf(" insize2 = %s done \n", bufftwo); } #if COMPILER_REQUIRES_SORT_RETURN - return list; + return list; #endif } diff --git a/riscv-coremark/coremark/core_main.c b/riscv-coremark/coremark/core_main.c index b5d5e6da4..b1ec758bf 100644 --- a/riscv-coremark/coremark/core_main.c +++ b/riscv-coremark/coremark/core_main.c @@ -17,383 +17,431 @@ Original Author: Shay Gal-on */ /* File: core_main.c - This file contains the framework to acquire a block of memory, seed initial parameters, tun t he benchmark and report the results. + This file contains the framework to acquire a block of memory, seed + initial parameters, tun t he benchmark and report the results. */ #include "coremark.h" /* Function: iterate - Run the benchmark for a specified number of iterations. + Run the benchmark for a specified number of iterations. - Operation: - For each type of benchmarked algorithm: - a - Initialize the data block for the algorithm. - b - Execute the algorithm N times. + Operation: + For each type of benchmarked algorithm: + a - Initialize the data block for the algorithm. + b - Execute the algorithm N times. - Returns: - NULL. + Returns: + NULL. */ -static ee_u16 list_known_crc[] = {(ee_u16)0xd4b0,(ee_u16)0x3340,(ee_u16)0x6a79,(ee_u16)0xe714,(ee_u16)0xe3c1}; -static ee_u16 matrix_known_crc[] = {(ee_u16)0xbe52,(ee_u16)0x1199,(ee_u16)0x5608,(ee_u16)0x1fd7,(ee_u16)0x0747}; -static ee_u16 state_known_crc[] = {(ee_u16)0x5e47,(ee_u16)0x39bf,(ee_u16)0xe5a4,(ee_u16)0x8e3a,(ee_u16)0x8d84}; -int gg_printf(const char *fmt, ...); -int sendstring(const char *p); -void _send_char(char c); -void *iterate(void *pres) { - ee_u32 i; - ee_u16 crc; - core_results *res=(core_results *)pres; - ee_u32 iterations=res->iterations; - res->crc=0; - res->crclist=0; - res->crcmatrix=0; - res->crcstate=0; +static ee_u16 list_known_crc[] = { (ee_u16)0xd4b0, + (ee_u16)0x3340, + (ee_u16)0x6a79, + (ee_u16)0xe714, + (ee_u16)0xe3c1 }; +static ee_u16 matrix_known_crc[] = { (ee_u16)0xbe52, + (ee_u16)0x1199, + (ee_u16)0x5608, + (ee_u16)0x1fd7, + (ee_u16)0x0747 }; +static ee_u16 state_known_crc[] = { (ee_u16)0x5e47, + (ee_u16)0x39bf, + (ee_u16)0xe5a4, + (ee_u16)0x8e3a, + (ee_u16)0x8d84 }; +void * +iterate(void *pres) +{ + ee_u32 i; + ee_u16 crc; + core_results *res = (core_results *)pres; + ee_u32 iterations = res->iterations; + res->crc = 0; + res->crclist = 0; + res->crcmatrix = 0; + res->crcstate = 0; - for (i=0; icrc=crcu16(crc,res->crc); - crc=core_bench_list(res,-1); - res->crc=crcu16(crc,res->crc); - if (i==0) res->crclist=res->crc; - } - return NULL; + for (i = 0; i < iterations; i++) + { + crc = core_bench_list(res, 1); + res->crc = crcu16(crc, res->crc); + crc = core_bench_list(res, -1); + res->crc = crcu16(crc, res->crc); + if (i == 0) + res->crclist = res->crc; + } + return NULL; } -#if (SEED_METHOD==SEED_ARG) +#if (SEED_METHOD == SEED_ARG) ee_s32 get_seed_args(int i, int argc, char *argv[]); -#define get_seed(x) (ee_s16)get_seed_args(x,argc,argv) -#define get_seed_32(x) get_seed_args(x,argc,argv) +#define get_seed(x) (ee_s16) get_seed_args(x, argc, argv) +#define get_seed_32(x) get_seed_args(x, argc, argv) #else /* via function or volatile */ ee_s32 get_seed_32(int i); -#define get_seed(x) (ee_s16)get_seed_32(x) +#define get_seed(x) (ee_s16) get_seed_32(x) #endif -#if (MEM_METHOD==MEM_STATIC) +#if (MEM_METHOD == MEM_STATIC) ee_u8 static_memblk[TOTAL_DATA_SIZE]; #endif -char *mem_name[3] = {"Static","Heap","Stack"}; +char *mem_name[3] = { "Static", "Heap", "Stack" }; /* Function: main - Main entry routine for the benchmark. - This function is responsible for the following steps: + Main entry routine for the benchmark. + This function is responsible for the following steps: - 1 - Initialize input seeds from a source that cannot be determined at compile time. - 2 - Initialize memory block for use. - 3 - Run and time the benchmark. - 4 - Report results, testing the validity of the output if the seeds are known. + 1 - Initialize input seeds from a source that cannot be determined at + compile time. 2 - Initialize memory block for use. 3 - Run and time the + benchmark. 4 - Report results, testing the validity of the output if the + seeds are known. - Arguments: - 1 - first seed : Any value - 2 - second seed : Must be identical to first for iterations to be identical - 3 - third seed : Any value, should be at least an order of magnitude less then the input size, but bigger then 32. - 4 - Iterations : Special, if set to 0, iterations will be automatically determined such that the benchmark will run between 10 to 100 secs + Arguments: + 1 - first seed : Any value + 2 - second seed : Must be identical to first for iterations to be + identical 3 - third seed : Any value, should be at least an order of + magnitude less then the input size, but bigger then 32. 4 - Iterations : + Special, if set to 0, iterations will be automatically determined such that + the benchmark will run between 10 to 100 secs */ #if MAIN_HAS_NOARGC -MAIN_RETURN_TYPE main(void) { - int argc=0; - char *argv[1]; +MAIN_RETURN_TYPE +main(void) +{ + int argc = 0; + char *argv[1]; #else -MAIN_RETURN_TYPE main(int argc, char *argv[]) { +MAIN_RETURN_TYPE +main(int argc, char *argv[]) +{ #endif - //const char s[] = "Elizabeth"; - ee_printf("eeprint"); - //ee_printf("Trying to print: %d", 0); - /*gg_printf("Elizabeth");*/ - //sendstring("Elizabeth"); - - //sendstring(s); - //return(0); - ee_u16 i,j=0,num_algorithms=0; - ee_s16 known_id=-1,total_errors=0; - ee_u16 seedcrc=0; - CORE_TICKS total_time; - core_results results[MULTITHREAD]; -#if (MEM_METHOD==MEM_STACK) - ee_u8 stack_memblock[TOTAL_DATA_SIZE*MULTITHREAD]; + ee_printf("SHOWTIME\n"); + ee_u16 i, j = 0, num_algorithms = 0; + ee_s16 known_id = -1, total_errors = 0; + ee_u16 seedcrc = 0; + CORE_TICKS total_time; + core_results results[MULTITHREAD]; +#if (MEM_METHOD == MEM_STACK) + ee_u8 stack_memblock[TOTAL_DATA_SIZE * MULTITHREAD]; #endif - /* first call any initializations needed */ - portable_init(&(results[0].port), &argc, argv); - /* First some checks to make sure benchmark will run ok */ - if (sizeof(struct list_head_s)>128) { - ee_printf("list_head structure too big for comparable data!\n"); - return MAIN_RETURN_VAL; - } - results[0].seed1=get_seed(1); - results[0].seed2=get_seed(2); - results[0].seed3=get_seed(3); - results[0].iterations=get_seed_32(4); + /* first call any initializations needed */ + portable_init(&(results[0].port), &argc, argv); + /* First some checks to make sure benchmark will run ok */ + if (sizeof(struct list_head_s) > 128) + { + ee_printf("list_head structure too big for comparable data!\n"); + return MAIN_RETURN_VAL; + } + results[0].seed1 = get_seed(1); + results[0].seed2 = get_seed(2); + results[0].seed3 = get_seed(3); + results[0].iterations = get_seed_32(4); #if CORE_DEBUG - results[0].iterations=1; + results[0].iterations = 1; #endif - results[0].execs=get_seed_32(5); - if (results[0].execs==0) { /* if not supplied, execute all algorithms */ - results[0].execs=ALL_ALGORITHMS_MASK; - } - /* put in some default values based on one seed only for easy testing */ - if ((results[0].seed1==0) && (results[0].seed2==0) && (results[0].seed3==0)) { /* validation run */ - results[0].seed1=0; - results[0].seed2=0; - results[0].seed3=0x66; - } - if ((results[0].seed1==1) && (results[0].seed2==0) && (results[0].seed3==0)) { /* perfromance run */ - results[0].seed1=0x3415; - results[0].seed2=0x3415; - results[0].seed3=0x66; - } -#if (MEM_METHOD==MEM_STATIC) - results[0].memblock[0]=(void *)static_memblk; - results[0].size=TOTAL_DATA_SIZE; - ee_printf("%d \n total data size", TOTAL_DATA_SIZE); - results[0].err=0; - #if (MULTITHREAD>1) - #error "Cannot use a static data area with multiple contexts!" - #endif -#elif (MEM_METHOD==MEM_MALLOC) - for (i=0 ; i 1) +#error "Cannot use a static data area with multiple contexts!" +#endif +#elif (MEM_METHOD == MEM_MALLOC) + for (i = 0; i < MULTITHREAD; i++) + { + ee_s32 malloc_override = get_seed(7); + if (malloc_override != 0) + results[i].size = malloc_override; + else + results[i].size = TOTAL_DATA_SIZE; + results[i].memblock[0] = portable_malloc(results[i].size); + results[i].seed1 = results[0].seed1; + results[i].seed2 = results[0].seed2; + results[i].seed3 = results[0].seed3; + results[i].err = 0; + results[i].execs = results[0].execs; + } +#elif (MEM_METHOD == MEM_STACK) +for (i = 0; i < MULTITHREAD; i++) +{ + results[i].memblock[0] = stack_memblock + i * TOTAL_DATA_SIZE; + results[i].size = TOTAL_DATA_SIZE; + results[i].seed1 = results[0].seed1; + results[i].seed2 = results[0].seed2; + results[i].seed3 = results[0].seed3; + results[i].err = 0; + results[i].execs = results[0].execs; +} #else #error "Please define a way to initialize a memory block." #endif - /* Data init */ - /* Find out how space much we have based on number of algorithms */ - for (i=0; i1) - if (default_num_contexts>MULTITHREAD) { - default_num_contexts=MULTITHREAD; - } - for (i=0 ; i 1) + if (default_num_contexts > MULTITHREAD) + { + default_num_contexts = MULTITHREAD; + } + for (i = 0; i < default_num_contexts; i++) + { + results[i].iterations = results[0].iterations; + results[i].execs = results[0].execs; + core_start_parallel(&results[i]); + } + for (i = 0; i < default_num_contexts; i++) + { + core_stop_parallel(&results[i]); + } #else - iterate(&results[0]); + iterate(&results[0]); #endif - stop_time(); - total_time=get_time(); - ee_printf("total time is %u\n", total_time); - ee_printf("ending benchmark\n"); - /* get a function of the input to report */ - seedcrc=crc16(results[0].seed1,seedcrc); - seedcrc=crc16(results[0].seed2,seedcrc); - seedcrc=crc16(results[0].seed3,seedcrc); - seedcrc=crc16(results[0].size,seedcrc); - - switch (seedcrc) { /* test known output for common seeds */ - case 0x8a02: /* seed1=0, seed2=0, seed3=0x66, size 2000 per algorithm */ - known_id=0; - ee_printf("6k performance run parameters for coremark.\n"); - break; - case 0x7b05: /* seed1=0x3415, seed2=0x3415, seed3=0x66, size 2000 per algorithm */ - known_id=1; - ee_printf("6k validation run parameters for coremark.\n"); - break; - case 0x4eaf: /* seed1=0x8, seed2=0x8, seed3=0x8, size 400 per algorithm */ - known_id=2; - ee_printf("Profile generation run parameters for coremark.\n"); - break; - case 0xe9f5: /* seed1=0, seed2=0, seed3=0x66, size 666 per algorithm */ - known_id=3; - ee_printf("2K performance run parameters for coremark.\n"); - break; - case 0x18f2: /* seed1=0x3415, seed2=0x3415, seed3=0x66, size 666 per algorithm */ - known_id=4; - ee_printf("2K validation run parameters for coremark.\n"); - break; - default: - total_errors=-1; - break; - } - if (known_id>=0) { - for (i=0 ; i 0) - ee_printf("Iterations/Sec : %f\n",default_num_contexts*results[0].iterations/time_in_secs(total_time)); -#else - ee_printf("Total time (secs): %d\n,time_in_secs(total_time)"); - if (time_in_secs(total_time) > 0) - ee_printf("Iterations/Sec : %d\n",default_num_contexts*results[0].iterations/time_in_secs(total_time)); -#endif - if (time_in_secs(total_time) < 10) { - ee_printf("ERROR! Must execute for at least 10 secs for a valid result!\n"); - total_errors++; - } + stop_time(); + total_time = get_time(); + /* get a function of the input to report */ + seedcrc = crc16(results[0].seed1, seedcrc); + seedcrc = crc16(results[0].seed2, seedcrc); + seedcrc = crc16(results[0].seed3, seedcrc); + seedcrc = crc16(results[0].size, seedcrc); - ee_printf("Iterations : %lu\n", (long unsigned) default_num_contexts*results[0].iterations); - ee_printf("Compiler version : %s\n",COMPILER_VERSION); - ee_printf("Compiler flags : %s\n",COMPILER_FLAGS); -#if (MULTITHREAD>1) - ee_printf("Parallel %s : %d\n",PARALLEL_METHOD,default_num_contexts); -#endif - ee_printf("Memory location : %s\n",MEM_LOCATION); - /* output for verification */ - ee_printf("seedcrc : 0x%04x\n",seedcrc); - if (results[0].execs & ID_LIST) - for (i=0 ; i= 0) + { + for (i = 0; i < default_num_contexts; i++) + { + results[i].err = 0; + if ((results[i].execs & ID_LIST) + && (results[i].crclist != list_known_crc[known_id])) + { + ee_printf("[%u]ERROR! list crc 0x%04x - should be 0x%04x\n", + i, + results[i].crclist, + list_known_crc[known_id]); + results[i].err++; + } + if ((results[i].execs & ID_MATRIX) + && (results[i].crcmatrix != matrix_known_crc[known_id])) + { + ee_printf("[%u]ERROR! matrix crc 0x%04x - should be 0x%04x\n", + i, + results[i].crcmatrix, + matrix_known_crc[known_id]); + results[i].err++; + } + if ((results[i].execs & ID_STATE) + && (results[i].crcstate != state_known_crc[known_id])) + { + ee_printf("[%u]ERROR! state crc 0x%04x - should be 0x%04x\n", + i, + results[i].crcstate, + state_known_crc[known_id]); + results[i].err++; + } + total_errors += results[i].err; + } + } + total_errors += check_data_types(); + /* and report results */ + ee_printf("CoreMark Size : %lu\n", (long unsigned)results[0].size); + ee_printf("Total ticks : %lu\n", (long unsigned)total_time); #if HAS_FLOAT - if (known_id==3) { - unsigned long long tmp = (unsigned long long) 1000.0*default_num_contexts*results[0].iterations/time_in_secs(total_time); + ee_printf("Total time (secs): %f\n", time_in_secs(total_time)); + if (time_in_secs(total_time) > 0) + ee_printf("Iterations/Sec : %f\n", + default_num_contexts * results[0].iterations + / time_in_secs(total_time)); +#else + ee_printf("Total time (secs): %d\n", time_in_secs(total_time)); + if (time_in_secs(total_time) > 0) + ee_printf("Iterations/Sec : %d\n", + default_num_contexts * results[0].iterations + / time_in_secs(total_time)); +#endif + if (time_in_secs(total_time) < 10) + { + ee_printf( + "ERROR! Must execute for at least 10 secs for a valid result!\n"); + total_errors++; + } + + ee_printf("Iterations : %lu\n", + (long unsigned)default_num_contexts * results[0].iterations); + ee_printf("Compiler version : %s\n", COMPILER_VERSION); + ee_printf("Compiler flags : %s\n", COMPILER_FLAGS); +#if (MULTITHREAD > 1) + ee_printf("Parallel %s : %d\n", PARALLEL_METHOD, default_num_contexts); +#endif + ee_printf("Memory location : %s\n", MEM_LOCATION); + /* output for verification */ + ee_printf("seedcrc : 0x%04x\n", seedcrc); + if (results[0].execs & ID_LIST) + for (i = 0; i < default_num_contexts; i++) + ee_printf("[%d]crclist : 0x%04x\n", i, results[i].crclist); + if (results[0].execs & ID_MATRIX) + for (i = 0; i < default_num_contexts; i++) + ee_printf("[%d]crcmatrix : 0x%04x\n", i, results[i].crcmatrix); + if (results[0].execs & ID_STATE) + for (i = 0; i < default_num_contexts; i++) + ee_printf("[%d]crcstate : 0x%04x\n", i, results[i].crcstate); + for (i = 0; i < default_num_contexts; i++) + ee_printf("[%d]crcfinal : 0x%04x\n", i, results[i].crc); + if (total_errors == 0) + { + ee_printf( + "Correct operation validated. See README.md for run and reporting " + "rules.\n"); +#if HAS_FLOAT + if (known_id == 3) + { + unsigned long long tmp = (unsigned long long) 1000.0*default_num_contexts*results[0].iterations/time_in_secs(total_time); secs_ret totalmsecs = time_in_secs(total_time); int totalmint = (int) totalmsecs; ee_printf("ELAPSED TIME: %d\n", totalmint); - ee_printf("CoreMark 1.0 : %d / %s %s\n",tmp,COMPILER_VERSION,COMPILER_FLAGS); + ee_printf("CoreMark 1.0 : %d / %s %s", + tmp, + COMPILER_VERSION, + COMPILER_FLAGS); #if defined(MEM_LOCATION) && !defined(MEM_LOCATION_UNSPEC) - ee_printf(" / %s",MEM_LOCATION); + ee_printf(" / %s", MEM_LOCATION); #else - ee_printf(" / %s",mem_name[MEM_METHOD]); + ee_printf(" / %s", mem_name[MEM_METHOD]); #endif -#if (MULTITHREAD>1) - ee_printf(" / %d:%s",default_num_contexts,PARALLEL_METHOD); +#if (MULTITHREAD > 1) + ee_printf(" / %d:%s", default_num_contexts, PARALLEL_METHOD); #endif - ee_printf("\n"); - } + ee_printf("\n"); + } #endif - } - if (total_errors>0) - ee_printf("Errors detected\n"); - if (total_errors<0) - ee_printf("Cannot validate operation for these seed values, please compare with results on a known platform.\n"); + } + if (total_errors > 0) + ee_printf("Errors detected\n"); + if (total_errors < 0) + ee_printf( + "Cannot validate operation for these seed values, please compare " + "with results on a known platform.\n"); -#if (MEM_METHOD==MEM_MALLOC) - for (i=0 ; i>(from)) & (~(0xffffffff << (to)))) +#define matrix_test_next(x) (x + 1) +#define matrix_clip(x, y) ((y) ? (x)&0x0ff : (x)&0x0ffff) +#define matrix_big(x) (0xf000 | (x)) +#define bit_extract(x, from, to) (((x) >> (from)) & (~(0xffffffff << (to)))) #if CORE_DEBUG -void printmat(MATDAT *A, ee_u32 N, char *name) { - ee_u32 i,j; - ee_printf("Matrix %s [%dx%d]:\n",name,N,N); - for (i=0; i N times, - changing the matrix values slightly by a constant amount each time. + Iterate N times, + changing the matrix values slightly by a constant amount each time. */ -ee_u16 core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc) { - ee_u32 N=p->N; - MATRES *C=p->C; - MATDAT *A=p->A; - MATDAT *B=p->B; - MATDAT val=(MATDAT)seed; +ee_u16 +core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc) +{ + ee_u32 N = p->N; + MATRES *C = p->C; + MATDAT *A = p->A; + MATDAT *B = p->B; + MATDAT val = (MATDAT)seed; - crc=crc16(matrix_test(N,C,A,B,val),crc); + crc = crc16(matrix_test(N, C, A, B, val), crc); - return crc; + return crc; } /* Function: matrix_test - Perform matrix manipulation. + Perform matrix manipulation. - Parameters: - N - Dimensions of the matrix. - C - memory for result matrix. - A - input matrix - B - operator matrix (not changed during operations) + Parameters: + N - Dimensions of the matrix. + C - memory for result matrix. + A - input matrix + B - operator matrix (not changed during operations) - Returns: - A CRC value that captures all results calculated in the function. - In particular, crc of the value calculated on the result matrix - after each step by . + Returns: + A CRC value that captures all results calculated in the function. + In particular, crc of the value calculated on the result matrix + after each step by . - Operation: - - 1 - Add a constant value to all elements of a matrix. - 2 - Multiply a matrix by a constant. - 3 - Multiply a matrix by a vector. - 4 - Multiply a matrix by a matrix. - 5 - Add a constant value to all elements of a matrix. + Operation: - After the last step, matrix A is back to original contents. + 1 - Add a constant value to all elements of a matrix. + 2 - Multiply a matrix by a constant. + 3 - Multiply a matrix by a vector. + 4 - Multiply a matrix by a matrix. + 5 - Add a constant value to all elements of a matrix. + + After the last step, matrix A is back to original contents. */ -ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val) { - ee_u16 crc=0; - MATDAT clipval=matrix_big(val); +ee_s16 +matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val) +{ + ee_u16 crc = 0; + MATDAT clipval = matrix_big(val); - matrix_add_const(N,A,val); /* make sure data changes */ + matrix_add_const(N, A, val); /* make sure data changes */ #if CORE_DEBUG - printmat(A,N,"matrix_add_const"); + printmat(A, N, "matrix_add_const"); #endif - matrix_mul_const(N,C,A,val); - crc=crc16(matrix_sum(N,C,clipval),crc); + matrix_mul_const(N, C, A, val); + crc = crc16(matrix_sum(N, C, clipval), crc); #if CORE_DEBUG - printmatC(C,N,"matrix_mul_const"); + printmatC(C, N, "matrix_mul_const"); #endif - matrix_mul_vect(N,C,A,B); - crc=crc16(matrix_sum(N,C,clipval),crc); + matrix_mul_vect(N, C, A, B); + crc = crc16(matrix_sum(N, C, clipval), crc); #if CORE_DEBUG - printmatC(C,N,"matrix_mul_vect"); + printmatC(C, N, "matrix_mul_vect"); #endif - matrix_mul_matrix(N,C,A,B); - crc=crc16(matrix_sum(N,C,clipval),crc); + matrix_mul_matrix(N, C, A, B); + crc = crc16(matrix_sum(N, C, clipval), crc); #if CORE_DEBUG - printmatC(C,N,"matrix_mul_matrix"); + printmatC(C, N, "matrix_mul_matrix"); #endif - matrix_mul_matrix_bitextract(N,C,A,B); - crc=crc16(matrix_sum(N,C,clipval),crc); + matrix_mul_matrix_bitextract(N, C, A, B); + crc = crc16(matrix_sum(N, C, clipval), crc); #if CORE_DEBUG - printmatC(C,N,"matrix_mul_matrix_bitextract"); + printmatC(C, N, "matrix_mul_matrix_bitextract"); #endif - - matrix_add_const(N,A,-val); /* return matrix to initial value */ - return crc; + + matrix_add_const(N, A, -val); /* return matrix to initial value */ + return crc; } /* Function : matrix_init - Initialize the memory block for matrix benchmarking. + Initialize the memory block for matrix benchmarking. - Parameters: - blksize - Size of memory to be initialized. - memblk - Pointer to memory block. - seed - Actual values chosen depend on the seed parameter. - p - pointers to containing initialized matrixes. + Parameters: + blksize - Size of memory to be initialized. + memblk - Pointer to memory block. + seed - Actual values chosen depend on the seed parameter. + p - pointers to containing initialized matrixes. - Returns: - Matrix dimensions. - - Note: - The seed parameter MUST be supplied from a source that cannot be determined at compile time + Returns: + Matrix dimensions. + + Note: + The seed parameter MUST be supplied from a source that cannot be + determined at compile time */ -ee_u32 core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p) { - ee_u32 N=0; - MATDAT *A; - MATDAT *B; - ee_s32 order=1; - MATDAT val; - ee_u32 i=0,j=0; - if (seed==0) - seed=1; - while (jA=A; - p->B=B; - p->C=(MATRES *)align_mem(B+N*N); - p->N=N; + p->A = A; + p->B = B; + p->C = (MATRES *)align_mem(B + N * N); + p->N = N; #if CORE_DEBUG - printmat(A,N,"A"); - printmat(B,N,"B"); + printmat(A, N, "A"); + printmat(B, N, "B"); #endif - return N; + return N; } /* Function: matrix_sum - Calculate a function that depends on the values of elements in the matrix. + Calculate a function that depends on the values of elements in the + matrix. - For each element, accumulate into a temporary variable. - - As long as this value is under the parameter clipval, - add 1 to the result if the element is bigger then the previous. - - Otherwise, reset the accumulator and add 10 to the result. + For each element, accumulate into a temporary variable. + + As long as this value is under the parameter clipval, + add 1 to the result if the element is bigger then the previous. + + Otherwise, reset the accumulator and add 10 to the result. */ -ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval) { - MATRES tmp=0,prev=0,cur=0; - ee_s16 ret=0; - ee_u32 i,j; - for (i=0; iclipval) { - ret+=10; - tmp=0; - } else { - ret += (cur>prev) ? 1 : 0; - } - prev=cur; - } - } - return ret; +ee_s16 +matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval) +{ + MATRES tmp = 0, prev = 0, cur = 0; + ee_s16 ret = 0; + ee_u32 i, j; + for (i = 0; i < N; i++) + { + for (j = 0; j < N; j++) + { + cur = C[i * N + j]; + tmp += cur; + if (tmp > clipval) + { + ret += 10; + tmp = 0; + } + else + { + ret += (cur > prev) ? 1 : 0; + } + prev = cur; + } + } + return ret; } /* Function: matrix_mul_const - Multiply a matrix by a constant. - This could be used as a scaler for instance. + Multiply a matrix by a constant. + This could be used as a scaler for instance. */ -void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val) { - ee_u32 i,j; - for (i=0; i0) { - for(i=0;i>3) & 0x3]; - next=4; - break; - case 3: /* float */ - case 4: /* float */ - buf=floatpat[(seed>>3) & 0x3]; - next=8; - break; - case 5: /* scientific */ - case 6: /* scientific */ - buf=scipat[(seed>>3) & 0x3]; - next=8; - break; - case 7: /* invalid */ - buf=errpat[(seed>>3) & 0x3]; - next=8; - break; - default: /* Never happen, just to make some compilers happy */ - break; - } - } - size++; - while (total 0) + { + for (i = 0; i < next; i++) + *(p + total + i) = buf[i]; + *(p + total + i) = ','; + total += next + 1; + } + seed++; + switch (seed & 0x7) + { + case 0: /* int */ + case 1: /* int */ + case 2: /* int */ + buf = intpat[(seed >> 3) & 0x3]; + next = 4; + break; + case 3: /* float */ + case 4: /* float */ + buf = floatpat[(seed >> 3) & 0x3]; + next = 8; + break; + case 5: /* scientific */ + case 6: /* scientific */ + buf = scipat[(seed >> 3) & 0x3]; + next = 8; + break; + case 7: /* invalid */ + buf = errpat[(seed >> 3) & 0x3]; + next = 8; + break; + default: /* Never happen, just to make some compilers happy */ + break; + } + } + size++; + while (total < size) + { /* fill the rest with 0 */ + *(p + total) = 0; + total++; + } #if CORE_DEBUG - ee_printf("State Input: %s\n",start); + ee_printf("State Input: %s\n", start); #endif } -static ee_u8 ee_isdigit(ee_u8 c) { - ee_u8 retval; - retval = ((c>='0') & (c<='9')) ? 1 : 0; - return retval; +static ee_u8 +ee_isdigit(ee_u8 c) +{ + ee_u8 retval; + retval = ((c >= '0') & (c <= '9')) ? 1 : 0; + return retval; } /* Function: core_state_transition - Actual state machine. + Actual state machine. - The state machine will continue scanning until either: - 1 - an invalid input is detcted. - 2 - a valid number has been detected. - - The input pointer is updated to point to the end of the token, and the end state is returned (either specific format determined or invalid). + The state machine will continue scanning until either: + 1 - an invalid input is detcted. + 2 - a valid number has been detected. + + The input pointer is updated to point to the end of the token, and the + end state is returned (either specific format determined or invalid). */ -enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count) { - ee_u8 *str=*instr; - ee_u8 NEXT_SYMBOL; - enum CORE_STATE state=CORE_START; - for( ; *str && state != CORE_INVALID; str++ ) { - NEXT_SYMBOL = *str; - if (NEXT_SYMBOL==',') /* end of this input */ { - str++; - break; - } - switch(state) { - case CORE_START: - if(ee_isdigit(NEXT_SYMBOL)) { - state = CORE_INT; - } - else if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) { - state = CORE_S1; - } - else if( NEXT_SYMBOL == '.' ) { - state = CORE_FLOAT; - } - else { - state = CORE_INVALID; - transition_count[CORE_INVALID]++; - } - transition_count[CORE_START]++; - break; - case CORE_S1: - if(ee_isdigit(NEXT_SYMBOL)) { - state = CORE_INT; - transition_count[CORE_S1]++; - } - else if( NEXT_SYMBOL == '.' ) { - state = CORE_FLOAT; - transition_count[CORE_S1]++; - } - else { - state = CORE_INVALID; - transition_count[CORE_S1]++; - } - break; - case CORE_INT: - if( NEXT_SYMBOL == '.' ) { - state = CORE_FLOAT; - transition_count[CORE_INT]++; - } - else if(!ee_isdigit(NEXT_SYMBOL)) { - state = CORE_INVALID; - transition_count[CORE_INT]++; - } - break; - case CORE_FLOAT: - if( NEXT_SYMBOL == 'E' || NEXT_SYMBOL == 'e' ) { - state = CORE_S2; - transition_count[CORE_FLOAT]++; - } - else if(!ee_isdigit(NEXT_SYMBOL)) { - state = CORE_INVALID; - transition_count[CORE_FLOAT]++; - } - break; - case CORE_S2: - if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) { - state = CORE_EXPONENT; - transition_count[CORE_S2]++; - } - else { - state = CORE_INVALID; - transition_count[CORE_S2]++; - } - break; - case CORE_EXPONENT: - if(ee_isdigit(NEXT_SYMBOL)) { - state = CORE_SCIENTIFIC; - transition_count[CORE_EXPONENT]++; - } - else { - state = CORE_INVALID; - transition_count[CORE_EXPONENT]++; - } - break; - case CORE_SCIENTIFIC: - if(!ee_isdigit(NEXT_SYMBOL)) { - state = CORE_INVALID; - transition_count[CORE_INVALID]++; - } - break; - default: - break; - } - } - *instr=str; - return state; +enum CORE_STATE +core_state_transition(ee_u8 **instr, ee_u32 *transition_count) +{ + ee_u8 * str = *instr; + ee_u8 NEXT_SYMBOL; + enum CORE_STATE state = CORE_START; + for (; *str && state != CORE_INVALID; str++) + { + NEXT_SYMBOL = *str; + if (NEXT_SYMBOL == ',') /* end of this input */ + { + str++; + break; + } + switch (state) + { + case CORE_START: + if (ee_isdigit(NEXT_SYMBOL)) + { + state = CORE_INT; + } + else if (NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-') + { + state = CORE_S1; + } + else if (NEXT_SYMBOL == '.') + { + state = CORE_FLOAT; + } + else + { + state = CORE_INVALID; + transition_count[CORE_INVALID]++; + } + transition_count[CORE_START]++; + break; + case CORE_S1: + if (ee_isdigit(NEXT_SYMBOL)) + { + state = CORE_INT; + transition_count[CORE_S1]++; + } + else if (NEXT_SYMBOL == '.') + { + state = CORE_FLOAT; + transition_count[CORE_S1]++; + } + else + { + state = CORE_INVALID; + transition_count[CORE_S1]++; + } + break; + case CORE_INT: + if (NEXT_SYMBOL == '.') + { + state = CORE_FLOAT; + transition_count[CORE_INT]++; + } + else if (!ee_isdigit(NEXT_SYMBOL)) + { + state = CORE_INVALID; + transition_count[CORE_INT]++; + } + break; + case CORE_FLOAT: + if (NEXT_SYMBOL == 'E' || NEXT_SYMBOL == 'e') + { + state = CORE_S2; + transition_count[CORE_FLOAT]++; + } + else if (!ee_isdigit(NEXT_SYMBOL)) + { + state = CORE_INVALID; + transition_count[CORE_FLOAT]++; + } + break; + case CORE_S2: + if (NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-') + { + state = CORE_EXPONENT; + transition_count[CORE_S2]++; + } + else + { + state = CORE_INVALID; + transition_count[CORE_S2]++; + } + break; + case CORE_EXPONENT: + if (ee_isdigit(NEXT_SYMBOL)) + { + state = CORE_SCIENTIFIC; + transition_count[CORE_EXPONENT]++; + } + else + { + state = CORE_INVALID; + transition_count[CORE_EXPONENT]++; + } + break; + case CORE_SCIENTIFIC: + if (!ee_isdigit(NEXT_SYMBOL)) + { + state = CORE_INVALID; + transition_count[CORE_INVALID]++; + } + break; + default: + break; + } + } + *instr = str; + return state; } diff --git a/riscv-coremark/coremark/core_util.c b/riscv-coremark/coremark/core_util.c index 581adcc24..67c5d7757 100644 --- a/riscv-coremark/coremark/core_util.c +++ b/riscv-coremark/coremark/core_util.c @@ -18,193 +18,232 @@ Original Author: Shay Gal-on #include "coremark.h" /* Function: get_seed - Get a values that cannot be determined at compile time. + Get a values that cannot be determined at compile time. - Since different embedded systems and compilers are used, 3 different methods are provided: - 1 - Using a volatile variable. This method is only valid if the compiler is forced to generate code that - reads the value of a volatile variable from memory at run time. - Please note, if using this method, you would need to modify core_portme.c to generate training profile. - 2 - Command line arguments. This is the preferred method if command line arguments are supported. - 3 - System function. If none of the first 2 methods is available on the platform, - a system function which is not a stub can be used. - - e.g. read the value on GPIO pins connected to switches, or invoke special simulator functions. + Since different embedded systems and compilers are used, 3 different + methods are provided: 1 - Using a volatile variable. This method is only + valid if the compiler is forced to generate code that reads the value of a + volatile variable from memory at run time. Please note, if using this method, + you would need to modify core_portme.c to generate training profile. 2 - + Command line arguments. This is the preferred method if command line + arguments are supported. 3 - System function. If none of the first 2 methods + is available on the platform, a system function which is not a stub can be + used. + + e.g. read the value on GPIO pins connected to switches, or invoke + special simulator functions. */ -#if (SEED_METHOD==SEED_VOLATILE) - extern volatile ee_s32 seed1_volatile; - extern volatile ee_s32 seed2_volatile; - extern volatile ee_s32 seed3_volatile; - extern volatile ee_s32 seed4_volatile; - extern volatile ee_s32 seed5_volatile; - ee_s32 get_seed_32(int i) { - ee_s32 retval; - switch (i) { - case 1: - retval=seed1_volatile; - break; - case 2: - retval=seed2_volatile; - break; - case 3: - retval=seed3_volatile; - break; - case 4: - retval=seed4_volatile; - break; - case 5: - retval=seed5_volatile; - break; - default: - retval=0; - break; - } - return retval; - } -#elif (SEED_METHOD==SEED_ARG) -ee_s32 parseval(char *valstring) { - ee_s32 retval=0; - ee_s32 neg=1; - int hexmode=0; - if (*valstring == '-') { - neg=-1; - valstring++; - } - if ((valstring[0] == '0') && (valstring[1] == 'x')) { - hexmode=1; - valstring+=2; - } - /* first look for digits */ - if (hexmode) { - while (((*valstring >= '0') && (*valstring <= '9')) || ((*valstring >= 'a') && (*valstring <= 'f'))) { - ee_s32 digit=*valstring-'0'; - if (digit>9) - digit=10+*valstring-'a'; - retval*=16; - retval+=digit; - valstring++; - } - } else { - while ((*valstring >= '0') && (*valstring <= '9')) { - ee_s32 digit=*valstring-'0'; - retval*=10; - retval+=digit; - valstring++; - } - } - /* now add qualifiers */ - if (*valstring=='K') - retval*=1024; - if (*valstring=='M') - retval*=1024*1024; +#if (SEED_METHOD == SEED_VOLATILE) +extern volatile ee_s32 seed1_volatile; +extern volatile ee_s32 seed2_volatile; +extern volatile ee_s32 seed3_volatile; +extern volatile ee_s32 seed4_volatile; +extern volatile ee_s32 seed5_volatile; +ee_s32 +get_seed_32(int i) +{ + ee_s32 retval; + switch (i) + { + case 1: + retval = seed1_volatile; + break; + case 2: + retval = seed2_volatile; + break; + case 3: + retval = seed3_volatile; + break; + case 4: + retval = seed4_volatile; + break; + case 5: + retval = seed5_volatile; + break; + default: + retval = 0; + break; + } + return retval; +} +#elif (SEED_METHOD == SEED_ARG) +ee_s32 +parseval(char *valstring) +{ + ee_s32 retval = 0; + ee_s32 neg = 1; + int hexmode = 0; + if (*valstring == '-') + { + neg = -1; + valstring++; + } + if ((valstring[0] == '0') && (valstring[1] == 'x')) + { + hexmode = 1; + valstring += 2; + } + /* first look for digits */ + if (hexmode) + { + while (((*valstring >= '0') && (*valstring <= '9')) + || ((*valstring >= 'a') && (*valstring <= 'f'))) + { + ee_s32 digit = *valstring - '0'; + if (digit > 9) + digit = 10 + *valstring - 'a'; + retval *= 16; + retval += digit; + valstring++; + } + } + else + { + while ((*valstring >= '0') && (*valstring <= '9')) + { + ee_s32 digit = *valstring - '0'; + retval *= 10; + retval += digit; + valstring++; + } + } + /* now add qualifiers */ + if (*valstring == 'K') + retval *= 1024; + if (*valstring == 'M') + retval *= 1024 * 1024; - retval*=neg; - return retval; + retval *= neg; + return retval; } -ee_s32 get_seed_args(int i, int argc, char *argv[]) { - if (argc>i) - return parseval(argv[i]); - return 0; +ee_s32 +get_seed_args(int i, int argc, char *argv[]) +{ + if (argc > i) + return parseval(argv[i]); + return 0; } -#elif (SEED_METHOD==SEED_FUNC) -/* If using OS based function, you must define and implement the functions below in core_portme.h and core_portme.c ! */ -ee_s32 get_seed_32(int i) { - ee_s32 retval; - switch (i) { - case 1: - retval=portme_sys1(); - break; - case 2: - retval=portme_sys2(); - break; - case 3: - retval=portme_sys3(); - break; - case 4: - retval=portme_sys4(); - break; - case 5: - retval=portme_sys5(); - break; - default: - retval=0; - break; - } - return retval; +#elif (SEED_METHOD == SEED_FUNC) +/* If using OS based function, you must define and implement the functions below + * in core_portme.h and core_portme.c ! */ +ee_s32 +get_seed_32(int i) +{ + ee_s32 retval; + switch (i) + { + case 1: + retval = portme_sys1(); + break; + case 2: + retval = portme_sys2(); + break; + case 3: + retval = portme_sys3(); + break; + case 4: + retval = portme_sys4(); + break; + case 5: + retval = portme_sys5(); + break; + default: + retval = 0; + break; + } + return retval; } #endif /* Function: crc* - Service functions to calculate 16b CRC code. + Service functions to calculate 16b CRC code. */ -ee_u16 crcu8(ee_u8 data, ee_u16 crc ) +ee_u16 +crcu8(ee_u8 data, ee_u16 crc) { - ee_u8 i=0,x16=0,carry=0; + ee_u8 i = 0, x16 = 0, carry = 0; - for (i = 0; i < 8; i++) + for (i = 0; i < 8; i++) { - x16 = (ee_u8)((data & 1) ^ ((ee_u8)crc & 1)); - data >>= 1; + x16 = (ee_u8)((data & 1) ^ ((ee_u8)crc & 1)); + data >>= 1; - if (x16 == 1) - { - crc ^= 0x4002; - carry = 1; - } - else - carry = 0; - crc >>= 1; - if (carry) - crc |= 0x8000; - else - crc &= 0x7fff; + if (x16 == 1) + { + crc ^= 0x4002; + carry = 1; + } + else + carry = 0; + crc >>= 1; + if (carry) + crc |= 0x8000; + else + crc &= 0x7fff; } - return crc; -} -ee_u16 crcu16(ee_u16 newval, ee_u16 crc) { - crc=crcu8( (ee_u8) (newval) ,crc); - crc=crcu8( (ee_u8) ((newval)>>8) ,crc); - return crc; + return crc; } -ee_u16 crcu32(ee_u32 newval, ee_u16 crc) { - crc=crc16((ee_s16) newval ,crc); - crc=crc16((ee_s16) (newval>>16) ,crc); - return crc; +ee_u16 +crcu16(ee_u16 newval, ee_u16 crc) +{ + crc = crcu8((ee_u8)(newval), crc); + crc = crcu8((ee_u8)((newval) >> 8), crc); + return crc; } -ee_u16 crc16(ee_s16 newval, ee_u16 crc) { - return crcu16((ee_u16)newval, crc); +ee_u16 +crcu32(ee_u32 newval, ee_u16 crc) +{ + crc = crc16((ee_s16)newval, crc); + crc = crc16((ee_s16)(newval >> 16), crc); + return crc; +} +ee_u16 +crc16(ee_s16 newval, ee_u16 crc) +{ + return crcu16((ee_u16)newval, crc); } -ee_u8 check_data_types() { - ee_u8 retval=0; - if (sizeof(ee_u8) != 1) { - ee_printf("ERROR: ee_u8 is not an 8b datatype!\n"); - retval++; - } - if (sizeof(ee_u16) != 2) { - ee_printf("ERROR: ee_u16 is not a 16b datatype!\n"); - retval++; - } - if (sizeof(ee_s16) != 2) { - ee_printf("ERROR: ee_s16 is not a 16b datatype!\n"); - retval++; - } - if (sizeof(ee_s32) != 4) { - ee_printf("ERROR: ee_s32 is not a 32b datatype!\n"); - retval++; - } - if (sizeof(ee_u32) != 4) { - ee_printf("ERROR: ee_u32 is not a 32b datatype!\n"); - retval++; - } - if (sizeof(ee_ptr_int) != sizeof(int *)) { - ee_printf("ERROR: ee_ptr_int is not a datatype that holds an int pointer!\n"); - retval++; - } - if (retval>0) { - ee_printf("ERROR: Please modify the datatypes in core_portme.h!\n"); - } - return retval; +ee_u8 +check_data_types() +{ + ee_u8 retval = 0; + if (sizeof(ee_u8) != 1) + { + ee_printf("ERROR: ee_u8 is not an 8b datatype!\n"); + retval++; + } + if (sizeof(ee_u16) != 2) + { + ee_printf("ERROR: ee_u16 is not a 16b datatype!\n"); + retval++; + } + if (sizeof(ee_s16) != 2) + { + ee_printf("ERROR: ee_s16 is not a 16b datatype!\n"); + retval++; + } + if (sizeof(ee_s32) != 4) + { + ee_printf("ERROR: ee_s32 is not a 32b datatype!\n"); + retval++; + } + if (sizeof(ee_u32) != 4) + { + ee_printf("ERROR: ee_u32 is not a 32b datatype!\n"); + retval++; + } + if (sizeof(ee_ptr_int) != sizeof(int *)) + { + ee_printf( + "ERROR: ee_ptr_int is not a datatype that holds an int pointer!\n"); + retval++; + } + if (retval > 0) + { + ee_printf("ERROR: Please modify the datatypes in core_portme.h!\n"); + } + return retval; } diff --git a/riscv-coremark/coremark/coremark.h b/riscv-coremark/coremark/coremark.h index dc9f8c7ae..9c5e4060a 100644 --- a/riscv-coremark/coremark/coremark.h +++ b/riscv-coremark/coremark/coremark.h @@ -17,23 +17,23 @@ Original Author: Shay Gal-on */ /* Topic: Description - This file contains declarations of the various benchmark functions. + This file contains declarations of the various benchmark functions. */ /* Configuration: TOTAL_DATA_SIZE - Define total size for data algorithms will operate on + Define total size for data algorithms will operate on */ -#ifndef TOTAL_DATA_SIZE -#define TOTAL_DATA_SIZE 2*1000 +#ifndef TOTAL_DATA_SIZE +#define TOTAL_DATA_SIZE 2 * 1000 #endif -#define SEED_ARG 0 -#define SEED_FUNC 1 +#define SEED_ARG 0 +#define SEED_FUNC 1 #define SEED_VOLATILE 2 #define MEM_STATIC 0 #define MEM_MALLOC 1 -#define MEM_STACK 2 +#define MEM_STACK 2 #include "core_portme.h" @@ -48,8 +48,8 @@ Original Author: Shay Gal-on void *iterate(void *pres); /* Typedef: secs_ret - For machines that have floating point support, get number of seconds as a double. - Otherwise an unsigned int. + For machines that have floating point support, get number of seconds as + a double. Otherwise an unsigned int. */ #if HAS_FLOAT typedef double secs_ret; @@ -58,47 +58,48 @@ typedef ee_u32 secs_ret; #endif #if MAIN_HAS_NORETURN -#define MAIN_RETURN_VAL +#define MAIN_RETURN_VAL #define MAIN_RETURN_TYPE void #else -#define MAIN_RETURN_VAL 0 +#define MAIN_RETURN_VAL 0 #define MAIN_RETURN_TYPE int -#endif +#endif -void start_time(void); -void stop_time(void); +void start_time(void); +void stop_time(void); CORE_TICKS get_time(void); -secs_ret time_in_secs(CORE_TICKS ticks); +secs_ret time_in_secs(CORE_TICKS ticks); /* Misc useful functions */ ee_u16 crcu8(ee_u8 data, ee_u16 crc); ee_u16 crc16(ee_s16 newval, ee_u16 crc); ee_u16 crcu16(ee_u16 newval, ee_u16 crc); ee_u16 crcu32(ee_u32 newval, ee_u16 crc); -ee_u8 check_data_types(); -void *portable_malloc(ee_size_t size); -void portable_free(void *p); +ee_u8 check_data_types(void); +void * portable_malloc(ee_size_t size); +void portable_free(void *p); ee_s32 parseval(char *valstring); /* Algorithm IDS */ -#define ID_LIST (1<<0) -#define ID_MATRIX (1<<1) -#define ID_STATE (1<<2) -#define ALL_ALGORITHMS_MASK (ID_LIST|ID_MATRIX|ID_STATE) -#define NUM_ALGORITHMS 3 +#define ID_LIST (1 << 0) +#define ID_MATRIX (1 << 1) +#define ID_STATE (1 << 2) +#define ALL_ALGORITHMS_MASK (ID_LIST | ID_MATRIX | ID_STATE) +#define NUM_ALGORITHMS 3 /* list data structures */ -typedef struct list_data_s { - ee_s16 data16; - ee_s16 idx; +typedef struct list_data_s +{ + ee_s16 data16; + ee_s16 idx; } list_data; -typedef struct list_head_s { - struct list_head_s *next; - struct list_data_s *info; +typedef struct list_head_s +{ + struct list_head_s *next; + struct list_data_s *info; } list_head; - /*matrix benchmark related stuff */ #define MATDAT_INT 1 #if MATDAT_INT @@ -109,66 +110,74 @@ typedef ee_f16 MATDAT; typedef ee_f32 MATRES; #endif -typedef struct MAT_PARAMS_S { - int N; - MATDAT *A; - MATDAT *B; - MATRES *C; +typedef struct MAT_PARAMS_S +{ + int N; + MATDAT *A; + MATDAT *B; + MATRES *C; } mat_params; /* state machine related stuff */ /* List of all the possible states for the FSM */ -typedef enum CORE_STATE { - CORE_START=0, - CORE_INVALID, - CORE_S1, - CORE_S2, - CORE_INT, - CORE_FLOAT, - CORE_EXPONENT, - CORE_SCIENTIFIC, - NUM_CORE_STATES -} core_state_e ; +typedef enum CORE_STATE +{ + CORE_START = 0, + CORE_INVALID, + CORE_S1, + CORE_S2, + CORE_INT, + CORE_FLOAT, + CORE_EXPONENT, + CORE_SCIENTIFIC, + NUM_CORE_STATES +} core_state_e; - /* Helper structure to hold results */ -typedef struct RESULTS_S { - /* inputs */ - ee_s16 seed1; /* Initializing seed */ - ee_s16 seed2; /* Initializing seed */ - ee_s16 seed3; /* Initializing seed */ - void *memblock[4]; /* Pointer to safe memory location */ - ee_u32 size; /* Size of the data */ - ee_u32 iterations; /* Number of iterations to execute */ - ee_u32 execs; /* Bitmask of operations to execute */ - struct list_head_s *list; - mat_params mat; - /* outputs */ - ee_u16 crc; - ee_u16 crclist; - ee_u16 crcmatrix; - ee_u16 crcstate; - ee_s16 err; - /* ultithread specific */ - core_portable port; +typedef struct RESULTS_S +{ + /* inputs */ + ee_s16 seed1; /* Initializing seed */ + ee_s16 seed2; /* Initializing seed */ + ee_s16 seed3; /* Initializing seed */ + void * memblock[4]; /* Pointer to safe memory location */ + ee_u32 size; /* Size of the data */ + ee_u32 iterations; /* Number of iterations to execute */ + ee_u32 execs; /* Bitmask of operations to execute */ + struct list_head_s *list; + mat_params mat; + /* outputs */ + ee_u16 crc; + ee_u16 crclist; + ee_u16 crcmatrix; + ee_u16 crcstate; + ee_s16 err; + /* ultithread specific */ + core_portable port; } core_results; /* Multicore execution handling */ -#if (MULTITHREAD>1) +#if (MULTITHREAD > 1) ee_u8 core_start_parallel(core_results *res); ee_u8 core_stop_parallel(core_results *res); #endif /* list benchmark functions */ list_head *core_list_init(ee_u32 blksize, list_head *memblock, ee_s16 seed); -ee_u16 core_bench_list(core_results *res, ee_s16 finder_idx); +ee_u16 core_bench_list(core_results *res, ee_s16 finder_idx); /* state benchmark functions */ -void core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p); -ee_u16 core_bench_state(ee_u32 blksize, ee_u8 *memblock, - ee_s16 seed1, ee_s16 seed2, ee_s16 step, ee_u16 crc); +void core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p); +ee_u16 core_bench_state(ee_u32 blksize, + ee_u8 *memblock, + ee_s16 seed1, + ee_s16 seed2, + ee_s16 step, + ee_u16 crc); /* matrix benchmark functions */ -ee_u32 core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p); +ee_u32 core_init_matrix(ee_u32 blksize, + void * memblk, + ee_s32 seed, + mat_params *p); ee_u16 core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc); - diff --git a/riscv-coremark/coremark/coremark.md5 b/riscv-coremark/coremark/coremark.md5 new file mode 100644 index 000000000..94160db22 --- /dev/null +++ b/riscv-coremark/coremark/coremark.md5 @@ -0,0 +1,6 @@ +8d082dc4a9676c02731a8cf209339072 core_list_join.c +c984863b84b59185d8b5fb81c1ca7535 core_main.c +5fa21a0f7c3964167c9691db531ca652 core_matrix.c +edcfc7a0b146a50028014f06e6826aa3 core_state.c +45540ba2145adea1ec7ea2c72a1fbbcb core_util.c +8ca974c013b380dc7f0d6d1afb76eb2d coremark.h diff --git a/riscv-coremark/coremark/cygwin/core_portme.mak b/riscv-coremark/coremark/cygwin/core_portme.mak old mode 100755 new mode 100644 index 721ba2e3d..97b6d6ace --- a/riscv-coremark/coremark/cygwin/core_portme.mak +++ b/riscv-coremark/coremark/cygwin/core_portme.mak @@ -14,128 +14,4 @@ # # Original Author: Shay Gal-on -#File: core_portme.mak - -# Flag: OUTFLAG -# Use this flag to define how to to get an executable (e.g -o) -OUTFLAG= -o -# Flag: CC -# Use this flag to define compiler to use -CC = gcc -# Flag: CFLAGS -# Use this flag to define compiler options. Note, you can add compiler options from the command line using XCFLAGS="other flags" -PORT_CFLAGS = -O2 -FLAGS_STR = "$(PORT_CFLAGS) $(XCFLAGS) $(XLFLAGS) $(LFLAGS_END)" -CFLAGS = $(PORT_CFLAGS) -I$(PORT_DIR) -I. -DFLAGS_STR=\"$(FLAGS_STR)\" -#Flag: LFLAGS_END -# Define any libraries needed for linking or other flags that should come at the end of the link line (e.g. linker scripts). -# Note: On certain platforms, the default clock_gettime implementation is supported but requires linking of librt. -LFLAGS_END = -# Flag: PORT_SRCS -# Port specific source files can be added here -PORT_SRCS = $(PORT_DIR)/core_portme.c -# Flag: LOAD -# Define this flag if you need to load to a target, as in a cross compile environment. - -# Flag: RUN -# Define this flag if running does not consist of simple invocation of the binary. -# In a cross compile environment, you need to define this. - -#For flashing and using a tera term macro, you could use -#LOAD = flash ADDR -#RUN = ttpmacro coremark.ttl - -#For copying to target and executing via SSH connection, you could use -#LOAD = scp $(OUTFILE) user@target:~ -#RUN = ssh user@target -c - -#For native compilation and execution -LOAD = echo Loading done -RUN = - -OEXT = .o -EXE = .exe - -# Flag: SEPARATE_COMPILE -# Define if you need to separate compilation from link stage. -# In this case, you also need to define below how to create an object file, and how to link. -ifdef SEPARATE_COMPILE - -LD = gcc -OBJOUT = -o -LFLAGS = -OFLAG = -o -COUT = -c -# Flag: PORT_OBJS -# Port specific object files can be added here -PORT_OBJS = $(PORT_DIR)/core_portme$(OEXT) -PORT_CLEAN = *$(OEXT) - -$(OPATH)%$(OEXT) : %.c - $(CC) $(CFLAGS) $(XCFLAGS) $(COUT) $< $(OBJOUT) $@ - -endif - -# Target: port_prebuild -# Generate any files that are needed before actual build starts. -# E.g. generate profile guidance files. Sample PGO generation for gcc enabled with PGO=1 -# - First, check if PGO was defined on the command line, if so, need to add -fprofile-use to compile line. -# - Second, if PGO reference has not yet been generated, add a step to the prebuild that will build a profile-generate version and run it. -# Note - Using REBUILD=1 -# -# Use make PGO=1 to invoke this sample processing. - -ifdef PGO - ifeq (,$(findstring $(PGO),gen)) - PGO_STAGE=build_pgo_gcc - CFLAGS+=-fprofile-use - endif - PORT_CLEAN+=*.gcda *.gcno gmon.out -endif - -.PHONY: port_prebuild -port_prebuild: $(PGO_STAGE) - -.PHONY: build_pgo_gcc -build_pgo_gcc: - $(MAKE) PGO=gen XCFLAGS="$(XCFLAGS) -fprofile-generate -DTOTAL_DATA_SIZE=1200" ITERATIONS=10 gen_pgo_data REBUILD=1 - -# Target: port_postbuild -# Generate any files that are needed after actual build end. -# E.g. change format to srec, bin, zip in order to be able to load into flash -.PHONY: port_postbuild -port_postbuild: - -# Target: port_postrun -# Do platform specific after run stuff. -# E.g. reset the board, backup the logfiles etc. -.PHONY: port_postrun -port_postrun: - -# Target: port_prerun -# Do platform specific after run stuff. -# E.g. reset the board, backup the logfiles etc. -.PHONY: port_prerun -port_prerun: - -# Target: port_postload -# Do platform specific after load stuff. -# E.g. reset the reset power to the flash eraser -.PHONY: port_postload -port_postload: - -# Target: port_preload -# Do platform specific before load stuff. -# E.g. reset the reset power to the flash eraser -.PHONY: port_preload -port_preload: - - -# FLAG: OPATH -# Path to the output folder. Default - current folder. -OPATH = ./ -MKDIR = mkdir -p - -# FLAG: PERL -# Define perl executable to calculate the geomean if running separate. -PERL=perl +include posix/core_portme.mak diff --git a/riscv-coremark/coremark/freebsd/core_portme.mak b/riscv-coremark/coremark/freebsd/core_portme.mak new file mode 100644 index 000000000..97b6d6ace --- /dev/null +++ b/riscv-coremark/coremark/freebsd/core_portme.mak @@ -0,0 +1,17 @@ +# Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Original Author: Shay Gal-on + +include posix/core_portme.mak diff --git a/riscv-coremark/coremark/linux/core_portme.mak b/riscv-coremark/coremark/linux/core_portme.mak old mode 100755 new mode 100644 index 5cfabee32..97b6d6ace --- a/riscv-coremark/coremark/linux/core_portme.mak +++ b/riscv-coremark/coremark/linux/core_portme.mak @@ -14,127 +14,4 @@ # # Original Author: Shay Gal-on -#File: core_portme.mak - -# Flag: OUTFLAG -# Use this flag to define how to to get an executable (e.g -o) -OUTFLAG= -o -# Flag: CC -# Use this flag to define compiler to use -CC = gcc -# Flag: CFLAGS -# Use this flag to define compiler options. Note, you can add compiler options from the command line using XCFLAGS="other flags" -PORT_CFLAGS = -O2 -FLAGS_STR = "$(PORT_CFLAGS) $(XCFLAGS) $(XLFLAGS) $(LFLAGS_END)" -CFLAGS = $(PORT_CFLAGS) -I$(PORT_DIR) -I. -DFLAGS_STR=\"$(FLAGS_STR)\" -#Flag: LFLAGS_END -# Define any libraries needed for linking or other flags that should come at the end of the link line (e.g. linker scripts). -# Note: On certain platforms, the default clock_gettime implementation is supported but requires linking of librt. -LFLAGS_END += -lrt -# Flag: PORT_SRCS -# Port specific source files can be added here -PORT_SRCS = $(PORT_DIR)/core_portme.c -# Flag: LOAD -# Define this flag if you need to load to a target, as in a cross compile environment. - -# Flag: RUN -# Define this flag if running does not consist of simple invocation of the binary. -# In a cross compile environment, you need to define this. - -#For flashing and using a tera term macro, you could use -#LOAD = flash ADDR -#RUN = ttpmacro coremark.ttl - -#For copying to target and executing via SSH connection, you could use -#LOAD = scp $(OUTFILE) user@target:~ -#RUN = ssh user@target -c - -#For native compilation and execution -LOAD = echo Loading done -RUN = - -OEXT = .o -EXE = .exe - -# Flag: SEPARATE_COMPILE -# Define if you need to separate compilation from link stage. -# In this case, you also need to define below how to create an object file, and how to link. -ifdef SEPARATE_COMPILE - -LD = gcc -OBJOUT = -o -LFLAGS = -OFLAG = -o -COUT = -c -# Flag: PORT_OBJS -# Port specific object files can be added here -PORT_OBJS = $(PORT_DIR)/core_portme$(OEXT) -PORT_CLEAN = *$(OEXT) - -$(OPATH)%$(OEXT) : %.c - $(CC) $(CFLAGS) $(XCFLAGS) $(COUT) $< $(OBJOUT) $@ - -endif - -# Target: port_prebuild -# Generate any files that are needed before actual build starts. -# E.g. generate profile guidance files. Sample PGO generation for gcc enabled with PGO=1 -# - First, check if PGO was defined on the command line, if so, need to add -fprofile-use to compile line. -# - Second, if PGO reference has not yet been generated, add a step to the prebuild that will build a profile-generate version and run it. -# Note - Using REBUILD=1 -# -# Use make PGO=1 to invoke this sample processing. - -ifdef PGO - ifeq (,$(findstring $(PGO),gen)) - PGO_STAGE=build_pgo_gcc - CFLAGS+=-fprofile-use - endif - PORT_CLEAN+=*.gcda *.gcno gmon.out -endif - -.PHONY: port_prebuild -port_prebuild: $(PGO_STAGE) - -.PHONY: build_pgo_gcc -build_pgo_gcc: - $(MAKE) PGO=gen XCFLAGS="$(XCFLAGS) -fprofile-generate -DTOTAL_DATA_SIZE=1200" ITERATIONS=10 gen_pgo_data REBUILD=1 - -# Target: port_postbuild -# Generate any files that are needed after actual build end. -# E.g. change format to srec, bin, zip in order to be able to load into flash -.PHONY: port_postbuild -port_postbuild: - -# Target: port_postrun -# Do platform specific after run stuff. -# E.g. reset the board, backup the logfiles etc. -.PHONY: port_postrun -port_postrun: - -# Target: port_prerun -# Do platform specific after run stuff. -# E.g. reset the board, backup the logfiles etc. -.PHONY: port_prerun -port_prerun: - -# Target: port_postload -# Do platform specific after load stuff. -# E.g. reset the reset power to the flash eraser -.PHONY: port_postload -port_postload: - -# Target: port_preload -# Do platform specific before load stuff. -# E.g. reset the reset power to the flash eraser -.PHONY: port_preload -port_preload: - -# FLAG: OPATH -# Path to the output folder. Default - current folder. -OPATH = ./ -MKDIR = mkdir -p - -# FLAG: PERL -# Define perl executable to calculate the geomean if running separate. -PERL=/usr/bin/perl +include posix/core_portme.mak diff --git a/riscv-coremark/coremark/macos/core_portme.mak b/riscv-coremark/coremark/macos/core_portme.mak new file mode 100644 index 000000000..6b27c3c41 --- /dev/null +++ b/riscv-coremark/coremark/macos/core_portme.mak @@ -0,0 +1,18 @@ +# Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Original Author: Shay Gal-on + +NO_LIBRT = 1 +include posix/core_portme.mak diff --git a/riscv-coremark/coremark/posix/core_portme.c b/riscv-coremark/coremark/posix/core_portme.c new file mode 100644 index 000000000..f5a7f5b3d --- /dev/null +++ b/riscv-coremark/coremark/posix/core_portme.c @@ -0,0 +1,419 @@ +/* +Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Original Author: Shay Gal-on +*/ + +#include +#include +#include "coremark.h" +#if CALLGRIND_RUN +#include +#endif + +#if (MEM_METHOD == MEM_MALLOC) +/* Function: portable_malloc + Provide malloc() functionality in a platform specific way. +*/ +void * +portable_malloc(size_t size) +{ + return malloc(size); +} +/* Function: portable_free + Provide free() functionality in a platform specific way. +*/ +void +portable_free(void *p) +{ + free(p); +} +#else +void * +portable_malloc(size_t size) +{ + return NULL; +} +void +portable_free(void *p) +{ + p = NULL; +} +#endif + +#if (SEED_METHOD == SEED_VOLATILE) +#if VALIDATION_RUN +volatile ee_s32 seed1_volatile = 0x3415; +volatile ee_s32 seed2_volatile = 0x3415; +volatile ee_s32 seed3_volatile = 0x66; +#endif +#if PERFORMANCE_RUN +volatile ee_s32 seed1_volatile = 0x0; +volatile ee_s32 seed2_volatile = 0x0; +volatile ee_s32 seed3_volatile = 0x66; +#endif +#if PROFILE_RUN +volatile ee_s32 seed1_volatile = 0x8; +volatile ee_s32 seed2_volatile = 0x8; +volatile ee_s32 seed3_volatile = 0x8; +#endif +volatile ee_s32 seed4_volatile = ITERATIONS; +volatile ee_s32 seed5_volatile = 0; +#endif +/* Porting: Timing functions + How to capture time and convert to seconds must be ported to whatever is + supported by the platform. e.g. Read value from on board RTC, read value from + cpu clock cycles performance counter etc. Sample implementation for standard + time.h and windows.h definitions included. +*/ +/* Define: TIMER_RES_DIVIDER + Divider to trade off timer resolution and total time that can be + measured. + + Use lower values to increase resolution, but make sure that overflow + does not occur. If there are issues with the return value overflowing, + increase this value. + */ +#if USE_CLOCK +#define NSECS_PER_SEC CLOCKS_PER_SEC +#define EE_TIMER_TICKER_RATE 1000 +#define CORETIMETYPE clock_t +#define GETMYTIME(_t) (*_t = clock()) +#define MYTIMEDIFF(fin, ini) ((fin) - (ini)) +#define TIMER_RES_DIVIDER 1 +#define SAMPLE_TIME_IMPLEMENTATION 1 +#elif defined(_MSC_VER) +#define NSECS_PER_SEC 10000000 +#define EE_TIMER_TICKER_RATE 1000 +#define CORETIMETYPE FILETIME +#define GETMYTIME(_t) GetSystemTimeAsFileTime(_t) +#define MYTIMEDIFF(fin, ini) \ + (((*(__int64 *)&fin) - (*(__int64 *)&ini)) / TIMER_RES_DIVIDER) +/* setting to millisces resolution by default with MSDEV */ +#ifndef TIMER_RES_DIVIDER +#define TIMER_RES_DIVIDER 1000 +#endif +#define SAMPLE_TIME_IMPLEMENTATION 1 +#elif HAS_TIME_H +#define NSECS_PER_SEC 1000000000 +#define EE_TIMER_TICKER_RATE 1000 +#define CORETIMETYPE struct timespec +#define GETMYTIME(_t) clock_gettime(CLOCK_REALTIME, _t) +#define MYTIMEDIFF(fin, ini) \ + ((fin.tv_sec - ini.tv_sec) * (NSECS_PER_SEC / TIMER_RES_DIVIDER) \ + + (fin.tv_nsec - ini.tv_nsec) / TIMER_RES_DIVIDER) +/* setting to 1/1000 of a second resolution by default with linux */ +#ifndef TIMER_RES_DIVIDER +#define TIMER_RES_DIVIDER 1000000 +#endif +#define SAMPLE_TIME_IMPLEMENTATION 1 +#else +#define SAMPLE_TIME_IMPLEMENTATION 0 +#endif +#define EE_TICKS_PER_SEC (NSECS_PER_SEC / TIMER_RES_DIVIDER) + +#if SAMPLE_TIME_IMPLEMENTATION +/** Define Host specific (POSIX), or target specific global time variables. */ +static CORETIMETYPE start_time_val, stop_time_val; + +/* Function: start_time + This function will be called right before starting the timed portion of + the benchmark. + + Implementation may be capturing a system timer (as implemented in the + example code) or zeroing some system parameters - e.g. setting the cpu clocks + cycles to 0. +*/ +void +start_time(void) +{ + GETMYTIME(&start_time_val); +#if CALLGRIND_RUN + CALLGRIND_START_INSTRUMENTATION +#endif +#if MICA + asm volatile("int3"); /*1 */ +#endif +} +/* Function: stop_time + This function will be called right after ending the timed portion of the + benchmark. + + Implementation may be capturing a system timer (as implemented in the + example code) or other system parameters - e.g. reading the current value of + cpu cycles counter. +*/ +void +stop_time(void) +{ +#if CALLGRIND_RUN + CALLGRIND_STOP_INSTRUMENTATION +#endif +#if MICA + asm volatile("int3"); /*1 */ +#endif + GETMYTIME(&stop_time_val); +} +/* Function: get_time + Return an abstract "ticks" number that signifies time on the system. + + Actual value returned may be cpu cycles, milliseconds or any other + value, as long as it can be converted to seconds by . This + methodology is taken to accomodate any hardware or simulated platform. The + sample implementation returns millisecs by default, and the resolution is + controlled by +*/ +CORE_TICKS +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. + + The type is used to accomodate systems with no support for + 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; +} +#else +#error "Please implement timing functionality in core_portme.c" +#endif /* SAMPLE_TIME_IMPLEMENTATION */ + +ee_u32 default_num_contexts = MULTITHREAD; + +/* Function: portable_init + Target specific initialization code + Test for some common mistakes. +*/ +void +portable_init(core_portable *p, int *argc, char *argv[]) +{ +#if PRINT_ARGS + int i; + for (i = 0; i < *argc; i++) + { + ee_printf("Arg[%d]=%s\n", i, argv[i]); + } +#endif + 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"); + } +#if (MAIN_HAS_NOARGC && (SEED_METHOD == SEED_ARG)) + ee_printf( + "ERROR! Main has no argc, but SEED_METHOD defined to SEED_ARG!\n"); +#endif + +#if (MULTITHREAD > 1) && (SEED_METHOD == SEED_ARG) + int nargs = *argc, i; + if ((nargs > 1) && (*argv[1] == 'M')) + { + default_num_contexts = parseval(argv[1] + 1); + if (default_num_contexts > MULTITHREAD) + default_num_contexts = MULTITHREAD; + /* Shift args since first arg is directed to the portable part and not + * to coremark main */ + --nargs; + for (i = 1; i < nargs; i++) + argv[i] = argv[i + 1]; + *argc = nargs; + } +#endif /* sample of potential platform specific init via command line, reset \ + the number of contexts being used if first argument is M*/ + p->portable_id = 1; +} +/* Function: portable_fini + Target specific final code +*/ +void +portable_fini(core_portable *p) +{ + p->portable_id = 0; +} + +#if (MULTITHREAD > 1) + +/* Function: core_start_parallel + Start benchmarking in a parallel context. + + Three implementations are provided, one using pthreads, one using fork + and shared mem, and one using fork and sockets. Other implementations using + MCAPI or other standards can easily be devised. +*/ +/* Function: core_stop_parallel + Stop a parallel context execution of coremark, and gather the results. + + Three implementations are provided, one using pthreads, one using fork + and shared mem, and one using fork and sockets. Other implementations using + MCAPI or other standards can easily be devised. +*/ +#if USE_PTHREAD +ee_u8 +core_start_parallel(core_results *res) +{ + return (ee_u8)pthread_create( + &(res->port.thread), NULL, iterate, (void *)res); +} +ee_u8 +core_stop_parallel(core_results *res) +{ + void *retval; + return (ee_u8)pthread_join(res->port.thread, &retval); +} +#elif USE_FORK +static int key_id = 0; +ee_u8 +core_start_parallel(core_results *res) +{ + key_t key = 4321 + key_id; + key_id++; + res->port.pid = fork(); + res->port.shmid = shmget(key, 8, IPC_CREAT | 0666); + if (res->port.shmid < 0) + { + ee_printf("ERROR in shmget!\n"); + } + if (res->port.pid == 0) + { + iterate(res); + res->port.shm = shmat(res->port.shmid, NULL, 0); + /* copy the validation values to the shared memory area and quit*/ + if (res->port.shm == (char *)-1) + { + ee_printf("ERROR in child shmat!\n"); + } + else + { + memcpy(res->port.shm, &(res->crc), 8); + shmdt(res->port.shm); + } + exit(0); + } + return 1; +} +ee_u8 +core_stop_parallel(core_results *res) +{ + int status; + pid_t wpid = waitpid(res->port.pid, &status, WUNTRACED); + if (wpid != res->port.pid) + { + ee_printf("ERROR waiting for child.\n"); + if (errno == ECHILD) + ee_printf("errno=No such child %d\n", res->port.pid); + if (errno == EINTR) + ee_printf("errno=Interrupted\n"); + return 0; + } + /* after process is done, get the values from the shared memory area */ + res->port.shm = shmat(res->port.shmid, NULL, 0); + if (res->port.shm == (char *)-1) + { + ee_printf("ERROR in parent shmat!\n"); + return 0; + } + memcpy(&(res->crc), res->port.shm, 8); + shmdt(res->port.shm); + return 1; +} +#elif USE_SOCKET +static int key_id = 0; +ee_u8 +core_start_parallel(core_results *res) +{ + int bound, buffer_length = 8; + res->port.sa.sin_family = AF_INET; + res->port.sa.sin_addr.s_addr = htonl(0x7F000001); + res->port.sa.sin_port = htons(7654 + key_id); + key_id++; + res->port.pid = fork(); + if (res->port.pid == 0) + { /* benchmark child */ + iterate(res); + res->port.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (-1 == res->port.sock) /* if socket failed to initialize, exit */ + { + ee_printf("Error Creating Socket"); + } + else + { + int bytes_sent = sendto(res->port.sock, + &(res->crc), + buffer_length, + 0, + (struct sockaddr *)&(res->port.sa), + sizeof(struct sockaddr_in)); + if (bytes_sent < 0) + ee_printf("Error sending packet: %s\n", strerror(errno)); + close(res->port.sock); /* close the socket */ + } + exit(0); + } + /* parent process, open the socket */ + res->port.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + bound = bind(res->port.sock, + (struct sockaddr *)&(res->port.sa), + sizeof(struct sockaddr)); + if (bound < 0) + ee_printf("bind(): %s\n", strerror(errno)); + return 1; +} +ee_u8 +core_stop_parallel(core_results *res) +{ + int status; + int fromlen = sizeof(struct sockaddr); + int recsize = recvfrom(res->port.sock, + &(res->crc), + 8, + 0, + (struct sockaddr *)&(res->port.sa), + &fromlen); + if (recsize < 0) + { + ee_printf("Error in receive: %s\n", strerror(errno)); + return 0; + } + pid_t wpid = waitpid(res->port.pid, &status, WUNTRACED); + if (wpid != res->port.pid) + { + ee_printf("ERROR waiting for child.\n"); + if (errno == ECHILD) + ee_printf("errno=No such child %d\n", res->port.pid); + if (errno == EINTR) + ee_printf("errno=Interrupted\n"); + return 0; + } + return 1; +} +#else /* no standard multicore implementation */ +#error \ + "Please implement multicore functionality in core_portme.c to use multiple contexts." +#endif /* multithread implementations */ +#endif diff --git a/riscv-coremark/coremark/posix/core_portme.h b/riscv-coremark/coremark/posix/core_portme.h new file mode 100644 index 000000000..e49e474b1 --- /dev/null +++ b/riscv-coremark/coremark/posix/core_portme.h @@ -0,0 +1,314 @@ +/* +Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Original Author: Shay Gal-on +*/ + +/* Topic: Description + This file contains configuration constants required to execute on + different platforms +*/ +#ifndef CORE_PORTME_H +#define CORE_PORTME_H + +#include "core_portme_posix_overrides.h" + +/************************/ +/* Data types and settings */ +/************************/ +/* Configuration: HAS_FLOAT + Define to 1 if the platform supports floating point. +*/ +#ifndef HAS_FLOAT +#define HAS_FLOAT 1 +#endif +/* Configuration: HAS_TIME_H + Define to 1 if platform has the time.h header file, + and implementation of functions thereof. +*/ +#ifndef HAS_TIME_H +#define HAS_TIME_H 1 +#endif +/* Configuration: USE_CLOCK + Define to 1 if platform has the time.h header file, + and implementation of functions thereof. +*/ +#ifndef USE_CLOCK +#define USE_CLOCK 0 +#endif +/* Configuration: HAS_STDIO + Define to 1 if the platform has stdio.h. +*/ +#ifndef HAS_STDIO +#define HAS_STDIO 1 +#endif +/* Configuration: HAS_PRINTF + Define to 1 if the platform has stdio.h and implements the printf + function. +*/ +#ifndef HAS_PRINTF +#define HAS_PRINTF 1 +#endif + +/* Configuration: CORE_TICKS + Define type of return from the timing functions. + */ +#if defined(_MSC_VER) +#include +typedef size_t CORE_TICKS; +#elif HAS_TIME_H +#include +typedef clock_t CORE_TICKS; +#else +#error \ + "Please define type of CORE_TICKS and implement start_time, end_time get_time and time_in_secs functions!" +#endif + +/* Definitions: COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION + Initialize these strings per platform +*/ +#ifndef COMPILER_VERSION +#ifdef __GNUC__ +#define COMPILER_VERSION "GCC"__VERSION__ +#else +#define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)" +#endif +#endif +#ifndef COMPILER_FLAGS +#define COMPILER_FLAGS \ + FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */ +#endif +#ifndef MEM_LOCATION +#define MEM_LOCATION \ + "Please put data memory location here\n\t\t\t(e.g. code in flash, data " \ + "on heap etc)" +#define MEM_LOCATION_UNSPEC 1 +#endif + +#include + +/* Data Types: + To avoid compiler issues, define the data types that need ot be used for + 8b, 16b and 32b in . + + *Imprtant*: + ee_ptr_int needs to be the data type used to hold pointers, otherwise + coremark may fail!!! +*/ +typedef signed short ee_s16; +typedef unsigned short ee_u16; +typedef signed int ee_s32; +typedef double ee_f32; +typedef unsigned char ee_u8; +typedef unsigned int ee_u32; +typedef uintptr_t ee_ptr_int; +typedef size_t ee_size_t; +/* align an offset to point to a 32b value */ +#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x)-1) & ~3)) + +/* Configuration: SEED_METHOD + Defines method to get seed values that cannot be computed at compile + time. + + Valid values: + SEED_ARG - from command line. + SEED_FUNC - from a system function. + SEED_VOLATILE - from volatile variables. +*/ +#ifndef SEED_METHOD +#define SEED_METHOD SEED_ARG +#endif + +/* Configuration: MEM_METHOD + Defines method to get a block of memry. + + Valid values: + MEM_MALLOC - for platforms that implement malloc and have malloc.h. + MEM_STATIC - to use a static memory array. + MEM_STACK - to allocate the data block on the stack (NYI). +*/ +#ifndef MEM_METHOD +#define MEM_METHOD MEM_MALLOC +#endif + +/* Configuration: MULTITHREAD + Define for parallel execution + + Valid values: + 1 - only one context (default). + N>1 - will execute N copies in parallel. + + Note: + If this flag is defined to more then 1, an implementation for launching + parallel contexts must be defined. + + Two sample implementations are provided. Use or + to enable them. + + It is valid to have a different implementation of + and in , to fit a particular architecture. +*/ +#ifndef MULTITHREAD +#define MULTITHREAD 1 +#endif + +/* Configuration: USE_PTHREAD + Sample implementation for launching parallel contexts + This implementation uses pthread_thread_create and pthread_join. + + Valid values: + 0 - Do not use pthreads API. + 1 - Use pthreads API + + Note: + This flag only matters if MULTITHREAD has been defined to a value + greater then 1. +*/ +#ifndef USE_PTHREAD +#define USE_PTHREAD 0 +#endif + +/* Configuration: USE_FORK + Sample implementation for launching parallel contexts + This implementation uses fork, waitpid, shmget,shmat and shmdt. + + Valid values: + 0 - Do not use fork API. + 1 - Use fork API + + Note: + This flag only matters if MULTITHREAD has been defined to a value + greater then 1. +*/ +#ifndef USE_FORK +#define USE_FORK 0 +#endif + +/* Configuration: USE_SOCKET + Sample implementation for launching parallel contexts + This implementation uses fork, socket, sendto and recvfrom + + Valid values: + 0 - Do not use fork and sockets API. + 1 - Use fork and sockets API + + Note: + This flag only matters if MULTITHREAD has been defined to a value + greater then 1. +*/ +#ifndef USE_SOCKET +#define USE_SOCKET 0 +#endif + +/* Configuration: MAIN_HAS_NOARGC + Needed if platform does not support getting arguments to main. + + Valid values: + 0 - argc/argv to main is supported + 1 - argc/argv to main is not supported +*/ +#ifndef MAIN_HAS_NOARGC +#define MAIN_HAS_NOARGC 0 +#endif + +/* Configuration: MAIN_HAS_NORETURN + Needed if platform does not support returning a value from main. + + Valid values: + 0 - main returns an int, and return value will be 0. + 1 - platform does not support returning a value from main +*/ +#ifndef MAIN_HAS_NORETURN +#define MAIN_HAS_NORETURN 0 +#endif + +/* Variable: default_num_contexts + Number of contexts to spawn in multicore context. + Override this global value to change number of contexts used. + + Note: + This value may not be set higher then the define. + + To experiment, you can set the define to the highest value + expected, and use argc/argv in the to set this value from the + command line. +*/ +extern ee_u32 default_num_contexts; + +#if (MULTITHREAD > 1) +#if USE_PTHREAD +#include +#define PARALLEL_METHOD "PThreads" +#elif USE_FORK +#include +#include +#include +#include +#include /* for memcpy */ +#define PARALLEL_METHOD "Fork" +#elif USE_SOCKET +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define PARALLEL_METHOD "Sockets" +#else +#define PARALLEL_METHOD "Proprietary" +#error \ + "Please implement multicore functionality in core_portme.c to use multiple contexts." +#endif /* Method for multithreading */ +#endif /* MULTITHREAD > 1 */ + +typedef struct CORE_PORTABLE_S +{ +#if (MULTITHREAD > 1) +#if USE_PTHREAD + pthread_t thread; +#elif USE_FORK + pid_t pid; + int shmid; + void *shm; +#elif USE_SOCKET + pid_t pid; + int sock; + struct sockaddr_in sa; +#endif /* Method for multithreading */ +#endif /* MULTITHREAD>1 */ + ee_u8 portable_id; +} core_portable; + +/* target specific init/fini */ +void portable_init(core_portable *p, int *argc, char *argv[]); +void portable_fini(core_portable *p); + +#if (SEED_METHOD == SEED_VOLATILE) +#if (VALIDATION_RUN || PERFORMANCE_RUN || PROFILE_RUN) +#define RUN_TYPE_FLAG 1 +#else +#if (TOTAL_DATA_SIZE == 1200) +#define PROFILE_RUN 1 +#else +#define PERFORMANCE_RUN 1 +#endif +#endif +#endif /* SEED_METHOD==SEED_VOLATILE */ + +#endif /* CORE_PORTME_H */ diff --git a/riscv-coremark/coremark/posix/core_portme.mak b/riscv-coremark/coremark/posix/core_portme.mak new file mode 100755 index 000000000..e6be71a7e --- /dev/null +++ b/riscv-coremark/coremark/posix/core_portme.mak @@ -0,0 +1,151 @@ +# Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Original Author: Shay Gal-on + +#File: core_portme.mak + +# Flag: OUTFLAG +# Use this flag to define how to to get an executable (e.g -o) +OUTFLAG= -o +# Flag: CC +# Use this flag to define compiler to use +CC?= cc +# Flag: CFLAGS +# Use this flag to define compiler options. Note, you can add compiler options from the command line using XCFLAGS="other flags" +PORT_CFLAGS = -O2 +FLAGS_STR = "$(PORT_CFLAGS) $(XCFLAGS) $(XLFLAGS) $(LFLAGS_END)" +CFLAGS = $(PORT_CFLAGS) -I$(PORT_DIR) -Iposix -I. -DFLAGS_STR=\"$(FLAGS_STR)\" +# Flag: NO_LIBRT +# Define if the platform does not provide a librt +ifndef NO_LIBRT +#Flag: LFLAGS_END +# Define any libraries needed for linking or other flags that should come at the end of the link line (e.g. linker scripts). +# Note: On certain platforms, the default clock_gettime implementation is supported but requires linking of librt. +LFLAGS_END += -lrt +endif +# Flag: PORT_SRCS +# Port specific source files can be added here +PORT_SRCS = posix/core_portme.c +vpath %.c posix +vpath %.h posix +vpath %.mak posix +# Flag: EXTRA_DEPENDS +# Port specific extra build dependencies. +# Some ports inherit from us, so ensure this Makefile is always a dependency. +EXTRA_DEPENDS += posix/core_portme.mak +# Flag: LOAD +# Define this flag if you need to load to a target, as in a cross compile environment. + +# Flag: RUN +# Define this flag if running does not consist of simple invocation of the binary. +# In a cross compile environment, you need to define this. + +#For flashing and using a tera term macro, you could use +#LOAD = flash ADDR +#RUN = ttpmacro coremark.ttl + +#For copying to target and executing via SSH connection, you could use +#LOAD = scp $(OUTFILE) user@target:~ +#RUN = ssh user@target -c + +#For native compilation and execution +LOAD = echo Loading done +RUN = + +OEXT = .o +EXE = .exe + +# Flag: SEPARATE_COMPILE +# Define if you need to separate compilation from link stage. +# In this case, you also need to define below how to create an object file, and how to link. +ifdef SEPARATE_COMPILE + +LD = gcc +OBJOUT = -o +LFLAGS = +OFLAG = -o +COUT = -c +# Flag: PORT_OBJS +# Port specific object files can be added here +PORT_OBJS = $(PORT_DIR)/core_portme$(OEXT) +PORT_CLEAN = *$(OEXT) + +$(OPATH)%$(OEXT) : %.c + $(CC) $(CFLAGS) $(XCFLAGS) $(COUT) $< $(OBJOUT) $@ + +endif + +# Target: port_prebuild +# Generate any files that are needed before actual build starts. +# E.g. generate profile guidance files. Sample PGO generation for gcc enabled with PGO=1 +# - First, check if PGO was defined on the command line, if so, need to add -fprofile-use to compile line. +# - Second, if PGO reference has not yet been generated, add a step to the prebuild that will build a profile-generate version and run it. +# Note - Using REBUILD=1 +# +# Use make PGO=1 to invoke this sample processing. + +ifdef PGO + ifeq (,$(findstring $(PGO),gen)) + PGO_STAGE=build_pgo_gcc + CFLAGS+=-fprofile-use + endif + PORT_CLEAN+=*.gcda *.gcno gmon.out +endif + +.PHONY: port_prebuild +port_prebuild: $(PGO_STAGE) + +.PHONY: build_pgo_gcc +build_pgo_gcc: + $(MAKE) PGO=gen XCFLAGS="$(XCFLAGS) -fprofile-generate -DTOTAL_DATA_SIZE=1200" ITERATIONS=10 gen_pgo_data REBUILD=1 + +# Target: port_postbuild +# Generate any files that are needed after actual build end. +# E.g. change format to srec, bin, zip in order to be able to load into flash +.PHONY: port_postbuild +port_postbuild: + +# Target: port_postrun +# Do platform specific after run stuff. +# E.g. reset the board, backup the logfiles etc. +.PHONY: port_postrun +port_postrun: + +# Target: port_prerun +# Do platform specific after run stuff. +# E.g. reset the board, backup the logfiles etc. +.PHONY: port_prerun +port_prerun: + +# Target: port_postload +# Do platform specific after load stuff. +# E.g. reset the reset power to the flash eraser +.PHONY: port_postload +port_postload: + +# Target: port_preload +# Do platform specific before load stuff. +# E.g. reset the reset power to the flash eraser +.PHONY: port_preload +port_preload: + +# FLAG: OPATH +# Path to the output folder. Default - current folder. +OPATH = ./ +MKDIR = mkdir -p + +# FLAG: PERL +# Define perl executable to calculate the geomean if running separate. +PERL=/usr/bin/perl diff --git a/riscv-coremark/coremark/posix/core_portme_posix_overrides.h b/riscv-coremark/coremark/posix/core_portme_posix_overrides.h new file mode 100644 index 000000000..c0e998adf --- /dev/null +++ b/riscv-coremark/coremark/posix/core_portme_posix_overrides.h @@ -0,0 +1,28 @@ +/* +Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC) + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +Original Author: Shay Gal-on +*/ + +/* Topic: Description + This file contains additional configuration constants required to execute on + different platforms over and above the POSIX defaults +*/ +#ifndef CORE_PORTME_POSIX_OVERRIDES_H +#define CORE_PORTME_POSIX_OVERRIDES_H + +/* None by default */ + +#endif diff --git a/riscv-coremark/coremark/rtems/core_portme.mak b/riscv-coremark/coremark/rtems/core_portme.mak new file mode 100644 index 000000000..6b27c3c41 --- /dev/null +++ b/riscv-coremark/coremark/rtems/core_portme.mak @@ -0,0 +1,18 @@ +# Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Original Author: Shay Gal-on + +NO_LIBRT = 1 +include posix/core_portme.mak diff --git a/riscv-coremark/coremark/rtems/init.c b/riscv-coremark/coremark/rtems/init.c new file mode 100644 index 000000000..64d3e59ae --- /dev/null +++ b/riscv-coremark/coremark/rtems/init.c @@ -0,0 +1,63 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2021 Hesham Almatary + * + * This software was developed by SRI International and the University of + * Cambridge Computer Laboratory (Department of Computer Science and + * Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the + * DARPA SSITH research programme. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include + +int main( + int argc, + void **args +); + +rtems_task Init( + rtems_task_argument ignored +); + +rtems_task Init( + rtems_task_argument ignored +) +{ + int ret = main(0, NULL); + exit(ret); +} + +/* configuration information */ +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER + +#define CONFIGURE_MAXIMUM_TASKS 20 + +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE + +#define CONFIGURE_INIT + +#include diff --git a/riscv-coremark/coremark/simple/core_portme.c b/riscv-coremark/coremark/simple/core_portme.c old mode 100755 new mode 100644 index 33c863d1e..b95e3b21e --- a/riscv-coremark/coremark/simple/core_portme.c +++ b/riscv-coremark/coremark/simple/core_portme.c @@ -21,108 +21,129 @@ Original Author: Shay Gal-on #include "coremark.h" #if VALIDATION_RUN - volatile ee_s32 seed1_volatile=0x3415; - volatile ee_s32 seed2_volatile=0x3415; - volatile ee_s32 seed3_volatile=0x66; +volatile ee_s32 seed1_volatile = 0x3415; +volatile ee_s32 seed2_volatile = 0x3415; +volatile ee_s32 seed3_volatile = 0x66; #endif #if PERFORMANCE_RUN - volatile ee_s32 seed1_volatile=0x0; - volatile ee_s32 seed2_volatile=0x0; - volatile ee_s32 seed3_volatile=0x66; +volatile ee_s32 seed1_volatile = 0x0; +volatile ee_s32 seed2_volatile = 0x0; +volatile ee_s32 seed3_volatile = 0x66; #endif #if PROFILE_RUN - volatile ee_s32 seed1_volatile=0x8; - volatile ee_s32 seed2_volatile=0x8; - volatile ee_s32 seed3_volatile=0x8; +volatile ee_s32 seed1_volatile = 0x8; +volatile ee_s32 seed2_volatile = 0x8; +volatile ee_s32 seed3_volatile = 0x8; #endif - volatile ee_s32 seed4_volatile=ITERATIONS; - volatile ee_s32 seed5_volatile=0; +volatile ee_s32 seed4_volatile = ITERATIONS; +volatile ee_s32 seed5_volatile = 0; /* Porting : Timing functions - How to capture time and convert to seconds must be ported to whatever is supported by the platform. - e.g. Read value from on board RTC, read value from cpu clock cycles performance counter etc. - Sample implementation for standard time.h and windows.h definitions included. + How to capture time and convert to seconds must be ported to whatever is + supported by the platform. e.g. Read value from on board RTC, read value from + cpu clock cycles performance counter etc. Sample implementation for standard + time.h and windows.h definitions included. */ /* Define : TIMER_RES_DIVIDER - Divider to trade off timer resolution and total time that can be measured. + Divider to trade off timer resolution and total time that can be + measured. - Use lower values to increase resolution, but make sure that overflow does not occur. - If there are issues with the return value overflowing, increase this value. - */ -#define NSECS_PER_SEC CLOCKS_PER_SEC -#define CORETIMETYPE clock_t -#define GETMYTIME(_t) (*_t=clock()) -#define MYTIMEDIFF(fin,ini) ((fin)-(ini)) -#define TIMER_RES_DIVIDER 1 + Use lower values to increase resolution, but make sure that overflow + does not occur. If there are issues with the return value overflowing, + increase this value. + */ +#define NSECS_PER_SEC CLOCKS_PER_SEC +#define CORETIMETYPE clock_t +#define GETMYTIME(_t) (*_t = clock()) +#define MYTIMEDIFF(fin, ini) ((fin) - (ini)) +#define TIMER_RES_DIVIDER 1 #define SAMPLE_TIME_IMPLEMENTATION 1 -#define EE_TICKS_PER_SEC (NSECS_PER_SEC / TIMER_RES_DIVIDER) +#define EE_TICKS_PER_SEC (NSECS_PER_SEC / TIMER_RES_DIVIDER) /** Define Host specific (POSIX), or target specific global time variables. */ static CORETIMETYPE start_time_val, stop_time_val; /* Function : start_time - This function will be called right before starting the timed portion of the benchmark. + This function will be called right before starting the timed portion of + the benchmark. - Implementation may be capturing a system timer (as implemented in the example code) - or zeroing some system parameters - e.g. setting the cpu clocks cycles to 0. + Implementation may be capturing a system timer (as implemented in the + 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. + This function will be called right after ending the timed portion of the + benchmark. - Implementation may be capturing a system timer (as implemented in the example code) - or other system parameters - e.g. reading the current value of cpu cycles counter. + Implementation may be capturing a system timer (as implemented in the + 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. - - Actual value returned may be cpu cycles, milliseconds or any other value, - as long as it can be converted to seconds by . - This methodology is taken to accomodate any hardware or simulated platform. - The sample implementation returns millisecs by default, - and the resolution is controlled by + Return an abstract "ticks" number that signifies time on the system. + + Actual value returned may be cpu cycles, milliseconds or any other + value, as long as it can be converted to seconds by . This + methodology is taken to accomodate any hardware or simulated platform. The + sample implementation returns millisecs by default, and the resolution is + controlled by */ -CORE_TICKS get_time(void) { - CORE_TICKS elapsed=(CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val)); - return elapsed; +CORE_TICKS +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. + Convert the value returned by get_time to seconds. - The type is used to accomodate systems with no support for floating point. - Default implementation implemented by the EE_TICKS_PER_SEC macro above. + The type is used to accomodate systems with no support for + 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; +ee_u32 default_num_contexts = 1; /* Function : portable_init - Target specific initialization code - Test for some common mistakes. + Target specific initialization code + Test for some common mistakes. */ -void portable_init(core_portable *p, int *argc, char *argv[]) +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; + 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; } /* Function : portable_fini - Target specific final code + Target specific final code */ -void portable_fini(core_portable *p) +void +portable_fini(core_portable *p) { - p->portable_id=0; + p->portable_id = 0; } - - diff --git a/riscv-coremark/coremark/simple/core_portme.h b/riscv-coremark/coremark/simple/core_portme.h old mode 100755 new mode 100644 index a3607bfbb..dfd94cbfc --- a/riscv-coremark/coremark/simple/core_portme.h +++ b/riscv-coremark/coremark/simple/core_portme.h @@ -17,176 +17,188 @@ Original Author: Shay Gal-on */ /* Topic : Description - This file contains configuration constants required to execute on different platforms + This file contains configuration constants required to execute on + different platforms */ #ifndef CORE_PORTME_H #define CORE_PORTME_H /************************/ /* Data types and settings */ /************************/ -/* Configuration : HAS_FLOAT - Define to 1 if the platform supports floating point. +/* Configuration : HAS_FLOAT + Define to 1 if the platform supports floating point. */ -#ifndef HAS_FLOAT +#ifndef HAS_FLOAT #define HAS_FLOAT 1 #endif /* Configuration : HAS_TIME_H - Define to 1 if platform has the time.h header file, - and implementation of functions thereof. + Define to 1 if platform has the time.h header file, + and implementation of functions thereof. */ #ifndef HAS_TIME_H #define HAS_TIME_H 1 #endif /* Configuration : USE_CLOCK - Define to 1 if platform has the time.h header file, - and implementation of functions thereof. + Define to 1 if platform has the time.h header file, + and implementation of functions thereof. */ #ifndef USE_CLOCK #define USE_CLOCK 1 #endif /* Configuration : HAS_STDIO - Define to 1 if the platform has stdio.h. + Define to 1 if the platform has stdio.h. */ #ifndef HAS_STDIO #define HAS_STDIO 1 #endif /* Configuration : HAS_PRINTF - Define to 1 if the platform has stdio.h and implements the printf function. + Define to 1 if the platform has stdio.h and implements the printf + function. */ #ifndef HAS_PRINTF #define HAS_PRINTF 1 #endif /* Configuration : CORE_TICKS - Define type of return from the timing functions. + Define type of return from the timing functions. */ #include typedef clock_t CORE_TICKS; /* Definitions : COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION - Initialize these strings per platform + Initialize these strings per platform */ -#ifndef COMPILER_VERSION - #ifdef __GNUC__ - #define COMPILER_VERSION "GCC"__VERSION__ - #else - #define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)" - #endif +#ifndef COMPILER_VERSION +#ifdef __GNUC__ +#define COMPILER_VERSION "GCC"__VERSION__ +#else +#define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)" #endif -#ifndef COMPILER_FLAGS - #define COMPILER_FLAGS FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */ #endif -#ifndef MEM_LOCATION - #define MEM_LOCATION "STACK" +#ifndef COMPILER_FLAGS +#define COMPILER_FLAGS \ + FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */ +#endif +#ifndef MEM_LOCATION +#define MEM_LOCATION "STACK" #endif /* Data Types : - To avoid compiler issues, define the data types that need ot be used for 8b, 16b and 32b in . - - *Imprtant* : - ee_ptr_int needs to be the data type used to hold pointers, otherwise coremark may fail!!! + To avoid compiler issues, define the data types that need ot be used for + 8b, 16b and 32b in . + + *Imprtant* : + ee_ptr_int needs to be the data type used to hold pointers, otherwise + coremark may fail!!! */ -typedef signed short ee_s16; +typedef signed short ee_s16; typedef unsigned short ee_u16; -typedef signed int ee_s32; -typedef double ee_f32; -typedef unsigned char ee_u8; -typedef unsigned int ee_u32; -typedef ee_u32 ee_ptr_int; -typedef size_t ee_size_t; +typedef signed int ee_s32; +typedef double ee_f32; +typedef unsigned char ee_u8; +typedef unsigned int ee_u32; +typedef ee_u32 ee_ptr_int; +typedef size_t ee_size_t; /* align_mem : - This macro is used to align an offset to point to a 32b value. It is used in the Matrix algorithm to initialize the input memory blocks. + This macro is used to align an offset to point to a 32b value. It is + used in the Matrix algorithm to initialize the input memory blocks. */ -#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x) - 1) & ~3)) +#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x)-1) & ~3)) /* Configuration : SEED_METHOD - Defines method to get seed values that cannot be computed at compile time. - - Valid values : - SEED_ARG - from command line. - SEED_FUNC - from a system function. - SEED_VOLATILE - from volatile variables. + Defines method to get seed values that cannot be computed at compile + time. + + Valid values : + SEED_ARG - from command line. + SEED_FUNC - from a system function. + SEED_VOLATILE - from volatile variables. */ #ifndef SEED_METHOD #define SEED_METHOD SEED_VOLATILE #endif /* Configuration : MEM_METHOD - Defines method to get a block of memry. - - Valid values : - MEM_MALLOC - for platforms that implement malloc and have malloc.h. - MEM_STATIC - to use a static memory array. - MEM_STACK - to allocate the data block on the stack (NYI). + Defines method to get a block of memry. + + Valid values : + MEM_MALLOC - for platforms that implement malloc and have malloc.h. + MEM_STATIC - to use a static memory array. + MEM_STACK - to allocate the data block on the stack (NYI). */ #ifndef MEM_METHOD #define MEM_METHOD MEM_STACK #endif /* Configuration : MULTITHREAD - Define for parallel execution - - Valid values : - 1 - only one context (default). - N>1 - will execute N copies in parallel. - - Note : - If this flag is defined to more then 1, an implementation for launching parallel contexts must be defined. - - Two sample implementations are provided. Use or to enable them. - - It is valid to have a different implementation of and in , - to fit a particular architecture. + Define for parallel execution + + Valid values : + 1 - only one context (default). + N>1 - will execute N copies in parallel. + + Note : + If this flag is defined to more then 1, an implementation for launching + parallel contexts must be defined. + + Two sample implementations are provided. Use or + to enable them. + + It is valid to have a different implementation of + and in , to fit a particular architecture. */ #ifndef MULTITHREAD #define MULTITHREAD 1 #define USE_PTHREAD 0 -#define USE_FORK 0 -#define USE_SOCKET 0 +#define USE_FORK 0 +#define USE_SOCKET 0 #endif /* Configuration : MAIN_HAS_NOARGC - Needed if platform does not support getting arguments to main. - - Valid values : - 0 - argc/argv to main is supported - 1 - argc/argv to main is not supported - - Note : - This flag only matters if MULTITHREAD has been defined to a value greater then 1. + Needed if platform does not support getting arguments to main. + + Valid values : + 0 - argc/argv to main is supported + 1 - argc/argv to main is not supported + + Note : + This flag only matters if MULTITHREAD has been defined to a value + greater then 1. */ -#ifndef MAIN_HAS_NOARGC +#ifndef MAIN_HAS_NOARGC #define MAIN_HAS_NOARGC 0 #endif /* Configuration : MAIN_HAS_NORETURN - Needed if platform does not support returning a value from main. - - Valid values : - 0 - main returns an int, and return value will be 0. - 1 - platform does not support returning a value from main + Needed if platform does not support returning a value from main. + + Valid values : + 0 - main returns an int, and return value will be 0. + 1 - platform does not support returning a value from main */ #ifndef MAIN_HAS_NORETURN #define MAIN_HAS_NORETURN 0 #endif /* Variable : default_num_contexts - Not used for this simple port, must cintain the value 1. + Not used for this simple port, must cintain the value 1. */ extern ee_u32 default_num_contexts; -typedef struct CORE_PORTABLE_S { - ee_u8 portable_id; +typedef struct CORE_PORTABLE_S +{ + ee_u8 portable_id; } core_portable; /* target specific init/fini */ void portable_init(core_portable *p, int *argc, char *argv[]); void portable_fini(core_portable *p); -#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) && !defined(VALIDATION_RUN) -#if (TOTAL_DATA_SIZE==1200) +#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) \ + && !defined(VALIDATION_RUN) +#if (TOTAL_DATA_SIZE == 1200) #define PROFILE_RUN 1 -#elif (TOTAL_DATA_SIZE==2000) +#elif (TOTAL_DATA_SIZE == 2000) #define PERFORMANCE_RUN 1 #else #define VALIDATION_RUN 1