123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- /*
- Author : Shay Gal-On, EEMBC
- This file is part of EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009
- All rights reserved.
- EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the
- CoreMark License that is distributed with the official EEMBC COREMARK Software release.
- If you received this EEMBC CoreMark Software without the accompanying CoreMark License,
- you must discontinue use and download the official release from www.coremark.org.
- Also, if you are publicly displaying scores generated from the EEMBC CoreMark software,
- make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file.
- EEMBC
- 4354 Town Center Blvd. Suite 114-200
- El Dorado Hills, CA, 95762
- */
- #include "coremark.h"
- /* local functions */
- enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count);
- /*
- Topic: Description
- Simple state machines like this one are used in many embedded products.
-
- For more complex state machines, sometimes a state transition table implementation is used instead,
- trading speed of direct coding for ease of maintenance.
-
- Since the main goal of using a state machine in CoreMark is to excercise the switch/if behaviour,
- we are using a small moore machine.
-
- In particular, this machine tests type of string input,
- trying to determine whether the input is a number or something else.
- (see core_state.png).
- */
- /* Function: core_bench_state
- Benchmark function
- Go over the input twice, once direct, and once after introducing some corruption.
- */
- ee_u16 core_bench_state(ee_u32 blksize, ee_u8 *memblock,
- ee_s16 seed1, ee_s16 seed2, ee_s16 step, ee_u16 crc)
- {
- ee_u32 final_counts[NUM_CORE_STATES];
- ee_u32 track_counts[NUM_CORE_STATES];
- ee_u8 *p=memblock;
- ee_u32 i;
- #if CORE_DEBUG
- ee_printf("State Bench: %d,%d,%d,%04x\n",seed1,seed2,step,crc);
- #endif
- for (i=0; i<NUM_CORE_STATES; i++) {
- final_counts[i]=track_counts[i]=0;
- }
- /* run the state machine over the input */
- while (*p!=0) {
- enum CORE_STATE fstate=core_state_transition(&p,track_counts);
- final_counts[fstate]++;
- #if CORE_DEBUG
- ee_printf("%d,",fstate);
- }
- ee_printf("\n");
- #else
- }
- #endif
- p=memblock;
- while (p < (memblock+blksize)) { /* insert some corruption */
- if (*p!=',')
- *p^=(ee_u8)seed1;
- p+=step;
- }
- p=memblock;
- /* run the state machine over the input again */
- while (*p!=0) {
- enum CORE_STATE fstate=core_state_transition(&p,track_counts);
- final_counts[fstate]++;
- #if CORE_DEBUG
- ee_printf("%d,",fstate);
- }
- ee_printf("\n");
- #else
- }
- #endif
- p=memblock;
- while (p < (memblock+blksize)) { /* undo corruption is seed1 and seed2 are equal */
- if (*p!=',')
- *p^=(ee_u8)seed2;
- p+=step;
- }
- /* end timing */
- for (i=0; i<NUM_CORE_STATES; i++) {
- crc=crcu32(final_counts[i],crc);
- crc=crcu32(track_counts[i],crc);
- }
- return crc;
- }
- /* Default initialization patterns */
- static ee_u8 *intpat[4] ={(ee_u8 *)"5012",(ee_u8 *)"1234",(ee_u8 *)"-874",(ee_u8 *)"+122"};
- static ee_u8 *floatpat[4]={(ee_u8 *)"35.54400",(ee_u8 *)".1234500",(ee_u8 *)"-110.700",(ee_u8 *)"+0.64400"};
- static ee_u8 *scipat[4] ={(ee_u8 *)"5.500e+3",(ee_u8 *)"-.123e-2",(ee_u8 *)"-87e+832",(ee_u8 *)"+0.6e-12"};
- static ee_u8 *errpat[4] ={(ee_u8 *)"T0.3e-1F",(ee_u8 *)"-T.T++Tq",(ee_u8 *)"1T3.4e4z",(ee_u8 *)"34.0e-T^"};
- /* Function: core_init_state
- Initialize the input data for the state machine.
- Populate the input with several predetermined strings, interspersed.
- Actual patterns chosen depend on the seed parameter.
-
- Note:
- The seed parameter MUST be supplied from a source that cannot be determined at compile time
- */
- void core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p) {
- ee_u32 total=0,next=0,i;
- ee_u8 *buf=0;
- #if CORE_DEBUG
- ee_u8 *start=p;
- ee_printf("State: %d,%d\n",size,seed);
- #endif
- size--;
- next=0;
- while ((total+next+1)<size) {
- if (next>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);
- #endif
- }
- 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.
- 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;
- }
|