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 #include "bypass_gen.h"
00043 #include <map>
00044 #include <list>
00045
00046
00047 typedef struct SUC_FU_BYPASS {
00048 kapi_fu_t suc_fu;
00049 BOOL use_eunit;
00050
00051 int eun_id;
00052 int use_opns;
00053
00054
00055
00056 int bypass_val;
00057 };
00058
00059 typedef struct bypass_care_fu {
00060 kapi_fu_t pre_fu;
00061 SUC_FU_BYPASS *succ_bypass;
00062 }BYPASS_CARE_FU;
00063 static BOOL first_in_pre_case = true;
00064 static BOOL first_in_suc_case = true;
00065 static BOOL last_in_suc_case = false;
00066
00067 static SUC_FU_BYPASS cur_state;
00068 static std::map <int, char*> oddfunc_pair;
00069 static std::list < BYPASS_CARE_FU > care_fu_bypasslist;
00070 static std::list < BYPASS_CARE_FU >::iterator cf_iter;
00071
00072
00073 void Print_OddLatency(void *pknobs, FILE *c_file);
00074 void Print_All_Bypass(void *pknobs, FILE *h_file, FILE *c_file);
00075
00076
00077
00079
00080
00081
00082
00083 inline char *Chop_fu(char *funame)
00084 {
00085 return funame? (funame+strlen("fu")): NULL;
00086 }
00087 void Print_OddLatency(void *pknobs, FILE *c_file)
00088 {
00089 int i, count;
00090 int listnum;
00091 int rcid, rid;
00092
00093 count = KAPI_fuCount(pknobs);
00094
00095 for(i=0; i<count; i++)
00096 {
00097 ODD_LATENCY *ol = EKAPI_OddLatencyList(pknobs, i, &listnum);
00098 if (ol != NULL) {
00099 if (listnum != 0) {
00100
00101
00102 BOOL has_odd_func = 0;
00103 for(int j=0; j<listnum; j++)
00104 {
00105 Line2Dot(ol[j].opndname);
00106 if (EKAPI_RegInfo4Name(pknobs, ol[j].opndname, &rcid, &rid))
00107 {
00108 has_odd_func = 1;
00109 }
00110 if (strcmp(ol[j].opndname, "addr") == 0) {
00111 }
00112
00113 }
00114
00115 if (has_odd_func) {
00116 char *func_name;
00117 func_name = (char *)malloc(100*sizeof(char));
00118 sprintf(func_name, "Odd_Latency_%s",
00119 Chop_fu(KAPI_fu2fuName(pknobs, i, 0))
00120 );
00121
00123
00124 oddfunc_pair[i] = func_name;
00125
00126
00127 fprintf(c_file, "static void\n%s(TOP pred_code, TOP succ_code, INT src_reg, "
00128 "INT dst_reg, INT *latency)\n{\n",
00129 func_name
00130 );
00131 if(strstr(func_name, "Odd_Latency_TO")!=NULL) {
00132 fprintf(c_file, "INT reg = dst_reg;");
00133 }
00134 else {
00135 fprintf(c_file, "INT reg = src_reg;");
00136 }
00137 BOOL find =0;
00138 int cur_latency = ol[0].oddlatency;
00139 for(int j=0; j<listnum; j++)
00140 {
00141
00142
00143 Line2Dot(ol[j].opndname);
00144 if (EKAPI_RegInfo4Name(pknobs, ol[j].opndname, &rcid, &rid))
00145 {
00146
00147
00148 if (!find) {
00149 fprintf(c_file, "switch (reg) {\n");
00150 }
00151 if ((cur_latency == ol[j].oddlatency)) {
00152 fprintf(c_file, " case %d:\t// %s\n", rid, ol[j].opndname);
00153 if (j == listnum-1)
00154 fprintf(c_file, " *latency = %d;\n break;\n", cur_latency);
00155 }
00156 else {
00157 fprintf(c_file, " *latency = %d;\n break;\n", cur_latency);
00158 fprintf(c_file, " case %d:\t// %s\n", rid, ol[j].opndname);
00159 cur_latency = ol[j].oddlatency;
00160 if (j == listnum-1)
00161 fprintf(c_file, " *latency = %d;\n break;\n", cur_latency);
00162
00163 }
00164
00165 find = 1;
00166 }
00167
00168 }
00169 if (find)
00170 fprintf(c_file, "}\n");
00171 fprintf(c_file, "}\n\n");
00172 }
00173 }
00174 }
00175 }
00176 }
00177
00178
00179 void Print_Bypass_Pre_Case(void *pknobs, FILE *c_file, int pre_i)
00180 {
00181 char *name = KAPI_fu2fuName(pknobs, pre_i, 0);
00182 if (name == NULL) {
00183 Is_True(false, ("KNOB FILE::fu %d not exited.", pre_i));
00184 return;
00185 }
00186 if (first_in_pre_case) {
00187 fprintf(c_file, " switch (pred_class) {\n");
00188 first_in_pre_case = 0;
00189 }
00190
00191 fprintf(c_file, "\tcase SIC_%s:\n", Chop_fu(name));
00192 }
00193
00194
00195 void Print_Bypass_Suc_Case(void *pknobs, FILE *c_file, int suc_i)
00196 {
00197 char *name = KAPI_fu2fuName(pknobs, suc_i, 0);
00198 if (name == NULL) {
00199 Is_True(false, ("KNOB FILE::fu %d not exited.", suc_i));
00200 return;
00201 }
00202 if (first_in_suc_case) {
00203 fprintf(c_file, "\t\tswitch (succ_class) {\n");
00204 first_in_suc_case = 0;
00205 }
00206
00207 fprintf(c_file, "\t\t case SIC_%s:\n", Chop_fu(name));
00208
00209 }
00210 void print_bypass_struct(void *pknobs, FILE *c_file,SUC_FU_BYPASS *bypass, BOOL fu_adjust=false)
00211 {
00212
00213 if ((cur_state.bypass_val == -1))
00214 {
00215 cur_state.bypass_val = bypass->bypass_val;
00216 cur_state.use_opns = bypass->use_opns;
00217 cur_state.use_eunit = bypass->use_eunit;
00218 cur_state.eun_id = bypass->eun_id;
00219 }
00220 if ((cur_state.bypass_val != bypass->bypass_val)
00221 ||(bypass->use_opns != cur_state.use_opns)
00222 ||(cur_state.use_eunit != bypass->use_eunit)
00223 ||(last_in_suc_case)) {
00224
00225 if (cur_state.use_opns > 0) {
00226
00227 if (cur_state.use_opns & 0x1)
00228 fprintf(c_file, "\t\t\tif (%s",
00229 "TOP_Find_Operand_Use(succ_code, OU_base) == opnd");
00230 if (cur_state.use_opns & 0x2)
00231 fprintf(c_file, "\t\t\tif (%s",
00232 "TOP_Find_Operand_Use(succ_code, OU_predicate) == opnd");
00233 }
00234
00235 if (cur_state.use_eunit == 1){
00236 if (cur_state.eun_id == kapi_utI) {
00237 if (cur_state.use_opns > 0)
00238 fprintf(c_file, "\n\t\t\t && ");
00239 else
00240 fprintf(c_file, "\t\t\tif (");
00241 if (!fu_adjust)
00242 fprintf(c_file, "EXEC_PROPERTY_is_%s(pred_code) ", "I_Unit");
00243 else
00244 fprintf(c_file, "!ports.Is_Subset_Of((PORT_SET)3) ");
00245 }
00246 if (cur_state.eun_id == kapi_utM) {
00247 if (cur_state.use_opns > 0)
00248 fprintf(c_file, "\n\t\t\t && ");
00249 else
00250 fprintf(c_file, "\t\t\tif (");
00251 if (!fu_adjust)
00252 fprintf(c_file, "EXEC_PROPERTY_is_%s(pred_code) ", "M_Unit");
00253 else
00254 fprintf(c_file, "!ports.Is_Subset_Of((PORT_SET)12) ");
00255 }
00256 }
00257 if (cur_state.use_opns >0 || cur_state.use_eunit == 1)
00258 fprintf(c_file, ")\n");
00259
00260 if (!fu_adjust)
00261 fprintf(c_file,"\t\t\t *latency += %d;\n", cur_state.bypass_val);
00262 else
00263 fprintf(c_file,"\t\t\t *adjust = -%d;\n", cur_state.bypass_val);
00264
00265 fprintf(c_file, "\t\t\tbreak;\n");
00266 if (!last_in_suc_case) {
00267 cur_state.bypass_val = bypass->bypass_val;
00268 cur_state.use_opns = bypass->use_opns;
00269 cur_state.use_eunit = bypass->use_eunit;
00270 cur_state.eun_id = bypass->eun_id;
00271 Print_Bypass_Suc_Case(pknobs, c_file, bypass->suc_fu);
00272 }
00273 }
00274 }
00275 void Print_All_Bypass(void *pknobs, FILE *h_file, FILE *c_file)
00276 {
00277 int pre_i;
00278 SUC_FU_BYPASS *suc_bypass;
00279 int count = KAPI_fuCount(pknobs);
00280
00281
00282
00283 fprintf(h_file,
00284 "extern void TARG_Adjust_Latency(TOP pred_code, TOP succ_code,\n"
00285 " INT src_reg, INT dst_reg, INT opnd, INT *latency, \n"
00286 " BOOL pred_is_chk=false, BOOL succ_is_chk=false);\n");
00287
00288 fprintf(c_file,
00289 "/* =============================================================\n"
00290 " *\n"
00291 " * TARG_Adjust_Latency\n"
00292 " *\n"
00293 " * See interface description\n"
00294 " *\n"
00295 " * =============================================================\n"
00296 " */\n");
00297 fprintf(c_file, "void\n"
00298 "TARG_Adjust_Latency(TOP pred_code, TOP succ_code, INT src_reg, INT dst_reg,\n"
00299 " INT opnd, INT *latency, BOOL pred_is_chk, BOOL succ_is_chk)\n"
00300 );
00301 fprintf(c_file, "{\n");
00302 fprintf(c_file, " const SCHED_INFO_CLASS pred_class = TARG_Sched_Info_Class(pred_code, pred_is_chk);\n"
00303 " const SCHED_INFO_CLASS succ_class = TARG_Sched_Info_Class(succ_code, succ_is_chk);\n"
00304 );
00305
00306
00307 int pa_num=0;
00308 for (pre_i=0; pre_i<count; pre_i++)
00309 {
00310 int cluster = -1;
00311 int no_set = -1;
00312 first_in_suc_case = 1;
00313 last_in_suc_case = 0;
00314 cur_state.use_opns = -1;
00315 cur_state.bypass_val = -1;
00316 cur_state.use_eunit = 0;
00317
00318
00319 if (oddfunc_pair[pre_i] != NULL) {
00320
00321
00322 Print_Bypass_Pre_Case(pknobs, c_file, pre_i);
00323
00324
00325 fprintf(c_file, "\t\t\t// From-%s register latency is determined\n",
00326 oddfunc_pair[pre_i]);
00327 fprintf(c_file, "\t\t\t// by source register\n");
00328 fprintf(c_file, "\t\t\t%s(pred_code, succ_code, src_reg, dst_reg, latency);\n",
00329 oddfunc_pair[pre_i]);
00330 }
00331 else {
00332 Print_Bypass_Pre_Case(pknobs, c_file, pre_i);
00333 }
00334
00335 for (int suc_i=0; suc_i<count; suc_i++)
00336 {
00337 papair_t *pa = KAPI_IntraClusterBypassList(
00338 pknobs, cluster, pre_i,
00339 -1, (kapi_ut_t)-1, -1,
00340 suc_i, -1, (kapi_ut_t)-1, -1,
00341 &pa_num);
00342 suc_bypass = (SUC_FU_BYPASS *)malloc(pa_num * sizeof(SUC_FU_BYPASS));
00343
00344 for(int pa_i=0; pa_i < pa_num; pa_i++)
00345 {
00346
00347
00348 suc_bypass[pa_i].use_opns = 0;
00349 suc_bypass[pa_i].use_eunit = 0;
00350 suc_bypass[pa_i].eun_id = -1;
00351
00352 if (pa[pa_i].utSrc>=0) {
00353 suc_bypass[pa_i].use_eunit = 1;
00354 suc_bypass[pa_i].eun_id = pa[pa_i].utSrc;
00355
00356 }
00357
00358 char *opnd_name = KAPI_srcOppName(pknobs, suc_i, pa[pa_i].oppDest);
00359 if (opnd_name != NULL) {
00360 if( strcmp(opnd_name, "addr")==0){
00361 suc_bypass[pa_i].use_opns = 1;
00362
00363 }
00364 if( strcmp(opnd_name, "predicate")==0){
00365 suc_bypass[pa_i].use_opns = 2;
00366 }
00367 }
00368 suc_bypass[pa_i].bypass_val = pa[pa_i].iValue;
00369 suc_bypass[pa_i].suc_fu = suc_i;
00370
00371
00372 if (suc_bypass[pa_i].use_eunit == 1 &&
00373 suc_bypass[pa_i].bypass_val >0 &&
00374 pa_i==0 ) {
00375 BYPASS_CARE_FU cf_bypass;
00376 cf_bypass.pre_fu = pre_i;
00377 cf_bypass.succ_bypass = (SUC_FU_BYPASS *)malloc(sizeof(SUC_FU_BYPASS));
00378
00379
00380 cf_bypass.succ_bypass->suc_fu = suc_bypass[pa_i].suc_fu;
00381 cf_bypass.succ_bypass->use_opns = suc_bypass[pa_i].use_opns;
00382 cf_bypass.succ_bypass->use_eunit = suc_bypass[pa_i].use_eunit;
00383 cf_bypass.succ_bypass->eun_id = suc_bypass[pa_i].eun_id;
00384 cf_bypass.succ_bypass->bypass_val = suc_bypass[pa_i].bypass_val;
00385 care_fu_bypasslist.push_back(cf_bypass);
00386 }
00387 }
00388 if (pa != NULL) {
00389
00390 pa = NULL;
00391 }
00392
00393 last_in_suc_case = (suc_i == count-1) ? 1:0;
00394
00395
00396
00397
00398 if (pa_num > 0) {
00399
00401
00402
00403
00404 if ( ((cur_state.bypass_val == suc_bypass->bypass_val)
00405 &&(cur_state.use_opns == suc_bypass->use_opns)
00406 &&(cur_state.use_eunit == suc_bypass->use_eunit))
00407 ||(cur_state.bypass_val == -1))
00408 Print_Bypass_Suc_Case(pknobs, c_file, suc_i);
00409 print_bypass_struct(pknobs, c_file, suc_bypass);
00410 }
00411
00412 if ((last_in_suc_case)&&(cur_state.bypass_val != -1)) {
00413 print_bypass_struct(pknobs, c_file, suc_bypass);
00414 }
00415
00416 free(suc_bypass);
00417 }
00418 if (!first_in_suc_case) {
00419 fprintf(c_file, "\t\t}/*suc fu end*/\n");
00420 }
00421 fprintf(c_file, "\t\tbreak;\n");
00422 if (pre_i == count-1) {
00423 fprintf(c_file, "\t}/*End of swtich of preceding fu*/\n\n");
00424 }
00425
00426 }
00427
00428
00429
00430 fprintf(c_file,
00431 "\n // TOP_alloc only cannot place one group with flushrs,loadrs,br.call,br1.call\n"
00432 " // br.ia,br.ret,clrrrb,cover,rfi;\n"
00433
00434
00435
00436 " if (pred_code == TOP_alloc &&\n"
00437 " (succ_code == TOP_flushrs ||\n"
00438 " succ_code == TOP_br_cexit||\n"
00439 " succ_code == TOP_br_ctop ||\n"
00440 " succ_code == TOP_br_wexit ||\n"
00441 " succ_code == TOP_br_wtop ||\n"
00442 " succ_code == TOP_br_call ||\n"
00443 " succ_code == TOP_br_ia ||\n"
00444 " succ_code == TOP_br_ret ||\n"
00445 " succ_code == TOP_clrrrb ||\n"
00446 " succ_code == TOP_clrrrb_pr ||\n"
00447 " succ_code == TOP_cover ||\n"
00448 " succ_code == TOP_rfi ))\n"
00449 " *latency = 1;\n");
00450
00451 fprintf(c_file, "}/* End of Adjust Latency*/\n\n");
00452
00453
00454 oddfunc_pair.clear ();
00455
00456 }
00457
00458 void Print_FU_Class(void *pknobs, FILE *h_file, FILE *c_file)
00459 {
00460 int count = KAPI_fuCount(pknobs);
00461 fprintf(h_file, "/*Function class of op*/\n");
00462 fprintf(h_file, "typedef enum {\n");
00463 for(int i=0; i<count; i++)
00464 {
00465 char *funame = KAPI_fu2fuName(pknobs, i, 0);
00466 fprintf(h_file, " SIC_%s,\n",Chop_fu(funame));
00467 }
00468 fprintf(h_file, " SIC_DUMMY,\n");
00469 fprintf(h_file, " SIC_UNKNOWN\n");
00470 fprintf(h_file, "} SCHED_INFO_CLASS;\n\n");
00471
00472
00473 fprintf(h_file, "extern SCHED_INFO_CLASS TARG_Sched_Info_Class(TOP top, BOOL is_chk=false);\n");
00474 fprintf(c_file, "SCHED_INFO_CLASS TARG_Sched_Info_Class(TOP top, BOOL is_chk)\n{\n");
00475
00476 fprintf(c_file, " switch (top) {\n");
00477 int op_count = EKAPI_OpCount(pknobs);
00478 char *cur_funame = EKAPI_Op2Fu(pknobs, 0);
00479 for (int i=0; i<op_count; i++)
00480 {
00481 char *funame = EKAPI_Op2Fu(pknobs, i);
00482 char *op_name = EKAPI_OpName4id(pknobs, i);
00483 Dot2Line(op_name);
00484
00485 if (strcmp(cur_funame, funame)==0) {
00486 fprintf(c_file, " case TOP_%s:\n", op_name);
00487 }
00488 else {
00489 BOOL special_ld_op = 0;
00490
00491 if (strcmp(cur_funame,"fuLD")==0) {
00492 fprintf(c_file, " return is_chk ? SIC_%s : SIC_%s;\n",
00493 "CLD",
00494 Chop_fu(cur_funame) );
00495 special_ld_op = 1;
00496 }
00497 if (strcmp(cur_funame,"fuFLD")==0) {
00498 fprintf(c_file, " return is_chk ? SIC_%s : SIC_%s;\n",
00499 "FCLD",
00500 Chop_fu(cur_funame) );
00501 special_ld_op = 1;
00502 }
00503 if (strcmp(cur_funame,"fuFLDP")==0)
00504 {
00505 fprintf(c_file, " return is_chk ? SIC_%s : SIC_%s;\n",
00506 "FCLD",
00507 Chop_fu(cur_funame) );
00508 special_ld_op = 1;
00509 }
00510
00511 if (!special_ld_op)
00512 fprintf(c_file, " return SIC_%s;\n", Chop_fu(cur_funame));
00513 fprintf(c_file, " case TOP_%s:\n", op_name);
00514 strcpy(cur_funame,funame);
00515 }
00516 free(funame);
00517 }
00518 fprintf(c_file, " return SIC_%s;\n", Chop_fu(cur_funame));
00519 fprintf(c_file, "}\n\n");
00520 free(cur_funame);
00521
00522 fprintf(c_file,
00523 " FmtAssert(FALSE, (\"no scheduling class for %s \", TOP_Name(top)));\n",
00524 "%s");
00525 fprintf(c_file," /*NOTREACHED*/\n");
00526 fprintf(c_file, "}\n");
00527
00528 }
00529 void Print_Bypass_Care_FU(void *pknobs, FILE *h_file, FILE *c_file)
00530 {
00531 int old_pre_fu=-1;
00532 int count=0;
00533 first_in_pre_case = 0;
00534
00535 fprintf(h_file, "extern void "
00536 "TARG_Adjust_Latency_FU(TOP pred_code, TOP succ_code, struct PORT_SET ports, INT *adjust);\n"
00537 );
00538 fprintf(c_file, "void\n"
00539 "TARG_Adjust_Latency_FU(TOP pred_code, TOP *succ_code, struct PORT_SET ports, INT *adjust)\n"
00540 );
00541 fprintf(c_file, "{\n");
00542 fprintf(c_file,
00543 " const SCHED_INFO_CLASS pred_class = TARG_Sched_Info_Class(pred_code);\n"
00544 " const SCHED_INFO_CLASS succ_class = TARG_Sched_Info_Class(succ_code);\n"
00545 );
00546 for (cf_iter = care_fu_bypasslist.begin(); cf_iter != care_fu_bypasslist.end(); ++cf_iter)
00547 {
00548 count++;
00549 if (old_pre_fu != cf_iter->pre_fu) {
00550 cur_state.use_opns = -1;
00551 cur_state.bypass_val = -1;
00552 cur_state.use_eunit = 0;
00553 last_in_suc_case = 0;
00554 first_in_pre_case = 1;
00555
00556 if (old_pre_fu >= 0) {
00557 fprintf(c_file, "\t\t}/*suc fu end*/\n");
00558 }
00559 Print_Bypass_Pre_Case(pknobs, c_file, cf_iter->pre_fu);
00560 old_pre_fu = cf_iter->pre_fu;
00561 }else {
00562 last_in_suc_case = (count == (care_fu_bypasslist.size()-1))? 1 : 0;
00563 first_in_pre_case = 0;
00564 }
00565 if ( ((cur_state.bypass_val == cf_iter->succ_bypass->bypass_val)
00566 &&(cur_state.use_opns == cf_iter->succ_bypass->use_opns)
00567 &&(cur_state.use_eunit == cf_iter->succ_bypass->use_eunit))
00568 ||(cur_state.bypass_val == -1))
00569 Print_Bypass_Suc_Case(pknobs, c_file, cf_iter->succ_bypass->suc_fu);
00570 if (!last_in_suc_case)
00571 print_bypass_struct(pknobs, c_file, cf_iter->succ_bypass, true);
00572
00573 }
00574 if (care_fu_bypasslist.size() >0 ) {
00575 last_in_suc_case = 1;
00576 print_bypass_struct(pknobs, c_file, &cur_state, true);
00577 fprintf(c_file, "\t\t}/*suc fu end*/\n");
00578 fprintf(c_file, "\t}/*pre fu end*/\n");
00579 }
00580
00581 for (cf_iter = care_fu_bypasslist.begin(); cf_iter != care_fu_bypasslist.end(); ++cf_iter)
00582 {
00583 free(cf_iter->succ_bypass);
00584 }
00585 fprintf(c_file, "}\n/*function end*/");
00586 }
00587
00588 void Bypass_Generator(void *pknobs, GEN_MODE mode, MACHINE_TYPE type)
00589 {
00590 FILE *c_file, *h_file, *export_file;
00591 int index;
00592 char * description[]= {
00593 "/***************************************************************************\n"
00594 "* Description:\n"
00595 "* void TARG_Adjust_Latency(TOP pred_code, TOP succ_code,\n"
00596 "* INT src_reg, INT dst_reg, INT *latency,\n"
00597 "* BOOL pred_is_chk, BOOL succ_is_chk)\n"
00598 "* Makes any target-specific latency adjustments that may be\n"
00599 "* required between <pred_code> and <succ_code>.\n"
00600 "*/\n", NULL};
00601
00602 first_in_pre_case = true;
00603 first_in_suc_case = true;
00604 last_in_suc_case = false;
00605
00606 if (type == MCK_TYPE)
00607 Init_Module_Files(mode, "targ_bypass_mck", &c_file, &h_file, &export_file, 1);
00608 else
00609 Init_Module_Files(mode, "targ_bypass", &c_file, &h_file, &export_file, 1);
00610 Emit_Header(h_file, "targ_bypass", description, 1);
00611
00612 fprintf(c_file, "#include \"errors.h\"\n");
00613 fprintf(c_file, "#include \"targ_isa_lits.h\"\n");
00614 fprintf(c_file, "#include \"targ_isa_bundle.h\"\n");
00615 fprintf(c_file, "#include \"targ_isa_registers.h\"\n");
00616 fprintf(c_file, "#include \"targ_issue_port.h\"\n");
00617 fprintf(c_file, "#include \"targ_isa_operands.h\"\n");
00618
00619
00620
00621 fprintf(c_file, "#include \"targ_bypass_mck.h\"\n\n\n");
00622
00623 Print_FU_Class(pknobs, h_file, c_file);
00624 Print_OddLatency(pknobs, c_file);
00625 Print_All_Bypass(pknobs, h_file, c_file);
00626
00627
00628 Emit_Tailer(h_file, 1);
00629 Close_Module_Files(mode, &c_file, &h_file, &export_file);
00630
00631 }
00632
00633