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