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