00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "coremark.h"
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 list_head *core_list_find(list_head *list,list_data *info);
00054 list_head *core_list_reverse(list_head *list);
00055 list_head *core_list_remove(list_head *item);
00056 list_head *core_list_undo_remove(list_head *item_removed, list_head *item_modified);
00057 list_head *core_list_insert_new(list_head *insert_point
00058 , list_data *info, list_head **memblock, list_data **datablock
00059 , list_head *memblock_end, list_data *datablock_end);
00060 typedef ee_s32(*list_cmp)(list_data *a, list_data *b, core_results *res);
00061 list_head *core_list_mergesort(list_head *list, list_cmp cmp, core_results *res);
00062
00063 ee_s16 calc_func(ee_s16 *pdata, core_results *res) {
00064 ee_s16 data=*pdata;
00065 ee_s16 retval;
00066 ee_u8 optype=(data>>7) & 1;
00067 if (optype)
00068 return (data & 0x007f);
00069 else {
00070 ee_s16 flag=data & 0x7;
00071 ee_s16 dtype=((data>>3) & 0xf);
00072 dtype |= dtype << 4;
00073 switch (flag) {
00074 case 0:
00075 if (dtype<0x22)
00076 dtype=0x22;
00077 retval=core_bench_state(res->size,res->memblock[3],res->seed1,res->seed2,dtype,res->crc);
00078 if (res->crcstate==0)
00079 res->crcstate=retval;
00080 break;
00081 case 1:
00082 retval=core_bench_matrix(&(res->mat),dtype,res->crc);
00083 if (res->crcmatrix==0)
00084 res->crcmatrix=retval;
00085 break;
00086 default:
00087 retval=data;
00088 break;
00089 }
00090 res->crc=crcu16(retval,res->crc);
00091 retval &= 0x007f;
00092 *pdata = (data & 0xff00) | 0x0080 | retval;
00093 return retval;
00094 }
00095 }
00096
00097
00098
00099
00100
00101 ee_s32 cmp_complex(list_data *a, list_data *b, core_results *res) {
00102 ee_s16 val1=calc_func(&(a->data16),res);
00103 ee_s16 val2=calc_func(&(b->data16),res);
00104 return val1 - val2;
00105 }
00106
00107
00108
00109
00110
00111
00112 ee_s32 cmp_idx(list_data *a, list_data *b, core_results *res) {
00113 if (res==NULL) {
00114 a->data16 = (a->data16 & 0xff00) | (0x00ff & (a->data16>>8));
00115 b->data16 = (b->data16 & 0xff00) | (0x00ff & (b->data16>>8));
00116 }
00117 return a->idx - b->idx;
00118 }
00119
00120 void copy_info(list_data *to,list_data *from) {
00121 to->data16=from->data16;
00122 to->idx=from->idx;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132 ee_u16 core_bench_list(core_results *res, ee_s16 finder_idx) {
00133 ee_u16 retval=0;
00134 ee_u16 found=0,missed=0;
00135 list_head *list=res->list;
00136 ee_s16 find_num=res->seed3;
00137 list_head *this_find;
00138 list_head *finder, *remover;
00139 list_data info;
00140 ee_s16 i;
00141
00142 info.idx=finder_idx;
00143
00144 for (i=0; i<find_num; i++) {
00145 info.data16= (i & 0xff) ;
00146 this_find=core_list_find(list,&info);
00147 list=core_list_reverse(list);
00148 if (this_find==NULL) {
00149 missed++;
00150 retval+=(list->next->info->data16 >> 8) & 1;
00151 }
00152 else {
00153 found++;
00154 if (this_find->info->data16 & 0x1)
00155 retval+=(this_find->info->data16 >> 9) & 1;
00156
00157 if (this_find->next != NULL) {
00158 finder = this_find->next;
00159 this_find->next = finder->next;
00160 finder->next=list->next;
00161 list->next=finder;
00162 }
00163 }
00164 if (info.idx>=0)
00165 info.idx++;
00166 #if CORE_DEBUG
00167 ee_printf("List find %d: [%d,%d,%d]\n",i,retval,missed,found);
00168 #endif
00169 }
00170 retval+=found*4-missed;
00171
00172 if (finder_idx>0)
00173 list=core_list_mergesort(list,cmp_complex,res);
00174 remover=core_list_remove(list->next);
00175
00176 finder=core_list_find(list,&info);
00177 if (!finder)
00178 finder=list->next;
00179 while (finder) {
00180 retval=crc16(list->info->data16,retval);
00181 finder=finder->next;
00182 }
00183 #if CORE_DEBUG
00184 ee_printf("List sort 1: %04x\n",retval);
00185 #endif
00186 remover=core_list_undo_remove(remover,list->next);
00187
00188 list=core_list_mergesort(list,cmp_idx,NULL);
00189
00190 finder=list->next;
00191 while (finder) {
00192 retval=crc16(list->info->data16,retval);
00193 finder=finder->next;
00194 }
00195 #if CORE_DEBUG
00196 ee_printf("List sort 2: %04x\n",retval);
00197 #endif
00198 return retval;
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 list_head *core_list_init(ee_u32 blksize, list_head *memblock, ee_s16 seed) {
00214
00215 ee_u32 per_item=16+sizeof(struct list_data_s);
00216 ee_u32 size=(blksize/per_item)-2;
00217 list_head *memblock_end=memblock+size;
00218 list_data *datablock=(list_data *)(memblock_end);
00219 list_data *datablock_end=datablock+size;
00220
00221 ee_u32 i;
00222 list_head *finder,*list=memblock;
00223 list_data info;
00224
00225
00226 list->next=NULL;
00227 list->info=datablock;
00228 list->info->idx=0x0000;
00229 list->info->data16=(ee_s16)0x8080;
00230 memblock++;
00231 datablock++;
00232 info.idx=0x7fff;
00233 info.data16=(ee_s16)0xffff;
00234 core_list_insert_new(list,&info,&memblock,&datablock,memblock_end,datablock_end);
00235
00236
00237 for (i=0; i<size; i++) {
00238 ee_u16 datpat=((ee_u16)(seed^i) & 0xf);
00239 ee_u16 dat=(datpat<<3) | (i&0x7);
00240 info.data16=(dat<<8) | dat;
00241 core_list_insert_new(list,&info,&memblock,&datablock,memblock_end,datablock_end);
00242 }
00243
00244 finder=list->next;
00245 i=1;
00246 while (finder->next!=NULL) {
00247 if (i<size/5)
00248 finder->info->idx=i++;
00249 else {
00250 ee_u16 pat=(ee_u16)(i++ ^ seed);
00251 finder->info->idx=0x3fff & (((i & 0x07) << 8) | pat);
00252 }
00253 finder=finder->next;
00254 }
00255 list = core_list_mergesort(list,cmp_idx,NULL);
00256 #if CORE_DEBUG
00257 ee_printf("Initialized list:\n");
00258 finder=list;
00259 while (finder) {
00260 ee_printf("[%04x,%04x]",finder->info->idx,(ee_u16)finder->info->data16);
00261 finder=finder->next;
00262 }
00263 ee_printf("\n");
00264 #endif
00265 return list;
00266 }
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 list_head *core_list_insert_new(list_head *insert_point, list_data *info, list_head **memblock, list_data **datablock
00283 , list_head *memblock_end, list_data *datablock_end) {
00284 list_head *newitem;
00285
00286 if ((*memblock+1) >= memblock_end)
00287 return NULL;
00288 if ((*datablock+1) >= datablock_end)
00289 return NULL;
00290
00291 newitem=*memblock;
00292 (*memblock)++;
00293 newitem->next=insert_point->next;
00294 insert_point->next=newitem;
00295
00296 newitem->info=*datablock;
00297 (*datablock)++;
00298 copy_info(newitem->info,info);
00299
00300 return newitem;
00301 }
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316 list_head *core_list_remove(list_head *item) {
00317 list_data *tmp;
00318 list_head *ret=item->next;
00319
00320 tmp=item->info;
00321 item->info=ret->info;
00322 ret->info=tmp;
00323
00324 item->next=item->next->next;
00325 ret->next=NULL;
00326 return ret;
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 list_head *core_list_undo_remove(list_head *item_removed, list_head *item_modified) {
00346 list_data *tmp;
00347
00348 tmp=item_removed->info;
00349 item_removed->info=item_modified->info;
00350 item_modified->info=tmp;
00351
00352 item_removed->next=item_modified->next;
00353 item_modified->next=item_removed;
00354 return item_removed;
00355 }
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370 list_head *core_list_find(list_head *list,list_data *info) {
00371 if (info->idx>=0) {
00372 while (list && (list->info->idx != info->idx))
00373 list=list->next;
00374 return list;
00375 } else {
00376 while (list && ((list->info->data16 & 0xff) != info->data16))
00377 list=list->next;
00378 return list;
00379 }
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 list_head *core_list_reverse(list_head *list) {
00396 list_head *next=NULL, *tmp;
00397 while (list) {
00398 tmp=list->next;
00399 list->next=next;
00400 next=list;
00401 list=tmp;
00402 }
00403 return next;
00404 }
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 list_head *core_list_mergesort(list_head *list, list_cmp cmp, core_results *res) {
00427 list_head *p, *q, *e, *tail;
00428 ee_s32 insize, nmerges, psize, qsize, i;
00429
00430 insize = 1;
00431
00432 while (1) {
00433 p = list;
00434 list = NULL;
00435 tail = NULL;
00436
00437 nmerges = 0;
00438
00439 while (p) {
00440 nmerges++;
00441
00442 q = p;
00443 psize = 0;
00444 for (i = 0; i < insize; i++) {
00445 psize++;
00446 q = q->next;
00447 if (!q) break;
00448 }
00449
00450
00451 qsize = insize;
00452
00453
00454 while (psize > 0 || (qsize > 0 && q)) {
00455
00456
00457 if (psize == 0) {
00458
00459 e = q; q = q->next; qsize--;
00460 } else if (qsize == 0 || !q) {
00461
00462 e = p; p = p->next; psize--;
00463 } else if (cmp(p->info,q->info,res) <= 0) {
00464
00465 e = p; p = p->next; psize--;
00466 } else {
00467
00468 e = q; q = q->next; qsize--;
00469 }
00470
00471
00472 if (tail) {
00473 tail->next = e;
00474 } else {
00475 list = e;
00476 }
00477 tail = e;
00478 }
00479
00480
00481 p = q;
00482 }
00483
00484 tail->next = NULL;
00485
00486
00487 if (nmerges <= 1)
00488 return list;
00489
00490
00491 insize *= 2;
00492 }
00493 #if COMPILER_REQUIRES_SORT_RETURN
00494 return list;
00495 #endif
00496 }