URL
https://opencores.org/ocsvn/openrisc/openrisc/trunk
Subversion Repositories openrisc
Compare Revisions
- This comparison shows the changes necessary to convert path
/openrisc/trunk/bootloaders/orpmon/coremark
- from Rev 355 to Rev 406
- ↔ Reverse comparison
Rev 355 → Rev 406
/core_portme.c
35,7 → 35,7
volatile ee_s32 seed1_volatile; |
volatile ee_s32 seed2_volatile; |
volatile ee_s32 seed3_volatile; |
volatile ee_s32 seed4_volatile = 0; // Iterations defaults to 0 |
volatile ee_s32 seed4_volatile = 0; // Iterations defaults to 0 |
volatile ee_s32 seed5_volatile = 0; |
|
/* Porting : Timing functions |
47,7 → 47,7
CORETIMETYPE barebones_clock() |
{ |
//#error "You must implement a method to measure time in |
//barebones_clock()! This function should return current time.\n" |
//barebones_clock()! This function should return current time.\n" |
return timestamp; |
} |
|
131,60 → 131,58
void portable_init(core_portable * p, int *argc, char *argv[]) |
{ |
|
// In ORPmon - UART already initialised: uart_init(DEFAULT_UART); |
if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) { |
ee_printf |
("ERROR! Please define ee_ptr_int to a type that holds a pointer!\n"); |
while (1) ; // FINISH |
} |
if (sizeof(ee_u32) != 4) { |
ee_printf |
("ERROR! Please define ee_u32 to a 32b unsigned type!\n"); |
while (1) ; // FINISH |
} |
// In ORPmon - things already initialised |
// Clear timer variable |
//clear_timer_ticks(); |
// init timer |
//enable_timer(); |
|
// |
// In ORPmon - UART already initialised: uart_init(DEFAULT_UART); |
if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) { |
ee_printf |
("ERROR! Please define ee_ptr_int to a type that holds a pointer!\n"); |
while (1) ; // FINISH |
} |
if (sizeof(ee_u32) != 4) { |
ee_printf |
("ERROR! Please define ee_u32 to a 32b unsigned type!\n"); |
while (1) ; // FINISH |
} |
// In ORPmon - things already initialised |
// Clear timer variable |
//clear_timer_ticks(); |
// init timer |
//enable_timer(); |
|
// Parse argv and figure out what kind of run we do |
if (argc > 0) |
{ |
switch((char) argv[0][0]) |
{ |
case 'p': |
//PERFORMANCE_RUN |
seed1_volatile = 0x0; |
seed2_volatile = 0x0; |
seed3_volatile = 0x66; |
break; |
case 'o': |
//PROFILE_RUN |
seed1_volatile = 0x8; |
seed2_volatile = 0x8; |
seed3_volatile = 0x8; |
break; |
default: |
//VALIDATION_RUN |
seed1_volatile = 0x3415; |
seed2_volatile = 0x3415; |
seed3_volatile = 0x66; |
break; |
// |
|
// Parse argv and figure out what kind of run we do |
if (argc > 0) { |
switch ((char)argv[0][0]) { |
case 'p': |
//PERFORMANCE_RUN |
seed1_volatile = 0x0; |
seed2_volatile = 0x0; |
seed3_volatile = 0x66; |
break; |
case 'o': |
//PROFILE_RUN |
seed1_volatile = 0x8; |
seed2_volatile = 0x8; |
seed3_volatile = 0x8; |
break; |
default: |
//VALIDATION_RUN |
seed1_volatile = 0x3415; |
seed2_volatile = 0x3415; |
seed3_volatile = 0x66; |
break; |
} |
} |
} |
|
if (argc > 1) |
seed4_volatile = strtoul(argv[1],0,0); // Iterations as second argument |
else |
seed4_volatile = 0; // Zero (test runs a minimum amount of time) |
|
seed5_volatile = 0; |
|
p->portable_id = 1; |
|
if (argc > 1) |
seed4_volatile = strtoul(argv[1], 0, 0); // Iterations as second argument |
else |
seed4_volatile = 0; // Zero (test runs a minimum amount of time) |
|
seed5_volatile = 0; |
|
p->portable_id = 1; |
|
} |
|
/* Function : portable_fini |
/core_list_join.c
15,7 → 15,7
EEMBC |
4354 Town Center Blvd. Suite 114-200 |
El Dorado Hills, CA, 95762 |
*/ |
*/ |
|
#include "coremark.h" |
/* |
50,57 → 50,67
|
/* local functions */ |
|
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_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); |
|
ee_s16 calc_func(ee_s16 *pdata, core_results *res) { |
ee_s16 data=*pdata; |
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 */ |
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 */ |
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; |
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 */ |
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. |
|
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); |
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; |
} |
|
109,17 → 119,19
|
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)); |
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 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: |
129,74 → 141,76
- 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; |
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; |
info.idx = finder_idx; |
/* find <find_num> 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) { |
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 { |
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; |
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; |
finder->next = list->next; |
list->next = finder; |
} |
} |
if (info.idx>=0) |
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); |
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); |
finder = core_list_find(list, &info); |
if (!finder) |
finder=list->next; |
finder = list->next; |
while (finder) { |
retval=crc16(list->info->data16,retval); |
finder=finder->next; |
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); |
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); |
list = core_list_mergesort(list, cmp_idx, NULL); |
/* CRC data content of list */ |
finder=list->next; |
finder = list->next; |
while (finder) { |
retval=crc16(list->info->data16,retval); |
finder=finder->next; |
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; |
} |
|
/* Function: core_list_init |
Initialize list with data. |
|
210,55 → 224,59
Pointer to the head of the list. |
|
*/ |
list_head *core_list_init(ee_u32 blksize, list_head *memblock, ee_s16 seed) { |
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; |
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_head *finder, *list = memblock; |
list_data info; |
|
/* 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; |
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); |
|
info.idx = 0x7fff; |
info.data16 = (ee_s16) 0xffff; |
core_list_insert_new(list, &info, &memblock, &datablock, memblock_end, |
datablock_end); |
|
/* 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); |
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 = 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; |
finder = finder->next; |
} |
list = core_list_mergesort(list,cmp_idx,NULL); |
list = core_list_mergesort(list, cmp_idx, NULL); |
#if CORE_DEBUG |
ee_printf("Initialized list:\n"); |
finder=list; |
finder = list; |
while (finder) { |
ee_printf("[%04x,%04x]",finder->info->idx,(ee_u16)finder->info->data16); |
finder=finder->next; |
ee_printf("[%04x,%04x]", finder->info->idx, |
(ee_u16) finder->info->data16); |
finder = finder->next; |
} |
ee_printf("\n"); |
#endif |
279,24 → 297,27
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 *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) |
|
if ((*memblock + 1) >= memblock_end) |
return NULL; |
if ((*datablock+1) >= datablock_end) |
if ((*datablock + 1) >= datablock_end) |
return NULL; |
|
newitem=*memblock; |
|
newitem = *memblock; |
(*memblock)++; |
newitem->next=insert_point->next; |
insert_point->next=newitem; |
|
newitem->info=*datablock; |
newitem->next = insert_point->next; |
insert_point->next = newitem; |
|
newitem->info = *datablock; |
(*datablock)++; |
copy_info(newitem->info,info); |
|
copy_info(newitem->info, info); |
|
return newitem; |
} |
|
313,16 → 334,17
Returns: |
Removed item. |
*/ |
list_head *core_list_remove(list_head *item) { |
list_head *core_list_remove(list_head * item) |
{ |
list_data *tmp; |
list_head *ret=item->next; |
list_head *ret = item->next; |
/* swap data pointers */ |
tmp=item->info; |
item->info=ret->info; |
ret->info=tmp; |
tmp = item->info; |
item->info = ret->info; |
ret->info = tmp; |
/* and eliminate item */ |
item->next=item->next->next; |
ret->next=NULL; |
item->next = item->next->next; |
ret->next = NULL; |
return ret; |
} |
|
342,15 → 364,17
The item that was linked back to the list. |
|
*/ |
list_head *core_list_undo_remove(list_head *item_removed, list_head *item_modified) { |
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; |
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; |
item_removed->next = item_modified->next; |
item_modified->next = item_removed; |
return item_removed; |
} |
|
367,17 → 391,19
Returns: |
Found item, or NULL if not found. |
*/ |
list_head *core_list_find(list_head *list,list_data *info) { |
if (info->idx>=0) { |
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; |
list = list->next; |
return list; |
} else { |
while (list && ((list->info->data16 & 0xff) != info->data16)) |
list=list->next; |
list = list->next; |
return list; |
} |
} |
|
/* Function: core_list_reverse |
Reverse a list |
|
392,16 → 418,18
Found item, or NULL if not found. |
*/ |
|
list_head *core_list_reverse(list_head *list) { |
list_head *next=NULL, *tmp; |
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; |
tmp = list->next; |
list->next = next; |
next = list; |
list = tmp; |
} |
return next; |
} |
|
/* Function: core_list_mergesort |
Sort the list in place without recursion. |
|
423,73 → 451,84
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 *p, *q, *e, *tail; |
ee_s32 insize, nmerges, psize, qsize, i; |
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; |
|
insize = 1; |
insize = 1; |
|
while (1) { |
p = list; |
list = NULL; |
tail = NULL; |
while (1) { |
p = list; |
list = NULL; |
tail = NULL; |
|
nmerges = 0; /* count number of merges we do in this pass */ |
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; |
psize = 0; |
for (i = 0; i < insize; i++) { |
psize++; |
q = q->next; |
if (!q) break; |
} |
while (p) { |
nmerges++; /* there exists a merge to be done */ |
/* step `insize' places along from p */ |
q = p; |
psize = 0; |
for (i = 0; i < insize; i++) { |
psize++; |
q = q->next; |
if (!q) |
break; |
} |
|
/* if q hasn't fallen off end, we have two lists to merge */ |
qsize = insize; |
/* if q hasn't fallen off end, we have two lists to merge */ |
qsize = insize; |
|
/* now we have two lists; merge them */ |
while (psize > 0 || (qsize > 0 && q)) { |
/* now we have two lists; merge them */ |
while (psize > 0 || (qsize > 0 && q)) { |
|
/* 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--; |
/* 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--; |
/* 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--; |
/* 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 */ |
/* add the next element to the merged list */ |
if (tail) { |
tail->next = e; |
tail->next = e; |
} else { |
list = e; |
list = e; |
} |
tail = e; |
} |
} |
|
/* now p has stepped `insize' places along, and q has too */ |
p = q; |
} |
|
tail->next = NULL; |
} |
|
/* If we have done only one merge, we're finished. */ |
if (nmerges <= 1) /* allow for nmerges==0, the empty list case */ |
return list; |
tail->next = NULL; |
|
/* Otherwise repeat, merging lists twice the size */ |
insize *= 2; |
} |
/* If we have done only one merge, we're finished. */ |
if (nmerges <= 1) /* allow for nmerges==0, the empty list case */ |
return list; |
|
/* Otherwise repeat, merging lists twice the size */ |
insize *= 2; |
} |
#if COMPILER_REQUIRES_SORT_RETURN |
return list; |
#endif |
/core_util.c
15,7 → 15,7
EEMBC |
4354 Town Center Blvd. Suite 114-200 |
El Dorado Hills, CA, 95762 |
*/ |
*/ |
#include "coremark.h" |
/* Function: get_seed |
Get a values that cannot be determined at compile time. |
31,78 → 31,82
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; |
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; |
ee_s32 parseval(char *valstring) |
{ |
ee_s32 retval = 0; |
ee_s32 neg = 1; |
int hexmode = 0; |
if (*valstring == '-') { |
neg=-1; |
neg = -1; |
valstring++; |
} |
if ((valstring[0] == '0') && (valstring[1] == 'x')) { |
hexmode=1; |
valstring+=2; |
hexmode = 1; |
valstring += 2; |
} |
/* first look for digits */ |
/* 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; |
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; |
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 (*valstring == 'K') |
retval *= 1024; |
if (*valstring == 'M') |
retval *= 1024 * 1024; |
|
retval*=neg; |
retval *= neg; |
return retval; |
} |
|
ee_s32 get_seed_args(int i, int argc, char *argv[]) { |
if (argc>i) |
ee_s32 get_seed_args(int i, int argc, char *argv[]) |
{ |
if (argc > i) |
return parseval(argv[i]); |
return 0; |
} |
109,27 → 113,28
|
#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 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; |
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; |
} |
139,46 → 144,50
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++) |
{ |
x16 = (ee_u8)((data & 1) ^ ((ee_u8)crc & 1)); |
for (i = 0; i < 8; i++) { |
x16 = (ee_u8) ((data & 1) ^ ((ee_u8) crc & 1)); |
data >>= 1; |
|
if (x16 == 1) |
{ |
crc ^= 0x4002; |
carry = 1; |
} |
else |
if (x16 == 1) { |
crc ^= 0x4002; |
carry = 1; |
} else |
carry = 0; |
crc >>= 1; |
if (carry) |
crc |= 0x8000; |
crc |= 0x8000; |
else |
crc &= 0x7fff; |
} |
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); |
} |
|
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 crcu32(ee_u32 newval, ee_u16 crc) { |
crc=crc16((ee_s16) newval ,crc); |
crc=crc16((ee_s16) (newval>>16) ,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_u16 crc16(ee_s16 newval, ee_u16 crc) |
{ |
return crcu16((ee_u16) newval, crc); |
} |
|
ee_u8 check_data_types() { |
ee_u8 retval=0; |
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++; |
200,11 → 209,13
retval++; |
} |
if (sizeof(ee_ptr_int) != sizeof(int *)) { |
ee_printf("ERROR: ee_ptr_int is not a datatype that holds an int pointer!\n"); |
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"); |
if (retval > 0) { |
ee_printf |
("ERROR: Please modify the datatypes in core_portme.h!\n"); |
} |
return retval; |
} |
/fmod.c
3,17 → 3,14
typedef signed int int32_t; |
|
// Big endian struct... |
typedef union |
{ |
double value; |
struct |
{ |
u_int32_t msw; |
u_int32_t lsw; |
} parts; |
typedef union { |
double value; |
struct { |
u_int32_t msw; |
u_int32_t lsw; |
} parts; |
} ieee_double_shape_type; |
|
|
/* |
typedef union |
{ |
87,10 → 84,9
/* A union which permits us to convert between a float and a 32 bit |
int. */ |
|
typedef union |
{ |
float value; |
u_int32_t word; |
typedef union { |
float value; |
u_int32_t word; |
} ieee_float_shape_type; |
|
/* Get a 32 bit int from a float. */ |
111,49 → 107,48
(d) = sf_u.value; \ |
} while (0) |
|
|
static const double one = 1.0; |
|
double modf(double x, double *iptr) |
{ |
int32_t i0,i1,j0; |
int32_t i0, i1, j0; |
u_int32_t i; |
EXTRACT_WORDS(i0,i1,x); |
j0 = ((i0>>20)&0x7ff)-0x3ff; /* exponent of x */ |
if(j0<20) { /* integer part in high x */ |
if(j0<0) { /* |x|<1 */ |
INSERT_WORDS(*iptr,i0&0x80000000,0); /* *iptr = +-0 */ |
EXTRACT_WORDS(i0, i1, x); |
j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; /* exponent of x */ |
if (j0 < 20) { /* integer part in high x */ |
if (j0 < 0) { /* |x|<1 */ |
INSERT_WORDS(*iptr, i0 & 0x80000000, 0); /* *iptr = +-0 */ |
return x; |
} else { |
i = (0x000fffff) >> j0; |
if (((i0 & i) | i1) == 0) { /* x is integral */ |
u_int32_t high; |
*iptr = x; |
GET_HIGH_WORD(high, x); |
INSERT_WORDS(x, high & 0x80000000, 0); /* return +-0 */ |
return x; |
} else { |
INSERT_WORDS(*iptr, i0 & (~i), 0); |
return x - *iptr; |
} |
} |
} else if (j0 > 51) { /* no fraction part */ |
u_int32_t high; |
*iptr = x * one; |
GET_HIGH_WORD(high, x); |
INSERT_WORDS(x, high & 0x80000000, 0); /* return +-0 */ |
return x; |
} else { |
i = (0x000fffff)>>j0; |
if(((i0&i)|i1)==0) { /* x is integral */ |
u_int32_t high; |
*iptr = x; |
GET_HIGH_WORD(high,x); |
INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ |
return x; |
} else { /* fraction part in low x */ |
i = ((u_int32_t) (0xffffffff)) >> (j0 - 20); |
if ((i1 & i) == 0) { /* x is integral */ |
u_int32_t high; |
*iptr = x; |
GET_HIGH_WORD(high, x); |
INSERT_WORDS(x, high & 0x80000000, 0); /* return +-0 */ |
return x; |
} else { |
INSERT_WORDS(*iptr,i0&(~i),0); |
return x - *iptr; |
INSERT_WORDS(*iptr, i0, i1 & (~i)); |
return x - *iptr; |
} |
} |
} else if (j0>51) { /* no fraction part */ |
u_int32_t high; |
*iptr = x*one; |
GET_HIGH_WORD(high,x); |
INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ |
return x; |
} else { /* fraction part in low x */ |
i = ((u_int32_t)(0xffffffff))>>(j0-20); |
if((i1&i)==0) { /* x is integral */ |
u_int32_t high; |
*iptr = x; |
GET_HIGH_WORD(high,x); |
INSERT_WORDS(x,high&0x80000000,0); /* return +-0 */ |
return x; |
} else { |
INSERT_WORDS(*iptr,i0,i1&(~i)); |
return x - *iptr; |
} |
} |
} |
/core_state.c
15,10 → 15,11
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); |
enum CORE_STATE core_state_transition(ee_u8 ** instr, |
ee_u32 * transition_count); |
|
/* |
Topic: Description |
40,69 → 41,77
|
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_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_u8 *p = memblock; |
ee_u32 i; |
|
|
#if CORE_DEBUG |
ee_printf("State Bench: %d,%d,%d,%04x\n",seed1,seed2,step,crc); |
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; |
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); |
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("%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; |
while (p < (memblock + blksize)) { /* insert some corruption */ |
if (*p != ',') |
*p ^= (ee_u8) seed1; |
p += step; |
} |
p=memblock; |
p = memblock; |
/* run the state machine over the input again */ |
while (*p!=0) { |
enum CORE_STATE fstate=core_state_transition(&p,track_counts); |
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("%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; |
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); |
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^"}; |
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. |
113,61 → 122,63
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; |
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); |
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; |
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; |
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; |
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; |
case 5: /* scientific */ |
case 6: /* scientific */ |
buf = scipat[(seed >> 3) & 0x3]; |
next = 8; |
break; |
case 7: /* invalid */ |
buf=errpat[(seed>>3) & 0x3]; |
next=8; |
case 7: /* invalid */ |
buf = errpat[(seed >> 3) & 0x3]; |
next = 8; |
break; |
default: /* Never happen, just to make some compilers happy */ |
default: /* Never happen, just to make some compilers happy */ |
break; |
} |
} |
size++; |
while (total<size) { /* fill the rest with 0 */ |
*(p+total)=0; |
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) { |
static ee_u8 ee_isdigit(ee_u8 c) |
{ |
ee_u8 retval; |
retval = ((c>='0') & (c<='9')) ? 1 : 0; |
retval = ((c >= '0') & (c <= '9')) ? 1 : 0; |
return retval; |
} |
|
181,28 → 192,26
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; |
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++ ) { |
enum CORE_STATE state = CORE_START; |
for (; *str && state != CORE_INVALID; str++) { |
NEXT_SYMBOL = *str; |
if (NEXT_SYMBOL==',') /* end of this input */ { |
if (NEXT_SYMBOL == ',') { /* end of this input */ |
str++; |
break; |
} |
switch(state) { |
switch (state) { |
case CORE_START: |
if(ee_isdigit(NEXT_SYMBOL)) { |
if (ee_isdigit(NEXT_SYMBOL)) { |
state = CORE_INT; |
} |
else if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) { |
} else if (NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-') { |
state = CORE_S1; |
} |
else if( NEXT_SYMBOL == '.' ) { |
} else if (NEXT_SYMBOL == '.') { |
state = CORE_FLOAT; |
} |
else { |
} else { |
state = CORE_INVALID; |
transition_count[CORE_INVALID]++; |
} |
209,61 → 218,55
transition_count[CORE_START]++; |
break; |
case CORE_S1: |
if(ee_isdigit(NEXT_SYMBOL)) { |
if (ee_isdigit(NEXT_SYMBOL)) { |
state = CORE_INT; |
transition_count[CORE_S1]++; |
} |
else if( NEXT_SYMBOL == '.' ) { |
} else if (NEXT_SYMBOL == '.') { |
state = CORE_FLOAT; |
transition_count[CORE_S1]++; |
} |
else { |
} else { |
state = CORE_INVALID; |
transition_count[CORE_S1]++; |
} |
break; |
case CORE_INT: |
if( NEXT_SYMBOL == '.' ) { |
if (NEXT_SYMBOL == '.') { |
state = CORE_FLOAT; |
transition_count[CORE_INT]++; |
} |
else if(!ee_isdigit(NEXT_SYMBOL)) { |
} else if (!ee_isdigit(NEXT_SYMBOL)) { |
state = CORE_INVALID; |
transition_count[CORE_INT]++; |
} |
break; |
case CORE_FLOAT: |
if( NEXT_SYMBOL == 'E' || NEXT_SYMBOL == 'e' ) { |
if (NEXT_SYMBOL == 'E' || NEXT_SYMBOL == 'e') { |
state = CORE_S2; |
transition_count[CORE_FLOAT]++; |
} |
else if(!ee_isdigit(NEXT_SYMBOL)) { |
} else if (!ee_isdigit(NEXT_SYMBOL)) { |
state = CORE_INVALID; |
transition_count[CORE_FLOAT]++; |
} |
break; |
case CORE_S2: |
if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) { |
if (NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-') { |
state = CORE_EXPONENT; |
transition_count[CORE_S2]++; |
} |
else { |
} else { |
state = CORE_INVALID; |
transition_count[CORE_S2]++; |
} |
break; |
case CORE_EXPONENT: |
if(ee_isdigit(NEXT_SYMBOL)) { |
if (ee_isdigit(NEXT_SYMBOL)) { |
state = CORE_SCIENTIFIC; |
transition_count[CORE_EXPONENT]++; |
} |
else { |
} else { |
state = CORE_INVALID; |
transition_count[CORE_EXPONENT]++; |
} |
break; |
case CORE_SCIENTIFIC: |
if(!ee_isdigit(NEXT_SYMBOL)) { |
if (!ee_isdigit(NEXT_SYMBOL)) { |
state = CORE_INVALID; |
transition_count[CORE_INVALID]++; |
} |
272,6 → 275,6
break; |
} |
} |
*instr=str; |
*instr = str; |
return state; |
} |
/ee_printf.c
53,154 → 53,164
|
static size_t strnlen(const char *s, 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) |
{ |
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) |
{ |
sign = '-'; |
num = -num; |
size--; |
} |
else if (type & PLUS) |
{ |
sign = '+'; |
size--; |
} |
else if (type & SPACE) |
{ |
sign = ' '; |
size--; |
} |
} |
if (type & UPPERCASE) |
dig = upper_digits; |
if (type & LEFT) |
type &= ~ZEROPAD; |
if (base < 2 || base > 36) |
return 0; |
|
if (type & HEX_PREP) |
{ |
if (base == 16) |
size -= 2; |
else if (base == 8) |
size--; |
} |
c = (type & ZEROPAD) ? '0' : ' '; |
sign = 0; |
if (type & SIGN) { |
if (num < 0) { |
sign = '-'; |
num = -num; |
size--; |
} else if (type & PLUS) { |
sign = '+'; |
size--; |
} else if (type & SPACE) { |
sign = ' '; |
size--; |
} |
} |
|
i = 0; |
if (type & HEX_PREP) { |
if (base == 16) |
size -= 2; |
else if (base == 8) |
size--; |
} |
|
if (num == 0) |
tmp[i++] = '0'; |
else |
{ |
while (num != 0) |
{ |
tmp[i++] = dig[((unsigned long) num) % (unsigned) base]; |
num = ((unsigned long) num) / (unsigned) base; |
} |
} |
i = 0; |
|
if (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 (num == 0) |
tmp[i++] = '0'; |
else { |
while (num != 0) { |
tmp[i++] = dig[((unsigned long)num) % (unsigned)base]; |
num = ((unsigned long)num) / (unsigned)base; |
} |
} |
|
if (!(type & LEFT)) while (size-- > 0) *str++ = c; |
while (i < precision--) *str++ = '0'; |
while (i-- > 0) *str++ = tmp[i]; |
while (size-- > 0) *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) |
static char *eaddr(char *str, unsigned char *addr, int size, int precision, |
int type) |
{ |
char tmp[24]; |
char *dig = digits; |
int i, len; |
char tmp[24]; |
char *dig = digits; |
int i, len; |
|
if (type & UPPERCASE) dig = upper_digits; |
len = 0; |
for (i = 0; i < 6; i++) |
{ |
if (i != 0) tmp[len++] = ':'; |
tmp[len++] = dig[addr[i] >> 4]; |
tmp[len++] = dig[addr[i] & 0x0F]; |
} |
if (type & UPPERCASE) |
dig = upper_digits; |
len = 0; |
for (i = 0; i < 6; i++) { |
if (i != 0) |
tmp[len++] = ':'; |
tmp[len++] = dig[addr[i] >> 4]; |
tmp[len++] = dig[addr[i] & 0x0F]; |
} |
|
if (!(type & LEFT)) while (len < size--) *str++ = ' '; |
for (i = 0; i < len; ++i) *str++ = tmp[i]; |
while (len < size--) *str++ = ' '; |
if (!(type & LEFT)) |
while (len < size--) |
*str++ = ' '; |
for (i = 0; i < len; ++i) |
*str++ = tmp[i]; |
while (len < size--) |
*str++ = ' '; |
|
return str; |
return str; |
} |
|
static char *iaddr(char *str, unsigned char *addr, int size, int precision, int type) |
static char *iaddr(char *str, unsigned char *addr, int size, int precision, |
int type) |
{ |
char tmp[24]; |
int i, n, len; |
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; |
} |
len = 0; |
for (i = 0; i < 4; i++) { |
if (i != 0) |
tmp[len++] = '.'; |
n = addr[i]; |
|
tmp[len++] = digits[n]; |
} |
} |
if (n == 0) |
tmp[len++] = digits[0]; |
else { |
if (n >= 100) { |
tmp[len++] = digits[n / 100]; |
n = n % 100; |
tmp[len++] = digits[n / 10]; |
n = n % 10; |
} else if (n >= 10) { |
tmp[len++] = digits[n / 10]; |
n = n % 10; |
} |
|
if (!(type & LEFT)) while (len < size--) *str++ = ' '; |
for (i = 0; i < len; ++i) *str++ = tmp[i]; |
while (len < size--) *str++ = ' '; |
tmp[len++] = digits[n]; |
} |
} |
|
return str; |
if (!(type & LEFT)) |
while (len < size--) |
*str++ = ' '; |
for (i = 0; i < len; ++i) |
*str++ = tmp[i]; |
while (len < size--) |
*str++ = ' '; |
|
return str; |
} |
|
#ifdef HAS_FLOAT |
207,213 → 217,205
|
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 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) |
{ |
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' || fmt == 'E') { |
capexp = 1; |
fmt += 'a' - 'A'; |
} |
|
if (fmt == 'g') |
{ |
digits = ecvtbuf(value, precision, &decpt, &sign, cvtbuf); |
magnitude = decpt - 1; |
if (magnitude < -4 || magnitude > precision - 1) |
{ |
fmt = 'e'; |
precision -= 1; |
} |
else |
{ |
fmt = 'f'; |
precision -= decpt; |
} |
} |
if (fmt == 'g') { |
digits = ecvtbuf(value, precision, &decpt, &sign, cvtbuf); |
magnitude = decpt - 1; |
if (magnitude < -4 || magnitude > precision - 1) { |
fmt = 'e'; |
precision -= 1; |
} else { |
fmt = 'f'; |
precision -= decpt; |
} |
} |
|
if (fmt == 'e') |
{ |
digits = ecvtbuf(value, precision + 1, &decpt, &sign, cvtbuf); |
if (fmt == 'e') { |
digits = ecvtbuf(value, precision + 1, &decpt, &sign, cvtbuf); |
|
if (sign) *buffer++ = '-'; |
*buffer++ = *digits; |
if (precision > 0) *buffer++ = '.'; |
ee_bufcpy(buffer, digits + 1, precision); |
buffer += precision; |
*buffer++ = capexp ? 'E' : 'e'; |
if (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 (decpt == 0) { |
if (value == 0.0) |
exp = 0; |
else |
exp = -1; |
} else |
exp = decpt - 1; |
|
if (exp < 0) |
{ |
*buffer++ = '-'; |
exp = -exp; |
} |
else |
*buffer++ = '+'; |
if (exp < 0) { |
*buffer++ = '-'; |
exp = -exp; |
} else |
*buffer++ = '+'; |
|
buffer[2] = (exp % 10) + '0'; |
exp = exp / 10; |
buffer[1] = (exp % 10) + '0'; |
exp = exp / 10; |
buffer[0] = (exp % 10) + '0'; |
buffer += 3; |
} |
else if (fmt == 'f') |
{ |
digits = fcvtbuf(value, precision, &decpt, &sign, cvtbuf); |
if (sign) *buffer++ = '-'; |
if (*digits) |
{ |
if (decpt <= 0) |
{ |
*buffer++ = '0'; |
*buffer++ = '.'; |
for (pos = 0; pos < -decpt; pos++) *buffer++ = '0'; |
while (*digits) *buffer++ = *digits++; |
} |
else |
{ |
pos = 0; |
while (*digits) |
{ |
if (pos++ == decpt) *buffer++ = '.'; |
*buffer++ = *digits++; |
} |
} |
} |
else |
{ |
*buffer++ = '0'; |
if (precision > 0) |
{ |
*buffer++ = '.'; |
for (pos = 0; pos < precision; pos++) *buffer++ = '0'; |
} |
} |
} |
buffer[2] = (exp % 10) + '0'; |
exp = exp / 10; |
buffer[1] = (exp % 10) + '0'; |
exp = exp / 10; |
buffer[0] = (exp % 10) + '0'; |
buffer += 3; |
} else if (fmt == 'f') { |
digits = fcvtbuf(value, precision, &decpt, &sign, cvtbuf); |
if (sign) |
*buffer++ = '-'; |
if (*digits) { |
if (decpt <= 0) { |
*buffer++ = '0'; |
*buffer++ = '.'; |
for (pos = 0; pos < -decpt; pos++) |
*buffer++ = '0'; |
while (*digits) |
*buffer++ = *digits++; |
} else { |
pos = 0; |
while (*digits) { |
if (pos++ == decpt) |
*buffer++ = '.'; |
*buffer++ = *digits++; |
} |
} |
} else { |
*buffer++ = '0'; |
if (precision > 0) { |
*buffer++ = '.'; |
for (pos = 0; pos < precision; pos++) |
*buffer++ = '0'; |
} |
} |
} |
|
*buffer = '\0'; |
*buffer = '\0'; |
} |
|
static void decimal_point(char *buffer) |
{ |
while (*buffer) |
{ |
if (*buffer == '.') return; |
if (*buffer == 'e' || *buffer == 'E') break; |
buffer++; |
} |
while (*buffer) { |
if (*buffer == '.') |
return; |
if (*buffer == 'e' || *buffer == 'E') |
break; |
buffer++; |
} |
|
if (*buffer) |
{ |
int n = strnlen(buffer,256); |
while (n > 0) |
{ |
buffer[n + 1] = buffer[n]; |
n--; |
} |
if (*buffer) { |
int n = strnlen(buffer, 256); |
while (n > 0) { |
buffer[n + 1] = buffer[n]; |
n--; |
} |
|
*buffer = '.'; |
} |
else |
{ |
*buffer++ = '.'; |
*buffer = '\0'; |
} |
*buffer = '.'; |
} else { |
*buffer++ = '.'; |
*buffer = '\0'; |
} |
} |
|
static void cropzeros(char *buffer) |
{ |
char *stop; |
char *stop; |
|
while (*buffer && *buffer != '.') buffer++; |
if (*buffer++) |
{ |
while (*buffer && *buffer != 'e' && *buffer != 'E') buffer++; |
stop = buffer--; |
while (*buffer == '0') buffer--; |
if (*buffer == '.') buffer--; |
while (buffer!=stop) |
*++buffer=0; |
} |
while (*buffer && *buffer != '.') |
buffer++; |
if (*buffer++) { |
while (*buffer && *buffer != 'e' && *buffer != 'E') |
buffer++; |
stop = buffer--; |
while (*buffer == '0') |
buffer--; |
if (*buffer == '.') |
buffer--; |
while (buffer != stop) |
*++buffer = 0; |
} |
} |
|
static char *flt(char *str, double num, int size, int precision, char fmt, int flags) |
static char *flt(char *str, double num, int size, int precision, char fmt, |
int flags) |
{ |
char tmp[80]; |
char c, sign; |
int n, i; |
char tmp[80]; |
char c, sign; |
int n, i; |
|
// Left align means no zero padding |
if (flags & LEFT) flags &= ~ZEROPAD; |
// Left align means no zero padding |
if (flags & LEFT) |
flags &= ~ZEROPAD; |
|
// Determine padding and sign char |
c = (flags & ZEROPAD) ? '0' : ' '; |
sign = 0; |
if (flags & SIGN) |
{ |
if (num < 0.0) |
{ |
sign = '-'; |
num = -num; |
size--; |
} |
else if (flags & PLUS) |
{ |
sign = '+'; |
size--; |
} |
else if (flags & SPACE) |
{ |
sign = ' '; |
size--; |
} |
} |
// Determine padding and sign char |
c = (flags & ZEROPAD) ? '0' : ' '; |
sign = 0; |
if (flags & SIGN) { |
if (num < 0.0) { |
sign = '-'; |
num = -num; |
size--; |
} else if (flags & PLUS) { |
sign = '+'; |
size--; |
} else if (flags & SPACE) { |
sign = ' '; |
size--; |
} |
} |
// Compute the precision value |
if (precision < 0) |
precision = 6; // Default precision: 6 |
|
// 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 |
420,188 → 422,202
|
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 != '%') |
{ |
*str++ = *fmt; |
continue; |
} |
|
// Process flags |
flags = 0; |
for (str = buf; *fmt; fmt++) { |
if (*fmt != '%') { |
*str++ = *fmt; |
continue; |
} |
// Process flags |
flags = 0; |
repeat: |
fmt++; // This also skips first '%' |
switch (*fmt) |
{ |
case '-': flags |= LEFT; goto repeat; |
case '+': flags |= PLUS; goto repeat; |
case ' ': flags |= SPACE; goto repeat; |
case '#': flags |= HEX_PREP; goto repeat; |
case '0': flags |= ZEROPAD; goto repeat; |
} |
|
// 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; |
} |
} |
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 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 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; |
|
// Get the conversion qualifier |
qualifier = -1; |
if (*fmt == 'l' || *fmt == 'L') |
{ |
qualifier = *fmt; |
fmt++; |
} |
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; |
|
// Default base |
base = 10; |
case 's': |
s = va_arg(args, char *); |
if (!s) |
s = "<NULL>"; |
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; |
|
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 '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 's': |
s = va_arg(args, char *); |
if (!s) s = "<NULL>"; |
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 'A': |
flags |= UPPERCASE; |
|
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': |
if (qualifier == 'l') |
str = |
eaddr(str, va_arg(args, unsigned char *), |
field_width, precision, flags); |
else |
str = |
iaddr(str, va_arg(args, unsigned char *), |
field_width, precision, flags); |
continue; |
|
case 'A': |
flags |= UPPERCASE; |
// Integer number formats - set up the flags and "break" |
case 'o': |
base = 8; |
break; |
|
case 'a': |
if (qualifier == 'l') |
str = eaddr(str, va_arg(args, unsigned char *), field_width, precision, flags); |
else |
str = iaddr(str, va_arg(args, unsigned char *), field_width, precision, flags); |
continue; |
case 'X': |
flags |= UPPERCASE; |
|
// Integer number formats - set up the flags and "break" |
case 'o': |
base = 8; |
break; |
case 'x': |
base = 16; |
break; |
|
case 'X': |
flags |= UPPERCASE; |
case 'd': |
case 'i': |
flags |= SIGN; |
|
case 'x': |
base = 16; |
break; |
case 'u': |
break; |
|
case 'd': |
case 'i': |
flags |= SIGN; |
|
case 'u': |
break; |
|
#ifdef HAS_FLOAT |
|
case 'f': |
str = flt(str, va_arg(args, double), field_width, precision, *fmt, flags | SIGN); |
continue; |
case 'f': |
str = |
flt(str, va_arg(args, double), field_width, |
precision, *fmt, flags | SIGN); |
continue; |
|
#endif |
|
default: |
if (*fmt != '%') *str++ = '%'; |
if (*fmt) |
*str++ = *fmt; |
else |
--fmt; |
continue; |
} |
default: |
if (*fmt != '%') |
*str++ = '%'; |
if (*fmt) |
*str++ = *fmt; |
else |
--fmt; |
continue; |
} |
|
if (qualifier == 'l') |
num = va_arg(args, unsigned long); |
else if (flags & SIGN) |
num = va_arg(args, int); |
else |
num = va_arg(args, unsigned int); |
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 = number(str, num, base, field_width, precision, flags); |
} |
|
*str = '\0'; |
return str - buf; |
*str = '\0'; |
return str - buf; |
} |
|
void uart_send_char(char c) { |
|
uart_putc(c); |
void uart_send_char(char c) |
{ |
|
uart_putc(c); |
|
} |
|
int ee_printf(const char *fmt, ...) |
{ |
char buf[256],*p; |
va_list args; |
int n=0; |
char buf[256], *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++; |
} |
va_start(args, fmt); |
ee_vsprintf(buf, fmt, args); |
va_end(args); |
p = buf; |
while (*p) { |
uart_send_char(*p); |
n++; |
p++; |
} |
|
return n; |
return n; |
} |
|
/core_main.c
112,7 → 112,6
|
*/ |
|
|
#if MAIN_HAS_NOARGC |
MAIN_RETURN_TYPE coremark_main(void) |
{ |
145,8 → 144,8
results[0].iterations = 1; |
#endif |
results[0].execs = get_seed_32(5); |
if (results[0].execs == 0) { |
/* if not supplied, execute all algorithms */ |
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 */ |
290,7 → 289,7
ee_printf("6k performance run parameters for coremark.\n"); |
break; |
case 0x7b05: /* seed1=0x3415, seed2=0x3415, seed3=0x66, |
size 2000 per algorithm */ |
size 2000 per algorithm */ |
known_id = 1; |
ee_printf("6k validation run parameters for coremark.\n"); |
break; |
305,7 → 304,7
ee_printf("2K performance run parameters for coremark.\n"); |
break; |
case 0x18f2: /* seed1=0x3415, seed2=0x3415, seed3=0x66, |
size 666 per algorithm */ |
size 666 per algorithm */ |
known_id = 4; |
ee_printf("2K validation run parameters for coremark.\n"); |
break; |
431,17 → 430,15
return MAIN_RETURN_VAL; |
} |
|
int coremark_cmd(int argc, char *argv[]) |
{ |
return coremark_main(argc, argv); |
|
|
int coremark_cmd (int argc, char *argv[]) |
{ |
return coremark_main(argc, argv); |
|
} |
|
void module_coremark_init (void) |
void module_coremark_init(void) |
{ |
register_command ("coremark", "[<mode>] [<iterations>]", |
"run coremark, mode: p - performance run, o - profile run, default - validation run", |
coremark_cmd); |
register_command("coremark", "[<mode>] [<iterations>]", |
"run coremark, mode: p - performance run, o - profile run, default - validation run", |
coremark_cmd); |
} |
/core_matrix.c
15,7 → 15,7
EEMBC |
4354 Town Center Blvd. Suite 114-200 |
El Dorado Hills, CA, 95762 |
*/ |
*/ |
#include "coremark.h" |
/* |
Topic: Description |
33,13 → 33,13
|
The actual values for A and B must be derived based on input that is not available at compile time. |
*/ |
ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val); |
ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval); |
void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val); |
void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B); |
void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B); |
void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B); |
void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val); |
ee_s16 matrix_test(ee_u32 N, MATRES * C, MATDAT * A, MATDAT * B, MATDAT val); |
ee_s16 matrix_sum(ee_u32 N, MATRES * C, MATDAT clipval); |
void matrix_mul_const(ee_u32 N, MATRES * C, MATDAT * A, MATDAT val); |
void matrix_mul_vect(ee_u32 N, MATRES * C, MATDAT * A, MATDAT * B); |
void matrix_mul_matrix(ee_u32 N, MATRES * C, MATDAT * A, MATDAT * B); |
void matrix_mul_matrix_bitextract(ee_u32 N, MATRES * C, MATDAT * A, MATDAT * B); |
void matrix_add_const(ee_u32 N, MATDAT * A, MATDAT val); |
|
#define matrix_test_next(x) (x+1) |
#define matrix_clip(x,y) ((y) ? (x) & 0x0ff : (x) & 0x0ffff) |
47,26 → 47,29
#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; i++) { |
for (j=0; j<N; j++) { |
if (j!=0) |
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; i++) { |
for (j = 0; j < N; j++) { |
if (j != 0) |
ee_printf(","); |
ee_printf("%d",A[i*N+j]); |
ee_printf("%d", A[i * N + j]); |
} |
ee_printf("\n"); |
} |
} |
void printmatC(MATRES *C, ee_u32 N, char *name) { |
ee_u32 i,j; |
ee_printf("Matrix %s [%dx%d]:\n",name,N,N); |
for (i=0; i<N; i++) { |
for (j=0; j<N; j++) { |
if (j!=0) |
|
void printmatC(MATRES * C, ee_u32 N, char *name) |
{ |
ee_u32 i, j; |
ee_printf("Matrix %s [%dx%d]:\n", name, N, N); |
for (i = 0; i < N; i++) { |
for (j = 0; j < N; j++) { |
if (j != 0) |
ee_printf(","); |
ee_printf("%d",C[i*N+j]); |
ee_printf("%d", C[i * N + j]); |
} |
ee_printf("\n"); |
} |
78,14 → 81,15
Iterate <matrix_test> 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; |
} |
114,36 → 118,37
|
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 */ |
|
matrix_add_const(N, A, -val); /* return matrix to initial value */ |
return crc; |
} |
|
162,43 → 167,45
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; |
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; |
ee_s32 order = 1; |
MATDAT val; |
ee_u32 i=0,j=0; |
if (seed==0) |
seed=1; |
while (j<blksize) { |
ee_u32 i = 0, j = 0; |
if (seed == 0) |
seed = 1; |
while (j < blksize) { |
i++; |
j=i*i*2*4; |
j = i * i * 2 * 4; |
} |
N=i-1; |
A=(MATDAT *)align_mem(memblk); |
B=A+N*N; |
N = i - 1; |
A = (MATDAT *) align_mem(memblk); |
B = A + N * N; |
|
for (i=0; i<N; i++) { |
for (j=0; j<N; j++) { |
seed = ( ( order * seed ) % 65536 ); |
for (i = 0; i < N; i++) { |
for (j = 0; j < N; j++) { |
seed = ((order * seed) % 65536); |
val = (seed + order); |
val=matrix_clip(val,0); |
B[i*N+j] = val; |
val = (val + order); |
val=matrix_clip(val,1); |
A[i*N+j] = val; |
val = matrix_clip(val, 0); |
B[i * N + j] = val; |
val = (val + order); |
val = matrix_clip(val, 1); |
A[i * N + j] = val; |
order++; |
} |
} |
|
p->A=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; |
} |
213,21 → 220,22
|
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; i<N; i++) { |
for (j=0; j<N; j++) { |
cur=C[i*N+j]; |
tmp+=cur; |
if (tmp>clipval) { |
ret+=10; |
tmp=0; |
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; |
ret += (cur > prev) ? 1 : 0; |
} |
prev=cur; |
prev = cur; |
} |
} |
return ret; |
237,11 → 245,12
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; i<N; i++) { |
for (j=0; j<N; j++) { |
C[i*N+j]=(MATRES)A[i*N+j] * (MATRES)val; |
void matrix_mul_const(ee_u32 N, MATRES * C, MATDAT * A, MATDAT val) |
{ |
ee_u32 i, j; |
for (i = 0; i < N; i++) { |
for (j = 0; j < N; j++) { |
C[i * N + j] = (MATRES) A[i * N + j] * (MATRES) val; |
} |
} |
} |
249,11 → 258,12
/* Function: matrix_add_const |
Add a constant value to all elements of a matrix. |
*/ |
void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val) { |
ee_u32 i,j; |
for (i=0; i<N; i++) { |
for (j=0; j<N; j++) { |
A[i*N+j] += val; |
void matrix_add_const(ee_u32 N, MATDAT * A, MATDAT val) |
{ |
ee_u32 i, j; |
for (i = 0; i < N; i++) { |
for (j = 0; j < N; j++) { |
A[i * N + j] += val; |
} |
} |
} |
262,12 → 272,13
Multiply a matrix by a vector. |
This is common in many simple filters (e.g. fir where a vector of coefficients is applied to the matrix.) |
*/ |
void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) { |
ee_u32 i,j; |
for (i=0; i<N; i++) { |
C[i]=0; |
for (j=0; j<N; j++) { |
C[i]+=(MATRES)A[i*N+j] * (MATRES)B[j]; |
void matrix_mul_vect(ee_u32 N, MATRES * C, MATDAT * A, MATDAT * B) |
{ |
ee_u32 i, j; |
for (i = 0; i < N; i++) { |
C[i] = 0; |
for (j = 0; j < N; j++) { |
C[i] += (MATRES) A[i * N + j] * (MATRES) B[j]; |
} |
} |
} |
276,14 → 287,16
Multiply a matrix by a matrix. |
Basic code is used in many algorithms, mostly with minor changes such as scaling. |
*/ |
void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) { |
ee_u32 i,j,k; |
for (i=0; i<N; i++) { |
for (j=0; j<N; j++) { |
C[i*N+j]=0; |
for(k=0;k<N;k++) |
{ |
C[i*N+j]+=(MATRES)A[i*N+k] * (MATRES)B[k*N+j]; |
void matrix_mul_matrix(ee_u32 N, MATRES * C, MATDAT * A, MATDAT * B) |
{ |
ee_u32 i, j, k; |
for (i = 0; i < N; i++) { |
for (j = 0; j < N; j++) { |
C[i * N + j] = 0; |
for (k = 0; k < N; k++) { |
C[i * N + j] += |
(MATRES) A[i * N + k] * (MATRES) B[k * N + |
j]; |
} |
} |
} |
293,15 → 306,19
Multiply a matrix by a matrix, and extract some bits from the result. |
Basic code is used in many algorithms, mostly with minor changes such as scaling. |
*/ |
void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) { |
ee_u32 i,j,k; |
for (i=0; i<N; i++) { |
for (j=0; j<N; j++) { |
C[i*N+j]=0; |
for(k=0;k<N;k++) |
{ |
MATRES tmp=(MATRES)A[i*N+k] * (MATRES)B[k*N+j]; |
C[i*N+j]+=bit_extract(tmp,2,4)*bit_extract(tmp,5,7); |
void matrix_mul_matrix_bitextract(ee_u32 N, MATRES * C, MATDAT * A, MATDAT * B) |
{ |
ee_u32 i, j, k; |
for (i = 0; i < N; i++) { |
for (j = 0; j < N; j++) { |
C[i * N + j] = 0; |
for (k = 0; k < N; k++) { |
MATRES tmp = |
(MATRES) A[i * N + k] * (MATRES) B[k * N + |
j]; |
C[i * N + j] += |
bit_extract(tmp, 2, 4) * bit_extract(tmp, 5, |
7); |
} |
} |
} |
/cvt.c
1,105 → 1,99
//#include <math.h> |
|
double modf(double x, double *iptr); // Our local version of modf() |
double modf(double x, double *iptr); // Our local version of modf() |
|
#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) |
{ |
fj = modf(fi / 10, &fi); |
*--p1 = (int)((fj + .03) * 10) + '0'; |
r2++; |
} |
while (p1 < &buf[CVTBUFSIZE]) *p++ = *p1++; |
} |
else if (arg > 0) |
{ |
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'; |
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; |
if (fi != 0) { |
p1 = &buf[CVTBUFSIZE]; |
while (fi != 0) { |
fj = modf(fi / 10, &fi); |
*--p1 = (int)((fj + .03) * 10) + '0'; |
r2++; |
} |
while (p1 < &buf[CVTBUFSIZE]) |
*p++ = *p1++; |
} else if (arg > 0) { |
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'; |
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) |
{ |
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) |
{ |
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) |
{ |
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) |
{ |
return cvt(arg, ndigits, decpt, sign, buf, 0); |
return cvt(arg, ndigits, decpt, sign, buf, 0); |
} |