Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 /* ==================================================================== 00037 * ==================================================================== 00038 * 00039 * 00040 * Revision history: 00041 * 21-Mar-93 - Original Version 00042 * 00043 * Description: 00044 * 00045 * declaration of the initialized data structures 00046 * 00047 * 00048 * ==================================================================== 00049 * ==================================================================== 00050 */ 00051 00052 #ifdef USE_PCH 00053 #include "common_com_pch.h" 00054 #endif /* USE_PCH */ 00055 #pragma hdrstop 00056 00057 #include "defs.h" 00058 #include "tracing.h" // for TFile 00059 #include "irbdata.h" 00060 #include "ir_a2b_util.h" // for b2a and a2b utilities 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 } // add_initv 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 // note that it is assumed that the size will include space 00129 // for an ending null if needed. 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 // st could be zero for mutually referencing structures 00178 // one such example is in CONFORM_ANSI c65.c 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 /* FRONT_END */ 00183 00184 return idx; 00185 } // Irb_Init_Symoff 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 } // Irb_Init_Symoff 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 // note that it is assumed that the size will include space 00309 // for an ending null if needed. 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 /* MONGOOSE_BE */ 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 //we don't need init exp for shared variables 00391 return 0; 00392 } 00393 return For_all_until (Inito_Table, ST_IDX_level (idx), 00394 find_inito_predicate (st)); 00395 00396 } // Find_INITO_For_Symbol 00397 00398 00399 template <class OP> 00400 void 00401 #ifdef __GNU_BUG_WORKAROUND 00402 // Work around an obnoxious compiler bug 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 // eraxxon (2005.01): InitvKind_Name, Name_To_InitvKind: Implement 00417 // these routines to support conversion in both directions. 00418 00419 // The type for enumeration value -> string tables 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 } // Print_INITV 00531 00532 00533 // eraxxon: we need this functor for use with the 'For_all_initv' 00534 // template. The template was being instatiated with Print_INITV (a 00535 // function pointer type), but one cannot generally template accross 00536 // an object and a function pointer. 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 /* add up size of all the initv under the inito */ 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