00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 #include <list>
00045 #include <map>
00046 #include <stdarg.h>
00047 #include "ekapi_ia64.h"
00048 #include "ekapi_util.h"
00049 #include "ekapi_itanium.h"
00050
00052
00054
00055 int VARNAME::count = 0;
00056
00057 VARNAME::VARNAME() {
00058 sprintf(varname,"&varname%d",count++);
00059 }
00060
00061 VARNAME::VARNAME(char* prefix) {
00062 assert(strlen(prefix) <= 10);
00063 sprintf(varname,"&%s%d",prefix,count++);
00064 }
00065
00066 char* VARNAME::Addr_Of_Vname() {
00067 return varname;
00068 }
00069
00070 char* VARNAME::Vname() {
00071 return varname + 1;
00072 }
00073
00075
00077
00078
00079
00080 int RESOURCE::total = 0;
00081 int RESOURCE::shift_count_total =0;
00082 std::map <int,RESOURCE*> RESOURCE::resources;
00083
00084
00085 RESOURCE::RESOURCE(char *name)
00086 :varname("resource"),name(name),id(total++),count(0)
00087 {
00088 resources[id] = this;
00089 }
00090
00091
00092 RESOURCE* RESOURCE::Get(int i)
00093 {
00094 assert(total > 0 && i >= 0 && i < total);
00095 return resources[i];
00096 }
00097
00098
00099 void RESOURCE::Update_Res(int res_count, bv32_t res_mask, int is_issue)
00101
00103 {
00104 count = res_count;
00105 mask = res_mask;
00106 issue_res = is_issue;
00107 shift_count = shift_count_total;
00108 Calculate_Field_Word();
00109 Calculate_Field_Shift_Total();
00110 }
00112 void RESOURCE::Calculate_Field_Word()
00114
00115
00117 {
00118 int i;
00119 Is_True(count > 0,("count in class resource is lower than 0"));
00120 word = 0;
00121 }
00122
00123
00125 void RESOURCE::Calculate_Field_Shift_Total()
00127
00128
00130 {
00131 int i;
00132 Is_True(count > 0,("count in class resource is lower than 0"));
00133
00134 for ( i = 31 ; i >= 0 ; --i )
00135 {
00136 if ((1 << i) & count) {
00137 shift_count_total += i + 2;
00138 field_width = i + 2;
00139 break;
00140 }
00141 }
00142 }
00143
00145 void RESOURCE::Output( FILE* fd )
00147
00149 {
00150 fprintf(fd,"SI_RESOURCE %s = {\"%s\",%d,%d,%d,%d};\n",
00151 varname.Vname(),
00152 name,
00153 id,
00154 count,
00155 word,
00156 shift_count);
00157 }
00158
00159 void RESOURCE::Output_All( FILE* fd )
00160 {
00161 int i, _width, _max;
00162 UINT64 init_rrw=0;
00163 UINT64 over_rrw=0;
00164
00165 for ( i = 0; i < total; ++i )
00166 resources[i]->Output(fd);
00167
00168 fprintf(fd,"const int SI_resource_count = %d;\n",total);
00169 fprintf(fd,"SI_RESOURCE * const SI_resources[] = {");
00170
00171 bool is_first = true;
00172 for ( i = 0; i < total; ++i ) {
00173 fprintf(fd,"\n %s",resources[i]->varname.Addr_Of_Vname());
00174 if (i!=total) fprintf(fd, ",");
00175
00176
00177 _width = resources[i]->field_width;
00178 _max = 1ULL << (_width-1);
00179
00180 init_rrw |= (UINT64)(_max - resources[i]->count - 1) << resources[i]->shift_count;
00181 over_rrw |= (UINT64)(_max) << resources[i]->shift_count;
00182 }
00183 fprintf(fd,"\n};\n");
00184
00185
00186 fprintf(fd, "const SI_RRW SI_RRW_initializer = 0x%llxLL;\n", init_rrw);
00187 fprintf(fd, "const SI_RRW SI_RRW_overuse_mask = 0x%llxLL;\n", over_rrw);
00188 fprintf(fd, "const int SI_issue_slot_count = %d;\n", 0);
00189 fprintf(fd, "SI_ISSUE_SLOT * const SI_issue_slots[1] = {0};\n\n");
00190
00191 }
00193
00195
00196 int SCHE_INFO::total = 0;
00197 std::map <int,SCHE_INFO*> SCHE_INFO::fusi_list;
00198
00199 SCHE_INFO::SCHE_INFO(void *pknobs, int fuid):
00200 si_name("varname"), res_req_name("res_req"), total_res_name("varname"),id_set_name("varname"),
00201 res_req_num(0), id(total++), fu_id(fuid), res_req_cycle(1), use_res_sem(0)
00202 {
00203 bv32_t mask;
00204 char *buf;
00205 int i;
00206 int sem_res_id = 1;
00207
00208 mask = KAPI_cportMask4fu(pknobs, 0, fuid);
00209 buf = KAPI_EnumName(pknobs, fuid, "fu_t");
00210 name = strdup(buf+strlen("fu"));
00211
00212 free(buf);
00213
00214 Caculate_Field(mask);
00215 fusi_list[id] = this;
00216
00217
00218 if (use_res_sem) {
00219 int latency = KAPI_CoreLatency(pknobs, fu_id, 0);
00220 res_req_cycle = latency;
00221 for (i=1; i<latency; i++)
00222 {
00223 rrw[i] = 1ULL << RESOURCE::Get(sem_res_id)->Shift_Count();
00224 rrw_id[i] = 1ULL << sem_res_id;
00225 }
00226 }
00227 }
00228
00229 SCHE_INFO::SCHE_INFO(void *pknobs, char *funame):
00230 si_name("varname"), res_req_name("res_req"), total_res_name("varname"),id_set_name("varname"),
00231 res_req_num(0), id(total++), fu_id(-1), res_req_cycle(1)
00232 {
00233 bv32_t mask;
00234 mask = 0;
00235 name = funame;
00236
00237
00238 fusi_list[id] = this;
00239 }
00240 void SCHE_INFO::Req_Issue_Resource()
00241 {
00242 FmtAssert(RESOURCE::Get(0)->Is_Issue_Res(),
00243 ("The first source must be issue resource"));
00244 res_req_id[0] = 0;
00245 res_req_num++;
00246 rrw_id[res_req_cycle - 1] |= 1;
00247 rrw[res_req_cycle - 1] |= 1;
00248 }
00249
00250 void SCHE_INFO::Caculate_Field(bv32_t cport_mask)
00251 {
00252 int index;
00253 RESOURCE* res;
00254
00255
00256 rrw[res_req_cycle - 1]=0;
00257 rrw_id[res_req_cycle - 1]=0;
00258
00259
00260 for (index=0; index < RESOURCE::Total() ; index++)
00261 {
00262 res = RESOURCE::Get(index);
00263 if ( ((res->CportMask() & cport_mask) == cport_mask)
00264 && (cport_mask != 0)) {
00265 rrw_id[res_req_cycle - 1] |= 1ULL << index;
00266 rrw[res_req_cycle - 1] |= 1ULL << res->Shift_Count();
00267 res_req_id[res_req_num+1] = index;
00268 res_req_num++;
00269 issue = 1;
00270 }
00271
00272
00273
00274
00275
00276 if ((strcmp(name, "SEM")==0) &&
00277 (strcasecmp(res->Name(), "SEM")==0)) {
00278 rrw_id[res_req_cycle - 1] |= 1ULL << index;
00279 rrw[res_req_cycle - 1] |= 1ULL << res->Shift_Count();
00280 res_req_id[res_req_num+1] = index;
00281 res_req_num++;
00282 use_res_sem = 1;
00283 }
00284 }
00285
00286
00287
00288
00289
00290 if (issue) {
00291 FmtAssert(RESOURCE::Get(0)->Is_Issue_Res(),
00292 ("The first source must be issue resource"));
00293 res_req_id[0] = 0;
00294 res_req_num++;
00295 rrw_id[res_req_cycle - 1] |= 1;
00296 rrw[res_req_cycle - 1] |= 1;
00297 }
00298 }
00299
00300 void SCHE_INFO::Output_SI(void *pknobs, FILE *fd)
00301 {
00302 int i;
00303 int max_src, max_dest;
00304 int load_access_time=0;
00305 int store_avail_time=0;
00306
00307 VARNAME* operand_latency_info = new VARNAME("latency");
00308 VARNAME* result_latency_info = new VARNAME("latency");
00309
00310 max_src = EKAPI_GetSrcOpndsMax(pknobs);
00311 max_dest = EKAPI_GetDestOpndsMax(pknobs);
00312
00313 fprintf(fd, "/* Instruction group %s */\n", name);
00314 fprintf(fd, "static const SI_RRW %s[] = {\n", res_req_name.Vname());
00315
00316
00317 if (res_req_num != 0) {
00318 fprintf(fd, " %d", res_req_cycle);
00319 for(i=0; i<res_req_cycle; i++)
00320 {
00321 fprintf(fd, ",\n 0x%llxLL", rrw[i]);
00322 }
00323
00324 fprintf(fd, "\n};\n");
00325
00326 fprintf(fd, "static const SI_RESOURCE_ID_SET %s[] = {\n", id_set_name.Vname());
00327 for(i=0; i<res_req_cycle; i++)
00328 {
00329 fprintf(fd, " 0x%llxLL", rrw_id[i]);
00330 if (i != res_req_cycle -1) fprintf(fd, ",\n");
00331 }
00332
00333 fprintf(fd, "\n};\n\n");
00334 fprintf(fd, "static SI_RESOURCE_TOTAL %s[] = {\n", total_res_name.Vname());
00335 for (i=0; i<res_req_num; i++)
00336 {
00337 fprintf(fd, " {%s,1}/* %s */",
00338 RESOURCE::Get(res_req_id[i])->Addr_Of_Vname(),
00339 RESOURCE::Get(res_req_id[i])->Name()
00340 );
00341 if (i != res_req_num-1 )fprintf(fd, ",\n");
00342 }
00343 fprintf(fd, "\n};\n\n");
00344 }
00345 else {
00346 fprintf(fd, " 0");
00347 fprintf(fd, "};\n");
00348 }
00349
00350
00351 fprintf(fd, "static const mUINT8 %s[] = {", operand_latency_info->Vname());
00352 for (i=0; i<max_src; i++)
00353 {
00354 fprintf(fd, "%d", 0);
00355 if (i != max_src-1) fprintf(fd, ",");
00356 }
00357 fprintf(fd, "};\n");
00358
00359 fprintf(fd, "static const mUINT8 %s[] = {", result_latency_info->Vname());
00360 for (i=0; i<max_dest; i++)
00361 {
00362 if (fu_id >= 0) {
00363 fprintf(fd, "%d", KAPI_CoreLatency(pknobs, fu_id, 0));
00364 }
00365 else { fprintf(fd, "%d", 0);}
00366 if (i != max_dest-1) fprintf(fd, ",");
00367 }
00368 fprintf(fd, "};\n");
00369
00370
00371
00372
00373 if (strstr(name, "LD")) {
00374 load_access_time = KAPI_CoreLatency(pknobs, fu_id, 0);
00375 }
00376 if (strcmp(name, "ST")==0 || strcmp(name, "STF")==0) {
00377 store_avail_time = KAPI_CoreLatency(pknobs, fu_id, 0);
00378 }
00379
00380
00381
00382 fprintf(fd, "static SI %s = {\n", si_name.Vname());
00383 fprintf(fd," \"%s\",\n",name);
00384 fprintf(fd," %-15d, /* id */\n",id);
00385 fprintf(fd," %-15s, /* operand latency */\n",
00386 operand_latency_info->Vname());
00387 fprintf(fd," %-15s, /* result latency */\n",
00388 result_latency_info->Vname());
00389 fprintf(fd," %-15d, /* load access time */\n",
00390 load_access_time);
00391 fprintf(fd," %-15d, /* last issue cycle */\n",
00392 0);
00393 fprintf(fd," %-15d, /* store available time */\n",
00394 store_avail_time);
00395 fprintf(fd," %-15s, /* resource requirement */\n",
00396 res_req_name.Vname());
00397 if (res_req_num != 0) {
00398 fprintf(fd," %-15s, /* res id used set vec */\n",
00399 id_set_name.Vname());
00400 }
00401 else {
00402 fprintf(fd," %-15s, /* res id used set vec */\n",
00403 "0");
00404 }
00405
00406 fprintf(fd," %-15d, /* II info size */\n",
00407 0);
00408 fprintf(fd," %-15s, /* II resource requirement vec */\n",
00409 "0");
00410 fprintf(fd," %-15s, /* II res id used set vec */\n",
00411 "0");
00412 fprintf(fd," {{");
00413
00414 for ( i = 0; i <2; ++i ) {
00415 fprintf(fd, "0x%d", 0);
00416 if ( i < 1) fprintf(fd, ",");
00417 }
00418 fprintf(fd, "}} , /* Bad IIs */\n");
00419 fprintf(fd," %-15d, /* valid issue slots vec size */\n",
00420 0);
00421 fprintf(fd," %-15s, /* valid issue slots vec */\n",
00422 "0");
00423 fprintf(fd," %-15d, /* resource count vec size */\n",
00424 res_req_num);
00425
00426 if (res_req_num != 0) {
00427 fprintf(fd," %-15s, /* resource count vec */\n",
00428 total_res_name.Vname());
00429 }
00430 else {
00431 fprintf(fd," %-15s, /* resource count vec */\n",
00432 "0");
00433 }
00434
00435 fprintf(fd," %-15s /* write-write interlock */\n",
00436 "0");
00437 fprintf(fd,"};\n");
00438
00439 }
00440 void SCHE_INFO::Output_SI_ID(FILE *fd)
00441
00442 {
00443 int i;
00444 fprintf(fd, "SI * const SI_ID_si[] = {");
00445 for ( i = 0; i < total; ++i )
00446 {
00447 fprintf(fd,"\n %s",fusi_list[i]->si_name.Addr_Of_Vname());
00448 if (i!=total) fprintf(fd, ",");
00449 }
00450
00451 fprintf(fd,"\n};\n");
00452 fprintf(fd,"const int SI_ID_count = %d;\n\n", total);
00453
00454 }
00455
00456 void SCHE_INFO::Output_OP_SI( void *pknobs, FILE *fd )
00457
00458
00459 {
00460 int i;
00461 int opcount, fuid;
00462 char *funame;
00463
00464 opcount = EKAPI_OpCount(pknobs);
00465
00466 fprintf(fd, "SI * const SI_top_si[%d] = {", opcount);
00467 for ( i = 0; i < opcount; ++i )
00468 {
00469 fuid = EKAPI_Op2FuIndex(pknobs, i);
00470 if (fuid>=0) {
00471 fprintf(fd,"\n %-12s /* %s */",
00472 fusi_list[fuid]->si_name.Addr_Of_Vname(),
00473 EKAPI_OpName4id(pknobs, i)
00474 );
00475 }
00476 else {
00477
00478
00479 char *funame = EKAPI_Op2Fu(pknobs, i);
00480 if (strcmp(funame, "fuUNKNOWN") == 0) {
00481 fprintf(fd, "\n %-12s /* %s */",
00482 fusi_list[total-2]->si_name.Addr_Of_Vname(),
00483 EKAPI_OpName4id(pknobs, i));
00484 }
00485 else {
00486 fprintf(fd, "\n %-12s /* %s */",
00487 fusi_list[total-1]->si_name.Addr_Of_Vname(),
00488 EKAPI_OpName4id(pknobs, i));
00489 }
00490 }
00491 if (i!=opcount) fprintf(fd, ",");
00492 }
00493
00494 fprintf(fd,"\n};\n");
00495 }
00496
00498
00500
00501 void EKAPI_MapResource(void *pknobs, char *name, kapi_cluster_t cluster, ...)
00502
00503
00504
00505
00506
00507
00508
00509
00510 {
00511 va_list ap;
00512 kapi_cluster_t clust;
00513 kapi_ut_t ut;
00514 kapi_port_t pport;
00515 kapi_cutport_t cutport;
00516 kapi_cport_t cport=0;
00517 int count = 0;
00518 bv32_t mask = 0;
00519
00520 RESOURCE *current_resource = new RESOURCE(name);
00521
00522 va_start(ap,cluster);
00523 while ( ( (ut = static_cast<kapi_ut_t>(va_arg(ap,int))) != -1 ) &&
00524 ( (cutport = va_arg(ap,int)) != -1) )
00525 {
00526 count++;
00527 KAPI_cutportInfo(pknobs, cluster, ut, cutport, &pport, &cport);
00528
00529 mask |= 1 << cport;
00530 }
00531
00532 current_resource->Update_Res(count, mask);
00533
00534 va_end(ap);
00535 }
00536
00537 void EKAPI_CreatResource(char *name, int count, int is_issue)
00538
00539
00540 {
00541 RESOURCE *current_resource = new RESOURCE(name);
00542 current_resource->Update_Res(count, 0, is_issue);
00543 }
00544 void EKAPI_ClearResource(void)
00545 {
00546 char *name="clear";
00547 RESOURCE *current_resource = new RESOURCE(name);
00548 current_resource->Clear();
00549 VARNAME* varname_clear = new VARNAME(name);
00550 varname_clear->Clear();
00551 SCHE_INFO* si_clear = new SCHE_INFO();
00552 si_clear->Clear();
00553 }