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
00045
00046
00047
00048
00049
00050
00051
00052 #ifdef USE_PCH
00053 #include "common_com_pch.h"
00054 #endif
00055 #pragma hdrstop
00056
00057 #include "defs.h"
00058 #include "tracing.h"
00059 #include "irbdata.h"
00060 #include "ir_a2b_util.h"
00061
00062
00063 INITO_IDX
00064 New_INITO (ST_IDX st, INITV_IDX val)
00065 {
00066 INITO_IDX idx;
00067 INITO &inito = Scope_tab[ST_IDX_level (st)].inito_tab->New_entry (idx);
00068
00069 Set_INITO_st_idx (inito, st);
00070 Set_INITO_val (inito, val);
00071
00072 return make_INITO_IDX (idx, ST_IDX_level (st));
00073 }
00074
00075 INITV_IDX
00076 New_INITV (void)
00077 {
00078 INITV_IDX idx;
00079 INITV& initv = Initv_Table.New_entry (idx);
00080 return idx;
00081 }
00082
00083 inline void
00084 add_initv (INITV_IDX ninv, INITO_IDX ino, INITV_IDX inv)
00085 {
00086 if (inv != 0)
00087 Initv_Table[inv].next = ninv;
00088 else if (ino != 0)
00089 Set_INITO_val (Inito_Table[ino], ninv);
00090 }
00091
00092 INITV_IDX
00093 Copy_INITV(INITV_IDX parent_inv, INITO_IDX ino, INITV_IDX inv)
00094 {
00095 INITV_IDX idx;
00096 INITV& initv = Initv_Table.New_entry (idx);
00097
00098 add_initv (idx, ino, parent_inv);
00099
00100 memcpy(&initv, &Initv_Table[inv], sizeof(INITV));
00101
00102 return idx;
00103 }
00104
00105 void
00106 INITV_Init_Integer (INITV_IDX inv, TYPE_ID mtype, INT64 val, UINT16 repeat)
00107 {
00108 if (val == 0)
00109 INITV_Set_ZERO (Initv_Table[inv], mtype, repeat);
00110 else if (val == 1)
00111 INITV_Set_ONE (Initv_Table[inv], mtype, repeat);
00112 else {
00113 TCON tc = Host_To_Targ (mtype, val);
00114 INITV_Set_VAL (Initv_Table[inv], Enter_tcon(tc), repeat);
00115 }
00116 }
00117
00118 void
00119 INITV_Init_Float (INITV_IDX inv, TYPE_ID mtype, double val, UINT16 repeat)
00120 {
00121 TCON tc = Host_To_Targ_Float (mtype, val);
00122 INITV_Set_VAL (Initv_Table[inv], Enter_tcon(tc), repeat);
00123 }
00124
00125 void
00126 INITV_Init_String (INITV_IDX inv, char *str, INT size, UINT16 repeat)
00127 {
00128
00129
00130 TCON tc = Host_To_Targ_String (MTYPE_STR, str, size);
00131 INITV_Set_VAL (Initv_Table[inv], Enter_tcon(tc), repeat);
00132 }
00133
00134 void
00135 INITV_Init_Symoff (INITV_IDX inv, ST *st, INT64 ofst, UINT16 repeat)
00136 {
00137 INITV_Set_SYMOFF (Initv_Table[inv], repeat, ST_st_idx(st), ofst);
00138 }
00139
00140 void
00141 INITV_Init_Label (INITV_IDX inv, LABEL_IDX lab, UINT16 repeat)
00142 {
00143 INITV_Set_LABEL (Initv_Table[inv], repeat, lab);
00144 }
00145
00146 void
00147 INITV_Init_Symdiff (INITV_IDX inv,
00148 LABEL_IDX lab1, ST *st2, BOOL halfword, UINT16 repeat)
00149 {
00150 INITV_Set_SYMDIFF (Initv_Table[inv], repeat,
00151 lab1, ST_st_idx (st2), halfword);
00152 }
00153
00154 void
00155 INITV_Init_Pad (INITV_IDX inv, UINT32 pad_bytes)
00156 {
00157 INITV_Set_PAD (Initv_Table[inv], pad_bytes);
00158 }
00159
00160 void
00161 INITV_Init_Block (INITV_IDX inv, INITV_IDX bval, UINT16 repeat)
00162 {
00163 INITV_Set_BLOCK (Initv_Table[inv], repeat, bval);
00164 }
00165
00166
00167 INITV_IDX
00168 Irb_Init_Symoff (INITO_IDX ino, INITV_IDX inv, mUINT16 repeat, ST *st,
00169 INT64 ofst)
00170 {
00171 INITV_IDX idx;
00172 INITV& initv = Initv_Table.New_entry (idx);
00173
00174 add_initv (idx, ino, inv);
00175
00176 #ifdef FRONT_END
00177
00178
00179 INITV_Set_SYMOFF (initv, repeat, st ? ST_st_idx (st) : 0, ofst);
00180 #else
00181 INITV_Set_SYMOFF (initv, repeat, ST_st_idx (st), ofst);
00182 #endif
00183
00184 return idx;
00185 }
00186
00187 INITV_IDX
00188 Irb_Init_Label (INITO_IDX ino, INITV_IDX inv, mUINT16 repeat, LABEL_IDX lab)
00189 {
00190 INITV_IDX idx;
00191 INITV& initv = Initv_Table.New_entry (idx);
00192
00193 add_initv (idx, ino, inv);
00194 INITV_Set_LABEL (initv, repeat, lab);
00195 return idx;
00196 }
00197
00198
00199 INITV_IDX
00200 Irb_Init_Symdiff (INITO_IDX ino, INITV_IDX inv, mUINT16 repeat, LABEL_IDX lab1,
00201 ST *st2, BOOL halfword)
00202 {
00203 INITV_IDX idx;
00204 INITV& initv = Initv_Table.New_entry (idx);
00205
00206 add_initv (idx, ino, inv);
00207 INITV_Set_SYMDIFF (initv, repeat, lab1, ST_st_idx (st2),
00208 halfword);
00209 return idx;
00210 }
00211
00212
00213 INITV_IDX
00214 Irb_Init_Val (INITO_IDX ino, INITV_IDX inv, UINT32 repeat, TCON_IDX tc)
00215 {
00216 INITV_IDX idx;
00217 INITV& initv = Initv_Table.New_entry (idx);
00218
00219 add_initv (idx, ino, inv);
00220 INITV_Set_VAL (initv, tc, repeat);
00221 return idx;
00222 }
00223
00224
00225 INITV_IDX
00226 Irb_Init_Pad (INITO_IDX ino, INITV_IDX inv, UINT32 pad_bytes)
00227 {
00228 INITV_IDX idx;
00229 INITV& initv = Initv_Table.New_entry (idx);
00230
00231 add_initv (idx, ino, inv);
00232 INITV_Set_PAD (initv, pad_bytes);
00233 return idx;
00234 }
00235
00236
00237 INITV_IDX
00238 Irb_Init_Block (INITO_IDX ino, INITV_IDX inv, mUINT16 repeat)
00239 {
00240 INITV_IDX idx;
00241 INITV& initv = Initv_Table.New_entry (idx);
00242
00243 add_initv (idx, ino, inv);
00244 INITV_Set_BLOCK (initv, repeat, 0);
00245 return idx;
00246 }
00247
00248
00249 static INITV_IDX
00250 Irb_Init_predefined_integer (INITO_IDX ino, INITV_IDX inv, INT32 repeat,
00251 TYPE_ID mtype, INT32 val)
00252 {
00253 INITV_IDX idx;
00254 INITV& initv = Initv_Table.New_entry (idx);
00255
00256 add_initv (idx, ino, inv);
00257 if (val == 0)
00258 INITV_Set_ZERO (initv, mtype, repeat);
00259 else
00260 INITV_Set_ONE (initv, mtype, repeat);
00261
00262 return idx;
00263 }
00264
00265
00266 INITV_IDX
00267 Irb_Init_Integer_Of_Type (TYPE_ID mtype, INT64 value, INT32 repeat,
00268 INITO_IDX ino, INITV_IDX inv)
00269 {
00270 if (value == 0 || value == 1)
00271 return Irb_Init_predefined_integer (ino, inv, repeat, mtype, value);
00272
00273 TCON tc = Host_To_Targ(mtype, value);
00274
00275 return Irb_Init_Val (ino, inv, repeat, Enter_tcon (tc));
00276 }
00277
00278
00279 INITV_IDX
00280 Irb_Init_Integer (INT size, INT64 value, INT32 repeat, INITO_IDX ino,
00281 INITV_IDX inv)
00282 {
00283 TYPE_ID mtype;
00284
00285 switch (size) {
00286 case 1:
00287 mtype = MTYPE_I1;
00288 break;
00289 case 2:
00290 mtype = MTYPE_I2;
00291 break;
00292 case 4:
00293 mtype = MTYPE_I4;
00294 break;
00295 case 8:
00296 mtype = MTYPE_I8;
00297 break;
00298 }
00299
00300 return Irb_Init_Integer_Of_Type (mtype, value, repeat, ino, inv);
00301 }
00302
00303
00304 INITV_IDX
00305 Irb_Init_String (INT size, char *str, INT32 repeat, INITO_IDX ino,
00306 INITV_IDX inv)
00307 {
00308
00309
00310 TCON tc = Host_To_Targ_String (MTYPE_STR, str, size);
00311 return Irb_Init_Val (ino, inv, repeat, Enter_tcon (tc));
00312 }
00313
00314
00315 #ifndef MONGOOSE_BE
00316
00317 INITV_IDX
00318 Irb_Init_Float (INT size, double value, INT32 repeat, INITO_IDX ino,
00319 INITV_IDX inv)
00320 {
00321 TCON tc = Host_To_Targ_Float (size == 4 ? MTYPE_F4 : MTYPE_F8, value);
00322 return Irb_Init_Val (ino, inv, repeat, Enter_tcon (tc));
00323 }
00324
00325 INITV_IDX
00326 Irb_Init_Float_4 (INT size, float value, INT32 repeat, INITO_IDX ino,
00327 INITV_IDX inv)
00328 {
00329 TCON tc = Host_To_Targ_Float_4 (size == 4 ? MTYPE_F4 : MTYPE_F8, value);
00330 return Irb_Init_Val (ino, inv, repeat, Enter_tcon (tc));
00331 }
00332
00333
00334 INITV_IDX
00335 Irb_Init_Quad (INT size, QUAD_TYPE value, INT32 repeat, INITO_IDX ino,
00336 INITV_IDX inv)
00337 {
00338 TCON tc = Host_To_Targ_Quad (value);
00339 return Irb_Init_Val (ino, inv, repeat, Enter_tcon (tc));
00340 }
00341
00342
00343 INITV_IDX
00344 Irb_Init_Complex (INT size, double real, double imag, INT32 repeat,
00345 INITO_IDX ino, INITV_IDX inv)
00346 {
00347 TCON tc = Host_To_Targ_Complex (size == 8 ? MTYPE_C4 : MTYPE_C8, real,
00348 imag);
00349 return Irb_Init_Val (ino, inv, repeat, Enter_tcon (tc));
00350 }
00351
00352
00353 INITV_IDX
00354 Irb_Init_Complex_4 (INT size, float real, float imag, INT32 repeat,
00355 INITO_IDX ino, INITV_IDX inv)
00356 {
00357 TCON tc = Host_To_Targ_Complex_4 (size == 8 ? MTYPE_C4 : MTYPE_C8, real,
00358 imag);
00359 return Irb_Init_Val (ino, inv, repeat, Enter_tcon (tc));
00360 }
00361
00362
00363 INITV_IDX
00364 Irb_Init_Complex_Quad (INT size, QUAD_TYPE real, QUAD_TYPE imag,
00365 INT32 repeat, INITO_IDX ino, INITV_IDX inv)
00366 {
00367 TCON tc = Host_To_Targ_Complex_Quad (real, imag);
00368 return Irb_Init_Val (ino, inv, repeat, Enter_tcon (tc));
00369 }
00370 #endif
00371
00372
00373 struct find_inito_predicate
00374 {
00375 ST_IDX st;
00376
00377 find_inito_predicate (const ST *s) : st (ST_st_idx (s)) {}
00378
00379 BOOL operator () (UINT, const INITO *inito) const {
00380 return INITO_st_idx (*inito) == st;
00381 }
00382 };
00383
00384
00385 INITO_IDX
00386 Find_INITO_For_Symbol (const ST *st)
00387 {
00388 ST_IDX idx = ST_st_idx (st);
00389 if (TY_is_shared(ST_type(st))) {
00390
00391 return 0;
00392 }
00393 return For_all_until (Inito_Table, ST_IDX_level (idx),
00394 find_inito_predicate (st));
00395
00396 }
00397
00398
00399 template <class OP>
00400 void
00401 #ifdef __GNU_BUG_WORKAROUND
00402
00403 For_all_initv (INITV_IDX idx, const OP op)
00404 #else
00405 For_all_initv (INITV_IDX idx, const OP& op)
00406 #endif
00407 {
00408 while (idx) {
00409 const INITV& initv = Initv_Table[idx];
00410 op (initv);
00411 idx = INITV_next (initv);
00412 }
00413 }
00414
00415
00416
00417
00418
00419
00420 struct EnumToStr_t : public ir_a2b::enum2str_tbl_entry_t {
00421 EnumToStr_t(INT val_ = 0, const char* str_ = 0)
00422 : val(val_), str(str_) { }
00423
00424 virtual ~EnumToStr_t() { }
00425
00426 virtual INT getEnumVal() const { return val; }
00427 virtual const char* getStr() const { return str; }
00428
00429 INT val;
00430 const char* str;
00431 };
00432
00433
00434 EnumToStr_t InitvKindToNameTbl[INITVKIND_COUNT] = {
00435 EnumToStr_t(INITVKIND_UNK, "INITV_UNK"),
00436 EnumToStr_t(INITVKIND_SYMOFF, "INITV_SYMOFF"),
00437 EnumToStr_t(INITVKIND_ZERO, "INITV_ZERO"),
00438 EnumToStr_t(INITVKIND_ONE, "INITV_ONE"),
00439 EnumToStr_t(INITVKIND_VAL, "INITV_VAL"),
00440 EnumToStr_t(INITVKIND_BLOCK, "INITV_BLOCK"),
00441 EnumToStr_t(INITVKIND_PAD, "INITV_PAD"),
00442 EnumToStr_t(INITVKIND_SYMDIFF, "INITV_SYMDIFF"),
00443 EnumToStr_t(INITVKIND_SYMDIFF16, "INITV_SYMDIFF16"),
00444 EnumToStr_t(INITVKIND_LABEL, "INITV_LABEL"),
00445 };
00446
00447
00448 const char *
00449 InitvKind_Name (INITVKIND knd)
00450 {
00451 using namespace ir_a2b;
00452 return MapEnumToStr<EnumToStr_t, InitvKindToNameTbl,
00453 INITVKIND_COUNT>("InitvKindToNameTbl", (INT)knd);
00454 }
00455
00456 INITVKIND
00457 Name_To_InitvKind (const char* nm)
00458 {
00459 using namespace ir_a2b;
00460 return (INITVKIND)MapStrToEnum<EnumToStr_t, InitvKindToNameTbl,
00461 INITVKIND_COUNT>("InitvKindToNameTbl", nm);
00462 }
00463
00464
00465 void
00466 Print_INITV (const INITV& initv)
00467 {
00468 INT repeat = 0;
00469 switch (INITV_kind (initv)) {
00470
00471 case INITVKIND_ZERO:
00472 repeat = INITV_repeat2 (initv);
00473 fprintf (TFile, " VAL: 0");
00474 break;
00475
00476 case INITVKIND_ONE:
00477 repeat = INITV_repeat2 (initv);
00478 fprintf (TFile, " VAL: 1");
00479 break;
00480
00481 case INITVKIND_VAL:
00482 repeat = INITV_repeat2 (initv);
00483 fprintf (TFile," VAL: %s",
00484 Targ_Print (NULL, Tcon_Table[INITV_tc (initv)]));
00485 break;
00486
00487 case INITVKIND_SYMOFF:
00488 repeat = INITV_repeat1 (initv);
00489 fprintf (TFile," SYMOFF: %s(0x%x)+%d(0x%x)",
00490 ST_class(INITV_st(initv)) == CLASS_CONST ?
00491 "<constant>" : ST_name(INITV_st(initv)),
00492 INITV_st (initv),
00493 INITV_ofst (initv), INITV_ofst (initv));
00494 break;
00495 case INITVKIND_LABEL:
00496 repeat = INITV_repeat1 (initv);
00497 fprintf (TFile," LABEL: %s (%d)", LABEL_name (INITV_lab (initv)),
00498 INITV_lab (initv));
00499 break;
00500
00501 case INITVKIND_SYMDIFF:
00502 case INITVKIND_SYMDIFF16:
00503 repeat = INITV_repeat1 (initv);
00504 if (INITV_kind (initv) == INITVKIND_SYMDIFF16)
00505 fputs (" SYMDIFF16: ", TFile);
00506 else
00507 fputs (" SYMDIFF: ", TFile);
00508 fprintf (TFile," %s-%s(0x%x)", LABEL_name (INITV_lab1 (initv)),
00509 ST_name (INITV_st2 (initv)), INITV_st2 (initv));
00510 break;
00511
00512 case INITVKIND_BLOCK:
00513 repeat = INITV_repeat1 (initv);
00514 fprintf (TFile," BLOCK: \n");
00515 Print_INITVs (INITV_blk (initv));
00516 fprintf (TFile, " ENDBLOCK");
00517 break;
00518
00519 case INITVKIND_PAD:
00520 repeat = INITV_repeat1 (initv);
00521 fprintf (TFile," PAD: %d", INITV_pad (initv));
00522 break;
00523
00524 default:
00525 fprintf(TFile," bad initv kind %d", INITV_kind (initv));
00526 }
00527 if (repeat > 1)
00528 fprintf (TFile, " (repeat %d)", repeat);
00529 fprintf (TFile, "\n");
00530 }
00531
00532
00533
00534
00535
00536
00537 class Print_INITV_fnctr
00538 {
00539 public:
00540 Print_INITV_fnctr() { }
00541 ~Print_INITV_fnctr() { }
00542
00543 void operator()(const INITV& initv) const {
00544 Print_INITV(initv);
00545 }
00546 };
00547
00548
00549 void
00550 Print_INITVs (INITV_IDX idx)
00551 {
00552 For_all_initv (idx, Print_INITV_fnctr());
00553 }
00554
00555 void
00556 Print_INITVs (FILE *f, INITV_IDX idx)
00557 {
00558 FILE *save_file = Get_Trace_File();
00559 Set_Trace_File_internal(f);
00560 Print_INITVs(idx);
00561 Set_Trace_File_internal(save_file);
00562 }
00563
00564
00565 void
00566 INITO::Print (FILE *f) const
00567 {
00568 if (st_idx != 0)
00569 fprintf (f, "%s (0x%x):\n", ST_name (st_idx), st_idx);
00570 else
00571 fputs ("<noname>:\n", f);
00572
00573 Print_INITVs (f,val);
00574 }
00575
00576 void
00577 Print_INITO (const INITO& ino)
00578 {
00579 ino.Print (TFile);
00580 }
00581
00582
00583 void
00584 Print_Inits (UINT level)
00585 {
00586 UINT size = Scope_tab[level].inito_tab->Size ();
00587
00588 for (UINT i = 1; i < size; ++i)
00589 Print_INITO (i);
00590 }
00591
00592 extern void dump_INITO_idx(INITO_IDX idx)
00593 {
00594 FILE *temp;
00595
00596 temp = Get_Trace_File();
00597 Set_Trace_File_internal(stdout);
00598 Print_INITO(Inito_Table[idx]);
00599 Set_Trace_File_internal(temp);
00600 }
00601
00602 extern void dump_INITV_idx(INITV_IDX idx)
00603 {
00604 FILE *temp;
00605
00606 temp = Get_Trace_File();
00607 Set_Trace_File_internal(stdout);
00608 Print_INITV(Initv_Table[idx]);
00609 Set_Trace_File_internal(temp);
00610 }
00611
00612
00613 static UINT
00614 Get_INITV_Size (INITV_IDX inv)
00615 {
00616 UINT size;
00617 switch (INITV_kind(inv)) {
00618 case INITVKIND_SYMOFF:
00619 case INITVKIND_SYMDIFF:
00620 case INITVKIND_LABEL:
00621 size = Pointer_Size;
00622 break;
00623 case INITVKIND_VAL:
00624 if (TCON_ty(INITV_tc_val(inv)) == MTYPE_STR)
00625 size = TCON_str_len(INITV_tc_val(inv));
00626 else
00627 size = MTYPE_byte_size(TCON_ty(INITV_tc_val(inv)));
00628 break;
00629 case INITVKIND_ZERO:
00630 case INITVKIND_ONE:
00631 size = MTYPE_byte_size(INITV_mtype(inv));
00632 break;
00633 case INITVKIND_PAD:
00634 size = INITV_pad(inv);
00635 break;
00636 case INITVKIND_BLOCK:
00637 size = 0;
00638 inv = INITV_blk(inv);
00639 while (inv != 0) {
00640 size += Get_INITV_Size (inv);
00641 inv = INITV_next(inv);
00642 }
00643 break;
00644 default:
00645 FmtAssert(FALSE, ("Get_INITV_Size unexpected kind"));
00646 size = 0;
00647 break;
00648 }
00649 return size * INITV_repeat(inv);
00650 }
00651
00652
00653 extern UINT
00654 Get_INITO_Size (INITO_IDX ino)
00655 {
00656 INITV_IDX inv = INITO_val(ino);
00657 UINT sum = 0;
00658 while (inv != 0) {
00659 sum += Get_INITV_Size (inv);
00660 inv = INITV_next(inv);
00661 }
00662 return sum;
00663 }
00664