see http://mbed.org/users/no2chem/notebook/mbed-clock-control--benchmarks/

Dependencies:   mbed

Committer:
no2chem
Date:
Sun Jan 24 15:46:26 2010 +0000
Revision:
0:b5d3bd64d2dc

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
no2chem 0:b5d3bd64d2dc 1 /*
no2chem 0:b5d3bd64d2dc 2 Author : Shay Gal-On, EEMBC
no2chem 0:b5d3bd64d2dc 3
no2chem 0:b5d3bd64d2dc 4 This file is part of EEMBC(R) and CoreMark(TM), which are Copyright (C) 2009
no2chem 0:b5d3bd64d2dc 5 All rights reserved.
no2chem 0:b5d3bd64d2dc 6
no2chem 0:b5d3bd64d2dc 7 EEMBC CoreMark Software is a product of EEMBC and is provided under the terms of the
no2chem 0:b5d3bd64d2dc 8 CoreMark License that is distributed with the official EEMBC COREMARK Software release.
no2chem 0:b5d3bd64d2dc 9 If you received this EEMBC CoreMark Software without the accompanying CoreMark License,
no2chem 0:b5d3bd64d2dc 10 you must discontinue use and download the official release from www.coremark.org.
no2chem 0:b5d3bd64d2dc 11
no2chem 0:b5d3bd64d2dc 12 Also, if you are publicly displaying scores generated from the EEMBC CoreMark software,
no2chem 0:b5d3bd64d2dc 13 make sure that you are in compliance with Run and Reporting rules specified in the accompanying readme.txt file.
no2chem 0:b5d3bd64d2dc 14
no2chem 0:b5d3bd64d2dc 15 EEMBC
no2chem 0:b5d3bd64d2dc 16 4354 Town Center Blvd. Suite 114-200
no2chem 0:b5d3bd64d2dc 17 El Dorado Hills, CA, 95762
no2chem 0:b5d3bd64d2dc 18 */
no2chem 0:b5d3bd64d2dc 19 #include "coremark.h"
no2chem 0:b5d3bd64d2dc 20 /* local functions */
no2chem 0:b5d3bd64d2dc 21 enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count);
no2chem 0:b5d3bd64d2dc 22
no2chem 0:b5d3bd64d2dc 23 /*
no2chem 0:b5d3bd64d2dc 24 Topic: Description
no2chem 0:b5d3bd64d2dc 25 Simple state machines like this one are used in many embedded products.
no2chem 0:b5d3bd64d2dc 26
no2chem 0:b5d3bd64d2dc 27 For more complex state machines, sometimes a state transition table implementation is used instead,
no2chem 0:b5d3bd64d2dc 28 trading speed of direct coding for ease of maintenance.
no2chem 0:b5d3bd64d2dc 29
no2chem 0:b5d3bd64d2dc 30 Since the main goal of using a state machine in CoreMark is to excercise the switch/if behaviour,
no2chem 0:b5d3bd64d2dc 31 we are using a small moore machine.
no2chem 0:b5d3bd64d2dc 32
no2chem 0:b5d3bd64d2dc 33 In particular, this machine tests type of string input,
no2chem 0:b5d3bd64d2dc 34 trying to determine whether the input is a number or something else.
no2chem 0:b5d3bd64d2dc 35 (see core_state.png).
no2chem 0:b5d3bd64d2dc 36 */
no2chem 0:b5d3bd64d2dc 37
no2chem 0:b5d3bd64d2dc 38 /* Function: core_bench_state
no2chem 0:b5d3bd64d2dc 39 Benchmark function
no2chem 0:b5d3bd64d2dc 40
no2chem 0:b5d3bd64d2dc 41 Go over the input twice, once direct, and once after introducing some corruption.
no2chem 0:b5d3bd64d2dc 42 */
no2chem 0:b5d3bd64d2dc 43 ee_u16 core_bench_state(ee_u32 blksize, ee_u8 *memblock,
no2chem 0:b5d3bd64d2dc 44 ee_s16 seed1, ee_s16 seed2, ee_s16 step, ee_u16 crc)
no2chem 0:b5d3bd64d2dc 45 {
no2chem 0:b5d3bd64d2dc 46 ee_u32 final_counts[NUM_CORE_STATES];
no2chem 0:b5d3bd64d2dc 47 ee_u32 track_counts[NUM_CORE_STATES];
no2chem 0:b5d3bd64d2dc 48 ee_u8 *p=memblock;
no2chem 0:b5d3bd64d2dc 49 ee_u32 i;
no2chem 0:b5d3bd64d2dc 50
no2chem 0:b5d3bd64d2dc 51
no2chem 0:b5d3bd64d2dc 52 #if CORE_DEBUG
no2chem 0:b5d3bd64d2dc 53 ee_printf("State Bench: %d,%d,%d,%04x\n",seed1,seed2,step,crc);
no2chem 0:b5d3bd64d2dc 54 #endif
no2chem 0:b5d3bd64d2dc 55 for (i=0; i<NUM_CORE_STATES; i++) {
no2chem 0:b5d3bd64d2dc 56 final_counts[i]=track_counts[i]=0;
no2chem 0:b5d3bd64d2dc 57 }
no2chem 0:b5d3bd64d2dc 58 /* run the state machine over the input */
no2chem 0:b5d3bd64d2dc 59 while (*p!=0) {
no2chem 0:b5d3bd64d2dc 60 enum CORE_STATE fstate=core_state_transition(&p,track_counts);
no2chem 0:b5d3bd64d2dc 61 final_counts[fstate]++;
no2chem 0:b5d3bd64d2dc 62 #if CORE_DEBUG
no2chem 0:b5d3bd64d2dc 63 ee_printf("%d,",fstate);
no2chem 0:b5d3bd64d2dc 64 }
no2chem 0:b5d3bd64d2dc 65 ee_printf("\n");
no2chem 0:b5d3bd64d2dc 66 #else
no2chem 0:b5d3bd64d2dc 67 }
no2chem 0:b5d3bd64d2dc 68 #endif
no2chem 0:b5d3bd64d2dc 69 p=memblock;
no2chem 0:b5d3bd64d2dc 70 while (p < (memblock+blksize)) { /* insert some corruption */
no2chem 0:b5d3bd64d2dc 71 if (*p!=',')
no2chem 0:b5d3bd64d2dc 72 *p^=(ee_u8)seed1;
no2chem 0:b5d3bd64d2dc 73 p+=step;
no2chem 0:b5d3bd64d2dc 74 }
no2chem 0:b5d3bd64d2dc 75 p=memblock;
no2chem 0:b5d3bd64d2dc 76 /* run the state machine over the input again */
no2chem 0:b5d3bd64d2dc 77 while (*p!=0) {
no2chem 0:b5d3bd64d2dc 78 enum CORE_STATE fstate=core_state_transition(&p,track_counts);
no2chem 0:b5d3bd64d2dc 79 final_counts[fstate]++;
no2chem 0:b5d3bd64d2dc 80 #if CORE_DEBUG
no2chem 0:b5d3bd64d2dc 81 ee_printf("%d,",fstate);
no2chem 0:b5d3bd64d2dc 82 }
no2chem 0:b5d3bd64d2dc 83 ee_printf("\n");
no2chem 0:b5d3bd64d2dc 84 #else
no2chem 0:b5d3bd64d2dc 85 }
no2chem 0:b5d3bd64d2dc 86 #endif
no2chem 0:b5d3bd64d2dc 87 p=memblock;
no2chem 0:b5d3bd64d2dc 88 while (p < (memblock+blksize)) { /* undo corruption is seed1 and seed2 are equal */
no2chem 0:b5d3bd64d2dc 89 if (*p!=',')
no2chem 0:b5d3bd64d2dc 90 *p^=(ee_u8)seed2;
no2chem 0:b5d3bd64d2dc 91 p+=step;
no2chem 0:b5d3bd64d2dc 92 }
no2chem 0:b5d3bd64d2dc 93 /* end timing */
no2chem 0:b5d3bd64d2dc 94 for (i=0; i<NUM_CORE_STATES; i++) {
no2chem 0:b5d3bd64d2dc 95 crc=crcu32(final_counts[i],crc);
no2chem 0:b5d3bd64d2dc 96 crc=crcu32(track_counts[i],crc);
no2chem 0:b5d3bd64d2dc 97 }
no2chem 0:b5d3bd64d2dc 98 return crc;
no2chem 0:b5d3bd64d2dc 99 }
no2chem 0:b5d3bd64d2dc 100
no2chem 0:b5d3bd64d2dc 101 /* Default initialization patterns */
no2chem 0:b5d3bd64d2dc 102 static ee_u8 *intpat[4] ={(ee_u8 *)"5012",(ee_u8 *)"1234",(ee_u8 *)"-874",(ee_u8 *)"+122"};
no2chem 0:b5d3bd64d2dc 103 static ee_u8 *floatpat[4]={(ee_u8 *)"35.54400",(ee_u8 *)".1234500",(ee_u8 *)"-110.700",(ee_u8 *)"+0.64400"};
no2chem 0:b5d3bd64d2dc 104 static ee_u8 *scipat[4] ={(ee_u8 *)"5.500e+3",(ee_u8 *)"-.123e-2",(ee_u8 *)"-87e+832",(ee_u8 *)"+0.6e-12"};
no2chem 0:b5d3bd64d2dc 105 static ee_u8 *errpat[4] ={(ee_u8 *)"T0.3e-1F",(ee_u8 *)"-T.T++Tq",(ee_u8 *)"1T3.4e4z",(ee_u8 *)"34.0e-T^"};
no2chem 0:b5d3bd64d2dc 106
no2chem 0:b5d3bd64d2dc 107 /* Function: core_init_state
no2chem 0:b5d3bd64d2dc 108 Initialize the input data for the state machine.
no2chem 0:b5d3bd64d2dc 109
no2chem 0:b5d3bd64d2dc 110 Populate the input with several predetermined strings, interspersed.
no2chem 0:b5d3bd64d2dc 111 Actual patterns chosen depend on the seed parameter.
no2chem 0:b5d3bd64d2dc 112
no2chem 0:b5d3bd64d2dc 113 Note:
no2chem 0:b5d3bd64d2dc 114 The seed parameter MUST be supplied from a source that cannot be determined at compile time
no2chem 0:b5d3bd64d2dc 115 */
no2chem 0:b5d3bd64d2dc 116 void core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p) {
no2chem 0:b5d3bd64d2dc 117 ee_u32 total=0,next=0,i;
no2chem 0:b5d3bd64d2dc 118 ee_u8 *buf=0;
no2chem 0:b5d3bd64d2dc 119 #if CORE_DEBUG
no2chem 0:b5d3bd64d2dc 120 ee_u8 *start=p;
no2chem 0:b5d3bd64d2dc 121 ee_printf("State: %d,%d\n",size,seed);
no2chem 0:b5d3bd64d2dc 122 #endif
no2chem 0:b5d3bd64d2dc 123 size--;
no2chem 0:b5d3bd64d2dc 124 next=0;
no2chem 0:b5d3bd64d2dc 125 while ((total+next+1)<size) {
no2chem 0:b5d3bd64d2dc 126 if (next>0) {
no2chem 0:b5d3bd64d2dc 127 for(i=0;i<next;i++)
no2chem 0:b5d3bd64d2dc 128 *(p+total+i)=buf[i];
no2chem 0:b5d3bd64d2dc 129 *(p+total+i)=',';
no2chem 0:b5d3bd64d2dc 130 total+=next+1;
no2chem 0:b5d3bd64d2dc 131 }
no2chem 0:b5d3bd64d2dc 132 seed++;
no2chem 0:b5d3bd64d2dc 133 switch (seed & 0x7) {
no2chem 0:b5d3bd64d2dc 134 case 0: /* int */
no2chem 0:b5d3bd64d2dc 135 case 1: /* int */
no2chem 0:b5d3bd64d2dc 136 case 2: /* int */
no2chem 0:b5d3bd64d2dc 137 buf=intpat[(seed>>3) & 0x3];
no2chem 0:b5d3bd64d2dc 138 next=4;
no2chem 0:b5d3bd64d2dc 139 break;
no2chem 0:b5d3bd64d2dc 140 case 3: /* float */
no2chem 0:b5d3bd64d2dc 141 case 4: /* float */
no2chem 0:b5d3bd64d2dc 142 buf=floatpat[(seed>>3) & 0x3];
no2chem 0:b5d3bd64d2dc 143 next=8;
no2chem 0:b5d3bd64d2dc 144 break;
no2chem 0:b5d3bd64d2dc 145 case 5: /* scientific */
no2chem 0:b5d3bd64d2dc 146 case 6: /* scientific */
no2chem 0:b5d3bd64d2dc 147 buf=scipat[(seed>>3) & 0x3];
no2chem 0:b5d3bd64d2dc 148 next=8;
no2chem 0:b5d3bd64d2dc 149 break;
no2chem 0:b5d3bd64d2dc 150 case 7: /* invalid */
no2chem 0:b5d3bd64d2dc 151 buf=errpat[(seed>>3) & 0x3];
no2chem 0:b5d3bd64d2dc 152 next=8;
no2chem 0:b5d3bd64d2dc 153 break;
no2chem 0:b5d3bd64d2dc 154 default: /* Never happen, just to make some compilers happy */
no2chem 0:b5d3bd64d2dc 155 break;
no2chem 0:b5d3bd64d2dc 156 }
no2chem 0:b5d3bd64d2dc 157 }
no2chem 0:b5d3bd64d2dc 158 size++;
no2chem 0:b5d3bd64d2dc 159 while (total<size) { /* fill the rest with 0 */
no2chem 0:b5d3bd64d2dc 160 *(p+total)=0;
no2chem 0:b5d3bd64d2dc 161 total++;
no2chem 0:b5d3bd64d2dc 162 }
no2chem 0:b5d3bd64d2dc 163 #if CORE_DEBUG
no2chem 0:b5d3bd64d2dc 164 ee_printf("State Input: %s\n",start);
no2chem 0:b5d3bd64d2dc 165 #endif
no2chem 0:b5d3bd64d2dc 166 }
no2chem 0:b5d3bd64d2dc 167
no2chem 0:b5d3bd64d2dc 168 static ee_u8 ee_isdigit(ee_u8 c) {
no2chem 0:b5d3bd64d2dc 169 ee_u8 retval;
no2chem 0:b5d3bd64d2dc 170 retval = ((c>='0') & (c<='9')) ? 1 : 0;
no2chem 0:b5d3bd64d2dc 171 return retval;
no2chem 0:b5d3bd64d2dc 172 }
no2chem 0:b5d3bd64d2dc 173
no2chem 0:b5d3bd64d2dc 174 /* Function: core_state_transition
no2chem 0:b5d3bd64d2dc 175 Actual state machine.
no2chem 0:b5d3bd64d2dc 176
no2chem 0:b5d3bd64d2dc 177 The state machine will continue scanning until either:
no2chem 0:b5d3bd64d2dc 178 1 - an invalid input is detcted.
no2chem 0:b5d3bd64d2dc 179 2 - a valid number has been detected.
no2chem 0:b5d3bd64d2dc 180
no2chem 0:b5d3bd64d2dc 181 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).
no2chem 0:b5d3bd64d2dc 182 */
no2chem 0:b5d3bd64d2dc 183
no2chem 0:b5d3bd64d2dc 184 enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count) {
no2chem 0:b5d3bd64d2dc 185 ee_u8 *str=*instr;
no2chem 0:b5d3bd64d2dc 186 ee_u8 NEXT_SYMBOL;
no2chem 0:b5d3bd64d2dc 187 enum CORE_STATE state=CORE_START;
no2chem 0:b5d3bd64d2dc 188 for( ; *str && state != CORE_INVALID; str++ ) {
no2chem 0:b5d3bd64d2dc 189 NEXT_SYMBOL = *str;
no2chem 0:b5d3bd64d2dc 190 if (NEXT_SYMBOL==',') /* end of this input */ {
no2chem 0:b5d3bd64d2dc 191 str++;
no2chem 0:b5d3bd64d2dc 192 break;
no2chem 0:b5d3bd64d2dc 193 }
no2chem 0:b5d3bd64d2dc 194 switch(state) {
no2chem 0:b5d3bd64d2dc 195 case CORE_START:
no2chem 0:b5d3bd64d2dc 196 if(ee_isdigit(NEXT_SYMBOL)) {
no2chem 0:b5d3bd64d2dc 197 state = CORE_INT;
no2chem 0:b5d3bd64d2dc 198 }
no2chem 0:b5d3bd64d2dc 199 else if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) {
no2chem 0:b5d3bd64d2dc 200 state = CORE_S1;
no2chem 0:b5d3bd64d2dc 201 }
no2chem 0:b5d3bd64d2dc 202 else if( NEXT_SYMBOL == '.' ) {
no2chem 0:b5d3bd64d2dc 203 state = CORE_FLOAT;
no2chem 0:b5d3bd64d2dc 204 }
no2chem 0:b5d3bd64d2dc 205 else {
no2chem 0:b5d3bd64d2dc 206 state = CORE_INVALID;
no2chem 0:b5d3bd64d2dc 207 transition_count[CORE_INVALID]++;
no2chem 0:b5d3bd64d2dc 208 }
no2chem 0:b5d3bd64d2dc 209 transition_count[CORE_START]++;
no2chem 0:b5d3bd64d2dc 210 break;
no2chem 0:b5d3bd64d2dc 211 case CORE_S1:
no2chem 0:b5d3bd64d2dc 212 if(ee_isdigit(NEXT_SYMBOL)) {
no2chem 0:b5d3bd64d2dc 213 state = CORE_INT;
no2chem 0:b5d3bd64d2dc 214 transition_count[CORE_S1]++;
no2chem 0:b5d3bd64d2dc 215 }
no2chem 0:b5d3bd64d2dc 216 else if( NEXT_SYMBOL == '.' ) {
no2chem 0:b5d3bd64d2dc 217 state = CORE_FLOAT;
no2chem 0:b5d3bd64d2dc 218 transition_count[CORE_S1]++;
no2chem 0:b5d3bd64d2dc 219 }
no2chem 0:b5d3bd64d2dc 220 else {
no2chem 0:b5d3bd64d2dc 221 state = CORE_INVALID;
no2chem 0:b5d3bd64d2dc 222 transition_count[CORE_S1]++;
no2chem 0:b5d3bd64d2dc 223 }
no2chem 0:b5d3bd64d2dc 224 break;
no2chem 0:b5d3bd64d2dc 225 case CORE_INT:
no2chem 0:b5d3bd64d2dc 226 if( NEXT_SYMBOL == '.' ) {
no2chem 0:b5d3bd64d2dc 227 state = CORE_FLOAT;
no2chem 0:b5d3bd64d2dc 228 transition_count[CORE_INT]++;
no2chem 0:b5d3bd64d2dc 229 }
no2chem 0:b5d3bd64d2dc 230 else if(!ee_isdigit(NEXT_SYMBOL)) {
no2chem 0:b5d3bd64d2dc 231 state = CORE_INVALID;
no2chem 0:b5d3bd64d2dc 232 transition_count[CORE_INT]++;
no2chem 0:b5d3bd64d2dc 233 }
no2chem 0:b5d3bd64d2dc 234 break;
no2chem 0:b5d3bd64d2dc 235 case CORE_FLOAT:
no2chem 0:b5d3bd64d2dc 236 if( NEXT_SYMBOL == 'E' || NEXT_SYMBOL == 'e' ) {
no2chem 0:b5d3bd64d2dc 237 state = CORE_S2;
no2chem 0:b5d3bd64d2dc 238 transition_count[CORE_FLOAT]++;
no2chem 0:b5d3bd64d2dc 239 }
no2chem 0:b5d3bd64d2dc 240 else if(!ee_isdigit(NEXT_SYMBOL)) {
no2chem 0:b5d3bd64d2dc 241 state = CORE_INVALID;
no2chem 0:b5d3bd64d2dc 242 transition_count[CORE_FLOAT]++;
no2chem 0:b5d3bd64d2dc 243 }
no2chem 0:b5d3bd64d2dc 244 break;
no2chem 0:b5d3bd64d2dc 245 case CORE_S2:
no2chem 0:b5d3bd64d2dc 246 if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) {
no2chem 0:b5d3bd64d2dc 247 state = CORE_EXPONENT;
no2chem 0:b5d3bd64d2dc 248 transition_count[CORE_S2]++;
no2chem 0:b5d3bd64d2dc 249 }
no2chem 0:b5d3bd64d2dc 250 else {
no2chem 0:b5d3bd64d2dc 251 state = CORE_INVALID;
no2chem 0:b5d3bd64d2dc 252 transition_count[CORE_S2]++;
no2chem 0:b5d3bd64d2dc 253 }
no2chem 0:b5d3bd64d2dc 254 break;
no2chem 0:b5d3bd64d2dc 255 case CORE_EXPONENT:
no2chem 0:b5d3bd64d2dc 256 if(ee_isdigit(NEXT_SYMBOL)) {
no2chem 0:b5d3bd64d2dc 257 state = CORE_SCIENTIFIC;
no2chem 0:b5d3bd64d2dc 258 transition_count[CORE_EXPONENT]++;
no2chem 0:b5d3bd64d2dc 259 }
no2chem 0:b5d3bd64d2dc 260 else {
no2chem 0:b5d3bd64d2dc 261 state = CORE_INVALID;
no2chem 0:b5d3bd64d2dc 262 transition_count[CORE_EXPONENT]++;
no2chem 0:b5d3bd64d2dc 263 }
no2chem 0:b5d3bd64d2dc 264 break;
no2chem 0:b5d3bd64d2dc 265 case CORE_SCIENTIFIC:
no2chem 0:b5d3bd64d2dc 266 if(!ee_isdigit(NEXT_SYMBOL)) {
no2chem 0:b5d3bd64d2dc 267 state = CORE_INVALID;
no2chem 0:b5d3bd64d2dc 268 transition_count[CORE_INVALID]++;
no2chem 0:b5d3bd64d2dc 269 }
no2chem 0:b5d3bd64d2dc 270 break;
no2chem 0:b5d3bd64d2dc 271 default:
no2chem 0:b5d3bd64d2dc 272 break;
no2chem 0:b5d3bd64d2dc 273 }
no2chem 0:b5d3bd64d2dc 274 }
no2chem 0:b5d3bd64d2dc 275 *instr=str;
no2chem 0:b5d3bd64d2dc 276 return state;
no2chem 0:b5d3bd64d2dc 277 }