00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 #ifdef _KEEP_RCS_ID
00059 static char *rcs_id = "$Source: /proj/osprey/CVS/open64/osprey1.0/be/whirl2c/init2c.cxx,v $ $Revision: 1.1.1.1 $";
00060 #endif
00061
00062 #include "whirl2c_common.h"
00063 #include "st2c.h"
00064 #include "ty2c.h"
00065 #include "tcon2c.h"
00066 #include "init2c.h"
00067
00068
00069
00070
00071
00072 #define INITV_repeat(x) \
00073 ((INITV_kind(Initv_Table[x]) == INITVKIND_ZERO || \
00074 INITV_kind(Initv_Table[x]) == INITVKIND_ONE || \
00075 INITV_kind(Initv_Table[x]) == INITVKIND_VAL) ? \
00076 INITV_repeat2(Initv_Table[x]) : INITV_repeat1(Initv_Table[x]))
00077
00078 inline TCON
00079 TCON_For_Initv(INITV_IDX initv)
00080 {
00081 TCON tcon;
00082
00083 switch (INITV_kind(initv))
00084 {
00085 case INITVKIND_ZERO:
00086 tcon = Host_To_Targ(INITV_mtype(Initv_Table[initv]), 0);
00087 break;
00088 case INITVKIND_ONE:
00089 tcon = Host_To_Targ(INITV_mtype(Initv_Table[initv]), 1);
00090 break;
00091 case INITVKIND_VAL:
00092 tcon = INITV_tc_val(Initv_Table[initv]);
00093 break;
00094 default:
00095 Is_True(FALSE, ("Unexpected initv kind in TCON_For_Initv()"));
00096 break;
00097 }
00098 return tcon;
00099 }
00100
00101 static void
00102 INIT2C_Next_Initv(INITV_IDX *inv, INT *inv_repeat)
00103 {
00104
00105
00106 (*inv_repeat)--;
00107 if (*inv_repeat <= 0)
00108 {
00109 *inv = INITV_next(*inv);
00110 *inv_repeat = (*inv != 0) ? INITV_repeat(*inv) : 0;
00111 }
00112 }
00113
00114
00115 static void
00116 INITV2C_translate(TOKEN_BUFFER tokens,
00117 TY_IDX ty,
00118 INITV_IDX initv);
00119
00120
00121 static void
00122 INITV2C_symbol(TOKEN_BUFFER tokens,
00123 TY_IDX ty,
00124 INITV_IDX initv)
00125 {
00126
00127
00128
00129 TOKEN_BUFFER tmp_tokens;
00130 CONTEXT dummy_context;
00131 BOOL use_implicit_array_addressing, casted_address;
00132 ST_IDX initv_st = INITV_st(Initv_Table[initv]);
00133 TY_IDX sym_ty = (ST_class(initv_st) == CLASS_FUNC) ?
00134 ST_pu_type(initv_st) : ST_type(initv_st);
00135 TY2C_FLD_INFO fld_info;
00136 fld_info.select_tokens = NULL;
00137 fld_info.found_fld = FLD_HANDLE();
00138
00139 Is_True(TY_Is_Pointer_Or_Scalar(ty),
00140 ("Unexpected lhs type in INITV2C_symbol()"));
00141 Is_True(ST_sym_class(St_Table[initv_st]) != CLASS_PREG,
00142 ("Unexpected st class in INITV2C_symbol()"));
00143
00144
00145
00146
00147 use_implicit_array_addressing =
00148 (TY_Is_Pointer(ty) &&
00149 TY_Is_Array(sym_ty) &&
00150 Stab_Identical_Types(TY_pointed(ty),
00151 TY_AR_etype(sym_ty),
00152 FALSE,
00153 TRUE,
00154 FALSE));
00155
00156
00157
00158
00159 if (use_implicit_array_addressing)
00160 sym_ty = TY_AR_etype(sym_ty);
00161
00162
00163
00164
00165 casted_address = (!use_implicit_array_addressing &&
00166 (!TY_Is_Pointer(ty) ||
00167 !Stab_Identical_Types(TY_pointed(ty),
00168 sym_ty,
00169 FALSE,
00170 TRUE,
00171 FALSE)));
00172 if (casted_address)
00173 {
00174 tmp_tokens = New_Token_Buffer();
00175 TY2C_translate_unqualified(tmp_tokens, ty);
00176 WHIRL2C_parenthesize(tmp_tokens);
00177 Append_And_Reclaim_Token_List(tokens, &tmp_tokens);
00178 }
00179
00180
00181 tmp_tokens = New_Token_Buffer();
00182 CONTEXT_reset(dummy_context);
00183 if (INITV_ofst(Initv_Table[initv]) == 0)
00184 {
00185 if (ST_sym_class(St_Table[initv_st]) == CLASS_CONST)
00186 {
00187 TCON2C_translate(tmp_tokens, STC_val(&St_Table[initv_st]));
00188 }
00189 else
00190 {
00191 if (!use_implicit_array_addressing)
00192 Append_Token_Special(tmp_tokens, '&');
00193 ST2C_use_translate(tmp_tokens, &St_Table[initv_st], dummy_context);
00194 }
00195 }
00196 else if (INITV_ofst(Initv_Table[initv]) % TY_size(sym_ty) == 0)
00197 {
00198
00199 ST2C_use_translate(tmp_tokens, &St_Table[initv_st], dummy_context);
00200 Prepend_Token_Special(tmp_tokens, '&');
00201
00202 Append_Token_Special(tmp_tokens, '[');
00203 Append_Token_String(tmp_tokens,
00204 Number_as_String(INITV_ofst(Initv_Table[initv])/TY_size(sym_ty), "%lld"));
00205 Append_Token_Special(tmp_tokens, ']');
00206 }
00207 else
00208 {
00209
00210
00211
00212 ST2C_use_translate(tmp_tokens, &St_Table[initv_st], dummy_context);
00213 Prepend_Token_Special(tmp_tokens, '&');
00214
00215 if (TY_Is_Struct(sym_ty) && TY_Is_Pointer(ty))
00216 {
00217
00218 fld_info = TY2C_get_field_info(sym_ty,
00219 TY_pointed(ty),
00220 MTYPE_V,
00221 INITV_ofst(Initv_Table[initv]));
00222 if (!fld_info.found_fld.Is_Null ())
00223 {
00224 Append_Token_Special(tmp_tokens, '.');
00225 Append_And_Reclaim_Token_List(tmp_tokens, &fld_info.select_tokens);
00226 }
00227 }
00228
00229 if (fld_info.found_fld.Is_Null ())
00230 {
00231
00232 Prepend_Token_Special(tmp_tokens, ')');
00233 Prepend_Token_Special(tmp_tokens, '*');
00234 Prepend_Token_String(tmp_tokens, "char");
00235 Prepend_Token_Special(tmp_tokens, '(');
00236 Append_Token_Special(tmp_tokens, '+');
00237 Append_Token_String(tmp_tokens,
00238 Number_as_String(INITV_ofst(Initv_Table[initv]),
00239 "%lld"));
00240 WHIRL2C_parenthesize(tmp_tokens);
00241 if (!casted_address)
00242 {
00243 WHIRL2C_parenthesize(tmp_tokens);
00244 Prepend_Token_Special(tmp_tokens, ')');
00245 Prepend_Token_Special(tmp_tokens, '*');
00246 Prepend_Token_String(tmp_tokens, "void");
00247 Prepend_Token_Special(tmp_tokens, '(');
00248 }
00249 }
00250 }
00251 Append_And_Reclaim_Token_List(tokens, &tmp_tokens);
00252 }
00253
00254
00255 static void
00256 INITV2C_val(TOKEN_BUFFER tokens,
00257 TY_IDX ty,
00258 INITV_IDX initv)
00259 {
00260
00261
00262
00263
00264 TOKEN_BUFFER tmp_tokens;
00265 TCON tcon = TCON_For_Initv(initv);
00266
00267 Is_True(TY_Is_Pointer_Or_Scalar(ty) || TY_Is_Array_Of_Chars(ty),
00268 ("Unexpected lhs type in INITV2C_val()"));
00269
00270
00271
00272
00273
00274 if (TY_Is_Pointer(ty) && Targ_To_Host(tcon) != 0LL)
00275 {
00276 tmp_tokens = New_Token_Buffer();
00277 TY2C_translate_unqualified(tmp_tokens, ty);
00278 WHIRL2C_parenthesize(tmp_tokens);
00279 Append_And_Reclaim_Token_List(tokens, &tmp_tokens);
00280 }
00281
00282
00283 TCON2C_translate(tokens, tcon);
00284 }
00285
00286
00287 static void
00288 INITV2C_array_dimension(TOKEN_BUFFER tokens,
00289 TY_IDX etype,
00290 INITV_IDX next_initv,
00291 INT this_dim,
00292 INT num_dims)
00293 {
00294 INITV_IDX inv;
00295 INT repeat;
00296
00297
00298
00299
00300
00301
00302
00303 Append_Token_Special(tokens, '{');
00304 for (inv = next_initv; inv != 0; inv = INITV_next(inv))
00305 {
00306
00307 for (repeat = INITV_repeat(inv); repeat > 0; repeat--)
00308 {
00309 if (INITV_kind(Initv_Table[inv]) != INITVKIND_PAD)
00310 {
00311
00312 if (inv != next_initv || repeat < INITV_repeat(inv))
00313 Append_Token_Special(tokens, ',');
00314
00315 if (this_dim < num_dims &&
00316 INITV_kind(Initv_Table[inv]) == INITVKIND_BLOCK)
00317 INITV2C_array_dimension(tokens,
00318 etype,
00319 INITV_blk(inv),
00320 this_dim+1,
00321 num_dims);
00322 else
00323 INITV2C_translate(tokens, etype, inv);
00324 }
00325 }
00326 }
00327 Append_Token_Special(tokens, '}');
00328 }
00329
00330
00331 static void
00332 INITV2C_block_array(TOKEN_BUFFER tokens,
00333 TY_IDX ty,
00334 INITV_IDX initv)
00335 {
00336
00337
00338
00339 INITV_IDX first_inv = INITV_blk(initv);
00340 TY_IDX etype = TY_AR_etype(ty);
00341 INT ndims = TY_AR_ndims(ty);
00342
00343 if (!TY_Is_Array(etype) && !TY_Is_String(etype) &&
00344 INITV_kind(Initv_Table[first_inv]) == INITVKIND_VAL &&
00345 TCON_ty(INITV_tc_val(Initv_Table[first_inv])) == MTYPE_STRING)
00346 {
00347 Is_True((TY_size(ty) ==
00348 Targ_String_Length(INITV_tc_val(Initv_Table[first_inv]))) ||
00349 (INITV_next(first_inv) != 0 &&
00350 INITV_kind(Initv_Table[INITV_next(first_inv)]) == INITVKIND_PAD),
00351 ("Expected padding to follow incomplete string initializer"));
00352 INITV2C_translate(tokens, ty, first_inv);
00353 }
00354 else
00355 {
00356 if (first_inv != 0 &&
00357 INITV_kind(Initv_Table[first_inv]) == INITVKIND_PAD &&
00358 INITV_next(first_inv) == 0)
00359 {
00360
00361
00362
00363 Append_Token_Special(tokens, '{');
00364 Append_Token_String(tokens, "0L");
00365 Append_Token_Special(tokens, '}');
00366 }
00367 else
00368 {
00369 INITV2C_array_dimension(tokens, etype, first_inv, 1, ndims);
00370 }
00371 }
00372 }
00373
00374
00375 static void
00376 INITV2C_struct_fill(TOKEN_BUFFER tokens,
00377 INITV_IDX *current_inv,
00378 INT *inv_repeat,
00379 INT64 *current_offset,
00380 INT64 desired_offset)
00381 {
00382
00383
00384
00385
00386
00387
00388
00389 union Tcon_Bytes
00390 {
00391 struct
00392 {
00393 UINT32 u1;
00394 UINT32 u2;
00395 UINT32 u3;
00396 UINT32 u4;
00397 UINT32 u5;
00398 UINT32 u6;
00399 UINT32 u7;
00400 UINT32 u8;
00401 } val;
00402 mUINT8 byte[32];
00403 } tcon_bytes;
00404
00405 INT pad_byte;
00406 INT tcon_size;
00407 TCON tcon;
00408 BOOL do_paren = TRUE;
00409
00410 Is_True(*current_inv != 0 && *current_offset < desired_offset,
00411 ("Incorrect call to INITV2C_struct_fill()"));
00412
00413 if(*current_offset < desired_offset && *current_inv != 0 &&
00414 INITV_kind(Initv_Table[*current_inv]) == INITVKIND_PAD)
00415 do_paren = FALSE;
00416
00417 if(do_paren)
00418 Append_Token_Special(tokens, '{');
00419 while (*current_offset < desired_offset && *current_inv != 0)
00420 {
00421
00422 switch (INITV_kind(Initv_Table[*current_inv]))
00423 {
00424 case INITVKIND_UNK:
00425 Is_True(FALSE, ("Unknown initv kind in INITV2C_struct_fill()"));
00426 break;
00427
00428 case INITVKIND_SYMOFF:
00429 Is_True(FALSE, ("SYMOFF initv kind in INITV2C_struct_fill()"));
00430 break;
00431
00432 #ifdef TARG_IA64
00433 case INITVKIND_SYMIPLT:
00434 Is_True(FALSE, ("SYMIPLT initv kind in INITV2C_struct_fill()"));
00435 break;
00436 #endif
00437
00438 case INITVKIND_ZERO:
00439 case INITVKIND_ONE:
00440 case INITVKIND_VAL:
00441 do_paren = TRUE;
00442 tcon = TCON_For_Initv(*current_inv);
00443 tcon_size = TY_size(Stab_Mtype_To_Ty(TCON_ty(tcon)));
00444 if (tcon_size < sizeof(tcon.vals.uval.u0))
00445 {
00446
00447 tcon_bytes.val.u1 =
00448 (tcon.vals.uval.u0 <<
00449 8*(sizeof(tcon.vals.uval.u0) - tcon_size));
00450 }
00451 else
00452 {
00453
00454
00455
00456 tcon_bytes.val.u1 = tcon.vals.uval.u0;
00457 tcon_bytes.val.u2 = tcon.vals.uval.u1;
00458 tcon_bytes.val.u3 = tcon.vals.uval.u2;
00459 tcon_bytes.val.u4 = tcon.vals.uval.u3;
00460 tcon_bytes.val.u5 = tcon.cmplxval.ival.v0;
00461 tcon_bytes.val.u6 = tcon.cmplxval.ival.v1;
00462 tcon_bytes.val.u7 = tcon.cmplxval.ival.v2;
00463 tcon_bytes.val.u8 = tcon.cmplxval.ival.v3;
00464 }
00465
00466
00467 for (pad_byte = 0; pad_byte < tcon_size; pad_byte++)
00468 {
00469 #if 0 //this might be needed
00470 if (pad_byte > 0)
00471 Append_Token_Special(tokens, ',');
00472 Append_Token_String(tokens,
00473 Number_as_String(tcon_bytes.byte[pad_byte], "%llu"));
00474 #endif
00475 }
00476 *current_offset += tcon_size;
00477 break;
00478
00479 case INITVKIND_BLOCK:
00480 Is_True(FALSE, ("BLOCK initv kind in INITV2C_struct_fill()"));
00481 break;
00482
00483 case INITVKIND_PAD:
00484
00485 for (pad_byte = INITV_pad(Initv_Table[*current_inv]);
00486 pad_byte > 0;
00487 pad_byte--)
00488 {
00489 Append_Token_String(tokens, "0");
00490 if (pad_byte > 1)
00491 Append_Token_Special(tokens, ',');
00492 }
00493 *current_offset += INITV_pad(Initv_Table[*current_inv]);
00494 break;
00495
00496 default:
00497 Is_True(FALSE, ("Unexpected initv kind in INITV2C_struct_fill()"));
00498 break;
00499
00500 }
00501
00502 INIT2C_Next_Initv(current_inv, inv_repeat);
00503
00504
00505
00506
00507 if (*current_offset < desired_offset && *current_inv != 0)
00508 Append_Token_Special(tokens, ',');
00509
00510 }
00511 if(do_paren)
00512 Append_Token_Special(tokens, '}');
00513 }
00514
00515
00516 static void
00517 INITV2C_block_struct(TOKEN_BUFFER tokens,
00518 TY_IDX ty,
00519 INITV_IDX initv)
00520 {
00521
00522
00523
00524 INITV_IDX inv, first_inv = INITV_blk(initv);
00525 INT inv_repeat;
00526 INT64 local_offset;
00527 FLD_HANDLE fld;
00528 TY2C_FLD_INFO fld_info;
00529 BOOL a_field_is_initialized = FALSE;
00530 BOOL do_comma = TRUE;
00531
00532
00533
00534
00535 Append_Token_Special(tokens, '{');
00536 if (first_inv != 0 &&
00537 INITV_kind(Initv_Table[first_inv]) == INITVKIND_PAD &&
00538 INITV_next(first_inv) == 0)
00539 {
00540
00541
00542
00543 Append_Token_String(tokens, "0L");
00544 }
00545 else
00546 {
00547
00548
00549
00550
00551 local_offset = 0;
00552 inv = first_inv;
00553 inv_repeat = (inv != 0) ? INITV_repeat(inv) : 0;
00554 for (fld = TY_flist(Ty_Table[ty]);
00555 !fld.Is_Null () && inv != 0;
00556 fld = FLD_next(fld))
00557 {
00558 if (FLD_ofst(fld) >= local_offset)
00559 {
00560
00561
00562 fld_info = TY2C_get_field_info(ty,
00563 FLD_type(fld),
00564 MTYPE_V,
00565 FLD_ofst(fld));
00566 if (!fld_info.found_fld.Is_Null ())
00567 {
00568
00569
00570 Reclaim_Token_Buffer(&fld_info.select_tokens);
00571 if (FLD_ofst(fld) > local_offset)
00572 {
00573
00574
00575 if (a_field_is_initialized)
00576 Append_Token_Special(tokens, ',');
00577 else
00578 a_field_is_initialized = TRUE;
00579 if (INITV_kind(Initv_Table[inv]) == INITVKIND_PAD)
00580 do_comma = FALSE;
00581 INITV2C_struct_fill(tokens,
00582 &inv, &inv_repeat,
00583 &local_offset, FLD_ofst(fld));
00584 }
00585 if (inv != 0)
00586 {
00587
00588
00589 if (a_field_is_initialized)
00590 if(do_comma)
00591 Append_Token_Special(tokens, ',');
00592 else
00593 do_comma = TRUE;
00594 else
00595 a_field_is_initialized = TRUE;
00596
00597
00598
00599
00600 if (PU_src_lang(Get_Current_PU()) == PU_F77_LANG &&
00601 (INITV_kind(Initv_Table[inv]) == INITVKIND_ZERO ||
00602 INITV_kind(Initv_Table[inv]) == INITVKIND_ONE ||
00603 INITV_kind(Initv_Table[inv]) == INITVKIND_VAL))
00604 {
00605 INT fld_size = TY_size(Ty_Table[FLD_type(fld)]);
00606 TY_IDX inv_ty;
00607
00608 if (TY_Is_Array(FLD_type(fld)) ||
00609 TY_Is_Structured(FLD_type(fld)))
00610 {
00611 Append_Token_Special(tokens, '{');
00612 }
00613
00614 while (inv != 0 &&
00615 fld_size > 0 &&
00616 (INITV_kind(Initv_Table[inv]) == INITVKIND_ZERO ||
00617 INITV_kind(Initv_Table[inv]) == INITVKIND_ONE ||
00618 INITV_kind(Initv_Table[inv]) == INITVKIND_VAL))
00619 {
00620 inv_ty = Stab_Mtype_To_Ty(TCON_ty(TCON_For_Initv(inv)));
00621 INITV2C_translate(tokens, inv_ty, inv);
00622 fld_size -= TY_size(inv_ty);
00623 INIT2C_Next_Initv(&inv, &inv_repeat);
00624 if (fld_size > 0)
00625 Append_Token_Special(tokens, ',');
00626 }
00627 if (TY_Is_Array(FLD_type(fld)) ||
00628 TY_Is_Structured(FLD_type(fld)))
00629 {
00630 Append_Token_Special(tokens, '}');
00631 }
00632 }
00633 else
00634 {
00635 INITV2C_translate(tokens, FLD_type(fld), inv);
00636 INIT2C_Next_Initv(&inv, &inv_repeat);
00637 }
00638
00639 local_offset += TY_size(FLD_type(fld));
00640 }
00641 }
00642 }
00643 }
00644
00645
00646
00647
00648 if (local_offset < TY_size(ty) && inv != 0)
00649 {
00650 if (a_field_is_initialized)
00651 Append_Token_Special(tokens, ',');
00652 INITV2C_struct_fill(tokens,
00653 &inv, &inv_repeat,
00654 &local_offset, TY_size(ty));
00655 }
00656 }
00657 Append_Token_Special(tokens, '}');
00658 }
00659
00660
00661 static void
00662 INITV2C_block_union(TOKEN_BUFFER tokens,
00663 TY_IDX ty,
00664 INITV_IDX initv)
00665 {
00666
00667
00668
00669 INITV_IDX first_inv = INITV_blk(initv);
00670 INITV_IDX next_inv = INITV_next(first_inv);
00671
00672
00673
00674
00675 Is_True((next_inv == 0 ||
00676 (INITV_kind(Initv_Table[next_inv]) == INITVKIND_PAD &&
00677 INITV_next(next_inv) == 0)),
00678 ("Expected an initializer only for the first element of a union"));
00679
00680
00681 Append_Token_Special(tokens, '{');
00682 INITV2C_translate(tokens, FLD_type(TY_flist(Ty_Table[ty])),
00683 first_inv);
00684 Append_Token_Special(tokens, '}');
00685 }
00686
00687
00688 static void
00689 INITV2C_translate(TOKEN_BUFFER tokens,
00690 TY_IDX ty,
00691 INITV_IDX initv)
00692 {
00693 switch (INITV_kind(Initv_Table[initv]))
00694 {
00695 case INITVKIND_UNK:
00696 Is_True(FALSE, ("Unknown initv kind in INITV2C_translate()"));
00697 break;
00698
00699 case INITVKIND_SYMOFF:
00700 #ifdef TARG_IA64
00701 case INITVKIND_SYMIPLT:
00702 #endif
00703 INITV2C_symbol(tokens, ty, initv);
00704 break;
00705 case INITVKIND_ZERO:
00706 case INITVKIND_ONE:
00707 case INITVKIND_VAL:
00708
00709 INITV2C_val(tokens, ty, initv);
00710 break;
00711
00712 case INITVKIND_BLOCK:
00713
00714
00715
00716
00717 if (TY_Is_Array(ty))
00718 INITV2C_block_array(tokens, ty, initv);
00719 else if (TY_Is_Union(ty))
00720 INITV2C_block_union(tokens, ty, initv);
00721 else if (TY_Is_Struct(ty))
00722 INITV2C_block_struct(tokens, ty, initv);
00723 else
00724 Is_True(FALSE, ("Unexpected aggregate type in INITV2C_translate()"));
00725 break;
00726
00727 case INITVKIND_PAD:
00728
00729 break;
00730
00731 default:
00732 Is_True(FALSE, ("Unexpected initv kind in INITV2C_translate()"));
00733 break;
00734
00735 }
00736 }
00737
00738
00739 void
00740 INITO2C_translate(TOKEN_BUFFER tokens, INITO_IDX inito)
00741 {
00742
00743
00744
00745
00746
00747 if (Stab_Is_Common_Block(INITO_st(inito)) ||
00748 Stab_Is_Equivalence_Block(INITO_st(inito)))
00749 {
00750 Append_Token_Special(tokens, '{');
00751 INITV2C_translate(tokens, ST_type(INITO_st(inito)), INITO_val(inito));
00752 Append_Token_Special(tokens, '}');
00753 }
00754 else
00755 INITV2C_translate(tokens, ST_type(INITO_st(inito)), INITO_val(inito));
00756 }