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 #include "defs.h"
00051 #include "wn.h"
00052 #include "wn_util.h"
00053 #include "targ_const.h"
00054 #include "symtab_idx.h"
00055 #include "symtab.h"
00056 #include "symtab_access.h"
00057 #include "opcode.h"
00058 #include "strtab.h"
00059 #include "config_targ.h"
00060 #include "const.h"
00061 #include "dra_demangle.h"
00062 #include "dra_export.h"
00063 #include "dra_ec.h"
00064 #include "dra_internal.h"
00065
00066
00067
00068
00069
00070
00071
00072 TY_IDX DRA_EC_struct_ptr_ty = (TY_IDX) NULL;
00073
00074 #define OPC_UNKNOWN OPCODE_UNKNOWN
00075
00076 static OPCODE Ldid_Opcode [MTYPE_LAST + 1] = {
00077 OPC_UNKNOWN,
00078 OPC_UNKNOWN,
00079 OPC_I4I1LDID,
00080 OPC_I4I2LDID,
00081 OPC_I4I4LDID,
00082 OPC_I8I8LDID,
00083 OPC_U4U1LDID,
00084 OPC_U4U2LDID,
00085 OPC_U4U4LDID,
00086 OPC_U8U8LDID,
00087 OPC_F4F4LDID,
00088 OPC_F8F8LDID,
00089 OPC_UNKNOWN,
00090 OPC_UNKNOWN,
00091 OPC_UNKNOWN,
00092 OPC_FQFQLDID,
00093 OPC_UNKNOWN,
00094 OPC_C4C4LDID,
00095 OPC_C8C8LDID,
00096 OPC_CQCQLDID,
00097 OPC_UNKNOWN
00098 };
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 static WN* Gen_Malloc_Cart (WN* block,
00109 WN* insert_wn,
00110 INT32 size,
00111 ST* cart_st);
00112
00113 static void Gen_Free_Cart (WN* block,
00114 WN* prev_wn,
00115 WN* stid_wn,
00116 ST* cart_st);
00117
00118 static WN* Gen_Call_Array (WN* block,
00119 WN* prev_wn,
00120 WN* array_wn,
00121 ST* func_st,
00122 ST* retval_st);
00123
00124 static WN* Get_Array_Dim_Size (TY& array_ty,
00125 INT dim);
00126
00127 static ST* Create_Local_ST (char *name, TY_IDX ty);
00128
00129 static ST* Declare_Func_N_Arg (char* ty_name,
00130 char* st_name,
00131 TY_IDX ret_ty,
00132 INT nargs,
00133 TY_IDX ty_array[]);
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 static ST* ECHT_Check = NULL;
00144 static ST* ECHT_Compare = NULL;
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 void
00165 DRA_EC_Declare_Types ()
00166 {
00167
00168
00169
00170 TY_IDX I8_ty = Be_Type_Tbl(MTYPE_I8);
00171 TY_IDX index_array_ty_idx;
00172 TY& index_array_ty = New_TY (index_array_ty_idx);
00173
00174 ARB_HANDLE new_ari = New_ARB ();
00175 ARB_Init (new_ari, 1, 1, 1);
00176 Set_ARB_first_dimen(new_ari);
00177 Set_ARB_last_dimen(new_ari);
00178 Set_ARB_const_lbnd(new_ari);
00179 Set_ARB_lbnd_val(new_ari,0);
00180 Set_ARB_const_ubnd(new_ari);
00181 Set_ARB_ubnd_val(new_ari,9);
00182 Set_ARB_const_stride(new_ari);
00183 Set_ARB_stride_val(new_ari,TY_size(I8_ty));
00184
00185 TY_Init (index_array_ty, 10*TY_size(I8_ty), KIND_ARRAY, MTYPE_UNKNOWN, Save_Str("INDEX_ARRAY_TY"));
00186 Set_TY_arb(index_array_ty, new_ari);
00187 Set_TY_align (index_array_ty_idx, 8);
00188 index_array_ty.Set_etype(I8_ty);
00189
00190 FLD_HANDLE first_field = New_FLD ();
00191
00192 FLD_Init (first_field, Save_Str("array_base"), I8_ty, CART_array_base);
00193
00194 FLD_HANDLE field = New_FLD ();
00195 FLD_Init (field, Save_Str("ndims"), I8_ty, CART_ndims);
00196
00197 field = New_FLD ();
00198 FLD_Init (field, Save_Str("element_size"), I8_ty, CART_element_size);
00199
00200 field = New_FLD ();
00201 FLD_Init (field, Save_Str("index"), index_array_ty_idx, CART_index);
00202 Set_FLD_last_field(field);
00203
00204
00205 TY_IDX ec_struct_ty_idx;
00206 TY& ec_struct_ty = New_TY(ec_struct_ty_idx);
00207
00208 TY_Init (ec_struct_ty, 3*TY_size(I8_ty) + TY_size(index_array_ty), KIND_STRUCT, MTYPE_M, Save_Str("DRA_EC_STRUCT_TY"));
00209 Set_TY_fld(ec_struct_ty, first_field);
00210 Set_TY_align (ec_struct_ty_idx, 8);
00211
00212 DRA_EC_struct_ptr_ty = Make_Pointer_Type ( ec_struct_ty_idx, TRUE );
00213 Set_TY_ptr_as_array(Ty_Table[DRA_EC_struct_ptr_ty]);
00214
00215
00216 TY_IDX voidpty = Make_Pointer_Type (Be_Type_Tbl(MTYPE_V), TRUE);
00217 ECHT_Check = Declare_Func_N_Arg (".__dsm_echt_check",
00218 "__dsm_echt_check",
00219 voidpty,
00220 1,
00221 &voidpty);
00222
00223 TY_IDX string_ty = Make_Pointer_Type(Be_Type_Tbl(MTYPE_U1), TRUE);
00224 TY_IDX arg_ty[4] = {voidpty, voidpty, string_ty, string_ty};
00225 ECHT_Compare = Declare_Func_N_Arg (".__dsm_echt_compare",
00226 "__dsm_echt_compare",
00227 Be_Type_Tbl(MTYPE_V),
00228 4,
00229 arg_ty);
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 void
00244 DRA_EC_Array_Portion_Parms (WN* func_wn, WN* entry_wn)
00245 {
00246 Is_True (WN_opcode(func_wn) == OPC_FUNC_ENTRY &&
00247 (WN_opcode(entry_wn) == OPC_FUNC_ENTRY ||
00248 WN_opcode(entry_wn) == OPC_ALTENTRY),
00249 ("EC_Parms: expected a FUNC_ENTRY or ALTENTRY node\n"));
00250
00251
00252
00253 WN *block = WN_func_body(func_wn);
00254 WN *prev_wn = Get_Preamble_End(entry_wn);
00255 WN *insert_wn = WN_next(prev_wn);
00256
00257
00258
00259
00260 INT num_formals = (WN_opcode(entry_wn) == OPC_FUNC_ENTRY ?
00261 WN_num_formals(entry_wn) : WN_kid_count(entry_wn));
00262
00263 for (INT i = 0; i < num_formals; i++) {
00264
00265 ST& formal_st = St_Table[WN_st_idx(WN_formal(entry_wn, i))];
00266 TY_IDX array_ty = (TY_IDX) NULL;
00267 TY& formal_ty = Ty_Table[ST_type(formal_st)];
00268 Is_True (ST_sclass(formal_st) == SCLASS_FORMAL ||
00269 ST_sclass(formal_st) == SCLASS_FORMAL_REF,
00270 ("EC_Parms: IDNAME(%s) not a FORMAL\n", ST_name(formal_st)));
00271
00272 BOOL array_parm = FALSE;
00273 switch (ST_sclass(formal_st)) {
00274 case SCLASS_FORMAL:
00275 if (TY_kind(formal_ty) == KIND_POINTER &&
00276 TY_kind(TY_pointed(formal_ty)) == KIND_ARRAY) {
00277 array_ty = TY_pointed(formal_ty);
00278 array_parm = TRUE;
00279 }
00280 break;
00281 case SCLASS_FORMAL_REF:
00282 if (TY_kind(formal_ty) == KIND_ARRAY) {
00283 array_ty = ST_type(formal_st);
00284 array_parm = TRUE;
00285 }
00286 break;
00287 }
00288 if (!array_parm) continue;
00289
00290
00291
00292
00293
00294
00295
00296 char name[64];
00297 (void) strcpy(name, "$cart_formal_");
00298 (void) strncat(name, ST_name(WN_st(entry_wn)), 20);
00299 (void) strncat(name, ST_name(formal_st), 20);
00300 ST *cart_st = Create_Local_ST(name, DRA_EC_struct_ptr_ty);
00301
00302
00303
00304 WN *array_ldid = WN_Ldid(Pointer_type, (WN_OFFSET)0, &formal_st, ST_type(formal_st));
00305
00306 WN* stid_wn =
00307 Gen_Call_Array (block, prev_wn, array_ldid, ECHT_Check, cart_st);
00308 prev_wn = stid_wn;
00309
00310 WN* cart_ldid_wn = WN_Ldid (Pointer_type, 0, cart_st, ST_type(cart_st));
00311 WN* if_wn = WN_CreateIf(cart_ldid_wn, WN_CreateBlock(), WN_CreateBlock());
00312 WN_INSERT_BlockAfter (block, prev_wn, if_wn);
00313 WN_Set_Linenum (if_wn, WN_Get_Linenum(prev_wn));
00314 prev_wn = if_wn;
00315
00316
00317 array_ldid = WN_COPY_Tree(array_ldid);
00318 cart_ldid_wn = WN_COPY_Tree(cart_ldid_wn);
00319 WN *istore_wn =
00320 WN_CreateIstore (OPCODE_make_op (OPR_ISTORE, MTYPE_V, Pointer_type),
00321 CART_array_base,
00322 Make_Pointer_Type(Be_Type_Tbl(Pointer_type), TRUE),
00323 array_ldid,
00324 cart_ldid_wn);
00325 WN_Set_Linenum (istore_wn, WN_Get_Linenum(insert_wn));
00326 WN_INSERT_BlockBefore (WN_then(if_wn), NULL, istore_wn);
00327 insert_wn = WN_first(WN_then(if_wn));
00328 prev_wn = insert_wn;
00329
00330
00331 INT ndims = TY_AR_ndims(Ty_Table[array_ty]);
00332 WN* cart_stid_wn =
00333 Gen_Malloc_Cart (WN_then(if_wn), insert_wn, 8*(ndims+3), cart_st);
00334
00335
00336 OPCODE istore_op = OPCODE_make_op(OPR_ISTORE, MTYPE_V, MTYPE_I8);
00337 TY_IDX I8ptr_ty = Make_Pointer_Type(Be_Type_Tbl(MTYPE_I8), TRUE);
00338
00339
00340 cart_ldid_wn = WN_COPY_Tree(cart_ldid_wn);
00341 istore_wn = WN_CreateIstore (istore_op,
00342 CART_ndims,
00343 I8ptr_ty,
00344 WN_Intconst(MTYPE_I8, ndims),
00345 cart_ldid_wn);
00346 WN_Set_Linenum(istore_wn, WN_Get_Linenum(insert_wn));
00347 WN_INSERT_BlockAfter (WN_then(if_wn), prev_wn, istore_wn);
00348 prev_wn = istore_wn;
00349
00350
00351 cart_ldid_wn = WN_COPY_Tree(cart_ldid_wn);
00352 istore_wn = WN_CreateIstore(istore_op,
00353 CART_element_size,
00354 I8ptr_ty,
00355 WN_Intconst(MTYPE_I8,
00356 TY_size(TY_AR_etype(array_ty))),
00357 cart_ldid_wn);
00358 WN_Set_Linenum(istore_wn, WN_Get_Linenum(insert_wn));
00359 WN_INSERT_BlockAfter (WN_then(if_wn), prev_wn, istore_wn);
00360 prev_wn = istore_wn;
00361
00362 for (INT j=0; j<ndims; j++) {
00363
00364 WN* size_wn = Get_Array_Dim_Size (Ty_Table[array_ty], j);
00365 cart_ldid_wn = WN_COPY_Tree(cart_ldid_wn);
00366 istore_wn = WN_CreateIstore (istore_op,
00367 CART_index+8*j,
00368 I8ptr_ty,
00369 size_wn,
00370 cart_ldid_wn);
00371 WN_Set_Linenum(istore_wn, WN_Get_Linenum(insert_wn));
00372 WN_INSERT_BlockAfter (WN_then(if_wn), prev_wn, istore_wn);
00373 prev_wn = istore_wn;
00374 }
00375
00376
00377 {
00378 array_ldid = WN_COPY_Tree(array_ldid);
00379 cart_ldid_wn = WN_COPY_Tree(cart_ldid_wn);
00380
00381 WN* call_wn = WN_Create(OPCODE_make_op(OPR_CALL, MTYPE_V, MTYPE_V), 4);
00382
00383
00384 WN* parm_wn = WN_CreateParm (Pointer_type,
00385 array_ldid,
00386 Be_Type_Tbl(Pointer_type),
00387 WN_PARM_BY_VALUE);
00388 WN_kid(call_wn, 0) = parm_wn;
00389
00390
00391 parm_wn = WN_CreateParm (Pointer_type,
00392 cart_ldid_wn,
00393 Be_Type_Tbl(Pointer_type),
00394 WN_PARM_BY_VALUE);
00395 WN_kid(call_wn, 1) = parm_wn;
00396
00397
00398 OPCODE lda_op = OPCODE_make_op (OPR_LDA, Pointer_type, MTYPE_V);
00399 TY_IDX string_ty = Make_Pointer_Type(Be_Type_Tbl(MTYPE_U1), TRUE);
00400
00401 char *func_name = DRA_Demangle_Func(ST_name(WN_st(entry_wn)));
00402 if (func_name == NULL) {
00403 func_name = ST_name(WN_st(entry_wn));
00404 }
00405 TCON tcon =
00406 Host_To_Targ_String (MTYPE_STRING, func_name, strlen(func_name)+1);
00407 ST *rt_func_name =
00408 Gen_String_Sym (&tcon, Be_Type_Tbl(MTYPE_STRING), FALSE);
00409 WN *func_name_wn = WN_CreateLda (lda_op, 0, string_ty, rt_func_name);
00410 parm_wn = WN_CreateParm (Pointer_type,
00411 func_name_wn,
00412 Be_Type_Tbl(Pointer_type),
00413 WN_PARM_BY_REFERENCE);
00414 WN_kid(call_wn, 2) = parm_wn;
00415
00416
00417 char* array_name = ST_name(formal_st);
00418 tcon =
00419 Host_To_Targ_String (MTYPE_STRING, array_name, strlen(array_name)+1);
00420 ST *rt_array_name =
00421 Gen_String_Sym (&tcon, Be_Type_Tbl(MTYPE_STRING), FALSE);
00422 WN *array_name_wn = WN_CreateLda (lda_op, 0, string_ty, rt_array_name);
00423 parm_wn = WN_CreateParm (Pointer_type,
00424 array_name_wn,
00425 Be_Type_Tbl(Pointer_type),
00426 WN_PARM_BY_REFERENCE);
00427 WN_kid(call_wn, 3) = parm_wn;
00428
00429 WN_st_idx(call_wn) = ST_st_idx(ECHT_Compare);
00430 WN_INSERT_BlockAfter (WN_then(if_wn), prev_wn, call_wn);
00431 prev_wn = call_wn;
00432 }
00433
00434 Gen_Free_Cart (WN_then(if_wn), prev_wn, cart_stid_wn, cart_st);
00435 prev_wn = if_wn;
00436 }
00437 }
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 static WN*
00451 Get_Array_Dim_Size (TY& array_ty, INT dim)
00452 {
00453 INT ndims = TY_AR_ndims(array_ty);
00454
00455 if ((!TY_AR_const_lbnd(array_ty, dim)) &&
00456 (TY_AR_lbnd_val(array_ty, dim) == 0))
00457 return WN_Intconst (MTYPE_I8, -1);
00458 if ((!TY_AR_const_ubnd(array_ty, dim)) &&
00459 (TY_AR_ubnd_val(array_ty, dim) == 0))
00460 return WN_Intconst (MTYPE_I8, -1);
00461
00462 WN* lb;
00463 if (TY_AR_const_lbnd(array_ty, dim)) {
00464 lb = WN_Intconst(MTYPE_I8, TY_AR_lbnd_val(array_ty, dim));
00465 }
00466 else {
00467 ST_IDX lbnd_st_idx = TY_AR_lbnd_var(array_ty,dim);
00468 ST& lbnd_st = St_Table [lbnd_st_idx];
00469 TY_IDX lbnd_ty_idx = ST_type (lbnd_st);
00470
00471 TYPE_ID lty_mtype = TY_mtype (Ty_Table [lbnd_ty_idx]);
00472 lb = WN_CreateLdid (Ldid_Opcode [lty_mtype],
00473 (WN_OFFSET)0, &lbnd_st, lbnd_ty_idx);
00474 }
00475
00476 WN* ub;
00477 if (TY_AR_const_ubnd(array_ty, dim)) {
00478 ub = WN_Intconst(MTYPE_I8, TY_AR_ubnd_val(array_ty, dim));
00479 }
00480 else {
00481 ST_IDX ubnd_st_idx = TY_AR_ubnd_var(array_ty,dim);
00482 ST& ubnd_st = St_Table [ubnd_st_idx];
00483 TY_IDX ubnd_ty_idx = ST_type (ubnd_st);
00484
00485 TYPE_ID lty_mtype = TY_mtype (Ty_Table [ubnd_ty_idx]);
00486 ub = WN_CreateLdid (Ldid_Opcode [lty_mtype],
00487 (WN_OFFSET)0, &ubnd_st, ubnd_ty_idx);
00488 }
00489
00490 WN* size_wn = WN_Add (MTYPE_I8,
00491 WN_Sub (MTYPE_I8, ub, lb),
00492 WN_Intconst (MTYPE_I8, 1));
00493 return size_wn;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 static WN*
00510 Gen_Malloc_Cart (WN* block, WN* insert_wn, INT32 size, ST* cart_st)
00511 {
00512 OPCODE icallop = OPCODE_make_op(OPR_INTRINSIC_CALL, Pointer_type, MTYPE_V);
00513 WN* call_wn = WN_Create(icallop, 1);
00514 WN_intrinsic(call_wn) =
00515 Pointer_Size == 8 ? INTRN_U8I8MALLOC : INTRN_U4I4MALLOC;
00516 WN_Set_Linenum (call_wn, WN_Get_Linenum(insert_wn));
00517 WN* size_wn = WN_Intconst (Pointer_Size == 8 ? MTYPE_I8 : MTYPE_I4, size);
00518 WN* parm_wn = WN_CreateParm(MTYPE_U8, size_wn,
00519 Be_Type_Tbl(MTYPE_U8), WN_PARM_BY_VALUE);
00520 WN_kid0(call_wn) = parm_wn;
00521
00522 WN_INSERT_BlockBefore (block, insert_wn, call_wn);
00523 PREG_NUM rreg1, rreg2;
00524 ST* rst = Find_Return_Registers(Pointer_type, &rreg1, &rreg2);
00525 FmtAssert(rreg1 != 0 && rreg2 == 0, ("Bad pointer type ret regs"));
00526
00527 WN *ldid_wn = WN_CreateLdid (OPCODE_make_op(OPR_LDID,
00528 Pointer_type,
00529 Pointer_type),
00530 rreg1,
00531 rst,
00532 DRA_EC_struct_ptr_ty);
00533
00534 OPCODE op = OPCODE_make_op(OPR_STID, MTYPE_V, Pointer_type);
00535 WN *stid_wn = WN_CreateStid(op, 0, cart_st, ST_type(cart_st), ldid_wn);
00536
00537 WN_Set_Linenum (stid_wn, WN_Get_Linenum(insert_wn));
00538 WN_INSERT_BlockBefore (block, insert_wn, stid_wn);
00539
00540 return stid_wn;
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 static void
00556 Gen_Free_Cart (WN* block, WN* prev_wn, WN* stid_wn, ST *cart_st)
00557 {
00558 OPCODE icallop = OPCODE_make_op(OPR_INTRINSIC_CALL, MTYPE_V, MTYPE_V);
00559 WN* call_wn = WN_Create(icallop, 1);
00560 WN_intrinsic(call_wn) = Pointer_Size == 8 ? INTRN_U8FREE : INTRN_U4FREE;
00561
00562 WN* ldid_wn = WN_Ldid (Pointer_type, 0, cart_st, ST_type(cart_st));
00563 WN* parm_wn = WN_CreateParm(Pointer_type,
00564 ldid_wn,
00565 Be_Type_Tbl(Pointer_type),
00566 WN_PARM_BY_REFERENCE);
00567 WN_kid0(call_wn) = parm_wn;
00568
00569 WN_Set_Linenum (call_wn, WN_Get_Linenum(prev_wn));
00570 WN_INSERT_BlockAfter (block, prev_wn, call_wn);
00571 }
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588 static WN*
00589 Gen_Call_Array (WN* block,
00590 WN* prev_wn,
00591 WN* array_wn,
00592 ST* func_st,
00593 ST* retval_st)
00594 {
00595 WN* call_wn = WN_Create(OPCODE_make_op(OPR_CALL, Pointer_type, MTYPE_V), 1);
00596 WN* parm_wn = WN_CreateParm (Pointer_type,
00597 array_wn,
00598 Be_Type_Tbl(Pointer_type),
00599 WN_PARM_BY_VALUE);
00600 WN_kid(call_wn, 0) = parm_wn;
00601 WN_st_idx(call_wn) = ST_st_idx(func_st);
00602
00603 WN_INSERT_BlockAfter (block, prev_wn, call_wn);
00604 prev_wn = call_wn;
00605
00606
00607
00608 PREG_NUM rreg1, rreg2;
00609 ST* rst = Find_Return_Registers(Pointer_type, &rreg1, &rreg2);
00610 FmtAssert(rreg1 != 0 && rreg2 == 0, ("Bad pointer type ret regs"));
00611
00612 WN *ldid_wn = WN_CreateLdid (OPCODE_make_op(OPR_LDID,
00613 Pointer_type,
00614 Pointer_type),
00615 rreg1,
00616 rst,
00617 DRA_EC_struct_ptr_ty);
00618
00619 OPCODE op = OPCODE_make_op(OPR_STID, MTYPE_V, Pointer_type);
00620 WN *stid_wn = WN_CreateStid(op, 0, retval_st, ST_type(retval_st), ldid_wn);
00621
00622 WN_Set_Linenum (stid_wn, WN_Get_Linenum(prev_wn));
00623 WN_INSERT_BlockAfter (block, prev_wn, stid_wn);
00624
00625 return stid_wn;
00626 }
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636 static ST*
00637 Create_Local_ST(char *name, TY_IDX ty)
00638 {
00639 ST *st = New_ST(CURRENT_SYMTAB);
00640 Set_ST_is_temp_var(st);
00641 ST_Init(st, Save_Str(name), CLASS_VAR, SCLASS_AUTO, EXPORT_LOCAL, ty);
00642
00643
00644
00645 return st;
00646 }
00647
00648
00649
00650
00651
00652
00653
00654
00655 static ST*
00656 Declare_Func_N_Arg (char* ty_name,
00657 char* st_name,
00658 TY_IDX ret_ty,
00659 INT nargs,
00660 TY_IDX ty_array[])
00661 {
00662
00663
00664 TY_IDX voidpty = Make_Pointer_Type (Be_Type_Tbl(MTYPE_V), TRUE);
00665
00666 TY_IDX func_ty;
00667 TY& ty = New_TY(func_ty);
00668 PU_IDX pu_idx;
00669 PU& pu = New_PU (pu_idx);
00670
00671 TYLIST_IDX idx = Tylist_Table.Insert(ret_ty);
00672 for (INT i = 0; i < nargs; i++) {
00673 Tylist_Table.Insert(ty_array[i]);
00674 }
00675 Tylist_Table.Insert(0);
00676 TY_Init (ty, 0, KIND_FUNCTION, MTYPE_UNKNOWN, Save_Str(ty_name));
00677 Set_TY_tylist (ty, idx);
00678
00679 Set_TY_align (func_ty, TY_align(voidpty));
00680 PU_Init (pu, func_ty, GLOBAL_SYMTAB + 1);
00681
00682
00683
00684 ST *func_st = New_ST ( GLOBAL_SYMTAB );
00685 ST_Init(func_st, Save_Str(st_name), CLASS_FUNC, SCLASS_EXTERN, EXPORT_PREEMPTIBLE, (TY_IDX) pu_idx);
00686
00687 return func_st;
00688 }