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 #if defined(BUILD_OS_DARWIN)
00055 #include <limits.h>
00056 #else
00057 #include <values.h>
00058 #endif
00059 #include <sys/types.h>
00060 #if ! defined(BUILD_OS_DARWIN)
00061 #include <elf.h>
00062 #endif
00063 #include "defs.h"
00064 #include "errors.h"
00065 #include "erfe.h"
00066 extern "C" {
00067 #include "gnu_config.h"
00068 }
00069 #ifdef KEY
00070
00071 #include "gnu/hwint.h"
00072 #include "erglob.h"
00073 #endif
00074 extern "C" {
00075 #include "gnu/flags.h"
00076 #include "gnu/system.h"
00077 #include "gnu/tree.h"
00078 #include "gnu/toplev.h"
00079 #if defined(TARG_SL) || defined(TARG_MIPS)
00080 #include "function.h"
00081 #endif
00082 #include "c-pragma.h"
00083 }
00084 #if defined(TARG_IA32) || defined(TARG_X8664)
00085
00086
00087 #undef TARGET_PENTIUM
00088 #endif
00089
00090 #ifdef KEY
00091 #ifdef TARG_MIPS
00092
00093
00094 #undef ABI_N32
00095 #endif
00096 #endif
00097
00098 #ifdef __MINGW32__
00099 #include "WINDOWS.h"
00100 #endif
00101 #include "glob.h"
00102 #include "wn.h"
00103 #include "wn_util.h"
00104 #include "symtab.h"
00105 #include "const.h"
00106 #include "pu_info.h"
00107 #include "ir_bwrite.h"
00108 #include "ir_reader.h"
00109 #include "tree_symtab.h"
00110 #ifdef KEY // get REAL_VALUE_TYPE
00111 extern "C" {
00112 #include "real.h"
00113 #include "c-common.h"
00114 #include "gnu/c-tree.h"
00115 }
00116 #endif // KEY
00117 #include "wfe_decl.h"
00118 #include "wfe_misc.h"
00119 #include "wfe_dst.h"
00120 #include "wfe_expr.h"
00121 #include "wfe_stmt.h"
00122 #include "tree_cmp.h"
00123 #include "targ_sim.h"
00124
00125 extern FILE *tree_dump_file;
00126
00127 extern PU_Info *PU_Tree_Root;
00128 static PU_Info *PU_Info_Table [258] = {0};
00129 static ST *Return_Address_ST [258] = {0};
00130 static INT32 Save_Expr_Table [258] = {0};
00131 extern INT32 wfe_save_expr_stack_last;
00132 static BOOL map_mempool_initialized = FALSE;
00133 static MEM_POOL Map_Mem_Pool;
00134 ST* WFE_Vararg_Start_ST;
00135 #ifdef KEY
00136 bool defer_function = FALSE;
00137 extern void WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_ID, ST *);
00138 vector <pair<tree, tree> > alias_vector;
00139 static BOOL finish_alias = FALSE;
00140 #endif
00141
00142
00143
00144 static INITO_IDX aggregate_inito = 0;
00145 static INITV_IDX last_aggregate_initv = 0;
00146 static BOOL not_at_root = FALSE;
00147
00148 static int __ctors = 0;
00149 static int __dtors = 0;
00150
00151 extern "C" tree lookup_name (tree);
00152
00153
00154
00155 void
00156 WFE_Assemble_Asm(char *asm_string)
00157 {
00158 ST *asm_st = New_ST(GLOBAL_SYMTAB);
00159 ST_Init(asm_st,
00160 Str_To_Index (Save_Str (asm_string),
00161 Global_Strtab),
00162 CLASS_NAME,
00163 SCLASS_UNKNOWN,
00164 EXPORT_LOCAL,
00165 (TY_IDX) 0);
00166
00167 Set_ST_asm_function_st(*asm_st);
00168
00169 WN *func_wn = WN_CreateEntry(0,
00170 asm_st,
00171 WN_CreateBlock(),
00172 NULL,
00173 NULL);
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183 #ifdef ASM_NEEDS_WN_MAP
00184
00185 if (Current_Map_Tab) {
00186 WN_MAP_TAB_Delete(Current_Map_Tab);
00187 Current_Map_Tab = NULL;
00188 }
00189
00190
00191 if (!map_mempool_initialized) {
00192 MEM_POOL_Initialize(&Map_Mem_Pool,"Map_Mem_Pool",FALSE);
00193 map_mempool_initialized = TRUE;
00194 } else {
00195 MEM_POOL_Pop(&Map_Mem_Pool);
00196 }
00197
00198 MEM_POOL_Push(&Map_Mem_Pool);
00199
00200
00201 (void)WN_MAP_TAB_Create(&Map_Mem_Pool);
00202 #endif
00203
00204
00205
00206
00207
00208
00209 FmtAssert(CURRENT_SYMTAB == GLOBAL_SYMTAB,
00210 ("file-scope asm must be at global symtab scope."));
00211
00212 New_Scope (CURRENT_SYMTAB + 1, Malloc_Mem_Pool, TRUE);
00213
00214 if (Show_Progress) {
00215 fprintf (stderr, "Asm(%s)\n", ST_name (asm_st));
00216 fflush (stderr);
00217 }
00218 PU_Info *pu_info;
00219
00220 pu_info = TYPE_MEM_POOL_ALLOC(PU_Info, Malloc_Mem_Pool);
00221 PU_Info_init(pu_info);
00222
00223 Set_PU_Info_tree_ptr (pu_info, func_wn);
00224 PU_Info_maptab (pu_info) = Current_Map_Tab;
00225 PU_Info_proc_sym (pu_info) = ST_st_idx(asm_st);
00226 PU_Info_pu_dst (pu_info) = DST_Create_Subprogram (asm_st,0);
00227 PU_Info_cu_dst (pu_info) = DST_Get_Comp_Unit ();
00228
00229 Set_PU_Info_state(pu_info, WT_SYMTAB, Subsect_InMem);
00230 Set_PU_Info_state(pu_info, WT_TREE, Subsect_InMem);
00231 Set_PU_Info_state(pu_info, WT_PROC_SYM, Subsect_InMem);
00232
00233 Set_PU_Info_flags(pu_info, PU_IS_COMPILER_GENERATED);
00234
00235 if (PU_Info_Table [CURRENT_SYMTAB])
00236 PU_Info_next (PU_Info_Table [CURRENT_SYMTAB]) = pu_info;
00237 else
00238 PU_Tree_Root = pu_info;
00239
00240 PU_Info_Table [CURRENT_SYMTAB] = pu_info;
00241
00242
00243
00244
00245
00246 pu_info = PU_Info_Table [CURRENT_SYMTAB];
00247
00248
00249 if (Current_Map_Tab) {
00250 WN_MAP_TAB_Delete(Current_Map_Tab);
00251 Current_Map_Tab = NULL;
00252 }
00253
00254 PU_IDX pu_idx;
00255 PU &pu = New_PU(pu_idx);
00256 PU_Init(pu, (TY_IDX) 0, CURRENT_SYMTAB);
00257 Set_PU_no_inline(pu);
00258 Set_PU_no_delete(pu);
00259 Set_ST_pu(*asm_st, pu_idx);
00260
00261 Write_PU_Info (pu_info);
00262
00263
00264 PU_Info_Table [CURRENT_SYMTAB+1] = NULL;
00265
00266 Delete_Scope(CURRENT_SYMTAB);
00267 --CURRENT_SYMTAB;
00268 }
00269
00270 extern void
00271 WFE_Start_Function (tree fndecl)
00272 {
00273
00274 if (CURRENT_SYMTAB != GLOBAL_SYMTAB) {
00275
00276 Set_PU_uplevel (Get_Current_PU ());
00277 Set_PU_no_inline (Get_Current_PU ());
00278 }
00279
00280
00281 if (Current_Map_Tab) {
00282 WN_MAP_TAB_Delete(Current_Map_Tab);
00283 Current_Map_Tab = NULL;
00284 }
00285
00286 #ifdef KEY
00287 wfe_nesting_stack = wfe_loop_stack = wfe_case_stack = wfe_cond_stack = NULL;
00288 #endif // KEY
00289
00290
00291 if (!map_mempool_initialized) {
00292 MEM_POOL_Initialize(&Map_Mem_Pool,"Map_Mem_Pool",FALSE);
00293 map_mempool_initialized = TRUE;
00294 } else {
00295 MEM_POOL_Pop(&Map_Mem_Pool);
00296 }
00297
00298 MEM_POOL_Push(&Map_Mem_Pool);
00299
00300
00301 (void)WN_MAP_TAB_Create(&Map_Mem_Pool);
00302
00303 #ifdef KEY
00304 if (CURRENT_SYMTAB > 1)
00305 ErrMsg (EC_Unimplemented_Feature, "Nested functions");
00306 #endif
00307 New_Scope (CURRENT_SYMTAB + 1, Malloc_Mem_Pool, TRUE);
00308
00309
00310 WN *vla_block = WN_CreateBlock ();
00311 WFE_Stmt_Push (vla_block, wfe_stmk_func_body, Get_Srcpos());
00312
00313 ST *func_st;
00314 ST_EXPORT eclass;
00315
00316
00317 if (DECL_WEAK(fndecl))
00318 eclass = EXPORT_PREEMPTIBLE;
00319 else if (!TREE_PUBLIC(fndecl))
00320 eclass = EXPORT_LOCAL;
00321 else if (DECL_INLINE(fndecl))
00322 eclass = EXPORT_PROTECTED;
00323 else
00324 eclass = EXPORT_PREEMPTIBLE;
00325
00326 #ifdef KEY
00327 bool extern_inline = FALSE;
00328 #endif
00329 if (DECL_INLINE (fndecl) && TREE_PUBLIC (fndecl)) {
00330 if (DECL_EXTERNAL (fndecl) && DECL_ST2 (fndecl) == 0) {
00331
00332 ST *oldst = DECL_ST (fndecl);
00333 DECL_ST (fndecl) = 0;
00334 func_st = Get_ST (fndecl);
00335 DECL_ST (fndecl) = oldst;
00336 DECL_ST2 (fndecl) = func_st;
00337 #ifdef KEY // bugs 2178, 2152
00338 extern_inline = TRUE;
00339 #if defined(TARG_MIPS) && !defined(TARG_SL)
00340 eclass = EXPORT_LOCAL;
00341 #else
00342 eclass = EXPORT_PREEMPTIBLE;
00343 #endif
00344 #endif // KEY
00345 }
00346 else {
00347
00348 func_st = Get_ST (fndecl);
00349 DECL_ST2 (fndecl) = 0;
00350 }
00351 }
00352 else
00353 func_st = Get_ST (fndecl);
00354
00355 Set_ST_sclass (func_st, SCLASS_TEXT);
00356 Set_PU_lexical_level (Pu_Table [ST_pu (func_st)], CURRENT_SYMTAB);
00357 Set_PU_c_lang (Pu_Table [ST_pu (func_st)]);
00358
00359 #ifdef KEY
00360 if (DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (fndecl))
00361 Set_PU_no_instrument (Pu_Table [ST_pu (func_st)]);
00362 if (DECL_DECLARED_INLINE_P(fndecl))
00363 Set_PU_is_marked_inline (Pu_Table [ST_pu (func_st)]);
00364 #endif
00365
00366 if (DECL_INLINE(fndecl)) {
00367 Set_PU_is_inline_function (Pu_Table [ST_pu (func_st)]);
00368 wfe_invoke_inliner = TRUE;
00369 }
00370 Set_ST_export (func_st, eclass);
00371
00372 #ifdef KEY
00373 if (extern_inline)
00374 {
00375 Set_PU_is_extern_inline (Pu_Table [ST_pu (func_st)]);
00376 if (optimize)
00377 Set_PU_must_inline (Pu_Table [ST_pu (func_st)]);
00378 }
00379
00380
00381 if (strcmp (ST_name (func_st), "main") == 0) {
00382 PU& pu = Pu_Table [ST_pu (func_st)];
00383 Set_PU_is_mainpu (pu);
00384 Set_PU_no_inline (pu);
00385 }
00386
00387
00388 if (DECL_NOINLINE_ATTRIB (fndecl)) {
00389 Set_PU_no_inline (Pu_Table [ST_pu (func_st)]);
00390 #ifdef TARG_NVISA
00391 TY_IDX func_ty = ST_pu_type(func_st);
00392 if (!TY_has_prototype (func_ty)) {
00393
00394 ErrMsg(EC_Inline_Prototype, ST_name(func_st));
00395 Clear_PU_no_inline(ST_pu(func_st));
00396 Set_PU_must_inline(ST_pu(func_st));
00397 }
00398
00399 RETURN_INFO return_info = Get_Return_Info (TY_ret_type(func_ty), No_Simulated);
00400 if (RETURN_INFO_return_via_first_arg(return_info)) {
00401
00402 ErrMsg(EC_Inline_Return_Values, ST_name(func_st));
00403 Clear_PU_no_inline(ST_pu(func_st));
00404 Set_PU_must_inline(ST_pu(func_st));
00405 }
00406
00407 PLOC ploc = Setup_Input_Parameter_Locations (func_ty);
00408 TYLIST_IDX tl = TY_parms(func_ty);
00409 if (tl != (TYLIST_IDX) NULL) {
00410 INT i = 0;
00411 for (; TYLIST_ty(tl); tl = TYLIST_next(tl)) {
00412 TY_IDX ty = TYLIST_ty(tl);
00413 if (TY_kind(ty) == KIND_POINTER) {
00414
00415
00416 ErrMsg(EC_Inline_Ptr, ST_name(func_st));
00417 Clear_PU_no_inline(ST_pu(func_st));
00418 Set_PU_must_inline(ST_pu(func_st));
00419 }
00420 ploc = Get_Input_Parameter_Location (ty);
00421 ploc = First_Input_PLOC_Reg (ploc, ty);
00422 while (PLOC_is_nonempty(ploc)) {
00423 ++i;
00424 if (PLOC_on_stack(ploc) || i > MAX_NUMBER_OF_REGISTER_PARAMETERS)
00425 {
00426
00427 ErrMsg(EC_Inline_Parameters, ST_name(func_st));
00428 Clear_PU_no_inline(ST_pu(func_st));
00429 Set_PU_must_inline(ST_pu(func_st));
00430 break;
00431 }
00432 ploc = Next_Input_PLOC_Reg (ploc);
00433 }
00434
00435 if (!PU_no_inline(ST_pu(func_st))) break;
00436 }
00437 }
00438 }
00439 else if (!ST_in_global_mem(func_st)) {
00440
00441 Set_PU_must_inline (ST_pu (func_st));
00442 #endif
00443 }
00444
00445
00446
00447
00448
00449 if (DECL_ALWAYS_INLINE_ATTRIB (fndecl))
00450 Set_PU_must_inline (Pu_Table [ST_pu (func_st)]);
00451
00452 Scope_tab [Current_scope].st = func_st;
00453 #endif // KEY
00454
00455 #if 0 // this is causing IPA not to delete unused PUs (aug-5-03)
00456 #ifdef KEY
00457 if (TREE_USED(fndecl))
00458 Set_PU_no_delete (Pu_Table [ST_pu (func_st)]);
00459 #endif
00460 #endif
00461
00462 #if !defined(TARG_NVISA)
00463 if (lookup_attribute("used", DECL_ATTRIBUTES (fndecl)))
00464 Set_PU_no_delete (Pu_Table [ST_pu (func_st)]);
00465 #else
00466
00467
00468 if (lookup_attribute("global", DECL_ATTRIBUTES (fndecl)) != NULL)
00469 Set_PU_no_delete (Pu_Table [ST_pu (func_st)]);
00470 #endif
00471
00472 if (Show_Progress) {
00473 fprintf (stderr, "Compiling %s \n", ST_name (func_st));
00474 fflush (stderr);
00475 }
00476
00477 INT num_args = 0;
00478 tree pdecl;
00479 for (pdecl = DECL_ARGUMENTS (fndecl); pdecl; pdecl = TREE_CHAIN (pdecl)) {
00480 TY_IDX arg_ty_idx = Get_TY(TREE_TYPE(pdecl));
00481 if (!WFE_Keep_Zero_Length_Structs &&
00482 TY_mtype (arg_ty_idx) == MTYPE_M &&
00483 TY_size (arg_ty_idx) == 0) {
00484
00485 }
00486 else
00487 ++num_args;
00488 }
00489
00490 #ifndef KEY
00491
00492
00493
00494 Scope_tab [Current_scope].st = func_st;
00495 #endif // !KEY
00496
00497 WN *body, *wn;
00498 body = WN_CreateBlock ( );
00499 wn = WN_CreateEntry ( num_args, func_st, body, NULL, NULL );
00500
00501
00502 INT i = 0;
00503 for (pdecl = DECL_ARGUMENTS (fndecl); pdecl; pdecl = TREE_CHAIN (pdecl) )
00504 {
00505 TY_IDX arg_ty_idx = Get_TY(TREE_TYPE(pdecl));
00506 ST *st = Get_ST(pdecl);
00507 if (!WFE_Keep_Zero_Length_Structs &&
00508 TY_mtype (arg_ty_idx) == MTYPE_M &&
00509 TY_size (arg_ty_idx) == 0) {
00510
00511 }
00512 else {
00513 if (TY_mtype (arg_ty_idx) == MTYPE_F4 &&
00514 !TY_has_prototype (ST_pu_type (func_st)))
00515 Set_ST_promote_parm (st);
00516 WN_kid(wn,i) = WN_CreateIdname ( 0, ST_st_idx(st) );
00517 ++i;
00518 }
00519 }
00520
00521 PU_Info *pu_info;
00522
00523 pu_info = TYPE_MEM_POOL_ALLOC(PU_Info, Malloc_Mem_Pool);
00524 PU_Info_init(pu_info);
00525
00526 Set_PU_Info_tree_ptr (pu_info, wn);
00527 PU_Info_maptab (pu_info) = Current_Map_Tab;
00528 PU_Info_proc_sym (pu_info) = ST_st_idx(func_st);
00529 #ifdef KEY
00530 if ((Debug_Level >= 2) && (TREE_CODE (fndecl) == FUNCTION_DECL) &&
00531 (have_dst_idx (fndecl)))
00532 {
00533 DST_INFO_IDX id;
00534 cp_to_dst_from_tree (&id, &DECL_DST_IDX (fndecl));
00535 PU_Info_pu_dst (pu_info) = id;
00536 }
00537 else
00538 {
00539 PU_Info_pu_dst (pu_info) = DST_Create_Subprogram (func_st,fndecl);
00540 if ((Debug_Level >= 2) && (TREE_CODE (fndecl) == FUNCTION_DECL))
00541 {
00542 struct mongoose_gcc_DST_IDX var_idx;
00543 cp_to_tree_from_dst (&var_idx, &PU_Info_pu_dst (pu_info));
00544 DECL_DST_IDX (fndecl) = var_idx;
00545 }
00546 }
00547 #else
00548 PU_Info_pu_dst (pu_info) = DST_Create_Subprogram (func_st,fndecl);
00549 #endif // KEY
00550 PU_Info_cu_dst (pu_info) = DST_Get_Comp_Unit ();
00551
00552 Set_PU_Info_state(pu_info, WT_SYMTAB, Subsect_InMem);
00553 Set_PU_Info_state(pu_info, WT_TREE, Subsect_InMem);
00554 Set_PU_Info_state(pu_info, WT_PROC_SYM, Subsect_InMem);
00555
00556 Set_PU_Info_flags(pu_info, PU_IS_COMPILER_GENERATED);
00557
00558 if (PU_Info_Table [CURRENT_SYMTAB])
00559 PU_Info_next (PU_Info_Table [CURRENT_SYMTAB]) = pu_info;
00560
00561 else
00562 if (CURRENT_SYMTAB == GLOBAL_SYMTAB + 1)
00563 PU_Tree_Root = pu_info;
00564
00565 else
00566 PU_Info_child (PU_Info_Table [CURRENT_SYMTAB -1]) = pu_info;
00567
00568 PU_Info_Table [CURRENT_SYMTAB] = pu_info;
00569 Save_Expr_Table [CURRENT_SYMTAB] = wfe_save_expr_stack_last;
00570
00571 WFE_Stmt_Pop (wfe_stmk_func_body);
00572
00573 WFE_Stmt_Push (wn, wfe_stmk_func_entry, Get_Srcpos());
00574 WFE_Stmt_Push (body, wfe_stmk_func_body, Get_Srcpos());
00575
00576 wn = WN_CreatePragma (WN_PRAGMA_PREAMBLE_END, (ST_IDX) NULL, 0, 0);
00577 WFE_Stmt_Append (wn, Get_Srcpos());
00578 WFE_Stmt_Append (vla_block, Get_Srcpos());
00579
00580 WFE_Vararg_Start_ST = NULL;
00581 #ifndef KEY
00582
00583
00584 if (current_function_varargs) {
00585
00586
00587
00588 PU& pu = Pu_Table[ST_pu (func_st)];
00589 TY_IDX ty_idx;
00590 TY &ty = New_TY (ty_idx);
00591 TY_Init (ty, 0, KIND_FUNCTION, MTYPE_UNKNOWN, STR_IDX_ZERO);
00592 Set_TY_align (ty_idx, 1);
00593 TYLIST tylist_idx;
00594 Set_TYLIST_type (New_TYLIST (tylist_idx),
00595 Get_TY(TREE_TYPE(TREE_TYPE(fndecl))));
00596 Set_TY_tylist (ty, tylist_idx);
00597 for (pdecl = DECL_ARGUMENTS (fndecl); pdecl; pdecl = TREE_CHAIN (pdecl) ) {
00598 WFE_Vararg_Start_ST = Get_ST(pdecl);
00599 Set_TYLIST_type (New_TYLIST (tylist_idx), ST_type(WFE_Vararg_Start_ST));
00600 }
00601 Set_TYLIST_type (New_TYLIST (tylist_idx), 0);
00602 Set_TY_is_varargs (ty_idx);
00603 Set_PU_prototype (pu, ty_idx);
00604 }
00605 #endif // !KEY
00606 }
00607
00608 #ifdef KEY
00609
00610
00611
00612 static bool
00613 Search_and_Remove_PU_Info (PU_Info *pu_tree, PU_Info *search, PU_Info *prev=0)
00614 {
00615 PU_Info *prev_pu = NULL;
00616 for (PU_Info *pu = pu_tree; pu; pu = PU_Info_next (pu))
00617 {
00618 if (pu == search)
00619 {
00620 if (prev_pu)
00621 {
00622
00623
00624
00625
00626 Is_True (PU_Info_next (pu) == NULL, ("PU should be last PU in list"));
00627
00628 PU_Info_Table [CURRENT_SYMTAB] = prev_pu;
00629 PU_Info_next (prev_pu) = PU_Info_next (pu);
00630 }
00631 else
00632 {
00633 FmtAssert (prev, ("No previous PU found"));
00634 PU_Info_child (prev) = PU_Info_next (pu);
00635 }
00636 PU_Info_next (pu) = NULL;
00637 return TRUE;
00638 }
00639
00640 if (PU_Info_child (pu))
00641 {
00642 DevWarn ("Nested PU's not supported");
00643 if (Search_and_Remove_PU_Info (PU_Info_child (pu), search, pu))
00644 return TRUE;
00645 }
00646 prev_pu = pu;
00647 }
00648 Fail_FmtAssertion ("Deferred PU not found in PU tree");
00649 return FALSE;
00650 }
00651 #endif
00652
00653 extern void
00654 WFE_Finish_Function (void)
00655 {
00656 WFE_Check_Undefined_Labels ();
00657 PU_Info *pu_info = PU_Info_Table [CURRENT_SYMTAB];
00658 wfe_save_expr_stack_last = Save_Expr_Table [CURRENT_SYMTAB];
00659
00660 if (CURRENT_SYMTAB > GLOBAL_SYMTAB + 1) {
00661
00662 DevWarn ("Encountered nested function");
00663 Set_PU_is_nested_func (Get_Current_PU ());
00664 Set_PU_no_inline (Get_Current_PU ());
00665 }
00666
00667
00668 WN *wn = WFE_Stmt_Pop (wfe_stmk_func_body);
00669
00670
00671 if (WN_last (wn) == NULL ||
00672 (WN_operator (WN_last (wn)) != OPR_RETURN &&
00673 WN_operator (WN_last (wn)) != OPR_RETURN_VAL)) {
00674 WN *ret_wn = WN_CreateReturn();
00675 #ifdef TARG_NVISA
00676
00677 WN_Set_Linenum (ret_wn, Get_Srcpos());
00678 #endif
00679 WN_INSERT_BlockLast (wn, ret_wn);
00680 }
00681
00682 WN *func_wn = WFE_Stmt_Pop (wfe_stmk_func_entry);
00683 if (PU_has_syscall_linkage (Get_Current_PU ())) {
00684 Set_PU_no_inline (Get_Current_PU ());
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694 }
00695
00696 #ifdef KEY
00697
00698 if (defer_function)
00699 IPA_WN_DELETE_Tree (Current_Map_Tab, func_wn);
00700 #endif
00701
00702
00703 if (Current_Map_Tab) {
00704 WN_MAP_TAB_Delete(Current_Map_Tab);
00705 Current_Map_Tab = NULL;
00706 }
00707
00708 #ifdef KEY
00709 if (!defer_function)
00710 Write_PU_Info (pu_info);
00711 else
00712 {
00713
00714 Set_Max_Region_Id (0);
00715 if (PU_Tree_Root == pu_info)
00716 {
00717
00718 PU_Info_Table [CURRENT_SYMTAB] = PU_Tree_Root = PU_Info_next (pu_info);
00719 PU_Info_next (pu_info) = NULL;
00720 }
00721 else
00722 Search_and_Remove_PU_Info (PU_Tree_Root, pu_info);
00723 }
00724 #else
00725 Write_PU_Info (pu_info);
00726 #endif
00727
00728 PU_Info_Table [CURRENT_SYMTAB+1] = NULL;
00729
00730 if (Return_Address_ST [CURRENT_SYMTAB]) {
00731 Set_PU_has_return_address (Get_Current_PU ());
00732 Set_PU_no_inline (Get_Current_PU ());
00733 Return_Address_ST [CURRENT_SYMTAB] = NULL;
00734 }
00735
00736 Delete_Scope (CURRENT_SYMTAB);
00737 --CURRENT_SYMTAB;
00738
00739
00740 }
00741
00742
00743 void
00744 WFE_Start_Aggregate_Init (tree decl)
00745 {
00746 if (TREE_STATIC(decl)) {
00747 ST *st = Get_ST(decl);
00748 Set_ST_is_initialized(st);
00749 if (ST_sclass(st) == SCLASS_UGLOBAL ||
00750 ST_sclass(st) == SCLASS_EXTERN ||
00751 ST_sclass(st) == SCLASS_COMMON)
00752 Set_ST_sclass(st, SCLASS_DGLOBAL);
00753 aggregate_inito = New_INITO (st);
00754 not_at_root = FALSE;
00755 last_aggregate_initv = 0;
00756 }
00757 }
00758
00759 void
00760 WFE_Add_Aggregate_Init_Padding (INT size)
00761 {
00762 if (aggregate_inito == 0) return;
00763 if (size < 0) return;
00764 INITV_IDX inv = New_INITV();
00765 INITV_Init_Pad (inv, size);
00766 if (last_aggregate_initv != 0)
00767 Set_INITV_next(last_aggregate_initv, inv);
00768 else if (! not_at_root)
00769 Set_INITO_val(aggregate_inito, inv);
00770 last_aggregate_initv = inv;
00771 }
00772
00773 void
00774 WFE_Add_Aggregate_Init_Integer (INT64 val, INT size)
00775 {
00776 if (aggregate_inito == 0) return;
00777 INITV_IDX inv = New_INITV();
00778 TYPE_ID mtype;
00779 if (size == 1) mtype = MTYPE_I1;
00780 else if (size == 2) mtype = MTYPE_I2;
00781 else if (size == 4) mtype = MTYPE_I4;
00782 else if (size == 8) mtype = MTYPE_I8;
00783 else FmtAssert(FALSE, ("WFE_Add_Aggregate_Init_Integer unexpected size"));
00784 INITV_Init_Integer (inv, mtype, val);
00785 if (last_aggregate_initv != 0)
00786 Set_INITV_next(last_aggregate_initv, inv);
00787 else if (! not_at_root)
00788 Set_INITO_val(aggregate_inito, inv);
00789 last_aggregate_initv = inv;
00790 }
00791
00792 static void
00793 WFE_Add_Init_Block(void)
00794 {
00795 if (aggregate_inito == 0) return;
00796 INITV_IDX inv_blk = New_INITV();
00797 if (last_aggregate_initv != 0)
00798 Set_INITV_next(last_aggregate_initv, inv_blk);
00799 else if (! not_at_root)
00800 Set_INITO_val(aggregate_inito, inv_blk);
00801 last_aggregate_initv = inv_blk;
00802 }
00803
00804 #ifdef KEY
00805 float
00806 WFE_Convert_Internal_Real_to_IEEE_Single (REAL_VALUE_TYPE real)
00807 {
00808 INT32 retval;
00809
00810 Is_True (sizeof(INT32) == sizeof(float),
00811 ("The return value from REAL_VALUE_TO_TARGET_SINGLE() should be cast to"
00812 " a integer with the same size as float"));
00813 REAL_VALUE_TO_TARGET_SINGLE(real, retval);
00814 return *(float*)(void*)&retval;
00815 }
00816
00817 double
00818 WFE_Convert_Internal_Real_to_IEEE_Double (REAL_VALUE_TYPE real)
00819 {
00820 long buffer[4];
00821 int compact_buffer[8];
00822
00823 REAL_VALUE_TO_TARGET_DOUBLE (real, buffer);
00824 WFE_Convert_To_Host_Order(buffer);
00825 if (sizeof(long) > 4) {
00826 Is_True (sizeof(long) == 8, ("sizeof(long) shold be 64"));
00827 Is_True (sizeof(int) == 4, ("sizeof(int) should be 32"));
00828 for (INT i = 0; i < sizeof(buffer)/sizeof(buffer[0]); i++)
00829 compact_buffer[i] = (int)buffer[i];
00830 return *(double*)(void*)&compact_buffer[0];
00831 }
00832 return *(double*)(void*)&buffer[0];
00833 }
00834
00835 long double
00836 WFE_Convert_Internal_Real_to_IEEE_Double_Extended (REAL_VALUE_TYPE real)
00837 {
00838 long buffer[4];
00839 int compact_buffer[8];
00840
00841 REAL_VALUE_TO_TARGET_LONG_DOUBLE (real, buffer);
00842 WFE_Convert_To_Host_Order(buffer);
00843 if (sizeof(long) > 4) {
00844 for (INT i = 0; i < sizeof(buffer)/sizeof(buffer[0]); i++)
00845 compact_buffer[i] = buffer[i];
00846 return *(long double*)(void*)&compact_buffer[0];
00847 }
00848 return *(long double*)(void*)&buffer[0];
00849 }
00850 #endif
00851
00852 void
00853 WFE_Add_Aggregate_Init_Real (REAL_VALUE_TYPE real, INT size)
00854 {
00855 if (aggregate_inito == 0) return;
00856 INITV_IDX inv = New_INITV();
00857 TCON tc;
00858 int t1;
00859 #ifdef KEY
00860 long buffer [4];
00861 #else
00862 int buffer [4];
00863 #endif // KEY
00864 switch (size) {
00865 case 4:
00866 tc = Host_To_Targ_Float_4 (MTYPE_F4, WFE_Convert_Internal_Real_to_IEEE_Single (real));
00867 break;
00868 case 8:
00869 tc = Host_To_Targ_Float (MTYPE_F8, WFE_Convert_Internal_Real_to_IEEE_Double (real));
00870 break;
00871 #ifdef TARG_IA64
00872 case 16:
00873 tc = Host_To_Targ_Float_10 (MTYPE_F10, WFE_Convert_Internal_Real_to_IEEE_Double_Extended (real));
00874 break;
00875 #else
00876 case 12:
00877 case 16:
00878 REAL_VALUE_TO_TARGET_LONG_DOUBLE (real, buffer);
00879 WFE_Convert_To_Host_Order(buffer);
00880
00881 tc = Host_To_Targ_Quad (WFE_Convert_Internal_Real_to_IEEE_Double_Extended (real));
00882 break;
00883 #endif
00884 default:
00885 FmtAssert(FALSE, ("WFE_Add_Aggregate_Init_Real unexpected size"));
00886 break;
00887 }
00888 INITV_Set_VAL (Initv_Table[inv], Enter_tcon(tc), 1);
00889 if (last_aggregate_initv != 0)
00890 Set_INITV_next(last_aggregate_initv, inv);
00891 else if (! not_at_root)
00892 Set_INITO_val(aggregate_inito, inv);
00893 last_aggregate_initv = inv;
00894 }
00895
00896 void
00897 WFE_Add_Aggregate_Init_Complex (REAL_VALUE_TYPE rval, REAL_VALUE_TYPE ival, INT size)
00898 {
00899 if (aggregate_inito == 0) return;
00900 INITV_IDX inv = New_INITV();
00901 TCON rtc;
00902 TCON itc;
00903 int t1;
00904 #ifdef KEY
00905 long buffer [4];
00906 #else
00907 int buffer [4];
00908 #endif // KEY
00909 switch (size) {
00910 case 8:
00911 rtc = Host_To_Targ_Float_4 (MTYPE_F4,
00912 WFE_Convert_Internal_Real_to_IEEE_Single (rval));
00913 itc = Host_To_Targ_Float_4 (MTYPE_F4,
00914 WFE_Convert_Internal_Real_to_IEEE_Single (ival));
00915 break;
00916 case 16:
00917 rtc = Host_To_Targ_Float (MTYPE_F8,
00918 WFE_Convert_Internal_Real_to_IEEE_Double (rval));
00919 itc = Host_To_Targ_Float (MTYPE_F8,
00920 WFE_Convert_Internal_Real_to_IEEE_Double (ival));
00921 break;
00922 case 24:
00923 case 32:
00924 rtc = Host_To_Targ_Quad (
00925 WFE_Convert_Internal_Real_to_IEEE_Double_Extended (rval));
00926 itc = Host_To_Targ_Quad (
00927 WFE_Convert_Internal_Real_to_IEEE_Double_Extended (ival));
00928 break;
00929 default:
00930 FmtAssert(FALSE, ("WFE_Add_Aggregate_Init_Complex unexpected size"));
00931 break;
00932 }
00933 INITV_Set_VAL (Initv_Table[inv], Enter_tcon(rtc), 1);
00934 if (last_aggregate_initv != 0)
00935 Set_INITV_next(last_aggregate_initv, inv);
00936 else if (! not_at_root)
00937 Set_INITO_val(aggregate_inito, inv);
00938 last_aggregate_initv = inv;
00939 inv = New_INITV();
00940 INITV_Set_VAL (Initv_Table[inv], Enter_tcon(itc), 1);
00941 Set_INITV_next(last_aggregate_initv, inv);
00942 last_aggregate_initv = inv;
00943 }
00944
00945 void
00946 WFE_Add_Aggregate_Init_String (const char *s, INT size)
00947 {
00948 if (aggregate_inito == 0) return;
00949 INITV_IDX inv = New_INITV();
00950 INITV_Init_String (inv, (char *) s, size);
00951 if (last_aggregate_initv != 0)
00952 Set_INITV_next(last_aggregate_initv, inv);
00953 else if (! not_at_root)
00954 Set_INITO_val(aggregate_inito, inv);
00955 last_aggregate_initv = inv;
00956 }
00957
00958 void
00959 WFE_Add_Aggregate_Init_Symbol (ST *st, WN_OFFSET offset = 0)
00960 {
00961 if (aggregate_inito == 0) return;
00962 INITV_IDX inv = New_INITV();
00963 INITV_Init_Symoff (inv, st, offset);
00964 if (last_aggregate_initv != 0)
00965 Set_INITV_next(last_aggregate_initv, inv);
00966 else if (! not_at_root)
00967 Set_INITO_val(aggregate_inito, inv);
00968 last_aggregate_initv = inv;
00969 }
00970
00971 void
00972 WFE_Add_Aggregate_Init_Label (LABEL_IDX lab)
00973 {
00974 DevWarn ("taking address of a label at line %d", lineno);
00975 Set_PU_no_inline (Get_Current_PU ());
00976 if (aggregate_inito == 0) return;
00977 INITV_IDX inv = New_INITV();
00978 INITV_Init_Label (inv, lab, 1);
00979 if (last_aggregate_initv != 0)
00980 Set_INITV_next(last_aggregate_initv, inv);
00981 else if (! not_at_root)
00982 Set_INITO_val(aggregate_inito, inv);
00983 last_aggregate_initv = inv;
00984 Set_LABEL_addr_saved (lab);
00985 }
00986
00987 void
00988 WFE_Add_Aggregate_Init_Address (tree init)
00989 {
00990 switch (TREE_CODE (init)) {
00991
00992 case VAR_DECL:
00993 case FUNCTION_DECL:
00994 WFE_Add_Aggregate_Init_Symbol (Get_ST (init));
00995 break;
00996
00997 case STRING_CST:
00998 {
00999 TCON tcon = Host_To_Targ_String (MTYPE_STRING,
01000 const_cast<char*>TREE_STRING_POINTER(init),
01001 TREE_STRING_LENGTH(init));
01002 ST *const_st = New_Const_Sym (Enter_tcon (tcon),
01003 Get_TY(TREE_TYPE(init)));
01004 WFE_Add_Aggregate_Init_Symbol (const_st);
01005 }
01006 break;
01007
01008 case PLUS_EXPR:
01009 if ( TREE_CODE(TREE_OPERAND(init,0)) == ADDR_EXPR
01010 && TREE_CODE(TREE_OPERAND(init,1)) == INTEGER_CST)
01011 {
01012 tree addr_kid = TREE_OPERAND(TREE_OPERAND(init,0),0);
01013 FmtAssert(TREE_CODE(addr_kid) == VAR_DECL
01014 || TREE_CODE(addr_kid) == FUNCTION_DECL,
01015 ("expected decl under plus_expr"));
01016 WFE_Add_Aggregate_Init_Symbol ( Get_ST (addr_kid),
01017 Get_Integer_Value(TREE_OPERAND(init,1)) );
01018 }
01019 else
01020 {
01021 WN *init_wn = WFE_Expand_Expr (init);
01022 FmtAssert (WN_operator (init_wn) == OPR_LDA,
01023 ("expected decl under plus_expr"));
01024 WFE_Add_Aggregate_Init_Symbol (WN_st (init_wn),
01025 WN_offset (init_wn));
01026
01027 #ifdef KEY
01028 Set_ST_initv_in_other_st (WN_st(init_wn));
01029 #endif
01030 WN_Delete (init_wn);
01031 }
01032 break;
01033
01034 case INTEGER_CST:
01035 WFE_Add_Aggregate_Init_Integer (Get_Integer_Value (init), Pointer_Size);
01036 break;
01037
01038 case LABEL_DECL:
01039 {
01040 LABEL_IDX label_idx = WFE_Get_LABEL (init, FALSE);
01041 WFE_Add_Aggregate_Init_Label (label_idx);
01042 }
01043 break;
01044
01045 default:
01046 {
01047 #ifndef KEY
01048 WN *init_wn = WFE_Expand_Expr (init);
01049 FmtAssert (WN_operator (init_wn) == OPR_LDA,
01050 ("expected operator encountered"));
01051 WFE_Add_Aggregate_Init_Symbol (WN_st (init_wn),
01052 WN_offset (init_wn));
01053 #else
01054 int tmp_aggr_inito = aggregate_inito;
01055 int tmp_last_aggregate_initv = last_aggregate_initv;
01056 WN *init_wn = WFE_Expand_Expr (init);
01057 aggregate_inito = tmp_aggr_inito;
01058 last_aggregate_initv = tmp_last_aggregate_initv;
01059 WFE_Add_Aggregate_Init_Symbol (WN_st(init_wn));
01060 aggregate_inito = 0;
01061
01062 Set_ST_initv_in_other_st (WN_st(init_wn));
01063 #endif
01064 WN_Delete (init_wn);
01065 }
01066 break;
01067 }
01068 }
01069
01070 void
01071 WFE_Finish_Aggregate_Init (void)
01072 {
01073 if (aggregate_inito == 0) return;
01074 ST *st = INITO_st(aggregate_inito);
01075 TY_IDX ty = ST_type(st);
01076 #ifdef KEY
01077
01078 if ((TY_size(ty) == 0 &&
01079 (TY_kind(ty) != KIND_ARRAY ||
01080 (TY_kind(ty) == KIND_ARRAY &&
01081 !ARB_const_ubnd (TY_arb(ty))))) ||
01082 #else
01083 if (TY_size(ty) == 0 ||
01084 #endif
01085 (TY_kind(ty) == KIND_ARRAY &&
01086 !ARB_const_ubnd (TY_arb(ty)) &&
01087 TY_size(ty) <= Get_INITO_Size(aggregate_inito))) {
01088
01089
01090 Set_TY_size(ty, Get_INITO_Size(aggregate_inito));
01091 if (TY_kind(ty) == KIND_ARRAY) {
01092 Set_ARB_const_ubnd (TY_arb(ty));
01093 Set_ARB_ubnd_val (TY_arb(ty),
01094 (TY_size(ty) / TY_size(TY_etype(ty))) - 1 );
01095 }
01096 }
01097 if (last_aggregate_initv == 0) {
01098 WFE_Add_Aggregate_Init_Padding (0);
01099 }
01100 aggregate_inito = 0;
01101 not_at_root = FALSE;
01102 }
01103
01104
01105 static BOOL
01106 Has_Non_Constant_Init_Value (tree init)
01107 {
01108 if (init == NULL) {
01109 return FALSE;
01110 }
01111 switch (TREE_CODE(init)) {
01112 case CONSTRUCTOR:
01113 return Has_Non_Constant_Init_Value (CONSTRUCTOR_ELTS(init));
01114 case TREE_LIST:
01115 {
01116 tree p;
01117 for (p = init; p != NULL; p = TREE_CHAIN(p)) {
01118 if (Has_Non_Constant_Init_Value (TREE_VALUE(p))) {
01119 return TRUE;
01120 }
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130 }
01131 return FALSE;
01132 }
01133 case INTEGER_CST:
01134 case REAL_CST:
01135 case STRING_CST:
01136 return FALSE;
01137 case NOP_EXPR:
01138 if (TREE_CODE(TREE_OPERAND(init,0)) == ADDR_EXPR
01139 && TREE_CODE(TREE_OPERAND(TREE_OPERAND(init,0),0)) == STRING_CST)
01140 return FALSE;
01141 else
01142 return TRUE;
01143 default:
01144 return TRUE;
01145 }
01146 }
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156 static BOOL
01157 Use_Static_Init_For_Aggregate (ST *st, tree init)
01158 {
01159 #ifdef KEY
01160 FmtAssert( CURRENT_SYMTAB != GLOBAL_SYMTAB ||
01161 !Has_Non_Constant_Init_Value(init),
01162 ("Handle this case") );
01163
01164 if (CURRENT_SYMTAB == GLOBAL_SYMTAB)
01165 return TRUE;
01166 #endif
01167 if (TY_size(ST_type(st)) <= (2*MTYPE_byte_size(Spill_Int_Mtype))) {
01168 return FALSE;
01169 }
01170 else if (Has_Non_Constant_Init_Value(init)) {
01171 return FALSE;
01172 }
01173 else {
01174 return TRUE;
01175 }
01176 }
01177
01178
01179 static void
01180 Add_Initv_For_Tree (tree val, UINT size)
01181 {
01182 WN *init_block;
01183 WN * init_wn;
01184
01185 switch (TREE_CODE(val)) {
01186 case INTEGER_CST:
01187 WFE_Add_Aggregate_Init_Integer (
01188 Get_Integer_Value(val), size);
01189 break;
01190 case REAL_CST:
01191 WFE_Add_Aggregate_Init_Real (
01192 TREE_REAL_CST(val), size);
01193 break;
01194 #ifdef PATHSCALE_MERGE
01195
01196 case COMPLEX_CST:
01197 WFE_Add_Aggregate_Init_Complex (TREE_REAL_CST(TREE_REALPART(val)),
01198 TREE_REAL_CST(TREE_IMAGPART(val)), size);
01199 break;
01200 #endif
01201 case STRING_CST:
01202 WFE_Add_Aggregate_Init_String (
01203 TREE_STRING_POINTER(val), size);
01204 break;
01205 #if 0
01206 case PLUS_EXPR:
01207 if ( TREE_CODE(TREE_OPERAND(val,0)) == ADDR_EXPR
01208 && TREE_CODE(TREE_OPERAND(val,1)) == INTEGER_CST)
01209 {
01210 tree addr_kid = TREE_OPERAND(TREE_OPERAND(val,0),0);
01211 FmtAssert(TREE_CODE(addr_kid) == VAR_DECL
01212 || TREE_CODE(addr_kid) == FUNCTION_DECL,
01213 ("expected decl under plus_expr"));
01214 WFE_Add_Aggregate_Init_Symbol ( Get_ST (addr_kid),
01215 Get_Integer_Value(TREE_OPERAND(val,1)) );
01216 }
01217 else
01218 FmtAssert(FALSE, ("unexpected tree code %s",
01219 tree_code_name[TREE_CODE(val)]));
01220 break;
01221 #endif
01222 case NOP_EXPR:
01223 tree kid;
01224 kid = TREE_OPERAND(val,0);
01225 if (TREE_CODE(kid) == ADDR_EXPR
01226 && TREE_CODE(TREE_OPERAND(kid,0)) == STRING_CST)
01227 {
01228 kid = TREE_OPERAND(kid,0);
01229 WFE_Add_Aggregate_Init_Address (kid);
01230 break;
01231 }
01232
01233 default:
01234 {
01235 init_block = WN_CreateBlock ();
01236 WFE_Stmt_Push (init_block, wfe_stmk_func_body, Get_Srcpos());
01237 init_wn = WFE_Expand_Expr (val);
01238 WFE_Stmt_Pop (wfe_stmk_func_body);
01239
01240 if ((WN_opcode (init_wn) == OPC_I4U4CVT &&
01241 WN_opcode (WN_kid0 (init_wn)) == OPC_U4LDA) ||
01242 (WN_opcode (init_wn) == OPC_I8U8CVT &&
01243 WN_opcode (WN_kid0 (init_wn)) == OPC_U8LDA)) {
01244 WFE_Add_Aggregate_Init_Symbol (WN_st (WN_kid0 (init_wn)),
01245 WN_offset (WN_kid0 (init_wn)));
01246
01247 #ifdef KEY
01248 Set_ST_initv_in_other_st (WN_st(WN_kid0 (init_wn)));
01249 #endif
01250 WN_DELETE_Tree (init_wn);
01251 break;
01252 }
01253
01254 if (WN_operator (init_wn) == OPR_LDA) {
01255 WFE_Add_Aggregate_Init_Symbol (WN_st (init_wn),
01256 WN_offset (init_wn));
01257
01258 #ifdef KEY
01259 Set_ST_initv_in_other_st (WN_st(init_wn));
01260 #endif
01261 WN_DELETE_Tree (init_wn);
01262 break;
01263 }
01264 #ifdef KEY
01265 else if (WN_operator (init_wn) == OPR_LDA_LABEL) {
01266 tree label_decl =
01267 (TREE_CODE(TREE_OPERAND(val, 0)) == ADDR_EXPR)?
01268 TREE_OPERAND (TREE_OPERAND (val, 0), 0):
01269 TREE_OPERAND (val, 0);
01270 LABEL_IDX label_idx =
01271 WFE_Get_LABEL (label_decl, FALSE);
01272 WFE_Add_Aggregate_Init_Label (label_idx);
01273 WN_DELETE_Tree (init_wn);
01274 break;
01275 }
01276 #endif
01277 else if (WN_operator(init_wn) == OPR_INTCONST) {
01278 WFE_Add_Aggregate_Init_Integer (
01279 WN_const_val(init_wn), size);
01280 break;
01281 }
01282 #ifdef KEY // bug 3227
01283 else if ((WN_opcode (init_wn) == OPC_U4I4CVT ||
01284 WN_opcode (init_wn) == OPC_I4U4CVT) &&
01285 WN_operator (WN_kid0 (init_wn)) == OPR_INTCONST) {
01286 WFE_Add_Aggregate_Init_Integer (
01287 WN_const_val(WN_kid0(init_wn)), size);
01288 break;
01289 }
01290 #endif
01291
01292
01293
01294 else if (WN_operator(init_wn) == OPR_ADD) {
01295 WN *kid0 = WN_kid0(init_wn);
01296 WN *kid1 = WN_kid1(init_wn);
01297 if (WN_operator(kid0) == OPR_LDA &&
01298 WN_operator(kid1) == OPR_INTCONST) {
01299 WFE_Add_Aggregate_Init_Symbol (WN_st (kid0),
01300 WN_offset(kid0) + WN_const_val(kid1));
01301
01302 #ifdef KEY
01303 Set_ST_initv_in_other_st (WN_st(kid0));
01304 #endif
01305 WN_DELETE_Tree (init_wn);
01306 break;
01307 }
01308 else if (WN_operator(kid1) == OPR_LDA &&
01309 WN_operator(kid0) == OPR_INTCONST) {
01310 WFE_Add_Aggregate_Init_Symbol (WN_st (kid1),
01311 WN_offset(kid1) + WN_const_val(kid0));
01312
01313 #ifdef KEY
01314 Set_ST_initv_in_other_st (WN_st(kid1));
01315 #endif
01316 WN_DELETE_Tree (init_wn);
01317 break;
01318 }
01319 }
01320 else if (WN_operator(init_wn) == OPR_SUB) {
01321 WN *kid0 = WN_kid0(init_wn);
01322 WN *kid1 = WN_kid1(init_wn);
01323 if (WN_operator(kid0) == OPR_LDA &&
01324 WN_operator(kid1) == OPR_INTCONST) {
01325 WFE_Add_Aggregate_Init_Symbol (WN_st (kid0),
01326 WN_offset(kid0) - WN_const_val(kid1));
01327
01328 #ifdef KEY
01329 Set_ST_initv_in_other_st (WN_st(kid0));
01330 #endif
01331 WN_DELETE_Tree (init_wn);
01332 break;
01333 }
01334 }
01335 FmtAssert(FALSE, ("unexpected tree code %s",
01336 tree_code_name[TREE_CODE(val)]));
01337 }
01338 }
01339 }
01340
01341
01342
01343 class INITBUF {
01344 public:
01345 UINT64 ival;
01346
01347 INITBUF(void) {}
01348 INITBUF(UINT64 i): ival(i) {}
01349 ~INITBUF(void) {}
01350 mUINT8 Nth_byte(INT i) {
01351 INT rshft_amt = (Target_Byte_Sex == BIG_ENDIAN) ? 7-i : i;
01352 return (ival >> (rshft_amt * 8)) & 0xff;
01353 }
01354 };
01355
01356
01357
01358
01359 static void
01360 Add_Bitfield_Initv_For_Tree (tree val, FLD_HANDLE fld, INT &bytes)
01361 {
01362 FmtAssert(TREE_CODE(val) == INTEGER_CST,
01363 ("initialization value of bitfield expected to be integer, not %s",
01364 tree_code_name[TREE_CODE(val)]));
01365 INT bofst = FLD_bofst(fld);
01366 INT bsize = FLD_bsize(fld);
01367 if (bsize == 0)
01368 return;
01369
01370 INITBUF ib(Get_Integer_Value(val));
01371
01372 ib.ival = ib.ival << (64 - bsize);
01373
01374 if (Target_Byte_Sex == BIG_ENDIAN)
01375 ib.ival = ib.ival >> bofst;
01376 else ib.ival = ib.ival >> (64 - bofst - bsize);
01377
01378
01379 INT num_of_bytes = ((bofst + bsize - 1) >> 3) + 1;
01380
01381 INT bytes_out = bytes - FLD_ofst(fld);
01382 INT i;
01383 if (bytes_out > 0) {
01384
01385
01386 for (i = 0; i < bytes_out - 1; i++)
01387 FmtAssert(ib.Nth_byte(i) == 0,
01388 ("processing error in Add_Bitfield_Initv_For_Tree"));
01389 if (ib.Nth_byte(bytes_out-1) != 0) {
01390 if (INITV_kind(last_aggregate_initv) == INITVKIND_VAL) {
01391 TCON &tc = INITV_tc_val(last_aggregate_initv);
01392 mUINT8 last_ival = TCON_k0(tc);
01393 tc.vals.k0 = last_ival | ib.Nth_byte(bytes_out-1);
01394 }
01395 else {
01396 if (INITV_kind(last_aggregate_initv) == INITVKIND_ONE)
01397 INITV_Init_Integer(last_aggregate_initv, MTYPE_I1,
01398 1 | ib.Nth_byte(bytes_out-1));
01399 else {
01400 FmtAssert(INITV_kind(last_aggregate_initv) == INITVKIND_ZERO,
01401 ("processing error in static bit field initialization"));
01402 INITV_Init_Integer(last_aggregate_initv, MTYPE_I1,
01403 ib.Nth_byte(bytes_out-1));
01404 }
01405 }
01406 }
01407 }
01408
01409 for (i = bytes_out; i < num_of_bytes; i++)
01410 WFE_Add_Aggregate_Init_Integer(ib.Nth_byte(i), 1);
01411 bytes += num_of_bytes - bytes_out;
01412 }
01413
01414
01415
01416 static void
01417 Gen_Assign_Of_Init_Val (ST *st, tree init, UINT offset, UINT array_elem_offset,
01418 TY_IDX ty, BOOL is_bit_field, UINT field_id, FLD_HANDLE fld, INT &bytes)
01419 {
01420 WN *init_wn = WFE_Expand_Expr (init);
01421 if (TREE_CODE(init) == STRING_CST && TY_kind(ty) == KIND_ARRAY)
01422 {
01423
01424
01425
01426 UINT size = TY_size(ty);
01427
01428
01429 UINT load_size = ( size > TREE_STRING_LENGTH(init) ) ?
01430 TREE_STRING_LENGTH(init) : size;
01431 TY_IDX ptr_ty = Make_Pointer_Type(ty);
01432 WN *load_wn = WN_CreateMload (0, ptr_ty, init_wn,
01433 #ifdef KEY
01434 WN_Intconst(MTYPE_I4, load_size));
01435 #else
01436 WN_Intconst(MTYPE_I4, size));
01437 #endif
01438 WN *addr_wn = WN_Lda(Pointer_Mtype, 0, st);
01439 WFE_Stmt_Append(
01440 WN_CreateMstore (offset, ptr_ty,
01441 load_wn,
01442 addr_wn,
01443 #ifdef KEY
01444 WN_Intconst(MTYPE_I4, load_size)),
01445 #else
01446 WN_Intconst(MTYPE_I4,size)),
01447 #endif
01448 Get_Srcpos());
01449 #ifdef KEY // bug 3247
01450 if (size - load_size > 0) {
01451 load_wn = WN_Intconst(MTYPE_U4, 0);
01452 addr_wn = WN_Lda(Pointer_Mtype, 0, st);
01453 WFE_Stmt_Append(
01454 WN_CreateMstore (offset+load_size, ptr_ty,
01455 load_wn,
01456 addr_wn,
01457 WN_Intconst(MTYPE_I4,size-load_size)),
01458 Get_Srcpos());
01459 }
01460 #endif
01461 bytes += size;
01462 }
01463 else {
01464 TYPE_ID mtype = is_bit_field ? MTYPE_BS : TY_mtype(ty);
01465 if (is_bit_field) {
01466 offset = array_elem_offset;
01467 } else
01468 field_id = 0;
01469 WFE_Set_ST_Addr_Saved (init_wn);
01470 WN *wn = WN_Stid (mtype, ST_ofst(st) + offset, st,
01471 ty, init_wn, field_id);
01472 #ifdef KEY
01473 if (WFE_Stmt_Top_Kind() == wfe_stmk_for_cond)
01474 WFE_Stmt_Append_Before (wn, Get_Srcpos());
01475 else
01476 #endif
01477 WFE_Stmt_Append(wn, Get_Srcpos());
01478 #ifdef TARG_SL
01479 BOOL WN_Need_Append_Intrinsic(WN *rhs);
01480 if(WN_kid0(wn) && WN_Need_Append_Intrinsic(WN_kid0(wn))) {
01481 extern void WFE_Stmt_Append_Extend_Intrinsic(WN *wn, WN *master_variable, SRCPOS src);
01482 WN *ldid_wn = WN_Ldid(mtype, ST_ofst(st)+offset, st, ty, field_id);
01483 WFE_Stmt_Append_Extend_Intrinsic(wn, ldid_wn, Get_Srcpos());
01484 }
01485 #endif
01486 if (! is_bit_field)
01487 bytes += TY_size(ty);
01488 else {
01489 INT bofst = FLD_bofst(fld);
01490 INT bsize = FLD_bsize(fld);
01491
01492 INT num_of_bytes = ((bofst + bsize - 1) >> 3) + 1;
01493
01494 INT bytes_out = bytes - FLD_ofst(fld);
01495 bytes += num_of_bytes - bytes_out;
01496 }
01497 }
01498 }
01499
01500 UINT
01501 Traverse_Aggregate_Constructor (
01502 ST *st, tree init_list,
01503 #ifdef KEY
01504 tree struct_type,
01505 #endif
01506 tree type, BOOL gen_initv,
01507 UINT current_offset, UINT array_elem_offset, UINT field_id);
01508
01509 UINT
01510 Traverse_Aggregate_Struct (
01511 ST *st, tree init_list, tree type, BOOL gen_initv,
01512 UINT current_offset, UINT array_elem_offset, UINT field_id);
01513
01514
01515
01516
01517
01518 void
01519 Traverse_Aggregate_Pad (
01520 ST *st,
01521 BOOL gen_initv,
01522 UINT pad,
01523 UINT current_offset)
01524 {
01525 if (gen_initv) {
01526 WFE_Add_Aggregate_Init_Padding (pad);
01527 }
01528 else {
01529 WN *zero_wn = WN_Intconst(MTYPE_U4, 0);
01530 WN *pad_wn = WN_Intconst(MTYPE_U4, pad);
01531 WN *addr_wn = WN_Lda(Pointer_Mtype, 0, st);
01532 TY_IDX mstore_ty = Make_Pointer_Type(MTYPE_To_TY(MTYPE_U1));
01533 WFE_Stmt_Append (WN_CreateMstore (current_offset, mstore_ty,
01534 zero_wn, addr_wn, pad_wn),
01535 Get_Srcpos());
01536 }
01537 }
01538
01539
01540
01541
01542
01543
01544 void
01545 Traverse_Aggregate_Array (
01546 ST *st,
01547 tree init_list,
01548 tree type,
01549 BOOL gen_initv,
01550 UINT current_offset)
01551 {
01552 INT emitted_bytes = 0;
01553 INT pad;
01554 TY_IDX ty = Get_TY(type);
01555 TY_IDX ety = TY_etype (ty);
01556 UINT esize = TY_size (ety);
01557 tree init;
01558
01559 #ifdef KEY
01560
01561 if (gen_initv) {
01562 init = CONSTRUCTOR_ELTS(init_list);
01563 if (init &&
01564 TY_kind(ty) == KIND_ARRAY) {
01565 INT index = Get_Integer_Value(TREE_PURPOSE(init));
01566 while (index > 0) {
01567 Traverse_Aggregate_Pad (st, gen_initv, esize, current_offset);
01568 emitted_bytes += esize;
01569 current_offset = emitted_bytes;
01570 index --;
01571 }
01572 }
01573 }
01574 #endif
01575 for (init = CONSTRUCTOR_ELTS(init_list);
01576 init;
01577 init = TREE_CHAIN(init)) {
01578
01579 if (TREE_CODE(TREE_VALUE (init)) == CONSTRUCTOR) {
01580
01581
01582
01583
01584
01585 INT index = Get_Integer_Value(TREE_PURPOSE(init));
01586 if ( current_offset/esize < index ) {
01587
01588 Traverse_Aggregate_Pad (st, gen_initv,
01589 (index - current_offset/esize)*esize,
01590 current_offset);
01591 emitted_bytes += (index - current_offset/esize)*esize;
01592 current_offset = emitted_bytes;
01593 }
01594
01595 Traverse_Aggregate_Constructor (st, TREE_VALUE(init),
01596 #ifdef KEY
01597 TREE_TYPE(type),
01598 #endif
01599 TREE_TYPE(type),
01600 gen_initv, current_offset, current_offset,
01601 0);
01602 emitted_bytes += esize;
01603 }
01604
01605 else {
01606
01607
01608 #ifdef KEY
01609
01610
01611
01612
01613
01614
01615
01616
01617 INT index = Get_Integer_Value(TREE_PURPOSE(init));
01618 if ( current_offset/esize < index ) {
01619
01620 Traverse_Aggregate_Pad (st, gen_initv,
01621 (index - current_offset/esize)*esize,
01622 current_offset);
01623 emitted_bytes += (index - current_offset/esize)*esize;
01624 current_offset = emitted_bytes;
01625 }
01626 #endif
01627 if (gen_initv) {
01628 Add_Initv_For_Tree (TREE_VALUE(init), esize);
01629 emitted_bytes += esize;
01630 }
01631 else
01632 Gen_Assign_Of_Init_Val (st, TREE_VALUE(init), current_offset, 0,
01633 ety, FALSE, 0, FLD_HANDLE (), emitted_bytes);
01634 }
01635
01636 current_offset += esize;
01637 }
01638
01639 #ifdef KEY
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657
01658
01659
01660
01661
01662
01663
01664
01665
01666
01667
01668 if (TY_size(ty) == 0)
01669 Ty_Table[ty].size = emitted_bytes;
01670 #endif
01671
01672 pad = TY_size (ty) - emitted_bytes;
01673
01674 if (pad > 0)
01675 Traverse_Aggregate_Pad (st, gen_initv, pad, current_offset);
01676
01677 }
01678
01679 #ifdef KEY
01680
01681
01682
01683
01684
01685 UINT Advance_Field_Id (FLD_HANDLE field, UINT field_id) {
01686 if (field.Is_Null())
01687 return field_id;
01688 field_id++;
01689 TY_IDX ty = FLD_type(field);
01690 if (TY_kind(ty) == KIND_STRUCT) {
01691 field = TY_fld(ty);
01692 while (!field.Is_Null()) {
01693
01694 field_id=Advance_Field_Id(field,field_id);
01695 field=FLD_next(field);
01696 }
01697 }
01698 return field_id;
01699 }
01700 #endif
01701
01702
01703
01704
01705
01706
01707
01708
01709
01710 UINT
01711 Traverse_Aggregate_Struct (
01712 ST *st,
01713 tree init_list,
01714 #ifdef KEY
01715 tree struct_type,
01716 #endif
01717 tree type,
01718 BOOL gen_initv,
01719 UINT current_offset,
01720 UINT array_elem_offset,
01721
01722
01723
01724
01725
01726 UINT field_id)
01727 {
01728 TY_IDX ty = Get_TY(type);
01729 tree field = TREE_PURPOSE(type);
01730 FLD_HANDLE fld = TY_fld (ty);
01731
01732 INT emitted_bytes = 0;
01733 INT current_offset_base = current_offset;
01734 INT pad;
01735 BOOL is_bit_field;
01736 tree init;
01737 TY_IDX fld_ty;
01738
01739 #ifdef KEY
01740 if (CONSTRUCTOR_ELTS(init_list))
01741 ++field_id;
01742 #endif
01743 for (init = CONSTRUCTOR_ELTS(init_list);
01744 init;
01745 init = TREE_CHAIN(init)) {
01746
01747
01748 #ifdef KEY
01749
01750
01751
01752
01753
01754 #else
01755 ++field_id;
01756 #endif
01757
01758
01759
01760 if (field && TREE_PURPOSE(init) && TREE_CODE(TREE_PURPOSE(init)) == FIELD_DECL) {
01761 DevWarn ("Encountered FIELD_DECL during initialization");
01762 for (;;) {
01763 if (field == TREE_PURPOSE(init)) {
01764 break;
01765 }
01766 #ifndef KEY
01767 ++field_id;
01768 #else
01769 field_id = Advance_Field_Id(fld, field_id);
01770 #endif
01771 field = TREE_CHAIN(field);
01772 fld = FLD_next(fld);
01773 }
01774 }
01775
01776
01777 pad = FLD_ofst (fld) - emitted_bytes;
01778
01779 if (pad > 0) {
01780 Traverse_Aggregate_Pad (st, gen_initv, pad, current_offset);
01781 current_offset += pad;
01782 emitted_bytes += pad;
01783 }
01784
01785 fld_ty = FLD_type(fld);
01786 if (TREE_CODE(TREE_VALUE(init)) == CONSTRUCTOR) {
01787
01788 tree element_type;
01789 element_type = TREE_TYPE(field);
01790 #ifdef KEY
01791
01792
01793
01794 INT array_size = TY_size(fld_ty);
01795 #endif
01796 field_id = Traverse_Aggregate_Constructor (st, TREE_VALUE(init),
01797 #ifdef KEY
01798 struct_type,
01799 #endif
01800 element_type, gen_initv,
01801 current_offset,
01802 array_elem_offset, field_id);
01803 #ifdef KEY
01804
01805 if (TY_size(fld_ty) != array_size) {
01806 FmtAssert ((array_size == 0),
01807 ("Unexpected change in size of array"));
01808 TY_IDX struct_ty = Get_TY ( struct_type );
01809 Ty_Table[struct_ty].size += TY_size(fld_ty);
01810 }
01811 #endif
01812 emitted_bytes += TY_size(fld_ty);
01813 }
01814 else {
01815
01816 is_bit_field = FLD_is_bit_field(fld);
01817 if (gen_initv) {
01818 if (! is_bit_field) {
01819 #ifdef KEY
01820
01821
01822
01823 if (TY_size(fld_ty) == 0 &&
01824 TREE_CODE(TREE_VALUE(init)) == STRING_CST &&
01825 TREE_STRING_POINTER(TREE_VALUE(init))) {
01826 Ty_Table[fld_ty].size =
01827 strlen(TREE_STRING_POINTER(TREE_VALUE(init)));
01828 TY_IDX struct_ty = Get_TY ( struct_type );
01829 Ty_Table[struct_ty].size += TY_size(fld_ty);
01830 }
01831 #endif
01832 Add_Initv_For_Tree (TREE_VALUE(init), TY_size(fld_ty));
01833 emitted_bytes += TY_size(fld_ty);
01834 }
01835 else {
01836 Add_Bitfield_Initv_For_Tree (TREE_VALUE(init), fld, emitted_bytes);
01837
01838 }
01839 }
01840 else {
01841 Gen_Assign_Of_Init_Val (st, TREE_VALUE(init),
01842 current_offset, array_elem_offset,
01843 #ifndef KEY
01844 is_bit_field ? ty : fld_ty,
01845 #else
01846 is_bit_field ? Get_TY(struct_type) : fld_ty,
01847 #endif
01848 is_bit_field, field_id, fld, emitted_bytes);
01849
01850 }
01851 }
01852
01853 #ifdef KEY
01854
01855
01856
01857
01858 if (TREE_CHAIN(init))
01859 field_id = Advance_Field_Id(fld, field_id);
01860 #endif
01861
01862 current_offset = current_offset_base + emitted_bytes;
01863 field = TREE_CHAIN(field);
01864 fld = FLD_next(fld);
01865 }
01866
01867
01868
01869
01870
01871
01872 while ( ! fld.Is_Null()) {
01873 ++field_id;
01874 if (!gen_initv && FLD_is_bit_field(fld)) {
01875 INT bofst = FLD_bofst(fld);
01876 INT bsize = FLD_bsize(fld);
01877
01878 INT num_of_bytes = ((bofst + bsize - 1) >> 3) + 1;
01879
01880 INT bytes_out = current_offset - FLD_ofst(fld);
01881 if (num_of_bytes == bytes_out) {
01882 TY_IDX fld_ty = FLD_type(fld);
01883 #ifdef PATHSCALE_MERGE
01884
01885
01886 TYPE_ID mtyp = TY_mtype(fld_ty);
01887 mtyp = (mtyp == MTYPE_V) ? MTYPE_I4 : Widen_Mtype(mtyp);
01888 WN *init_wn = WN_Intconst (mtyp, 0);
01889 #endif
01890 WN *wn = WN_Stid (MTYPE_BS, ST_ofst(st) + array_elem_offset, st,
01891 #ifndef KEY
01892 ty,
01893 #else
01894 Get_TY(struct_type),
01895 #endif
01896 init_wn, field_id);
01897 WFE_Stmt_Append(wn, Get_Srcpos());
01898 }
01899 }
01900 #ifdef KEY
01901 field_id = Advance_Field_Id(fld,field_id)-1;
01902 #endif
01903 field = TREE_CHAIN(field);
01904 fld = FLD_next(fld);
01905 }
01906
01907
01908
01909 pad = TY_size (ty) - emitted_bytes;
01910
01911 if (pad > 0)
01912 Traverse_Aggregate_Pad (st, gen_initv, pad, current_offset);
01913
01914 return field_id;
01915 }
01916
01917 #ifdef KEY
01918
01919
01920
01921 void
01922 Traverse_Aggregate_Vector (
01923 ST * st,
01924 tree init_list,
01925 BOOL gen_initv,
01926 UINT current_offset,
01927 BOOL vec_cst = FALSE)
01928 {
01929 tree init;
01930 INT emitted_bytes = 0;
01931
01932 if (vec_cst)
01933 init = TREE_VECTOR_CST_ELTS (init_list);
01934 else
01935 init = CONSTRUCTOR_ELTS (init_list);
01936
01937 for (;
01938 init;
01939 init = TREE_CHAIN(init))
01940 {
01941 tree unit_type = TREE_TYPE(TREE_VALUE(init));
01942 tree size = TYPE_SIZE (unit_type);
01943 Is_True (TREE_CODE (size) == INTEGER_CST,
01944 ("Traverse_Aggregate_Vector: Vector of variable-sized units?"));
01945 UINT esize = Get_Integer_Value(size) / BITSPERBYTE;
01946 if (gen_initv)
01947 {
01948 Add_Initv_For_Tree (TREE_VALUE(init), esize);
01949 emitted_bytes += esize;
01950 }
01951 else
01952 Gen_Assign_Of_Init_Val (st, TREE_VALUE(init),
01953 current_offset, 0,
01954 Get_TY(unit_type),
01955 0, 0, FLD_HANDLE(), emitted_bytes);
01956 current_offset += esize;
01957 }
01958 }
01959
01960 void
01961 Traverse_Aggregate_Vector_Const (
01962 ST * st,
01963 tree init_list,
01964 BOOL gen_initv,
01965 UINT current_offset)
01966 {
01967 Traverse_Aggregate_Vector (st, init_list, gen_initv, current_offset, TRUE);
01968 }
01969 #endif
01970
01971
01972
01973
01974
01975
01976
01977
01978
01979
01980
01981 UINT
01982 Traverse_Aggregate_Constructor (
01983 ST *st,
01984 tree init_list,
01985 #ifdef KEY
01986 tree struct_type,
01987 #endif
01988 tree type,
01989 BOOL gen_initv,
01990
01991 UINT current_offset,
01992 UINT array_elem_offset,
01993 UINT field_id)
01994 {
01995 TY_IDX ty = Get_TY(type);
01996
01997 INITV_IDX last_aggregate_initv_save;
01998
01999 if (gen_initv) {
02000
02001 WFE_Add_Init_Block();
02002 INITV_Init_Block(last_aggregate_initv, INITV_Next_Idx());
02003 not_at_root = TRUE;
02004 last_aggregate_initv_save = last_aggregate_initv;
02005 last_aggregate_initv = 0;
02006 }
02007
02008 if (TY_kind (ty) == KIND_STRUCT) {
02009
02010 field_id = Traverse_Aggregate_Struct (st, init_list,
02011 #ifdef KEY
02012 struct_type,
02013 #endif
02014 type, gen_initv,
02015 current_offset, array_elem_offset,
02016 field_id);
02017 }
02018
02019 else
02020 if (TY_kind (ty) == KIND_ARRAY) {
02021
02022 Traverse_Aggregate_Array (st, init_list, type, gen_initv, current_offset);
02023 }
02024
02025 #ifdef KEY // bug 9550
02026 else
02027 if (TY_kind (ty) == KIND_SCALAR && MTYPE_is_vector (TY_mtype (ty))) {
02028
02029 Traverse_Aggregate_Vector (st, init_list, gen_initv, current_offset);
02030 }
02031 #endif
02032
02033 else
02034 Fail_FmtAssertion ("Traverse_Aggregate_Constructor: non STRUCT/ARRAY");
02035
02036 #ifdef KEY
02037 if (gen_initv && last_aggregate_initv == 0)
02038 INITV_Init_Block(last_aggregate_initv_save, INITV_IDX_ZERO);
02039 #endif
02040
02041
02042 last_aggregate_initv = last_aggregate_initv_save;
02043
02044 return field_id;
02045 }
02046
02047 static void
02048 Add_Inito_For_Tree (tree init, tree decl, ST *st)
02049 {
02050 tree kid;
02051 last_aggregate_initv = 0;
02052 switch (TREE_CODE(init)) {
02053 case INTEGER_CST:
02054 UINT64 val;
02055 val = Get_Integer_Value (init);
02056 #ifndef TARG_NVISA
02057
02058
02059
02060 #ifdef TARG_SL
02061
02062 if (val == 0 && ! DECL_SECTION_NAME (decl) && !DECL_VBUF(decl) && !DECL_SBUF(decl)) {
02063 #else
02064 if (val == 0 && ! DECL_SECTION_NAME (decl)) {
02065 #endif
02066 Set_ST_init_value_zero(st);
02067 if (ST_sclass(st) == SCLASS_DGLOBAL)
02068 Set_ST_sclass(st, SCLASS_UGLOBAL);
02069 return;
02070 }
02071 #endif
02072 aggregate_inito = New_INITO (st);
02073 not_at_root = FALSE;
02074 WFE_Add_Aggregate_Init_Integer (val, TY_size(ST_type(st)));
02075 return;
02076 case REAL_CST:
02077 aggregate_inito = New_INITO (st);
02078 not_at_root = FALSE;
02079 WFE_Add_Aggregate_Init_Real (TREE_REAL_CST(init),
02080 TY_size(ST_type(st)));
02081 return;
02082 case COMPLEX_CST:
02083 aggregate_inito = New_INITO (st);
02084 not_at_root = FALSE;
02085 WFE_Add_Aggregate_Init_Complex (TREE_REAL_CST(TREE_REALPART(init)),
02086 TREE_REAL_CST(TREE_IMAGPART(init)),
02087 TY_size(ST_type(st)));
02088 return;
02089 case STRING_CST:
02090 aggregate_inito = New_INITO (st);
02091 not_at_root = FALSE;
02092 WFE_Add_Aggregate_Init_String (TREE_STRING_POINTER(init),
02093 #ifdef KEY
02094 TY_size(ST_type(st)) < TREE_STRING_LENGTH(init) ?
02095 TY_size(ST_type(st)) :
02096 #endif
02097 TREE_STRING_LENGTH(init));
02098 if (TY_size (ST_type(st)) > TREE_STRING_LENGTH(init))
02099 WFE_Add_Aggregate_Init_Padding ( TY_size (ST_type(st)) -
02100 TREE_STRING_LENGTH(init));
02101 return;
02102 case NOP_EXPR:
02103 Add_Inito_For_Tree (TREE_OPERAND(init,0), decl, st);
02104 return;
02105 case ADDR_EXPR:
02106 kid = TREE_OPERAND(init,0);
02107 if (TREE_CODE(kid) == VAR_DECL ||
02108 TREE_CODE(kid) == FUNCTION_DECL ||
02109 #ifdef KEY
02110 TREE_CODE(kid) == COMPOUND_LITERAL_EXPR ||
02111
02112 TREE_CODE(kid) == LABEL_DECL ||
02113 #endif
02114 TREE_CODE(kid) == STRING_CST) {
02115 aggregate_inito = New_INITO (st);
02116 not_at_root = FALSE;
02117 WFE_Add_Aggregate_Init_Address (kid);
02118 return;
02119 }
02120 case PLUS_EXPR:
02121 kid = TREE_OPERAND(init,0);
02122 if (TREE_CODE(kid) == ADDR_EXPR) {
02123
02124 Add_Inito_For_Tree (kid, decl, st);
02125 kid = TREE_OPERAND(init,1);
02126 if (INITV_kind(last_aggregate_initv) == INITVKIND_SYMOFF
02127 && TREE_CODE(kid) == INTEGER_CST)
02128 {
02129 Set_INITV_ofst (last_aggregate_initv,
02130 Get_Integer_Value(kid));
02131 return;
02132 }
02133 }
02134 break;
02135 case MINUS_EXPR:
02136 kid = TREE_OPERAND(init,0);
02137 if (TREE_CODE(kid) == ADDR_EXPR) {
02138
02139 Add_Inito_For_Tree (kid, decl, st);
02140 kid = TREE_OPERAND(init,1);
02141 if (INITV_kind(last_aggregate_initv) == INITVKIND_SYMOFF
02142 && TREE_CODE(kid) == INTEGER_CST)
02143 {
02144 Set_INITV_ofst (last_aggregate_initv,
02145 -Get_Integer_Value(kid));
02146 return;
02147 }
02148 }
02149 break;
02150 case CONSTRUCTOR:
02151 aggregate_inito = New_INITO (st);
02152 not_at_root = FALSE;
02153 last_aggregate_initv = 0;
02154 Traverse_Aggregate_Constructor (st, init,
02155 #ifdef KEY
02156 TREE_TYPE(init),
02157 #endif
02158 TREE_TYPE(init),
02159 TRUE , 0, 0, 0);
02160 return;
02161 }
02162
02163
02164 WN *init_wn = WFE_Expand_Expr (init);
02165 if (WN_operator(init_wn) == OPR_INTCONST) {
02166 aggregate_inito = New_INITO (st);
02167 not_at_root = FALSE;
02168 WFE_Add_Aggregate_Init_Integer (
02169 WN_const_val(init_wn), TY_size(ST_type(st)));
02170 return;
02171 }
02172 else
02173 if (WN_operator(init_wn) == OPR_LDA) {
02174 aggregate_inito = New_INITO (st);
02175 not_at_root = FALSE;
02176 WFE_Add_Aggregate_Init_Symbol (WN_st (init_wn), WN_offset (init_wn));
02177
02178 #ifdef KEY
02179 Set_ST_initv_in_other_st (WN_st(init_wn));
02180 #endif
02181 return;
02182 }
02183 else
02184 if (WN_operator(init_wn) == OPR_ADD) {
02185 if (WN_operator(WN_kid0(init_wn)) == OPR_LDA &&
02186 WN_operator(WN_kid1(init_wn)) == OPR_INTCONST) {
02187 aggregate_inito = New_INITO (st);
02188 not_at_root = FALSE;
02189 WFE_Add_Aggregate_Init_Symbol (WN_st(WN_kid0(init_wn)),
02190 WN_offset(WN_kid0(init_wn)) + WN_const_val(WN_kid1(init_wn)));
02191
02192 #ifdef KEY
02193 Set_ST_initv_in_other_st (WN_st(WN_kid0(init_wn)));
02194 #endif
02195 return;
02196 }
02197 }
02198 else
02199 if (WN_operator(init_wn) == OPR_SUB) {
02200 if (WN_operator(WN_kid0(init_wn)) == OPR_LDA &&
02201 WN_operator(WN_kid1(init_wn)) == OPR_INTCONST) {
02202 aggregate_inito = New_INITO (st);
02203 not_at_root = FALSE;
02204 WFE_Add_Aggregate_Init_Symbol (WN_st(WN_kid0(init_wn)),
02205 WN_offset(WN_kid0(init_wn)) - WN_const_val(WN_kid1(init_wn)));
02206
02207 #ifdef KEY
02208 WN *kid_of_init_wn = WN_kid0(WN_kid0(init_wn));
02209 if (WN_has_sym(kid_of_init_wn))
02210 Set_ST_initv_in_other_st (WN_st(kid_of_init_wn));
02211 #endif
02212 return;
02213 }
02214 #ifdef KEY
02215 else if (WN_operator(WN_kid0(init_wn)) == OPR_CVT) {
02216
02217 WN *tmp_wn = WN_kid0(WN_kid0(init_wn));
02218 if (WN_operator(tmp_wn) == OPR_LDA) {
02219
02220
02221
02222
02223
02224
02225
02226
02227
02228 WN *tmp1_wn = WN_kid0(WN_kid1(init_wn));
02229 if (WN_operator(tmp1_wn) == OPR_LDA) {
02230 if (WN_st(tmp_wn) == WN_st(tmp1_wn)) {
02231 aggregate_inito = New_INITO (st);
02232 not_at_root = FALSE;
02233 WFE_Add_Aggregate_Init_Integer (WN_offset(tmp_wn) -
02234 WN_offset(tmp1_wn),
02235 TY_size(ST_type(st)));
02236 return;
02237 }
02238 }
02239 }
02240 }
02241 #endif
02242 }
02243 Fail_FmtAssertion ("unexpected static init tree for %s", ST_name(st));
02244 }
02245
02246
02247 extern ST *
02248 WFE_Generate_Temp_For_Initialized_Aggregate (tree init, char * name)
02249 {
02250 TY_IDX ty_idx = Get_TY(TREE_TYPE(init));
02251 ST *temp = New_ST (CURRENT_SYMTAB);
02252 ST_Init (temp,
02253 #ifdef TARG_NVISA
02254 Save_Str2 (name, "_init"),
02255 #else
02256 Save_Str2 (name, ".init"),
02257 #endif
02258 CLASS_VAR, SCLASS_PSTATIC, EXPORT_LOCAL,
02259 ty_idx );
02260 if (TREE_CODE(init) == CONSTRUCTOR
02261 && ! Use_Static_Init_For_Aggregate (temp, init))
02262 {
02263
02264 Set_ST_sclass(temp, SCLASS_AUTO);
02265 Traverse_Aggregate_Constructor (temp, init,
02266 #ifdef KEY
02267 TREE_TYPE(init),
02268 #endif
02269 TREE_TYPE(init),
02270 FALSE , 0, 0, 0);
02271 }
02272 else {
02273
02274 Set_ST_is_initialized(temp);
02275 aggregate_inito = New_INITO (temp);
02276 not_at_root = FALSE;
02277 last_aggregate_initv = 0;
02278 Traverse_Aggregate_Constructor (temp, init,
02279 #ifdef KEY
02280 TREE_TYPE(init),
02281 #endif
02282 TREE_TYPE(init),
02283 TRUE , 0, 0, 0);
02284 WFE_Finish_Aggregate_Init ();
02285 }
02286 return temp;
02287 }
02288
02289 extern void
02290 WFE_Initialize_Decl (tree decl)
02291 {
02292 #ifdef KEY
02293 if (CURRENT_SYMTAB != GLOBAL_SYMTAB &&
02294 !TREE_STATIC(decl) )
02295 return;
02296 #endif
02297 if (DECL_IGNORED_P(decl)) {
02298
02299
02300 return;
02301 }
02302 ST *st = Get_ST(decl);
02303 tree init = DECL_INITIAL(decl);
02304
02305 if (TREE_STATIC(decl) || DECL_CONTEXT(decl) == NULL)
02306 {
02307
02308 if ((ST_sclass(st) == SCLASS_UGLOBAL &&
02309 !ST_init_value_zero(st)) ||
02310 ST_sclass(st) == SCLASS_EXTERN ||
02311 ST_sclass(st) == SCLASS_COMMON)
02312 Set_ST_sclass(st, SCLASS_DGLOBAL);
02313 if (!ST_is_initialized(st)) {
02314 Set_ST_is_initialized(st);
02315 Add_Inito_For_Tree (init, decl, st);
02316 WFE_Finish_Aggregate_Init ();
02317 }
02318 if (TREE_READONLY(decl))
02319 Set_ST_is_const_var (st);
02320 }
02321 else {
02322
02323 if (TREE_CODE(init) == CONSTRUCTOR) {
02324
02325 if (Use_Static_Init_For_Aggregate (st, init)) {
02326
02327
02328 ST *copy = WFE_Generate_Temp_For_Initialized_Aggregate(
02329 init, ST_name(st));
02330 WN *init_wn = WN_CreateLdid (OPR_LDID, MTYPE_M, MTYPE_M,
02331 0, copy, ST_type(copy));
02332 WFE_Stmt_Append(
02333 WN_CreateStid (OPR_STID, MTYPE_V, MTYPE_M,
02334 0, st, ST_type(st), init_wn),
02335 Get_Srcpos());
02336 }
02337 else {
02338
02339 Traverse_Aggregate_Constructor (st, init,
02340 #ifdef KEY
02341 TREE_TYPE(init),
02342 #endif
02343 TREE_TYPE(init),
02344 FALSE ,
02345 0, 0, 0);
02346 }
02347 return;
02348 }
02349 else {
02350 INT emitted_bytes;
02351 Gen_Assign_Of_Init_Val (st, init,
02352 0 , 0 ,
02353 ST_type(st), FALSE, 0 ,
02354 FLD_HANDLE(), emitted_bytes);
02355 }
02356 }
02357 }
02358
02359 #ifdef KEY
02360
02361 extern void
02362 WFE_Initialize_Nested_Decl (tree decl)
02363 {
02364 if (DECL_IGNORED_P(decl)) {
02365
02366
02367 return;
02368 }
02369 ST *st = Get_ST(decl);
02370 tree init = DECL_INITIAL(decl);
02371
02372 if (TREE_STATIC(decl) || DECL_CONTEXT(decl) == NULL)
02373 {
02374
02375 if ((ST_sclass(st) == SCLASS_UGLOBAL &&
02376 !ST_init_value_zero(st)) ||
02377 ST_sclass(st) == SCLASS_EXTERN ||
02378 ST_sclass(st) == SCLASS_COMMON)
02379 Set_ST_sclass(st, SCLASS_DGLOBAL);
02380 if (!ST_is_initialized(st)) {
02381 Set_ST_is_initialized(st);
02382 Add_Inito_For_Tree (init, decl, st);
02383 WFE_Finish_Aggregate_Init ();
02384 }
02385 if (TREE_READONLY(decl))
02386 Set_ST_is_const_var (st);
02387 }
02388 else {
02389
02390 if (TREE_CODE(init) == CONSTRUCTOR) {
02391
02392 if (Use_Static_Init_For_Aggregate (st, init)) {
02393
02394
02395 ST *copy = WFE_Generate_Temp_For_Initialized_Aggregate(
02396 init, ST_name(st));
02397 WN *init_wn = WN_CreateLdid (OPR_LDID, MTYPE_M, MTYPE_M,
02398 0, copy, ST_type(copy));
02399 WFE_Stmt_Append(
02400 WN_CreateStid (OPR_STID, MTYPE_V, MTYPE_M,
02401 0, st, ST_type(st), init_wn),
02402 Get_Srcpos());
02403 }
02404 else {
02405
02406 Traverse_Aggregate_Constructor (st, init,
02407 #ifdef KEY
02408 TREE_TYPE(init),
02409 #endif
02410 TREE_TYPE(init),
02411 FALSE ,
02412 0, 0, 0);
02413 }
02414 return;
02415 }
02416 else {
02417 INT emitted_bytes;
02418 Gen_Assign_Of_Init_Val (st, init,
02419 0 , 0 ,
02420 ST_type(st), FALSE, 0 ,
02421 FLD_HANDLE(), emitted_bytes);
02422 }
02423 }
02424 }
02425
02426 extern INT WFE_Get_Current_Scope (void)
02427 {
02428 return CURRENT_SYMTAB;
02429 }
02430 #endif
02431
02432
02433
02434
02435
02436
02437 void
02438 WFE_Decl (tree decl)
02439 {
02440 #ifndef KEY
02441 if (DECL_INITIAL (decl) != 0) return;
02442 #endif
02443 if (DECL_IGNORED_P(decl)) return;
02444 if (TREE_CODE(decl) != VAR_DECL) return;
02445 #ifndef KEY
02446 if (DECL_CONTEXT(decl) != 0) return;
02447 if ( ! TREE_PUBLIC(decl)) return;
02448 if ( ! TREE_STATIC(decl)) return;
02449 #endif
02450
02451
02452 (void) Get_ST(decl);
02453 return;
02454 }
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465 void
02466 WFE_Assemble_Alias (tree decl, tree target)
02467 {
02468 #ifdef Is_True_On
02469 if (!finish_alias)
02470 DevWarn ("__attribute alias encountered at line %d", lineno);
02471 #endif
02472 tree base_decl = lookup_name (target);
02473 #ifndef KEY
02474 FmtAssert (base_decl != NULL,
02475 ("undeclared base symbol %s not yet declared in __attribute__ alias is not currently implemented",
02476 IDENTIFIER_POINTER (target)));
02477 #else
02478 if ((base_decl == NULL || TREE_CODE (decl) == FUNCTION_DECL) &&
02479 !finish_alias)
02480 {
02481
02482 if (!DECL_WEAK (decl))
02483 alias_vector.push_back (std::make_pair (decl, target));
02484 return;
02485 }
02486 #endif // KEY
02487
02488 #ifdef KEY
02489
02490 if (base_decl == NULL) {
02491 Is_True( TREE_CODE(target) == IDENTIFIER_NODE,
02492 ("Unexpected TREE_CODE of target, IDENTIFIER_NODE expected"));
02493 error ("'%s' aliased to undefined symbol '%s'",
02494 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
02495 IDENTIFIER_POINTER (target));
02496 return;
02497 }
02498 #endif
02499
02500 ST *base_st = Get_ST (base_decl);
02501 ST *st = Get_ST (decl);
02502 if (ST_is_weak_symbol(st)) {
02503 Set_ST_sclass (st, SCLASS_EXTERN);
02504 Set_ST_strong_idx (*st, ST_st_idx (base_st));
02505 }
02506 else {
02507 Set_ST_base_idx (st, ST_st_idx (base_st));
02508 Set_ST_emit_symbol(st);
02509 Set_ST_sclass (st, ST_sclass (base_st));
02510 if (ST_is_initialized (base_st))
02511 Set_ST_is_initialized (st);
02512 #ifdef KEY
02513 if (ST_init_value_zero (base_st))
02514 Set_ST_init_value_zero (st);
02515 #endif
02516 }
02517 #ifdef KEY
02518
02519 if (ST_sym_class (st) != ST_sym_class (base_st))
02520 ErrMsg (EC_Ill_Alias, ST_name (st), ST_name (base_st));
02521
02522
02523
02524 if (ST_sym_class (base_st) == CLASS_FUNC)
02525 Set_PU_no_delete (Pu_Table [ST_pu (base_st)]);
02526 #endif // KEY
02527
02528
02529
02530
02531
02532
02533
02534 }
02535
02536 void
02537 WFE_Assemble_Constructor (const char *name)
02538 {
02539 DevWarn ("__attribute__ ((constructor)) encountered at line %d", lineno);
02540 tree func_decl = lookup_name (get_identifier (name));
02541 ST *func_st = Get_ST (func_decl);
02542 INITV_IDX initv = New_INITV ();
02543 INITV_Init_Symoff (initv, func_st, 0, 1);
02544 ST *init_st = New_ST (GLOBAL_SYMTAB);
02545 ST_Init (init_st, Save_Str2i ("__ctors", "_", ++__ctors),
02546 CLASS_VAR, SCLASS_FSTATIC,
02547 EXPORT_LOCAL, Make_Pointer_Type (ST_pu_type (func_st), FALSE));
02548 Set_ST_is_initialized (init_st);
02549 INITO_IDX inito = New_INITO (init_st, initv);
02550 ST_ATTR_IDX st_attr_idx;
02551 ST_ATTR& st_attr = New_ST_ATTR (GLOBAL_SYMTAB, st_attr_idx);
02552 ST_ATTR_Init (st_attr, ST_st_idx (init_st), ST_ATTR_SECTION_NAME,
02553 Save_Str (".ctors"));
02554 }
02555
02556 void
02557 WFE_Assemble_Destructor (const char *name)
02558 {
02559 DevWarn ("__attribute__ ((destructor)) encountered at line %d", lineno);
02560 tree func_decl = lookup_name (get_identifier (name));
02561 ST *func_st = Get_ST (func_decl);
02562 INITV_IDX initv = New_INITV ();
02563 INITV_Init_Symoff (initv, func_st, 0, 1);
02564 ST *init_st = New_ST (GLOBAL_SYMTAB);
02565 ST_Init (init_st, Save_Str2i ("__dtors", "_", ++__dtors),
02566 CLASS_VAR, SCLASS_FSTATIC,
02567 EXPORT_LOCAL, Make_Pointer_Type (ST_pu_type (func_st), FALSE));
02568 Set_ST_is_initialized (init_st);
02569 INITO_IDX inito = New_INITO (init_st, initv);
02570 ST_ATTR_IDX st_attr_idx;
02571 ST_ATTR& st_attr = New_ST_ATTR (GLOBAL_SYMTAB, st_attr_idx);
02572 ST_ATTR_Init (st_attr, ST_st_idx (init_st), ST_ATTR_SECTION_NAME,
02573 Save_Str (".dtors"));
02574 Set_PU_no_inline (Pu_Table [ST_pu (func_st)]);
02575 Set_PU_no_delete (Pu_Table [ST_pu (func_st)]);
02576 Set_ST_addr_saved (func_st);
02577 }
02578
02579 ST *
02580 WFE_Get_Return_Address_ST (int level)
02581 {
02582 ST *return_address_st = Return_Address_ST [CURRENT_SYMTAB - level];
02583 if (return_address_st == NULL) {
02584 return_address_st = New_ST (CURRENT_SYMTAB - level);
02585 ST_Init (return_address_st, Save_Str ("__return_address"), CLASS_VAR,
02586 (PUSH_RETURN_ADDRESS_ON_STACK ? SCLASS_FORMAL : SCLASS_AUTO),
02587 EXPORT_LOCAL, Make_Pointer_Type (Be_Type_Tbl (MTYPE_V), FALSE));
02588 Set_ST_is_return_var (return_address_st);
02589 Return_Address_ST [CURRENT_SYMTAB - level] = return_address_st;
02590 }
02591
02592 return return_address_st;
02593 }
02594
02595 ST *
02596 WFE_Alloca_0 (void)
02597 {
02598 WN *wn;
02599 TY_IDX ty_idx = Make_Pointer_Type (Be_Type_Tbl (MTYPE_V), FALSE);
02600 ST* alloca_st = Gen_Temp_Symbol (ty_idx, "__alloca");
02601 #ifdef KEY
02602 WFE_add_pragma_to_enclosing_regions (WN_PRAGMA_LOCAL, alloca_st);
02603 #endif
02604 wn = WN_CreateAlloca (WN_CreateIntconst (OPC_I4INTCONST, 0));
02605 wn = WN_Stid (Pointer_Mtype, 0, alloca_st, ty_idx, wn);
02606 WFE_Stmt_Append (wn, Get_Srcpos());
02607 Set_PU_has_alloca (Get_Current_PU ());
02608 return alloca_st;
02609 }
02610
02611 ST *
02612 WFE_Alloca_ST (tree decl)
02613 {
02614 ST *st = Create_ST_For_Tree (decl);
02615 ST *alloca_st = New_ST (CURRENT_SYMTAB);
02616 ST_Init (alloca_st, Save_Str (ST_name (st)),
02617 CLASS_VAR, SCLASS_AUTO, EXPORT_LOCAL,
02618 Make_Pointer_Type (ST_type (st), FALSE));
02619 Set_ST_is_temp_var (alloca_st);
02620 Set_ST_pt_to_unique_mem (alloca_st);
02621 Set_ST_base_idx (st, ST_st_idx (alloca_st));
02622 WN *swn = WFE_Expand_Expr (TYPE_SIZE(TREE_TYPE(decl)));
02623 #ifdef KEY // TYPE_SIZE is size of array in bits. Convert to bytes. Bug 6887.
02624 TYPE_ID mtype = WN_rtype(swn);
02625 swn = WN_Div(mtype, swn, WN_Intconst(mtype, BITSPERBYTE));
02626 #endif
02627 WN *wn = WN_CreateAlloca (swn);
02628 wn = WN_Stid (Pointer_Mtype, 0, alloca_st, ST_type (alloca_st), wn);
02629 WFE_Stmt_Append (wn, Get_Srcpos());
02630 return st;
02631 }
02632
02633 void
02634 WFE_Dealloca (ST *alloca_st, tree vars)
02635 {
02636 int nkids = 0;
02637 tree decl;
02638 WN *wn;
02639 ST *st;
02640 ST *base_st;
02641
02642 for (decl =vars; decl; decl = TREE_CHAIN (decl))
02643 if (TREE_CODE (decl) == VAR_DECL && DECL_ST (decl)) {
02644 st = DECL_ST (decl);
02645 base_st = ST_base (st);
02646 if (st != base_st)
02647 ++nkids;
02648 }
02649
02650 wn = WN_CreateDealloca (nkids+1);
02651 WN_kid0 (wn) = WN_Ldid (Pointer_Mtype, 0, alloca_st, ST_type (alloca_st));
02652 nkids = 0;
02653
02654 for (decl =vars; decl; decl = TREE_CHAIN (decl))
02655 if (TREE_CODE (decl) == VAR_DECL && DECL_ST (decl)) {
02656 st = DECL_ST (decl);
02657 base_st = ST_base (st);
02658 if (st != base_st)
02659 WN_kid (wn, ++nkids) = WN_Ldid (Pointer_Mtype, 0, base_st, ST_type (base_st));
02660 }
02661
02662 WFE_Stmt_Append (wn, Get_Srcpos());
02663 }
02664
02665 void
02666 WFE_Record_Asmspec_For_ST (tree decl, const char *asmspec, int reg)
02667 {
02668 extern PREG_NUM Map_Reg_To_Preg [];
02669 PREG_NUM preg = Map_Reg_To_Preg [reg];
02670 FmtAssert (preg >= 0,
02671 ("mapping register %d to preg failed\n", reg));
02672 ST *st = Get_ST (decl);
02673 TY_IDX ty_idx = ST_type (st);
02674 Set_TY_is_volatile (ty_idx);
02675 Set_ST_type (st, ty_idx);
02676 Set_ST_assigned_to_dedicated_preg (st);
02677 ST_ATTR_IDX st_attr_idx;
02678 ST_ATTR& st_attr = New_ST_ATTR (CURRENT_SYMTAB, st_attr_idx);
02679 ST_ATTR_Init (st_attr, ST_st_idx (st), ST_ATTR_DEDICATED_REGISTER, preg);
02680 }
02681
02682 void
02683 WFE_Resolve_Duplicate_Decls (tree olddecl, tree newdecl)
02684 {
02685 ST *st = DECL_ST(olddecl);
02686 tree newtype = TREE_TYPE(newdecl);
02687 tree newsize = TYPE_SIZE(newtype);
02688 TY_IDX ty = ST_type (st);
02689
02690 if (TREE_STATIC(olddecl) == FALSE &&
02691 TREE_STATIC(newdecl) == TRUE &&
02692 TREE_PUBLIC(olddecl) == TRUE &&
02693 TREE_PUBLIC(newdecl) == FALSE) {
02694 Set_ST_sclass (st, SCLASS_FSTATIC);
02695 Set_ST_export (st, EXPORT_LOCAL);
02696 }
02697
02698 if (newsize &&
02699 TREE_CODE(newsize) == INTEGER_CST &&
02700 TY_size (ty) <= Get_Integer_Value (newsize) / BITSPERBYTE) {
02701 UINT64 size = Get_Integer_Value (newsize) / BITSPERBYTE;
02702 Set_TY_size (ty, size);
02703 if (TY_kind (ty) == KIND_ARRAY) {
02704 Set_ARB_const_ubnd (TY_arb(ty));
02705 #ifdef KEY
02706
02707
02708 if (!TY_size (TY_etype (ty)))
02709 {
02710 tree newesize = TYPE_SIZE (TREE_TYPE (newtype));
02711 if (newesize && TREE_CODE (newesize) == INTEGER_CST)
02712 {
02713 UINT64 esize = Get_Integer_Value (newesize) / BITSPERBYTE;
02714 Set_TY_size (TY_etype (ty), esize);
02715 }
02716 Is_True (TY_size (TY_etype (ty)), ("Invalid array of 0-size structs"));
02717 }
02718 #endif // KEY
02719 Set_ARB_ubnd_val (TY_arb(ty), (size / TY_size(TY_etype(ty))) - 1);
02720 }
02721 }
02722 }
02723
02724
02725 void
02726 WFE_Add_Weak ()
02727 {
02728 #ifdef KEY
02729
02730 if (!weak_decls)
02731 return;
02732 #endif // KEY
02733 tree decl =
02734 lookup_name (get_identifier (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME
02735 (TREE_VALUE (weak_decls)))));
02736 if (decl) {
02737 ST *st = DECL_ST (decl);
02738 if (st)
02739 Set_ST_is_weak_symbol (st);
02740 }
02741 }
02742
02743
02744 void
02745 WFE_Weak_Finish ()
02746 {
02747 tree t;
02748 for (t = weak_decls; t; t = TREE_CHAIN(t)) {
02749 if (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TREE_VALUE (t)))) {
02750 tree decl =
02751 lookup_name (get_identifier ( IDENTIFIER_POINTER
02752 (DECL_ASSEMBLER_NAME (TREE_VALUE (t)))));
02753 if (!decl)
02754 warning ("did not find declaration `%s' for used in #pragma weak",
02755 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME
02756 (TREE_VALUE (t))));
02757 else {
02758 ST *st = DECL_ST (decl);
02759 if (st == NULL && TREE_VALUE(t)) {
02760 st = Get_ST (decl);
02761 }
02762 if (st) {
02763 #ifndef KEY
02764 Set_ST_is_weak_symbol (st);
02765 if (TREE_VALUE(t)) {
02766 tree base_decl = lookup_name (get_identifier
02767 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME
02768 (TREE_VALUE(t)))));
02769 if (!base_decl)
02770 warning ("did not find declaration for `%s' used in \
02771 #pragma weak",
02772 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TREE_VALUE(t))));
02773 else {
02774 ST *base_st = DECL_ST (base_decl);
02775 if (base_st)
02776 Set_ST_strong_idx (*st, ST_st_idx (base_st));
02777 }
02778 }
02779 #else
02780 if (ST_base_idx (st) != ST_st_idx (st)) {
02781 Set_ST_is_weak_symbol (st);
02782 continue;
02783 }
02784
02785
02786 Set_ST_is_weak_symbol (st);
02787 tree alias;
02788 alias = lookup_attribute("alias", DECL_ATTRIBUTES (decl));
02789 if (!alias)
02790 continue;
02791 alias = TREE_VALUE (TREE_VALUE (alias));
02792 alias = get_identifier (TREE_STRING_POINTER (alias));
02793 tree base_decl = lookup_name (alias);
02794 if (!base_decl)
02795 warning ("did not find declaration for `%s' used in \
02796 #pragma weak",
02797 IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TREE_VALUE(t))));
02798 else {
02799 ST *base_st = DECL_ST (base_decl);
02800 if (ST_is_weak_symbol (st) && ST_sclass(st) != SCLASS_EXTERN)
02801 Clear_ST_is_weak_symbol (st);
02802 else if (base_st)
02803 Set_ST_strong_idx (*st, ST_st_idx (base_st));
02804 }
02805 #endif
02806 }
02807 }
02808 }
02809 }
02810 }
02811
02812 #ifdef KEY
02813 extern "C" void
02814 WFE_Alias_Finish (void)
02815 {
02816 finish_alias = TRUE;
02817 for (INT i=0; i<alias_vector.size(); i++)
02818 WFE_Assemble_Alias (alias_vector[i].first, alias_vector[i].second);
02819 alias_vector.clear ();
02820 }
02821 #endif // KEY