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 #ifdef USE_PCH
00051 #include "be_com_pch.h"
00052 #endif
00053 #pragma hdrstop
00054 #include <cmplrs/rcodes.h>
00055 #include <sys/resource.h>
00056
00057 #ifndef _USE_STL_EXT
00058 #include <list>
00059 #else
00060 #include <slist>
00061 #endif
00062
00063 using namespace std;
00064
00065 #include "defs.h"
00066 #include "erglob.h"
00067 #include "erbe.h"
00068 #include "config.h"
00069 #include "tracing.h"
00070 #include "strtab.h"
00071 #include "stab.h"
00072 #include "const.h"
00073 #include "glob.h"
00074 #include "mtypes.h"
00075 #include "targ_const.h"
00076 #include "targ_sim.h"
00077 #include "ttype.h"
00078 #include "irbdata.h"
00079 #include "util.h"
00080 #include "stblock.h"
00081 #include "data_layout.h"
00082 #include "wintrinsic.h"
00083 #include "sections.h"
00084 #include "betarget.h"
00085 #include "intrn_info.h"
00086
00087 extern void Early_Terminate (INT status);
00088
00089 #define ST_force_gprel(s) ST_gprel(s)
00090
00091 ST *SP_Sym;
00092 ST *FP_Sym;
00093 ST *Local_Spill_Sym;
00094 INT32 Current_PU_Actual_Size;
00095 STACK_MODEL Current_PU_Stack_Model = SMODEL_UNDEF;
00096
00097 #define ST_NAME(st) (ST_class(st) == CLASS_CONST ? \
00098 Targ_Print(NULL,STC_val(st)) : ST_name(st) )
00099
00100 static BOOL Frame_Has_Calls;
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 typedef enum {
00111 SFSEG_UNKNOWN,
00112 SFSEG_ACTUAL,
00113 SFSEG_FTEMP,
00114 SFSEG_FORMAL,
00115 SFSEG_UPFORMAL
00116
00117
00118
00119
00120
00121 } SF_SEGMENT;
00122
00123 #define SFSEG_FIRST SFSEG_ACTUAL
00124 #define SFSEG_LAST SFSEG_UPFORMAL
00125
00126 typedef struct {
00127 SF_SEGMENT seg;
00128 ST *block;
00129 mINT64 maxsize;
00130 char *name;
00131 } SF_SEG_DESC;
00132
00133 #define SFSEG_seg(s) ((s)->seg)
00134 #define SFSEG_block(s) ((s)->block)
00135 #define SFSEG_maxsize(s) ((s)->maxsize)
00136 #define SFSEG_name(s) ((s)->name)
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 #define DEFAULT_LARGE_OBJECT_BYTES 64
00147
00148 #define DEFAULT_TEMP_SPACE_BYTES 4096
00149 #define MAX_SFSEG_BYTES 0x7FFFFFFFFFFFFFFFLL
00150
00151 #define MAX_LARGE_FRAME_OFFSET 0x7FFFFFFFFFFFFFFFLL // 64bits on all targs
00152 #define MAX_FRAME_OFFSET \
00153 (Current_PU_Stack_Model == SMODEL_SMALL ? \
00154 Max_Small_Frame_Offset : MAX_LARGE_FRAME_OFFSET)
00155
00156 typedef enum _align {
00157 _BYTE_ALIGN = 1,
00158 _CARD_ALIGN = 2,
00159 _WORD_ALIGN = 4,
00160 _DWORD_ALIGN = 8,
00161 _QUAD_ALIGN = 16
00162 } ALIGN;
00163
00164 static STACK_DIR stack_direction;
00165
00166 #ifndef DEFAULT_STACK_ALIGNMENT
00167 #define DEFAULT_STACK_ALIGNMENT _QUAD_ALIGN
00168 #endif
00169 static INT16 stack_align = DEFAULT_STACK_ALIGNMENT;
00170
00171
00172
00173 static SF_SEG_DESC SF_Seg_Descriptors [SFSEG_LAST+1] = {
00174 { SFSEG_UNKNOWN, NULL, MAX_SFSEG_BYTES, "Unknown" },
00175 { SFSEG_ACTUAL, NULL, MAX_SFSEG_BYTES, "Actual_Arg" },
00176 { SFSEG_FTEMP, NULL, MAX_SFSEG_BYTES, "Fixed_Temp" },
00177 { SFSEG_FORMAL, NULL, MAX_SFSEG_BYTES, "Formal_Arg" },
00178 { SFSEG_UPFORMAL, NULL, MAX_SFSEG_BYTES, "UpFormal_Arg" }
00179 };
00180 #define SF_Seg_Desc(n) (&SF_Seg_Descriptors[n])
00181
00182 #define SF_Block(n) (SFSEG_block(SF_Seg_Desc(n)))
00183 #define SF_Maxsize(n) (SFSEG_maxsize(SF_Seg_Desc(n)))
00184 #define SF_Name(n) (SFSEG_name(SF_Seg_Desc(n)))
00185
00186
00187
00188
00189
00190 static INT32 Large_Object_Bytes;
00191
00192 static BOOL Trace_Frame = FALSE;
00193
00194
00195
00196
00197
00198
00199
00200
00201 #define Is_root_base(st) (ST_class(st) == CLASS_BLOCK && STB_root_base(st))
00202 #define Has_No_Base_Block(st) (ST_base(st) == st)
00203 #define Is_Allocatable(st) (!Has_Base_Block(st) && !Is_root_base(st))
00204 #define Is_Allocatable_Root_Block(st) \
00205 (ST_class(st) == CLASS_BLOCK && !Is_root_base(st) && Has_No_Base_Block(st))
00206
00207
00208
00209
00210
00211
00212 static SECTION_IDX Shorten_Section (ST *, SECTION_IDX);
00213 static void Allocate_Object_To_Section (ST *, SECTION_IDX, UINT);
00214 static void Allocate_Label (ST *lab);
00215
00216
00217 BOOL
00218 Is_Allocated (ST *st)
00219 {
00220 ST *base;
00221 INT64 ofst;
00222 Base_Symbol_And_Offset(st, &base, &ofst);
00223
00224 if (ST_sclass(st) == SCLASS_FORMAL && ST_class(base) == CLASS_BLOCK)
00225 return TRUE;
00226 return ((base != st && Is_root_base(base)) || Is_root_base(st));
00227 }
00228
00229
00230
00231
00232
00233 #define ROUNDUP(val,align) ( (-(INT64)align) & (INT64)(val+align-1) )
00234 #define ROUNDDOWN(val,align) ( (-(INT64)align) & (INT64)(val) )
00235 #define IS_POW2(num) ( (~((num)-1) & (num) ) == (num) )
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 BOOL ST_on_stack(ST *sym)
00248 {
00249 if (ST_sclass(sym) == SCLASS_AUTO)
00250 return TRUE;
00251 else if (ST_sclass(sym) == SCLASS_FORMAL)
00252 return TRUE;
00253 else if (sym == SP_Sym || sym == FP_Sym)
00254 return TRUE;
00255 else {
00256 ST *base = Base_Symbol(sym);
00257 if (base == SP_Sym || base == FP_Sym)
00258 return TRUE;
00259 else
00260 return FALSE;
00261 }
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 BOOL ST_pu_defined(ST *sym)
00277 {
00278 if ((ST_class(sym) == CLASS_VAR) ||
00279 (ST_class(sym) == CLASS_CONST))
00280 {
00281 switch(ST_sclass(sym))
00282 {
00283 case SCLASS_AUTO:
00284 case SCLASS_PSTATIC:
00285 case SCLASS_FSTATIC:
00286 case SCLASS_DGLOBAL:
00287 case SCLASS_FORMAL:
00288 return TRUE;
00289 default:
00290 return FALSE;
00291 }
00292 }
00293 return FALSE;
00294
00295 }
00296
00297
00298
00299
00300
00301 typedef struct {
00302 const ST *sym;
00303 ST *base;
00304 PREG_NUM preg;
00305
00306
00307
00308
00309 SYMTAB_IDX level;
00310 } formal_info;
00311 static formal_info *formal_info_array;
00312 static INT max_formal_info_index = 0;
00313
00314 static void
00315 Realloc_ST_formal_info (INT min_needed)
00316 {
00317 if (min_needed >= max_formal_info_index) {
00318
00319 formal_info_array = TYPE_MEM_POOL_REALLOC_N (
00320 formal_info, &MEM_src_pool,
00321 formal_info_array,
00322 max_formal_info_index,
00323 min_needed + 8);
00324 max_formal_info_index = min_needed + 8;
00325 }
00326 }
00327
00328
00329
00330 static void
00331 Init_ST_formal_info_for_PU (INT num_formals)
00332 {
00333 if (formal_info_array == NULL) {
00334 max_formal_info_index = MAX(8,num_formals);
00335 formal_info_array = (formal_info*) Src_Alloc (
00336 sizeof(formal_info) * max_formal_info_index);
00337 }
00338 else {
00339
00340
00341
00342 INT num_uplevel_entries = 0;
00343 for (INT i = 0; i < max_formal_info_index; i++) {
00344 if (formal_info_array[i].sym != NULL) {
00345 if (formal_info_array[i].level >=
00346 CURRENT_SYMTAB) {
00347 formal_info_array[i].sym = NULL;
00348 formal_info_array[i].base = NULL;
00349 formal_info_array[i].preg = 0;
00350 formal_info_array[i].level =
00351 SYMTAB_IDX_ZERO;
00352 } else {
00353 num_uplevel_entries++;
00354 }
00355 }
00356 }
00357 Realloc_ST_formal_info (num_formals + num_uplevel_entries);
00358 }
00359
00360 #ifdef Is_True_On
00361
00362
00363 Is_True(max_formal_info_index > 0, ("no elements allocated"));
00364 const ST *last = formal_info_array[0].sym;
00365 for (INT i = 0; i < max_formal_info_index; i++) {
00366 Is_True(last != NULL || last == formal_info_array[i].sym,
00367 ("NULL sym precedes non-NULL sym"));
00368 last = formal_info_array[i].sym;
00369 }
00370 #endif
00371 }
00372
00373
00374 ST *
00375 Get_ST_formal_ref_base (const ST *sym)
00376 {
00377 if (ST_sclass(sym) != SCLASS_FORMAL_REF)
00378 return NULL;
00379 INT i;
00380 for (i = 0; i < max_formal_info_index; i++) {
00381 if (formal_info_array[i].sym == sym)
00382 return formal_info_array[i].base;
00383 else if (formal_info_array[i].sym == NULL)
00384 break;
00385 }
00386 return NULL;
00387 }
00388
00389 void
00390 Set_ST_formal_ref_base (const ST *sym, ST *base)
00391 {
00392 INT i;
00393 for (i = 0; i < max_formal_info_index; i++) {
00394 if (formal_info_array[i].sym == NULL) {
00395 formal_info_array[i].sym = sym;
00396 formal_info_array[i].base = base;
00397 formal_info_array[i].level = ST_level(sym);
00398 return;
00399 }
00400 }
00401 Realloc_ST_formal_info (max_formal_info_index);
00402 formal_info_array[i].sym = sym;
00403 formal_info_array[i].base = base;
00404 formal_info_array[i].level = ST_level(sym);
00405 }
00406
00407
00408 PREG_NUM
00409 Get_ST_formal_preg_num (const ST *base)
00410 {
00411 INT i;
00412 for (i = 0; i < max_formal_info_index; i++) {
00413 if (formal_info_array[i].base == base)
00414 return formal_info_array[i].preg;
00415 else if (formal_info_array[i].sym == NULL)
00416 break;
00417 }
00418 return (PREG_NUM) 0;
00419 }
00420
00421 void
00422 Set_ST_formal_preg_num (const ST *base, PREG_NUM p)
00423 {
00424 INT i;
00425 for (i = 0; i < max_formal_info_index; i++) {
00426 if (formal_info_array[i].base == base) {
00427 formal_info_array[i].preg = p;
00428 return;
00429 }
00430 }
00431 Is_True(FALSE, ("Set_ST_formal_preg_num didn't find base"));
00432 }
00433
00434 static ST *Formal_Sym(ST *sym, BOOL onstack)
00435 {
00436 ST *base;
00437
00438 if (ST_sclass(sym) != SCLASS_FORMAL_REF)
00439 return sym;
00440
00441 if (Is_Allocated(sym))
00442 {
00443 return sym;
00444 }
00445 if (base = Get_ST_formal_ref_base(sym))
00446 {
00447 return base;
00448 }
00449
00450 base = Copy_ST(sym);
00451 Set_ST_name(base, Save_Str2(ST_name(base), ".base"));
00452 Set_ST_type(base, Make_Pointer_Type(ST_type(sym)) );
00453 Set_ST_sclass (base, SCLASS_FORMAL);
00454 Set_ST_formal_ref_base(sym, base);
00455
00456
00457
00458 Clear_ST_promote_parm(base);
00459
00460
00461
00462
00463
00464
00465 onstack |= (Debug_Level > 0 && Debug_Level != 3) ||
00466 ST_has_nested_ref(sym) ||
00467 ST_declared_static(sym) ||
00468 PU_has_mp(Get_Current_PU());
00469
00470 if (onstack == FALSE)
00471 {
00472 Set_ST_formal_preg_num(base, Create_Preg(TY_mtype(ST_type(base)), ST_name(base)));
00473 }
00474
00475 if ( Trace_Frame )
00476 {
00477 fprintf(TFile, "SCLASS_FORMAL (%s, base %s, onstack= %d, preg= %d) allocated\n",
00478 ST_name(sym), ST_name(base), onstack, Get_ST_formal_preg_num(base));
00479 }
00480
00481 return base;
00482 }
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 INT32
00496 Stack_Alignment ( void )
00497 {
00498 return stack_align;
00499 }
00500
00501
00502 STACK_DIR Stack_Direction(void)
00503 {
00504 return stack_direction;
00505 }
00506
00507 static STACK_DIR
00508 Get_Direction (ST *blk)
00509 {
00510 if (STB_decrement(blk)) return DECREMENT;
00511 else return INCREMENT;
00512 }
00513
00514 static void
00515 Set_Direction (STACK_DIR dir, ST *blk)
00516 {
00517 if (dir == DECREMENT) Set_STB_decrement(blk);
00518 else Reset_STB_decrement(blk);
00519 }
00520
00521 static ST*
00522 Create_Local_Block( STACK_DIR dir, STR_IDX name )
00523 {
00524 ST *new_blk = New_ST_Block(name, FALSE, SCLASS_UNKNOWN, stack_align, 0);
00525 Set_Direction(dir, new_blk);
00526 Enter_ST(new_blk);
00527 return new_blk;
00528 }
00529
00530 static ST *
00531 Create_Base_Reg (char *name, STACK_DIR dir)
00532 {
00533 ST *new_blk = Create_Local_Block(dir, Save_Str(name));
00534 Set_STB_root_base(new_blk);
00535 Set_STB_is_basereg(new_blk);
00536 return new_blk;
00537 }
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549 static void
00550 Assign_Offset (ST *blk, ST *base, INT32 lpad, INT32 rpad)
00551 {
00552 UINT align = Adjusted_Alignment(blk);
00553 Set_ST_ofst(blk, ROUNDUP(STB_size(base) + lpad, align));
00554 if (STB_decrement(base)) {
00555
00556 Set_ST_ofst(blk,
00557 -(INT64) ROUNDUP(ST_ofst(blk) + ST_size(blk) + rpad, align));
00558 }
00559 }
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571 static void
00572 Allocate_Space(ST *base, ST *blk, INT32 lpad, INT32 rpad, INT64 maxsize)
00573 {
00574 UINT align = Adjusted_Alignment(blk);
00575 INT64 old_offset;
00576 INT64 size = ST_size(blk);
00577
00578 Set_STB_align(base, MAX(STB_align(base), align));
00579 if (!STB_decrement(base)) {
00580 old_offset = STB_size(base);
00581 Set_ST_ofst(blk, ROUNDUP(old_offset + lpad, align));
00582 Set_STB_size(base, ROUNDUP(ST_ofst(blk) + size + rpad, align));
00583 }
00584 else {
00585 old_offset = STB_size(base);
00586
00587 Set_ST_ofst(blk, ROUNDUP(old_offset + lpad, align));
00588 Set_ST_ofst(blk,
00589 -(INT64) ROUNDUP(ST_ofst(blk) + size + rpad, align));
00590 Set_STB_size(base, -ST_ofst(blk));
00591 }
00592 if ((base == SP_Sym && Frame_Has_Calls) || base == FP_Sym) {
00593
00594
00595
00596
00597
00598 Set_ST_ofst(blk, ST_ofst(blk) + Stack_Offset_Adjustment);
00599 }
00600 if ( Trace_Frame ) {
00601 if (ST_class(blk) == CLASS_CONST)
00602 fprintf ( TFile, "Allocate <constant: %s>", Targ_Print(NULL,STC_val(blk)));
00603 else
00604 fprintf ( TFile, "Allocate %s", ST_name(blk));
00605 fprintf (TFile, " to %s: offset = %lld, size = %lld\n",
00606 ST_name(base), ST_ofst(blk), size);
00607 }
00608 if (STB_size(base) > maxsize
00609 && Is_Local_Symbol(base)
00610 && maxsize == Max_Small_Frame_Offset
00611 && Current_PU_Stack_Model == SMODEL_SMALL)
00612 {
00613 DevWarn("overflowed small stack frame; will try recompiling with -TENV:large_stack");
00614 Early_Terminate(RC_OVERFLOW_ERROR);
00615 }
00616 Is_True( old_offset <= STB_size(base) && STB_size(base) <= maxsize,
00617 ("Block size overflowed"));
00618 }
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636 static ST*
00637 ST_Block_Merge (ST *block, ST *sym, INT32 lpad, INT32 rpad, INT64 maxsize)
00638 {
00639 ST *base;
00640
00641 Is_True(ST_class(block) == CLASS_BLOCK, ("block-merge not given a block"));
00642 Set_ST_base(sym, block);
00643 base = ST_base(sym);
00644 Allocate_Space(base, sym, lpad, rpad, maxsize);
00645
00646
00647 if (ST_is_initialized(sym) && !STB_section(block))
00648 Set_ST_is_initialized(block);
00649
00650 return base;
00651 }
00652
00653
00654 static void
00655 Initialize_Frame_Segment (SF_SEGMENT seg, ST_SCLASS sclass, STACK_DIR dir)
00656 {
00657 if (SF_Block(seg) == NULL)
00658 {
00659 SF_Block(seg) = Create_Local_Block(dir,
00660 Save_Str2 (SF_Name(seg),"_StkSeg"));
00661 Set_ST_sclass (SF_Block(seg), sclass);
00662 }
00663 }
00664
00665 static void
00666 Assign_Object_To_Frame_Segment ( ST *sym, SF_SEGMENT seg, INT64 offset)
00667 {
00668 if (Trace_Frame) {
00669 fprintf ( TFile,
00670 "Assigning symbol %s to segment %s at offset %lld\n",
00671 ST_name(sym), SF_Name(seg), offset);
00672 }
00673 Initialize_Frame_Segment (seg, ST_sclass(sym), INCREMENT);
00674 Set_ST_base(sym, SF_Block(seg));
00675 Set_ST_ofst(sym, offset);
00676 }
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686
00687 static void
00688 Add_Object_To_Frame_Segment ( ST *sym, SF_SEGMENT seg, BOOL allocate )
00689 {
00690 if ( Trace_Frame && !allocate )
00691 {
00692 fprintf ( TFile, "Adding symbol to %s segment -- %s \n",
00693 SF_Name(seg), ST_name(sym)? ST_name(sym) : "<null>");
00694 }
00695
00696 Initialize_Frame_Segment (seg, ST_sclass(sym), INCREMENT);
00697
00698 if (SF_Block(seg) == sym)
00699 {
00700
00701
00702
00703 return;
00704 }
00705
00706 if (allocate)
00707 {
00708 INT64 size;
00709 INT32 lpad, rpad;
00710 lpad = rpad = 0;
00711
00712 switch (seg)
00713 {
00714 case SFSEG_ACTUAL:
00715 case SFSEG_UPFORMAL:
00716 case SFSEG_FORMAL:
00717 size = ST_size(sym);
00718
00719
00720 if (TY_kind(ST_type(sym)) == KIND_STRUCT)
00721 {
00722 rpad = ROUNDUP(size, MTYPE_RegisterSize(Spill_Int_Mtype)) - size;
00723 }
00724 else
00725 {
00726
00727
00728
00729
00730
00731
00732 if (size < MTYPE_RegisterSize(Spill_Int_Mtype)) {
00733 if (Target_Byte_Sex == LITTLE_ENDIAN ||
00734 MTYPE_is_float(TY_mtype(ST_type(sym)))) {
00735 rpad = MTYPE_RegisterSize(Spill_Int_Mtype) - size;
00736 }
00737 else
00738 lpad = MTYPE_RegisterSize(Spill_Int_Mtype) - size;
00739 }
00740 }
00741 break;
00742 }
00743 ST_Block_Merge (SF_Block(seg), sym, lpad, rpad, SF_Maxsize(seg));
00744
00745 if (seg == SFSEG_FORMAL)
00746 {
00747 ST *formal = SF_Block(seg);
00748
00749
00750
00751
00752 if (STB_size(formal) > Formal_Save_Area_Size)
00753 {
00754 ST *upformal = SF_Block(SFSEG_UPFORMAL);
00755
00756 if (Trace_Frame)
00757 fprintf(TFile, "<lay> split formal between segs\n");
00758
00759 Initialize_Frame_Segment (SFSEG_UPFORMAL, ST_sclass(sym), INCREMENT);
00760 Set_STB_size(upformal,
00761 STB_size(upformal) + STB_size(formal) - Formal_Save_Area_Size);
00762 Set_STB_size(formal, Formal_Save_Area_Size);
00763 }
00764 }
00765 }
00766 else
00767 {
00768 Set_ST_base(sym, SF_Block(seg));
00769 }
00770 }
00771
00772
00773
00774
00775
00776 static UINT32 *arg_area_size_array;
00777 static INT max_arg_area_size_index = 0;
00778
00779
00780 static void
00781 Init_PU_arg_area_size_array (void)
00782 {
00783 INT num_pus = TY_Table_Size();
00784 if (arg_area_size_array == NULL) {
00785 max_arg_area_size_index = num_pus;
00786 arg_area_size_array = (UINT32*) Src_Alloc (
00787 sizeof(UINT32) * (max_arg_area_size_index+1));
00788 }
00789 else if (num_pus >= max_arg_area_size_index) {
00790
00791 num_pus = MAX(num_pus, 2 * max_arg_area_size_index);
00792 arg_area_size_array = TYPE_MEM_POOL_REALLOC_N (
00793 UINT32, &MEM_src_pool,
00794 arg_area_size_array,
00795 max_arg_area_size_index,
00796 num_pus);
00797 max_arg_area_size_index = num_pus;
00798 }
00799 }
00800
00801
00802 UINT32
00803 Get_PU_arg_area_size (TY_IDX pu)
00804 {
00805 Is_True(TY_kind(pu) == KIND_FUNCTION, ("Get_PU_arg_area_size of non-pu"));
00806 INT index = TY_id(pu);
00807 if (index >= max_arg_area_size_index) {
00808
00809 Init_PU_arg_area_size_array ();
00810 }
00811 Is_True(index < max_arg_area_size_index, ("Get_PU_arg_area_size still overflows?"));
00812 return arg_area_size_array[index];
00813 }
00814
00815 void
00816 Set_PU_arg_area_size (TY_IDX pu, UINT32 size)
00817 {
00818 Is_True(TY_kind(pu) == KIND_FUNCTION, ("Set_PU_arg_area_size of non-pu"));
00819 INT index = TY_id(pu);
00820 if (index >= max_arg_area_size_index) {
00821
00822 Init_PU_arg_area_size_array ();
00823 }
00824 Is_True(index < max_arg_area_size_index, ("Set_PU_arg_area_size still overflows?"));
00825 arg_area_size_array[index] = size;
00826 }
00827
00828
00829
00830 struct is_return_address
00831 {
00832 BOOL operator () (UINT32, const ST *st) const {
00833 return (strcmp (ST_name (st), "__return_address") == 0);
00834 }
00835 };
00836
00837 ST *
00838 Find_Special_Return_Address_Symbol (void)
00839 {
00840 ST_IDX st_idx = For_all_until (St_Table, CURRENT_SYMTAB,
00841 is_return_address ());
00842
00843 if (st_idx == 0)
00844 return NULL;
00845 else
00846 return ST_ptr(st_idx);
00847
00848 }
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860 static ST*
00861 Get_Section_ST(SECTION_IDX sec, UINT align, ST_SCLASS sclass)
00862 {
00863 if (SEC_block(sec) == NULL) {
00864 ST *new_blk = New_ST_Block (Save_Str(SEC_name(sec)),
00865 TRUE, sclass, align, 0);
00866 Set_STB_section_idx(new_blk, sec);
00867 SEC_block(sec) = new_blk;
00868 Set_STB_section(new_blk);
00869 Set_STB_root_base(new_blk);
00870 if (SEC_is_gprel(sec)) {
00871 Set_STB_is_basereg(new_blk);
00872 Set_ST_gprel(new_blk);
00873 }
00874 if (SEC_is_merge(sec))
00875 Set_STB_merge(new_blk);
00876 if (SEC_is_exec(sec))
00877 Set_STB_exec(new_blk);
00878 if (SEC_is_nobits(sec))
00879 Set_STB_nobits(new_blk);
00880 Enter_ST(new_blk);
00881 }
00882 return SEC_block(sec);
00883 }
00884
00885
00886
00887
00888 static ST *
00889 Get_Section_ST_With_Given_Name (SECTION_IDX sec, ST_SCLASS sclass, STR_IDX name)
00890 {
00891 ST *newblk = NULL;
00892 ST *st;
00893 INT i;
00894 FOREACH_SYMBOL (GLOBAL_SYMTAB,st,i) {
00895 if (ST_class(st) != CLASS_BLOCK) continue;
00896 if (STB_section(st) && ST_name_idx(st) == name)
00897 {
00898 if (STB_section_idx(st) != sec) {
00899 ErrMsg (EC_LAY_section_name, ST_name(st), SEC_name(STB_section_idx(st)), SEC_name(sec));
00900 }
00901 newblk = st;
00902 break;
00903 }
00904 }
00905 if (newblk == NULL) {
00906 ST *blk = Get_Section_ST(sec, 0, sclass);
00907 newblk = Copy_ST_Block(blk);
00908 Set_ST_name_idx(newblk, name);
00909 }
00910 return newblk;
00911 }
00912
00913 static void
00914 Assign_ST_To_Named_Section (ST *st, STR_IDX name)
00915 {
00916 ST *newblk;
00917 if (ST_is_not_used(st))
00918 return;
00919 if (ST_class(st) == CLASS_FUNC) {
00920 if (ST_sclass(st) == SCLASS_EXTERN) {
00921
00922 return;
00923 }
00924
00925
00926 newblk = Get_Section_ST_With_Given_Name (_SEC_TEXT,
00927 ST_sclass(st), name);
00928 Set_ST_base(st, newblk);
00929 }
00930 else if (ST_class(st) == CLASS_VAR) {
00931
00932
00933
00934 SECTION_IDX sec;
00935 switch (ST_sclass(st)) {
00936 case SCLASS_DGLOBAL:
00937 case SCLASS_FSTATIC:
00938 case SCLASS_PSTATIC:
00939
00940 if (ST_is_constant(st)) sec = _SEC_RDATA;
00941 else sec = _SEC_DATA;
00942 break;
00943 case SCLASS_UGLOBAL:
00944 sec = _SEC_BSS;
00945 break;
00946 default:
00947 FmtAssert(FALSE,
00948 ("unexpected sclass %d for section attribute on %s",
00949 ST_sclass(st), ST_name(st)));
00950 }
00951 newblk = Get_Section_ST_With_Given_Name (sec,
00952 SCLASS_UNKNOWN, name);
00953 Set_ST_base(st, newblk);
00954
00955
00956
00957 if (sec == _SEC_BSS && STB_section_idx(newblk) != _SEC_BSS) {
00958 DevWarn("change bss symbol to be initialized to 0");
00959 Set_ST_sclass(st, SCLASS_DGLOBAL);
00960 Set_ST_is_initialized(st);
00961 INITO_IDX ino = New_INITO(st);
00962 INITV_IDX inv = New_INITV();
00963 INITV_Init_Pad (inv, ST_size(st));
00964 Set_INITO_val(ino, inv);
00965 }
00966 ST_Block_Merge (newblk, st, 0, 0, SEC_max_sec_size(sec));
00967 }
00968 else
00969 FmtAssert(FALSE, ("unexpected section attribute"));
00970 }
00971
00972 struct Assign_Section_Names
00973 {
00974 inline void operator() (UINT32, ST_ATTR *st_attr) const {
00975 ST *st;
00976 STR_IDX name;
00977 if (ST_ATTR_kind (*st_attr) != ST_ATTR_SECTION_NAME)
00978 return;
00979 st = ST_ptr(ST_ATTR_st_idx(*st_attr));
00980 name = ST_ATTR_section_name(*st_attr);
00981 Assign_ST_To_Named_Section (st, name);
00982 }
00983 };
00984
00985
00986 struct find_st_attr_secname {
00987 ST_IDX st;
00988 find_st_attr_secname (const ST *s) : st (ST_st_idx (s)) {}
00989
00990 BOOL operator () (UINT, const ST_ATTR *st_attr) const {
00991 return (ST_ATTR_kind (*st_attr) == ST_ATTR_SECTION_NAME &&
00992 ST_ATTR_st_idx (*st_attr) == st);
00993 }
00994 };
00995
00996 STR_IDX
00997 Find_Section_Name_For_ST (const ST *st)
00998 {
00999 ST_IDX idx = ST_st_idx (st);
01000 ST_ATTR_IDX d;
01001
01002 d = For_all_until (St_Attr_Table, ST_IDX_level (idx),
01003 find_st_attr_secname(st));
01004 FmtAssert(d != 0, ("didn't find section name for ST %s", ST_name(st)));
01005 return ST_ATTR_section_name(St_Attr_Table(ST_IDX_level (idx), d));
01006 }
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025 static INT32
01026 Calc_Actual_Area ( TY_IDX pu_type, WN *pu_tree )
01027 {
01028 INT size;
01029 PLOC ploc;
01030
01031 size = 0;
01032 if (size == 0) {
01033 INT i;
01034 INT num_parms;
01035 INT regsize = MTYPE_RegisterSize(Spill_Int_Mtype);
01036 INTRINSIC id;
01037
01038 switch (WN_operator(pu_tree)) {
01039 case OPR_PICCALL:
01040 case OPR_ICALL:
01041 case OPR_CALL:
01042 num_parms = WN_num_actuals(pu_tree);
01043 ploc = Setup_Output_Parameter_Locations(pu_type);
01044 for (i = 0; i < num_parms; i++) {
01045 ploc = Get_Output_Parameter_Location (TY_Of_Parameter(WN_actual(pu_tree,i)));
01046 }
01047 size = PLOC_total_size(ploc);
01048 break;
01049 case OPR_INTRINSIC_OP:
01050 case OPR_INTRINSIC_CALL:
01051 id = (INTRINSIC) WN_intrinsic(pu_tree);
01052
01053 switch(id) {
01054 case INTRN_CONCATEXPR:
01055 size = 5 * regsize;
01056 break;
01057 default:
01058 num_parms = WN_num_actuals(pu_tree);
01059
01060
01061
01062
01063
01064 if (MTYPE_id(WN_rtype(pu_tree)) == MTYPE_CQ)
01065 size = ROUNDUP(regsize, MTYPE_align_best(MTYPE_CQ));
01066 if (INTRN_by_value(id) == TRUE)
01067 {
01068 for(i= 0; i<num_parms; i++) {
01069 size += ROUNDUP(TY_size(TY_Of_Parameter(WN_actual(pu_tree,i))), regsize);
01070 }
01071 }
01072 else
01073 {
01074 size += num_parms * regsize;
01075 }
01076 break;
01077 }
01078 break;
01079 default:
01080 FmtAssert(FALSE, ("Calc_Actual_Area: unexpected opcode"));
01081 }
01082
01083
01084
01085 if (pu_type != (TY_IDX) NULL && TY_has_prototype (pu_type) &&
01086 !TY_is_varargs (pu_type)) {
01087 Set_PU_arg_area_size(pu_type, size);
01088 }
01089 }
01090 size -= Formal_Save_Area_Size;
01091 if (size < 0)
01092 size = 0;
01093 else if (Trace_Frame)
01094 fprintf(TFile, "<lay> actual_arg_area = %d\n", size);
01095
01096 return size;
01097 }
01098
01099
01100
01101
01102
01103 extern void
01104 Check_Actual_Stack_Size (WN *call_tree)
01105 {
01106 INT32 actual_size;
01107 switch (WN_operator(call_tree)) {
01108 case OPR_CALL:
01109 case OPR_PICCALL:
01110 actual_size = Calc_Actual_Area ( ST_pu_type(WN_st(call_tree)), call_tree);
01111 break;
01112 case OPR_ICALL:
01113 actual_size = Calc_Actual_Area ( WN_ty(call_tree), call_tree);
01114 break;
01115 default:
01116 FmtAssert(FALSE, ("unexpected opcode in Check_Actual_Stack_Size"));
01117 }
01118 FmtAssert(actual_size <= Current_PU_Actual_Size,
01119 ("size of actual area increased from %d to %d",
01120 Current_PU_Actual_Size, actual_size));
01121 }
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135 static INT32
01136 Max_Arg_Area_Bytes(WN *node)
01137 {
01138 OPCODE opcode;
01139 INT32 maxsize = 0;
01140
01141 opcode = WN_opcode (node);
01142
01143 switch (OPCODE_operator(opcode)) {
01144 case OPR_CALL:
01145 case OPR_PICCALL:
01146 maxsize = Calc_Actual_Area ( ST_pu_type (WN_st (node)), node);
01147 Frame_Has_Calls = TRUE;
01148 break;
01149 case OPR_ICALL:
01150 maxsize = Calc_Actual_Area ( WN_ty(node), node );
01151 Frame_Has_Calls = TRUE;
01152 break;
01153 case OPR_INTRINSIC_OP:
01154 case OPR_INTRINSIC_CALL:
01155 maxsize = Calc_Actual_Area ( (TY_IDX) NULL, node );
01156 Frame_Has_Calls = TRUE;
01157 break;
01158 #ifdef TARG_IA32
01159 case OPR_IO:
01160 maxsize = 16;
01161 break;
01162 #endif
01163 }
01164
01165 if (opcode == OPC_BLOCK) {
01166 WN *wn;
01167 for ( wn = WN_first(node); wn != NULL; wn = WN_next(wn) ) {
01168 INT32 wn_size;
01169 if (((WN_opcode(wn) == OPC_PRAGMA) || (WN_opcode(wn) == OPC_XPRAGMA)) &&
01170 (WN_pragma(wn) == WN_PRAGMA_COPYIN)) {
01171 INT32 copyincount = 3;
01172 WN *next;
01173 while ((next = WN_next(wn)) &&
01174 ((WN_opcode(next) == OPC_PRAGMA) ||
01175 (WN_opcode(next) == OPC_XPRAGMA)) &&
01176 (WN_pragma(next) == WN_PRAGMA_COPYIN)) {
01177 copyincount += 2;
01178 wn = next;
01179 }
01180 wn_size = copyincount * MTYPE_RegisterSize(Spill_Int_Mtype);
01181 maxsize = MAX(maxsize, wn_size);
01182 Frame_Has_Calls = TRUE;
01183 } else {
01184 wn_size = Max_Arg_Area_Bytes (wn);
01185 maxsize = MAX(maxsize, wn_size);
01186 }
01187 }
01188 }
01189 else if (!OPCODE_is_leaf(opcode)) {
01190 INT i;
01191
01192 for (i = 0; i < WN_kid_count(node); i++) {
01193 if (WN_kid(node, i) != NULL) {
01194 INT32 wn_size = Max_Arg_Area_Bytes (WN_kid(node, i));
01195 maxsize = MAX(maxsize, wn_size);
01196 }
01197 }
01198 }
01199
01200 return maxsize;
01201 }
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213 void
01214 Reset_UPFORMAL_Segment(void)
01215 {
01216 ST *block;
01217
01218 if (block = SF_Block(SFSEG_UPFORMAL))
01219 {
01220 Set_ST_ofst(block, 0);
01221 Set_STB_size(block, 0);
01222 }
01223 else
01224 {
01225 Initialize_Frame_Segment (SFSEG_UPFORMAL, SCLASS_AUTO, INCREMENT);
01226 }
01227 }
01228
01229
01230
01231
01232
01233 static void
01234 Allocate_Entry_Formal(ST *formal, BOOL on_stack, BOOL in_formal_reg)
01235 {
01236 if (Has_No_Base_Block(formal))
01237 {
01238
01239
01240
01241
01242 if (PU_has_altentry(Get_Current_PU()) && ST_declared_static(formal))
01243 {
01244 SECTION_IDX sec;
01245
01246 Set_ST_sclass(formal, SCLASS_PSTATIC);
01247 Clear_ST_is_value_parm(formal);
01248 sec = Shorten_Section(formal, _SEC_BSS);
01249 Allocate_Object_To_Section(formal, sec, Adjusted_Alignment(formal));
01250 }
01251 else if (in_formal_reg)
01252 {
01253
01254 Add_Object_To_Frame_Segment ( formal, SFSEG_FORMAL, TRUE );
01255 }
01256 else if (on_stack)
01257 {
01258
01259 if (PU_has_altentry(Get_Current_PU())) {
01260 Add_Object_To_Frame_Segment ( formal, SFSEG_FTEMP, TRUE );
01261 }
01262 else {
01263 Add_Object_To_Frame_Segment ( formal, SFSEG_UPFORMAL, TRUE );
01264 }
01265 }
01266 else
01267 {
01268
01269
01270 Add_Object_To_Frame_Segment ( formal, SFSEG_FTEMP, TRUE );
01271 }
01272 }
01273 }
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287 static TY_IDX Formal_ST_type(ST *sym)
01288 {
01289 TY_IDX type= ST_type(sym);
01290
01291 if (ST_sclass(sym) == SCLASS_FORMAL_REF)
01292 {
01293 return Make_Pointer_Type(type);
01294 }
01295 return type;
01296 }
01297
01298
01299 # if MAX_NUMBER_OF_REGISTER_PARAMETERS > 0
01300 ST *vararg_symbols[MAX_NUMBER_OF_REGISTER_PARAMETERS];
01301 # else
01302
01303 # define vararg_symbols ((ST * *)0) // Not accessed
01304 # endif
01305
01306
01307 static void
01308 Clear_Vararg_Symbols (void)
01309 {
01310 INT i;
01311 for (i = 0; i < MAX_NUMBER_OF_REGISTER_PARAMETERS; i++) {
01312 vararg_symbols[i] = NULL;
01313 }
01314 }
01315
01316
01317 extern ST*
01318 Get_Vararg_Symbol (PLOC ploc)
01319 {
01320 Is_True(PLOC_reg(ploc) <
01321 First_Int_Preg_Param_Offset+MAX_NUMBER_OF_REGISTER_PARAMETERS,
01322 ("Get_Vararg_Symbol: ploc %d out of range", PLOC_reg(ploc)));
01323 return vararg_symbols[PLOC_reg(ploc)-First_Int_Preg_Param_Offset];
01324 }
01325
01326
01327
01328
01329
01330 static void
01331 Allocate_All_Formals (WN *pu)
01332 {
01333 INT i;
01334 PLOC ploc;
01335 ST *sym;
01336 BOOL varargs;
01337 TY_IDX pu_type = ST_pu_type (WN_st (pu));
01338
01339 Init_ST_formal_info_for_PU (WN_num_formals(pu));
01340 varargs = TY_is_varargs (pu_type);
01341 ploc = Setup_Input_Parameter_Locations(pu_type);
01342
01343
01344
01345
01346 for (i = 0; i < WN_num_formals(pu); i++)
01347 {
01348 sym = WN_st(WN_formal(pu, i));
01349
01350 ploc = Get_Input_Parameter_Location( Formal_ST_type(sym));
01351
01352 sym = Formal_Sym(sym, PLOC_on_stack(ploc) || varargs);
01353
01354 Allocate_Entry_Formal (sym, PLOC_on_stack(ploc), Is_Formal_Preg(PLOC_reg(ploc)));
01355 }
01356
01357 if ( PU_has_altentry(Get_Current_PU()))
01358 {
01359 WN *tree;
01360
01361 for ( tree = WN_first(WN_func_body(pu)); tree != NULL; tree = WN_next(tree))
01362 {
01363 if (WN_opcode(tree) == OPC_ALTENTRY)
01364 {
01365 Reset_UPFORMAL_Segment();
01366 ploc = Setup_Input_Parameter_Locations(ST_pu_type(WN_st(tree)));
01367 for (i = 0; i < WN_kid_count(tree); i++)
01368 {
01369 sym = WN_st(WN_formal(tree, i));
01370
01371 ploc = Get_Input_Parameter_Location ( Formal_ST_type(sym));
01372
01373 sym = Formal_Sym(sym, PLOC_on_stack(ploc) || varargs);
01374
01375 Allocate_Entry_Formal (sym, TRUE, Is_Formal_Preg(PLOC_reg(ploc)));
01376 }
01377 }
01378 }
01379 }
01380
01381 if (varargs) {
01382
01383
01384
01385
01386
01387
01388
01389 ST *last_fixed_symbol = sym;
01390 PLOC last_fixed_ploc = ploc;
01391
01392 TY_IDX vararg_type = Copy_TY(ST_type(Int_Preg));
01393
01394 Set_TY_no_ansi_alias (vararg_type);
01395
01396 if (PLOC_is_nonempty(ploc) && !PLOC_on_stack(ploc)) {
01397
01398 ploc = Get_Vararg_Input_Parameter_Location (ploc);
01399 }
01400
01401 while (!PLOC_on_stack(ploc)) {
01402
01403
01404
01405 sym = Gen_Temp_Symbol (vararg_type, "vararg");
01406 Set_ST_sclass (sym, SCLASS_FORMAL);
01407 Set_ST_is_value_parm( sym);
01408 Set_ST_addr_saved(sym);
01409 vararg_symbols[PLOC_reg(ploc)-First_Int_Preg_Param_Offset] = sym;
01410 Allocate_Entry_Formal(sym, PLOC_on_stack(ploc), Is_Formal_Preg(PLOC_reg(ploc)));
01411
01412
01413
01414
01415
01416
01417 Set_ST_base(sym, last_fixed_symbol);
01418 Set_ST_ofst(sym, PLOC_offset(ploc) - PLOC_offset(last_fixed_ploc));
01419
01420 ploc = Get_Vararg_Input_Parameter_Location (ploc);
01421 }
01422 }
01423 }
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434 extern ST*
01435 Get_Altentry_UpFormal_Symbol (ST *formal, PLOC ploc)
01436 {
01437 ST* upformal = Copy_ST(formal);
01438 Set_ST_name(upformal, Save_Str2(ST_name(upformal), ".upformal."));
01439 Set_ST_sclass(upformal, SCLASS_FORMAL);
01440 Clear_ST_gprel(upformal);
01441
01442 INT offset = PLOC_offset(ploc) - Formal_Save_Area_Size;
01443 if (PUSH_FRAME_POINTER_ON_STACK) {
01444 offset += MTYPE_byte_size(Pointer_Mtype);
01445 }
01446 if (PUSH_RETURN_ADDRESS_ON_STACK) {
01447 offset += MTYPE_byte_size(Pointer_Mtype);
01448 }
01449
01450 Assign_Object_To_Frame_Segment (upformal, SFSEG_UPFORMAL, offset);
01451 return upformal;
01452 }
01453
01454
01455
01456 static void
01457 Calc_Formal_Area (WN *pu_tree, INT32 *formal_size, INT32 *upformal_size)
01458 {
01459 INT maxsize;
01460 ST *st = WN_st (pu_tree);
01461 TY_IDX pu_ty = ST_pu_type (st);
01462 FmtAssert(WN_opcode(pu_tree) == OPC_FUNC_ENTRY, ("not a func-entry"));
01463
01464 if (TY_is_varargs (pu_ty)) {
01465 *formal_size = Formal_Save_Area_Size;
01466 *upformal_size = 0;
01467
01468 return;
01469 }
01470 else if (Get_PU_arg_area_size(pu_ty) > 0) {
01471 ;
01472 }
01473 else {
01474 PLOC ploc;
01475 INT i;
01476 ploc = Setup_Input_Parameter_Locations(pu_ty);
01477 for (i = 0; i < WN_num_formals(pu_tree); i++) {
01478 ploc = Get_Input_Parameter_Location (TY_Of_Parameter(WN_formal(pu_tree,i)));
01479 }
01480 Set_PU_arg_area_size(pu_ty, PLOC_total_size(ploc));
01481 }
01482 maxsize = Get_PU_arg_area_size(pu_ty);
01483 if ( PU_has_altentry(Get_Current_PU())) {
01484
01485
01486
01487
01488 WN *tree = WN_first(WN_func_body(pu_tree));
01489 for (; tree != NULL; tree = WN_next(tree)) {
01490 if (WN_opcode(tree) == OPC_ALTENTRY) {
01491 PLOC ploc;
01492 INT i;
01493 ploc = Setup_Input_Parameter_Locations(ST_pu_type(WN_st(tree)));
01494 for (i = 0; i < WN_kid_count(tree); i++) {
01495 ploc = Get_Input_Parameter_Location (TY_Of_Parameter(WN_formal(tree,i)));
01496 }
01497 maxsize = MAX(maxsize, PLOC_total_size(ploc));
01498 }
01499 }
01500 }
01501
01502 *formal_size = MIN (Get_PU_arg_area_size(pu_ty), Formal_Save_Area_Size);
01503
01504 *upformal_size = MAX (maxsize - Formal_Save_Area_Size, 0);
01505 }
01506
01507
01508
01509 static inline INT64
01510 Calc_Local_Area (void)
01511 {
01512 INT64 local_size = 0;
01513 ST_ITER first = Scope_tab[CURRENT_SYMTAB].st_tab->begin ();
01514 const ST_ITER last = Scope_tab[CURRENT_SYMTAB].st_tab->end ();
01515
01516 while (++first != last) {
01517 ST &st = *first;
01518 switch (ST_sclass (st)) {
01519
01520 case SCLASS_AUTO:
01521
01522
01523 if (ST_base_idx (st) != ST_st_idx (st))
01524 break;
01525 if (Trace_Frame)
01526 fprintf (TFile, "local %s has size %lld\n", ST_name(&st),
01527 ST_size(&st));
01528 local_size += ST_size(&st);
01529 break;
01530
01531 case SCLASS_DGLOBAL:
01532 case SCLASS_COMMON:
01533
01534
01535 if (ST_type (st) != 0) {
01536 Set_ST_type (st, Make_Align_Type (ST_type (st),
01537 Adjusted_Alignment (&st)));
01538 }
01539 break;
01540 }
01541 }
01542
01543 return local_size;
01544 }
01545
01546
01547
01548
01549
01550
01551 static void
01552 Init_Segment_Descriptors(void)
01553 {
01554 SF_SEGMENT s;
01555
01556 for (s = (SF_SEGMENT) (SFSEG_UNKNOWN+1); s <= SFSEG_LAST; s = (SF_SEGMENT) (s + 1) )
01557 {
01558
01559
01560
01561 SF_Block(s) = Create_Local_Block(INCREMENT,
01562 Save_Str2 (SF_Name(s),"_StkSeg"));
01563 SF_Maxsize(s) = MAX_SFSEG_BYTES;
01564 }
01565
01566 Set_ST_is_not_used(SF_Block(SFSEG_FORMAL));
01567 }
01568
01569
01570 #define SEG_SIZE(s) \
01571 (SF_Block(s) ? \
01572 STB_size(SF_Block(s)) : \
01573 ((SF_Maxsize(s) == MAX_SFSEG_BYTES) ? 0 : SF_Maxsize(s) ) )
01574
01575
01576 static void
01577 Init_Formal_Segments (INT32 formal_size, INT32 upformal_size)
01578 {
01579 SF_Maxsize ( SFSEG_UPFORMAL ) = ROUNDUP(upformal_size, stack_align);
01580 SF_Maxsize ( SFSEG_FORMAL ) = ROUNDUP(formal_size, stack_align);
01581 }
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592 static void
01593 Init_Frame_For_PU (INT32 actual_size)
01594 {
01595
01596
01597
01598
01599
01600 SF_Maxsize ( SFSEG_ACTUAL ) = ROUNDUP(actual_size, stack_align);
01601
01602
01603
01604 SF_Maxsize ( SFSEG_FTEMP ) =
01605 MAX_FRAME_OFFSET - SEG_SIZE(SFSEG_FORMAL) - SEG_SIZE(SFSEG_ACTUAL);
01606
01607
01608
01609
01610
01611 Large_Object_Bytes = DEFAULT_LARGE_OBJECT_BYTES;
01612 }
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623 static void
01624 Bind_Stack_Frame ( ST *SP_baseST, ST *FP_baseST )
01625 {
01626 Set_Direction (Get_Direction(SP_baseST), SF_Block(SFSEG_ACTUAL));
01627 Set_Direction (Get_Direction(SP_baseST), SF_Block(SFSEG_UPFORMAL));
01628
01629 Set_Direction (Get_Direction(SP_baseST), SF_Block(SFSEG_FORMAL));
01630
01631 switch (Current_PU_Stack_Model) {
01632 case SMODEL_SMALL:
01633 case SMODEL_LARGE:
01634 Set_Direction (Get_Direction(SP_baseST), SF_Block(SFSEG_FTEMP));
01635 break;
01636 case SMODEL_DYNAMIC:
01637 Set_Direction (Get_Direction(FP_baseST), SF_Block(SFSEG_FTEMP));
01638 break;
01639 default:
01640 FmtAssert ( TRUE,
01641 ("UNDEFINED Stack Model in Bind_Stack_Frame" ));
01642 }
01643 }
01644
01645 #define MERGE_SEGMENT(base, seg, mxfrm) \
01646 ST_Block_Merge (base, SF_Block(seg), 0, 0, mxfrm)
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656
01657 static void
01658 Merge_Fixed_Stack_Frame(ST *SP_baseST, ST *FP_baseST)
01659 {
01660 INT32 orig_formal_size;
01661 FmtAssert(SP_baseST != NULL && FP_baseST != NULL,
01662 ("Initialize_Stack_Frame: Invalid parameters"));
01663
01664 Set_STB_size(SP_baseST,0);
01665 Set_STB_size(FP_baseST,0);
01666
01667
01668 Set_STB_size(SF_Block(SFSEG_ACTUAL), SF_Maxsize(SFSEG_ACTUAL));
01669
01670
01671 BOOL pu_is_varargs = TY_is_varargs (ST_pu_type (Get_Current_PU_ST()));
01672 if (pu_is_varargs) {
01673 orig_formal_size = STB_size(SF_Block(SFSEG_FORMAL));
01674 Set_STB_size(SF_Block(SFSEG_FORMAL), SF_Maxsize(SFSEG_FORMAL));
01675 }
01676
01677 switch ( Current_PU_Stack_Model) {
01678 case SMODEL_SMALL:
01679 MERGE_SEGMENT(SP_baseST, SFSEG_ACTUAL, Max_Small_Frame_Offset);
01680
01681 MERGE_SEGMENT(SP_baseST, SFSEG_FTEMP, Max_Small_Frame_Offset);
01682
01683
01684
01685 break;
01686
01687 case SMODEL_LARGE:
01688 MERGE_SEGMENT(SP_baseST, SFSEG_ACTUAL, MAX_LARGE_FRAME_OFFSET);
01689 MERGE_SEGMENT(SP_baseST, SFSEG_FTEMP, MAX_LARGE_FRAME_OFFSET);
01690 Set_ST_base(SF_Block(SFSEG_UPFORMAL), FP_baseST);
01691 Set_ST_ofst (SF_Block(SFSEG_UPFORMAL), Stack_Offset_Adjustment);
01692 MERGE_SEGMENT(FP_baseST, SFSEG_FORMAL, MAX_LARGE_FRAME_OFFSET);
01693 break;
01694
01695 case SMODEL_DYNAMIC:
01696 MERGE_SEGMENT(SP_baseST, SFSEG_ACTUAL, MAX_LARGE_FRAME_OFFSET);
01697 Set_ST_base(SF_Block(SFSEG_UPFORMAL), FP_baseST);
01698 Set_ST_ofst (SF_Block(SFSEG_UPFORMAL), Stack_Offset_Adjustment);
01699
01700 MERGE_SEGMENT(FP_baseST, SFSEG_FORMAL, MAX_LARGE_FRAME_OFFSET);
01701 MERGE_SEGMENT(FP_baseST, SFSEG_FTEMP, MAX_LARGE_FRAME_OFFSET);
01702 break;
01703
01704 default:
01705 FmtAssert ( TRUE,
01706 ("UNDEFINED Stack Model in Initialize_Stack_Frame" ));
01707 }
01708 if (pu_is_varargs) {
01709
01710 Set_STB_size(SF_Block(SFSEG_FORMAL), orig_formal_size);
01711 }
01712 }
01713
01714 static STACK_MODEL
01715 Choose_Stack_Model (INT64 frame_size)
01716 {
01717 if (PU_has_alloca(Get_Current_PU())) {
01718 return SMODEL_DYNAMIC;
01719 }
01720 else if (PU_has_nested(Get_Current_PU())) {
01721 return SMODEL_DYNAMIC;
01722 }
01723 else if (Force_Large_Stack_Model) {
01724 return SMODEL_LARGE;
01725 }
01726 else if (frame_size < Max_Small_Frame_Offset) {
01727 return SMODEL_SMALL;
01728 }
01729 else if (frame_size < MAX_LARGE_FRAME_OFFSET) {
01730 return SMODEL_LARGE;
01731 }
01732 else {
01733 FmtAssert ( FALSE, ("64-bit stack frame NYI"));
01734 return SMODEL_UNDEF;
01735 }
01736 }
01737
01738
01739
01740 static void
01741 Allocate_Local_Spill_Sym (void)
01742 {
01743 if (Current_PU_Stack_Model == SMODEL_SMALL) {
01744
01745 Local_Spill_Sym = NULL;
01746 }
01747 else {
01748 Local_Spill_Sym = Gen_Temp_Symbol (Spill_Int_Type, "reserved_spill");
01749 Allocate_Temp_To_Memory (Local_Spill_Sym);
01750 }
01751 }
01752
01753 extern void
01754 Initialize_Stack_Frame (WN *PU_tree)
01755 {
01756 INT32 actual_size;
01757 INT32 formal_size;
01758 INT32 upformal_size;
01759 INT64 frame_size = 0;
01760
01761 Set_Error_Phase("Data Layout");
01762 Trace_Frame = Get_Trace(TP_DATALAYOUT, 1);
01763 FmtAssert(WN_opcode(PU_tree) == OPC_FUNC_ENTRY,
01764 ("Determine_Stack_Model: The PU_tree node does not point to a OPC_FUNC_ENTRY"));
01765
01766 if (ST_asm_function_st(*WN_st(PU_tree))) {
01767
01768
01769 return;
01770 }
01771
01772 if (Trace_Frame)
01773 fprintf(TFile, "<lay> Determine_Stack_Model for %s\n",
01774 ST_name(WN_st(PU_tree)));
01775
01776 if (PU_has_return_address(Get_Current_PU())
01777 && MTYPE_byte_size(Pointer_Mtype) < MTYPE_byte_size(Spill_Int_Mtype) )
01778 {
01779
01780
01781
01782
01783
01784
01785 ST *ra_sym = Find_Special_Return_Address_Symbol();
01786 ST *st_base = New_ST ();
01787 ST_Init (st_base, Save_Str("return_address_base"),
01788 ST_class(ra_sym), ST_sclass(ra_sym), ST_export(ra_sym),
01789 MTYPE_To_TY(Spill_Int_Mtype) );
01790 Set_ST_base (ra_sym, st_base);
01791 Set_ST_ofst (ra_sym, MTYPE_byte_size(Spill_Int_Mtype) - MTYPE_byte_size(Pointer_Mtype));
01792 }
01793
01794 Init_Segment_Descriptors();
01795 Init_PU_arg_area_size_array();
01796
01797 Calc_Formal_Area (PU_tree, &formal_size, &upformal_size);
01798
01799
01800 Frame_Has_Calls = FALSE;
01801 actual_size = Max_Arg_Area_Bytes(PU_tree);
01802
01803 actual_size = ROUNDUP(actual_size, MTYPE_byte_size(Spill_Int_Mtype));
01804 Current_PU_Actual_Size = actual_size;
01805
01806 frame_size = Calc_Local_Area ();
01807
01808 if (PUSH_FRAME_POINTER_ON_STACK) {
01809
01810 ST* old_fp = New_ST ();
01811 ST_Init (old_fp,
01812 Save_Str("old_frame_pointer"),
01813 CLASS_VAR,
01814 SCLASS_AUTO,
01815 EXPORT_LOCAL,
01816 MTYPE_To_TY(Pointer_Mtype));
01817 Add_Object_To_Frame_Segment (old_fp, SFSEG_UPFORMAL, TRUE);
01818 upformal_size += MTYPE_byte_size(Pointer_Mtype);
01819 }
01820
01821 if (PUSH_RETURN_ADDRESS_ON_STACK) {
01822
01823 ST* ra_st = New_ST ();
01824 ST_Init (ra_st,
01825 Save_Str("return_address"),
01826 CLASS_VAR,
01827 SCLASS_AUTO,
01828 EXPORT_LOCAL,
01829 MTYPE_To_TY(Pointer_Mtype));
01830 Add_Object_To_Frame_Segment (ra_st, SFSEG_UPFORMAL, TRUE);
01831 upformal_size += MTYPE_byte_size(Pointer_Mtype);
01832 }
01833
01834 if (Trace_Frame) {
01835 fprintf(TFile, "<lay> locals' size = %lld\n", frame_size);
01836 fprintf(TFile, "<lay> upformal size = %d, formal size = %d\n",
01837 upformal_size, formal_size);
01838 fprintf(TFile, "<lay> actual size = %d\n", actual_size);
01839 }
01840 frame_size += formal_size + actual_size;
01841
01842
01843 frame_size += DEFAULT_TEMP_SPACE_BYTES;
01844
01845
01846
01847 frame_size += upformal_size;
01848
01849 Current_PU_Stack_Model = Choose_Stack_Model(frame_size);
01850 if (Trace_Frame) {
01851 fprintf(TFile, "<lay> guess frame_size = %lld\n", frame_size);
01852 fprintf(TFile, "<lay> stack model = %d\n", Current_PU_Stack_Model);
01853 }
01854
01855
01856 stack_direction = DECREMENT;
01857 SP_Sym = Create_Base_Reg (".SP", INCREMENT);
01858 FP_Sym = Create_Base_Reg (".FP", DECREMENT);
01859
01860
01861 Allocate_All_Formals (PU_tree);
01862 Init_Formal_Segments (formal_size, upformal_size);
01863 }
01864
01865
01866 extern void
01867 Calculate_Stack_Frame_Sizes (WN *PU_tree)
01868 {
01869 if (ST_asm_function_st(*Get_Current_PU_ST())) {
01870
01871
01872 return;
01873 }
01874
01875 INT32 actual_size;
01876
01877 actual_size = Max_Arg_Area_Bytes(PU_tree);
01878
01879 actual_size = ROUNDUP(actual_size, MTYPE_byte_size(Spill_Int_Mtype));
01880 if (Trace_Frame && actual_size != Current_PU_Actual_Size) {
01881 fprintf(TFile, "actual_size was %d, now is %d\n",
01882 Current_PU_Actual_Size, actual_size);
01883 }
01884
01885
01886 Current_PU_Actual_Size = MAX(Current_PU_Actual_Size, actual_size);
01887
01888 Init_Frame_For_PU (Current_PU_Actual_Size);
01889 Bind_Stack_Frame (SP_Sym, FP_Sym);
01890
01891 Merge_Fixed_Stack_Frame (SP_Sym, FP_Sym);
01892
01893 Allocate_Local_Spill_Sym ();
01894 }
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908 static void
01909 Process_Stack_Variable ( ST *st )
01910 {
01911 ST_SCLASS sc;
01912 UINT64 size;
01913 BOOL is_root_block = Is_Allocatable_Root_Block(st);
01914 ST *base;
01915
01916 if (! is_root_block && ST_class(st) == CLASS_BLOCK) return;
01917
01918 sc = ST_sclass(st);
01919 Is_True ( (sc == SCLASS_AUTO),
01920 ("Process_Stack_Variable: Invalid SCLASS %d\n",ST_sclass(st)) );
01921
01922 size = (is_root_block) ? STB_size(st) : TY_size(ST_type(st));
01923
01924
01925 if (Current_PU_Stack_Model == SMODEL_SMALL ||
01926 (Current_PU_Stack_Model == SMODEL_LARGE && size < Large_Object_Bytes))
01927 base = SP_Sym;
01928 else
01929 base = FP_Sym;
01930 ST_Block_Merge (base, st, 0, 0, MAX_FRAME_OFFSET);
01931 }
01932
01933 static void
01934 Trace_Stack_Segments( char *msg, ST *SP_baseST, ST *FP_baseST )
01935 {
01936 SF_SEGMENT s;
01937
01938 fprintf(TFile, "Stack Segment after \"%s\"\n", msg);
01939 fprintf(TFile, "SegName \toffset\tbase\tblksize\talign\tmaxsize\n");
01940
01941
01942 for ( s = SFSEG_FIRST; s <= SFSEG_LAST; s = (SF_SEGMENT) (s + 1) ) {
01943 ST *block;
01944 INT64 size, offset;
01945 INT align;
01946 char *basename;
01947
01948 block = SF_Block(s);
01949 basename = block ? ST_name(ST_base(block)) : (char *)"<none>";
01950 size = block? STB_size(block): 0;
01951 align = block? STB_align(block): 0;
01952 offset = block? ST_ofst(block): 0;
01953 fprintf(TFile, "%s \t%lld\t%s\t%lld\t%d\t%lld\n",
01954 SF_Name(s), offset, basename, size, align, SF_Maxsize(s));
01955 }
01956 if (SP_baseST != NULL)
01957 fprintf(TFile, "%s \t\t%lld\t\t%lld\t%d\n",
01958 ST_name(SP_baseST), ST_ofst(SP_baseST),
01959 STB_size(SP_baseST), STB_align(SP_baseST));
01960 if (FP_baseST != NULL)
01961 fprintf(TFile, "%s \t\t%lld\t\t%lld\t%d\n",
01962 ST_name(FP_baseST), ST_ofst(FP_baseST),
01963 STB_size(FP_baseST), STB_align(FP_baseST));
01964 }
01965
01966 #ifdef PV394813
01967
01968 static void
01969 Allocate_All_INITV (INITV *inv1)
01970 {
01971 INITV *inv;
01972 if (inv1 == NULL) return;
01973 FOREACH_INITV(inv1, inv) {
01974 if ( INITV_kind(inv) == INITVKIND_SYMOFF) {
01975
01976 Allocate_Object(INITV_st(inv));
01977 }
01978 else if (INITV_kind(inv) == INITVKIND_BLOCK) {
01979
01980 Allocate_All_INITV (INITV_blk(inv));
01981 }
01982 }
01983 }
01984 #endif
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996 struct finalize_inito
01997 {
01998 void operator() (UINT32, const INITO* inito) const {
01999 ST* st = INITO_st (*inito);
02000 if (Has_No_Base_Block(st))
02001 Allocate_Object(st);
02002 #ifdef PV394813
02003 Allocate_All_INITV (INITO_val(*inito));
02004 #endif
02005 }
02006 };
02007
02008 INT64 Finalize_Stack_Frame (void)
02009 {
02010 INT64 Frame_Size;
02011 ST *st;
02012 INT i;
02013
02014 Set_Error_Phase("Data Layout");
02015 Clear_Vararg_Symbols();
02016
02017 For_all (Inito_Table, CURRENT_SYMTAB, finalize_inito());
02018
02019
02020
02021 if (PU_has_nested(Get_Current_PU())) {
02022 FOREACH_SYMBOL (CURRENT_SYMTAB, st, i) {
02023 if (ST_class(st) == CLASS_VAR && ST_has_nested_ref(st)) {
02024 Allocate_Object(st);
02025 }
02026 }
02027 }
02028
02029 switch ( Current_PU_Stack_Model ) {
02030 case SMODEL_SMALL:
02031
02032
02033 if (SEG_SIZE(SFSEG_UPFORMAL) == 0
02034 && ST_is_not_used(SF_Block(SFSEG_FORMAL)) )
02035 {
02036 if (Trace_Frame) fprintf(TFile, "<lay> formals not used\n");
02037 }
02038 else {
02039 MERGE_SEGMENT(SP_Sym, SFSEG_FORMAL, Max_Small_Frame_Offset);
02040 }
02041 Frame_Size = STB_size(SP_Sym);
02042 Set_ST_base(SF_Block(SFSEG_UPFORMAL), SP_Sym);
02043 Assign_Offset(SF_Block(SFSEG_UPFORMAL), SP_Sym,
02044 (Frame_Has_Calls ? Stack_Offset_Adjustment : 0), 0);
02045 break;
02046
02047 case SMODEL_LARGE:
02048 Frame_Size = STB_size(SP_Sym) + STB_size(FP_Sym);
02049 break;
02050
02051 case SMODEL_DYNAMIC:
02052 Frame_Size = STB_size(SP_Sym) + STB_size(FP_Sym);
02053 break;
02054
02055 default:
02056 FmtAssert ( TRUE,
02057 ("UNDEFINED Stack Model in Finalize_Stack_Frame" ));
02058 }
02059
02060 Frame_Size = ROUNDUP(Frame_Size, stack_align);
02061
02062
02063
02064
02065
02066 if (!Frame_Has_Calls) {
02067 Frame_Size = MAX(0, Frame_Size - Stack_Offset_Adjustment);
02068 }
02069
02070 if ( Trace_Frame ) {
02071 Trace_Stack_Segments ( "Finalize_Stack_Frame", SP_Sym, FP_Sym);
02072 fprintf(TFile, "<lay> final frame_size = %lld\n", Frame_Size);
02073 }
02074 if (Current_PU_Stack_Model == SMODEL_SMALL
02075 && ((Frame_Size + STB_size(SF_Block(SFSEG_UPFORMAL)))
02076 > Max_Small_Frame_Offset))
02077 {
02078 DevWarn("upformals overflowed small stack frame; will try recompiling with -TENV:large_stack");
02079 Early_Terminate(RC_OVERFLOW_ERROR);
02080 }
02081 if (Current_PU_Stack_Model == SMODEL_LARGE && Frame_Size < Max_Small_Frame_Offset)
02082 if (Trace_Frame) fprintf(TFile, "<lay> stack-model underflowed\n");
02083
02084 {
02085
02086 #if (defined(__sgi) || defined(__sun) \
02087 || (defined(__linux__) && defined(__ia64__)))
02088 struct rlimit64 rlp;
02089 getrlimit64 (RLIMIT_STACK, &rlp);
02090 #else
02091 struct rlimit rlp;
02092 getrlimit(RLIMIT_STACK, &rlp);
02093 #endif
02094
02095 if (Frame_Size > rlp.rlim_cur)
02096 ErrMsg (EC_LAY_stack_limit, Frame_Size, (INT64) rlp.rlim_cur);
02097 }
02098 return Frame_Size;
02099 }
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110 void
02111 Allocate_Temp_To_Memory ( ST *st )
02112 {
02113 Is_True(ST_sclass(st) == SCLASS_AUTO, ("Allocate_Temp_To_Memory expect stack var"));
02114 Set_ST_is_temp_var(st);
02115 Process_Stack_Variable ( st );
02116 }
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126 static BOOL
02127 Is_String_Literal (ST *st)
02128 {
02129 if (ST_class(st) == CLASS_CONST && TCON_ty(STC_val(st)) == MTYPE_STR) {
02130 return TRUE;
02131 }
02132
02133 else if (ST_class(st) == CLASS_VAR && ST_is_const_var(st)
02134 && ST_is_initialized(st)
02135 && TY_kind(ST_type(st)) == KIND_ARRAY
02136 && TY_mtype(TY_AR_etype(ST_type(st))) == MTYPE_U1 )
02137 {
02138 return TRUE;
02139 }
02140 return FALSE;
02141 }
02142
02143
02144
02145
02146
02147
02148
02149
02150
02151
02152
02153
02154 static SECTION_IDX
02155 Shorten_Section ( ST *st, SECTION_IDX sec )
02156 {
02157 INT64 size;
02158 SECTION_IDX newsec;
02159 BOOL is_root_block = Is_Allocatable_Root_Block(st);
02160
02161 if (! is_root_block && ST_class(st) == CLASS_BLOCK) return sec;
02162
02163
02164
02165
02166 if ((Gen_PIC_Shared || Gen_PIC_Call_Shared) && ST_is_preemptible(st)
02167 && ! (ST_class(st) == CLASS_VAR && ST_force_gprel(st)) )
02168 {
02169 return sec;
02170 }
02171
02172 newsec = Corresponding_Short_Section (sec);
02173 if (newsec == sec) return sec;
02174
02175 size = ST_size(st);
02176
02177 if (size == 0) return sec;
02178
02179 if (ST_class(st) == CLASS_VAR && ST_not_gprel(st))
02180 return sec;
02181
02182 if (size > Max_Sdata_Elt_Size) {
02183
02184
02185
02186 if (ST_class(st) != CLASS_VAR)
02187 return sec;
02188
02189 else if (!ST_gprel(st) && !ST_force_gprel(st))
02190 return sec;
02191 }
02192
02193 if (Strings_Not_Gprelative && Is_String_Literal(st)) {
02194
02195 return sec;
02196 }
02197
02198 if ((ST_class(st) == CLASS_VAR || ST_class(st) == CLASS_CONST) && !ST_gprel(st))
02199 {
02200
02201
02202
02203 size = MAX(size, Adjusted_Alignment(st));
02204 if (size <= Gspace_Available) {
02205 Gspace_Available -= size;
02206 #if 0
02207 if (Trace_Frame) fprintf(TFile, "<lay> use Gspace for %s (size %d, align %d)\n", ST_NAME(st), TY_size(ST_type(st)), Adjusted_Alignment(st));
02208 #endif
02209 }
02210 else {
02211 if (Trace_Frame) fprintf(TFile, "<lay> not enough Gspace, so didn't assign %s to gprel section\n", ST_NAME(st));
02212 return sec;
02213 }
02214 }
02215 #if 0
02216 else {
02217 if (Trace_Frame) fprintf(TFile, "<lay> didn't check Gspace for %s\n", ST_NAME(st));
02218 }
02219 #endif
02220
02221 if (sec == _SEC_RDATA && ST_class(st) == CLASS_CONST) {
02222
02223
02224
02225 TCON tcon = STC_val(st);
02226 switch (TCON_ty (tcon)) {
02227 case MTYPE_F4:
02228 case MTYPE_I4:
02229 case MTYPE_U4:
02230 newsec = _SEC_LIT4;
02231 break;
02232 case MTYPE_F8:
02233 case MTYPE_I8:
02234 case MTYPE_U8:
02235 newsec = _SEC_LIT8;
02236 break;
02237 case MTYPE_FQ:
02238 newsec = _SEC_LIT16;
02239 break;
02240 }
02241 }
02242 Set_ST_gprel(st);
02243 return newsec;
02244 }
02245
02246
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262 static void
02263 Allocate_Object_To_Section (ST *st, SECTION_IDX sec, UINT align)
02264 {
02265 ST *block;
02266 INT64 max_size;
02267
02268
02269 Is_True( IS_POW2(align), ("Alignment %d must be power of 2",align));
02270
02271 block = Get_Section_ST (sec, align, SCLASS_UNKNOWN );
02272 max_size = SEC_max_sec_size(sec);
02273 ST_Block_Merge (block, st, 0, 0, max_size);
02274 }
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289 static void
02290 Assign_Object_To_Section( ST *st, SECTION_IDX sec, UINT align)
02291 {
02292 ST *block;
02293
02294
02295 Is_True( IS_POW2(align), ("Alignment %d must be power of 2",align));
02296
02297 block = Get_Section_ST(sec, align, ST_sclass (st));
02298 if ( Trace_Frame ) {
02299 fprintf ( TFile, "Assigning symbol %s to %s section \n",
02300 ST_name(st) ? ST_name(st) : "<null>", ST_name(block) );
02301 }
02302 Set_ST_base(st, block);
02303 }
02304
02305 static void
02306 Allocate_Label (ST *lab)
02307 {
02308 FmtAssert(ST_sclass(lab) == SCLASS_TEXT, ("non-text label?"));
02309
02310 Assign_Object_To_Section ( lab, _SEC_TEXT, 0 );
02311 }
02312
02313
02314
02315
02316
02317
02318
02319
02320
02321
02322
02323
02324
02325
02326
02327
02328
02329 extern void
02330 Allocate_Object ( ST *st )
02331 {
02332 SECTION_IDX sec;
02333 ST *base_st = st;
02334
02335 if ( ST_sclass(st) == SCLASS_FORMAL ) {
02336
02337 Clear_ST_is_not_used(SF_Block(SFSEG_FORMAL));
02338 }
02339
02340 if (Is_Allocated(st)) return;
02341 if (ST_is_not_used(st)) return;
02342
02343 if (ST_has_named_section(st)) {
02344 STR_IDX name = Find_Section_Name_For_ST (st);
02345 Assign_ST_To_Named_Section (st, name);
02346 return;
02347 }
02348 if (Has_Base_Block(st)) {
02349 base_st = Base_Symbol(st);
02350 }
02351
02352 if (ST_sclass(st) != ST_sclass(base_st))
02353 DevWarn("st sclass %d different from base sclass %d",
02354 ST_sclass(st), ST_sclass(base_st));
02355
02356 switch ( ST_sclass(base_st) ) {
02357 case SCLASS_UNKNOWN :
02358 break;
02359 case SCLASS_AUTO:
02360 Process_Stack_Variable(base_st);
02361 break;
02362 case SCLASS_FORMAL:
02363 case SCLASS_FORMAL_REF:
02364
02365
02366
02367 break;
02368 case SCLASS_PSTATIC :
02369 case SCLASS_FSTATIC :
02370 if (ST_is_thread_private(st)) {
02371 if (ST_is_initialized(st) && !ST_init_value_zero (st))
02372 sec = _SEC_LDATA;
02373 else
02374 sec = _SEC_LBSS;
02375 }
02376 else if (ST_is_initialized(st) && !ST_init_value_zero (st))
02377 sec = (ST_is_constant(st) ? _SEC_RDATA : _SEC_DATA);
02378 else
02379 sec = _SEC_BSS;
02380 sec = Shorten_Section ( st, sec );
02381 Allocate_Object_To_Section ( base_st, sec, Adjusted_Alignment (base_st) );
02382 break;
02383 case SCLASS_REG:
02384 break;
02385 case SCLASS_CPLINIT:
02386 sec = _SEC_CPLINIT;
02387 Allocate_Object_To_Section ( base_st, sec, Adjusted_Alignment(base_st));
02388 break;
02389 case SCLASS_EH_REGION:
02390 sec = _SEC_EH_REGION;
02391 Allocate_Object_To_Section ( base_st, sec, Adjusted_Alignment(base_st));
02392 break;
02393 case SCLASS_EH_REGION_SUPP:
02394 sec = _SEC_EH_REGION_SUPP;
02395 Allocate_Object_To_Section ( base_st, sec, Adjusted_Alignment(base_st));
02396 break;
02397 case SCLASS_DISTR_ARRAY:
02398 sec = _SEC_DISTR_ARRAY;
02399 Allocate_Object_To_Section ( base_st, sec, Adjusted_Alignment(base_st));
02400 break;
02401 case SCLASS_THREAD_PRIVATE_FUNCS:
02402 sec = _SEC_THREAD_PRIVATE_FUNCS;
02403 Allocate_Object_To_Section ( base_st, sec, Adjusted_Alignment(base_st));
02404 break;
02405 case SCLASS_COMMON:
02406
02407
02408
02409
02410
02411
02412 if (ST_type(st) != (TY_IDX) NULL)
02413 {
02414 TY_IDX type = ST_type(st);
02415
02416 Set_ST_type(st,
02417 Make_Align_Type(type, Adjusted_Alignment(st)) );
02418 }
02419 case SCLASS_EXTERN:
02420
02421
02422
02423
02424 if ( ! FILE_INFO_ipa (File_info) && !ST_is_weak_symbol(st)) {
02425 sec = Shorten_Section ( st, _SEC_DATA );
02426 if (sec != _SEC_DATA) Set_ST_gprel (st);
02427 }
02428 break;
02429 case SCLASS_UGLOBAL :
02430 if (ST_is_thread_private(st)) {
02431 sec = _SEC_LBSS;
02432 }
02433 else sec = _SEC_BSS;
02434 sec = Shorten_Section ( st, sec );
02435 Allocate_Object_To_Section ( base_st, sec, Adjusted_Alignment(base_st));
02436 break;
02437 case SCLASS_DGLOBAL :
02438 if (ST_is_thread_private(st)) sec = _SEC_LDATA;
02439 else if (ST_is_constant(st)) sec = _SEC_RDATA;
02440 else sec = _SEC_DATA;
02441 sec = Shorten_Section ( st, sec );
02442 Allocate_Object_To_Section ( base_st, sec, Adjusted_Alignment(base_st));
02443 break;
02444 case SCLASS_TEXT :
02445
02446
02447 sec = _SEC_TEXT;
02448 Assign_Object_To_Section ( base_st, sec, 0 );
02449 break;
02450 default:
02451 Is_True ( (FALSE)
02452 , ("Allocate_Object: Invalid SCLASS %d",ST_sclass(st)) );
02453 break;
02454 }
02455
02456 }
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469 extern void
02470 Allocate_File_Statics (void)
02471 {
02472 ST *st;
02473 INT i;
02474 Trace_Frame = Get_Trace(TP_DATALAYOUT, 1);
02475
02476
02477 if ( ST_ATTR_Table_Size (GLOBAL_SYMTAB)) {
02478 For_all (St_Attr_Table, GLOBAL_SYMTAB,
02479 Assign_Section_Names());
02480 }
02481
02482
02483
02484
02485 #ifndef _USE_STL_EXT
02486 list<ST*> common_list;
02487 list<ST*>::iterator cit;
02488 #else
02489 slist<ST*> common_list;
02490 slist<ST*>::iterator cit;
02491 #endif
02492
02493 FOREACH_SYMBOL (GLOBAL_SYMTAB,st,i) {
02494 if (ST_sclass(st) != SCLASS_COMMON) continue;
02495 if (Has_Base_Block(st)) continue;
02496
02497 for (cit = common_list.begin(); cit != common_list.end(); ++cit)
02498 {
02499 if (ST_name_idx(*cit) == ST_name_idx(st)
02500 && ST_export(*cit) == ST_export(st))
02501 {
02502
02503
02504
02505 if (TY_size(ST_type(st)) > TY_size(ST_type(*cit))) {
02506 Set_ST_base(*cit, st);
02507 DevWarn("found commons with same name %s; merge together %d->%d", ST_name(st), ST_index(*cit), ST_index(st));
02508
02509
02510 *cit = st;
02511 }
02512 else {
02513 Set_ST_base(st, *cit);
02514 DevWarn("found commons with same name %s; merge together %d->%d", ST_name(st), ST_index(st), ST_index(*cit));
02515 }
02516 break;
02517 }
02518 }
02519 if (cit == common_list.end()) {
02520 common_list.push_front(st);
02521 }
02522 }
02523
02524 FOREACH_SYMBOL (GLOBAL_SYMTAB,st,i) {
02525 if (ST_sclass(st) == SCLASS_REG) continue;
02526
02527
02528 if (ST_class(st) == CLASS_CONST && !Emit_Global_Data) continue;
02529
02530
02531
02532
02533 if (ST_class(st) == CLASS_VAR &&
02534 (ST_is_reshaped(st) || ST_is_fill_align(st)))
02535 continue;
02536 Allocate_Object(st);
02537 }
02538 }
02539
02540
02541
02542 BOOL
02543 Uses_Small_Offset (ST *st, WN_OFFSET wn_ofst)
02544 {
02545 switch(ST_sclass(st)) {
02546
02547 case SCLASS_AUTO:
02548 switch (Current_PU_Stack_Model) {
02549 case SMODEL_SMALL:
02550 return TRUE;
02551 case SMODEL_LARGE:
02552
02553
02554
02555 return (ST_size(st) < Large_Object_Bytes);
02556 case SMODEL_DYNAMIC:
02557
02558
02559 return FALSE;
02560 }
02561
02562 case SCLASS_FORMAL:
02563 return (Current_PU_Stack_Model != SMODEL_DYNAMIC);
02564 default:
02565 switch (ST_class(st)) {
02566 case CLASS_VAR:
02567 case CLASS_BLOCK:
02568 return ST_gprel(st);
02569 case CLASS_CONST:
02570
02571
02572 return TRUE;
02573 }
02574 return FALSE;
02575 }
02576 }
02577
02578
02579
02580
02581 static ST*
02582 Create_Global_Array_ST (TYPE_ID emtype, INT num, char *name)
02583 {
02584
02585 TY_IDX arr_ty = Make_Array_Type (emtype, 1, num);
02586 ST* st = New_ST ();
02587 ST_Init (st, Save_Str(name), CLASS_VAR, SCLASS_UGLOBAL, EXPORT_LOCAL, arr_ty);
02588 Set_ST_pt_to_unique_mem (st);
02589 return st;
02590 }
02591
02592
02593
02594
02595
02596 struct pad_global_arrays
02597 {
02598 inline void operator() (UINT32, ST* st) const {
02599 if ((ST_sclass(st) == SCLASS_UGLOBAL) && (ST_class(st) == CLASS_VAR)) {
02600 const TY_IDX ty = ST_type(st);
02601
02602 if (!ST_is_not_used(st) &&
02603 (TY_size (ty) > 0) &&
02604 !ST_is_fill_align(st) &&
02605 !ST_has_nested_ref(st) &&
02606 (TY_kind(ty) == KIND_ARRAY) &&
02607 (!ST_is_reshaped(st))) {
02608
02609 INT size = TY_size (ty);
02610 INT set_size = 256*1024;
02611 INT mod = size % set_size;
02612 INT pad_size=0;
02613 if ((size > 0.9*set_size) && (mod < set_size/20)) {
02614 pad_size = set_size/20 - mod;
02615 } else if ((size > 0.9*set_size) &&
02616 ((set_size - mod) < set_size/20)) {
02617 pad_size = set_size/20 + (set_size - mod);
02618 }
02619 size += pad_size;
02620 set_size = 16*1024;
02621 mod = size % set_size;
02622 if ((size > 0.9*set_size) && (mod < set_size/20)) {
02623 pad_size += set_size/20 - mod;
02624 } else if ((size > 0.9*set_size) &&
02625 ((set_size - mod) < set_size/20)) {
02626 pad_size += set_size/20 + (set_size - mod);
02627 }
02628 size += pad_size;
02629 if (pad_size) {
02630 static INT count;
02631 char name[64];
02632 sprintf (name, "global_pad_%d", count);
02633 count++;
02634 ST *pad_symbol = Create_Global_Array_ST (MTYPE_I1,size,name);
02635 St_Block_Union(st,pad_symbol);
02636 }
02637 }
02638 }
02639 }
02640 };
02641
02642 extern void
02643 Pad_Global_Arrays()
02644 {
02645 For_all (St_Table, GLOBAL_SYMTAB, pad_global_arrays ());
02646 }
02647
02648
02649 extern INT
02650 Stack_Offset_Adjustment_For_PU (void)
02651 {
02652 if (Frame_Has_Calls)
02653 return Stack_Offset_Adjustment;
02654 else
02655 return 0;
02656 }