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
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 static const char *source_file = __FILE__;
00069
00070 #ifdef _KEEP_RCS_ID
00071 static char *rcs_id = "$Source: crayf90/sgi/SCCS/s.cwh_intrin.cxx $ $Revision: 1.9 $";
00072 #endif
00073
00074
00075
00076 #include "defs.h"
00077 #include "glob.h"
00078 #include "stab.h"
00079 #include "strtab.h"
00080 #include "erfe90.h"
00081 #include "errors.h"
00082 #include "config_targ.h"
00083 #include "wn.h"
00084 #include "wn_util.h"
00085 #include "const.h"
00086 #include "wintrinsic.h"
00087 #include "f90_utils.h"
00088
00089
00090
00091 #include "i_cvrt.h"
00092
00093
00094
00095 #include "cwh_defines.h"
00096 #include "cwh_addr.h"
00097 #include "cwh_block.h"
00098 #include "cwh_stk.h"
00099 #include "cwh_types.h"
00100 #include "cwh_expr.h"
00101 #include "cwh_stmt.h"
00102 #include "cwh_preg.h"
00103 #include "cwh_stab.h"
00104 #include "cwh_intrin.h"
00105 #include "cwh_intrin.i"
00106
00107
00108
00109
00110
00111 static ST *ranget_st = NULL;
00112 static ST *ranset_st = NULL;
00113 static ST *rtc_st = NULL;
00114 static ST *unit_st = NULL;
00115 static ST *length_st = NULL;
00116 static ST *getpos_st = NULL;
00117 static ST *omp_set_lock_st=NULL;
00118 static ST *omp_unset_lock_st=NULL;
00119 static ST *omp_test_lock_st=NULL;
00120 #ifdef KEY
00121 static ST *erf_st = NULL;
00122 static ST *erfc_st = NULL;
00123 static ST *derf_st = NULL;
00124 static ST *derfc_st = NULL;
00125 #endif
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136 static WN *
00137 cwh_intrin_get_return_value(TYPE_ID rtype, const char *name )
00138 {
00139 PREG_NUM rpreg;
00140 PREG_det rpreg_det;
00141 WN *wn;
00142
00143 rpreg_det = cwh_preg_next_preg (rtype,name,NULL);
00144 rpreg = rpreg_det.preg;
00145 wn = cwh_expr_operand(NULL);
00146 wn = WN_StidPreg(rtype,rpreg,wn);
00147 cwh_block_append(wn);
00148 wn = WN_LdidPreg(rtype,rpreg);
00149 return (wn);
00150 }
00151
00152
00153
00154 static t_enum t_from_mtype(TYPE_ID ty)
00155 {
00156 t_enum t;
00157 t = t_BAD;
00158 switch (ty) {
00159 case MTYPE_I1: t = t_I1; break;
00160 case MTYPE_I2: t = t_I2; break;
00161 case MTYPE_I4: t = t_I4; break;
00162 case MTYPE_I8: t = t_I8; break;
00163 case MTYPE_F4: t = t_F4; break;
00164 case MTYPE_F8: t = t_F8; break;
00165 case MTYPE_FQ: t = t_FQ; break;
00166 case MTYPE_C4: t = t_C4; break;
00167 case MTYPE_C8: t = t_C8; break;
00168 case MTYPE_CQ: t = t_CQ; break;
00169 default: Fail_FmtAssertion(("Bad MTYPE %d seen in t_from_mtype"),ty);
00170 }
00171 return (t);
00172 }
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 static WN *
00185 cwh_intrin_null_parm(void)
00186 {
00187 WN *wn;
00188
00189 wn = WN_CreateParm(MTYPE_V,WN_Zerocon(MTYPE_I4),Be_Type_Tbl(MTYPE_V),0);
00190 return (wn);
00191 }
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 extern
00203 ST * cwh_intrin_make_intrinsic_symbol(const char *name, TYPE_ID bt)
00204 {
00205 ST *st;
00206 st = cwh_stab_mk_fn_0args(name, EXPORT_PREEMPTIBLE, GLOBAL_SYMTAB + 1,
00207 Be_Type_Tbl(bt));
00208 return (st);
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219 extern WN *
00220 cwh_intrin_wrap_value_parm(WN *w)
00221 {
00222 TYPE_ID t;
00223 WN *r;
00224 TY_IDX ty;
00225
00226 if (WNOPR(w) == OPR_PARM) {
00227 return (w);
00228 }
00229
00230 t = WN_rtype(w);
00231 if (t == MTYPE_M) {
00232
00233
00234
00235 ty = cwh_types_WN_TY(w,FALSE);
00236 } else {
00237 ty = Be_Type_Tbl(t);
00238 }
00239
00240 r = WN_CreateParm(t,w,ty,WN_PARM_BY_VALUE);
00241 return (r);
00242 }
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 extern WN *
00259 cwh_intrin_wrap_ref_parm(WN *wa, TY_IDX ty)
00260 {
00261 WN * wn ;
00262
00263
00264 if (ty == 0)
00265 ty = cwh_types_WN_TY(wa,TRUE);
00266
00267 wn = WN_CreateParm (Pointer_Mtype,
00268 wa,
00269 ty,
00270 WN_PARM_BY_REFERENCE);
00271
00272 return(wn);
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 extern WN *
00288 cwh_intrin_wrap_char_parm(WN *wa, WN *sz )
00289 {
00290 WN * wn ;
00291 TY_IDX ty ;
00292
00293
00294 DevAssert((sz != NULL),("Bad PARM TY"));
00295 ty = cwh_types_ch_parm_TY(sz);
00296
00297 wn = cwh_intrin_wrap_ref_parm(wa,ty);
00298
00299 return(wn);
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315 static void
00316 simple_intrinsic(i_enum intrin, TYPE_ID bt, INT numargs, INT numpop)
00317 {
00318 OPCODE opc ;
00319 INTRINSIC intr;
00320 WN *k[3];
00321 #ifdef KEY
00322 WN *wn = 0;
00323 #else
00324 WN *wn ;
00325 #endif
00326 INT i;
00327 TYPE_ID t;
00328 WN *ae=NULL;
00329
00330 DevAssert((numargs <= 3),("Can't handle that many arguments"));
00331
00332 intr = GET_ITAB_IOP(intrin,bt);
00333 opc = GET_ITAB_WOP(intrin,bt);
00334
00335 DevAssert((opc || intr),("Unsupported intr/ty combo"));
00336
00337
00338
00339 for (i = 0; i < numpop; i++) {
00340 WN_DELETE_Tree(cwh_expr_operand(NULL));
00341 }
00342
00343 for (i = numargs-1; i >= 0; i--)
00344 k[i] = cwh_expr_operand(&ae);
00345
00346
00347 t = WN_rtype(k[0]);
00348 for (i = 1; i < numargs; i++) {
00349 if (WNRTY(k[i]) != t) {
00350 k[i] = cwh_convert_to_ty(k[i],t);
00351
00352 if (intr)
00353 k[i] = WN_CreateParm(t,k[i],Be_Type_Tbl(t),WN_PARM_BY_VALUE);
00354 }
00355 }
00356
00357 if (intr)
00358 wn = cwh_intrin_build(k,intr,bt,numargs);
00359
00360 else {
00361 switch (numargs) {
00362 case 1:
00363 wn = WN_CreateExp1(opc,k[0]);
00364 break;
00365 case 2:
00366 wn = WN_CreateExp2(opc,k[0],k[1]);
00367 break;
00368 case 3:
00369 wn = WN_CreateExp3(opc,k[0],k[1],k[2]);
00370 break;
00371 }
00372 }
00373
00374 wn = cwh_expr_restore_arrayexp(wn,ae);
00375 cwh_stk_push(wn,WN_item);
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 static void
00393 simple_intrinsic_nt(i_enum intrin, INT numargs, INT numpop)
00394 {
00395 OPCODE opc ;
00396 INTRINSIC intr;
00397 WN *k[3];
00398 WN *wn ;
00399 INT i;
00400 TYPE_ID bt;
00401 WN *ae=NULL;
00402
00403 DevAssert((numargs <=3),("Can't handle that many arguments"));
00404
00405 for (i = 0; i < numpop; i++) {
00406 WN_DELETE_Tree(cwh_expr_operand(NULL));
00407 }
00408
00409 for (i = numargs-1; i >= 0; i--) {
00410 k[i] = cwh_expr_operand(&ae);
00411 }
00412
00413 bt = WN_rtype(k[0]);
00414
00415 intr = GET_ITAB_IOP(intrin,bt);
00416 opc = GET_ITAB_WOP(intrin,bt);
00417
00418 DevAssert((opc || intr),("Unsupported intr/ty combo"));
00419
00420 if (intr)
00421 wn = cwh_intrin_build(k,intr,bt,numargs);
00422
00423 else {
00424 switch (numargs) {
00425 case 1:
00426 wn = WN_CreateExp1(opc,k[0]);
00427 break;
00428 case 2:
00429 wn = WN_CreateExp2(opc,k[0],k[1]);
00430 break;
00431 case 3:
00432 wn = WN_CreateExp3(opc,k[0],k[1],k[2]);
00433 break;
00434 }
00435 }
00436
00437 wn = cwh_expr_restore_arrayexp(wn,ae);
00438 cwh_stk_push(wn,WN_item);
00439 }
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453 #define do_simple(name,numargs,numpop) void fei_##name(TYPE type) \
00454 {simple_intrinsic(i_##name,TY_mtype(cast_to_TY(t_TY(type))),numargs,numpop);}
00455
00456 #define do_simple_nt(name,numargs,numpop) void fei_##name(void) \
00457 {simple_intrinsic_nt(i_##name,numargs,numpop);}
00458
00459 do_simple(acos,1,0)
00460 do_simple(asin,1,0)
00461 do_simple(atan,1,0)
00462 do_simple(atan2,2,0)
00463 do_simple(conjg,1,0)
00464 do_simple(cos,1,0)
00465 do_simple(cosh,1,0)
00466 do_simple(exp,1,0)
00467 do_simple_nt(fraction,1,0)
00468 do_simple(ishftc,3,0)
00469 do_simple(log,1,0)
00470 do_simple(log10,1,0)
00471 do_simple(mod,2,0)
00472 do_simple(modulo,2,0)
00473 do_simple(nextafter,2,0)
00474 do_simple(rrspace,1,1)
00475 #ifdef KEY
00476 do_simple(sign_xfer,2,0)
00477 #endif
00478 do_simple(sin,1,0)
00479 do_simple(sinh,1,0)
00480 do_simple(space,1,1)
00481 do_simple(sqrt,1,0)
00482 do_simple(tan,1,0)
00483 do_simple(tanh,1,0)
00484
00485 do_simple(acosd,1,0)
00486 do_simple(asind,1,0)
00487 do_simple(atand,1,0)
00488 do_simple(atan2d,2,0)
00489 do_simple(cosd,1,0)
00490 do_simple(sind,1,0)
00491 do_simple(tand,1,0)
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512 void
00513 fei_complex(TYPE type)
00514 {
00515 TYPE_ID br ;
00516 #ifdef KEY
00517 TYPE_ID bt = 0;
00518 #else
00519 TYPE_ID bt ;
00520 #endif
00521 WN *k[2] ;
00522 WN * wn ;
00523 INT i ;
00524 WN *ae=NULL;
00525
00526 OPCODE opc ;
00527
00528 k[1] = cwh_expr_operand(&ae);
00529 k[0] = cwh_expr_operand(&ae);
00530 br = TY_mtype(cast_to_TY(t_TY(type))) ;
00531 opc = GET_ITAB_WOP(i_complex,br);
00532
00533 for (i = 0 ; i < 2 ; i ++ ) {
00534
00535 switch (br) {
00536 case MTYPE_C4: bt = MTYPE_F4; break;
00537 case MTYPE_C8: bt = MTYPE_F8; break;
00538 case MTYPE_CQ: bt = MTYPE_FQ; break;
00539 }
00540
00541 k[i] = cwh_convert_to_ty(k[i],bt);
00542 }
00543
00544 wn = WN_CreateExp2(opc,k[0],k[1]);
00545 wn = cwh_expr_restore_arrayexp(wn,ae);
00546 cwh_stk_push(wn,WN_item);
00547 }
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562 void
00563 fei_abs(TYPE type)
00564 {
00565 TYPE_ID ba ;
00566 TYPE_ID br ;
00567 TY_IDX ty ;
00568 WN *wn ;
00569 WN *ae=NULL;
00570
00571 #ifdef KEY
00572 INTRINSIC intr = INTRN_I4EXPEXPR;
00573 #else
00574 INTRINSIC intr;
00575 #endif
00576
00577 wn = cwh_expr_operand(&ae);
00578 ty = cwh_types_WN_TY(wn,FALSE);
00579 ty = cwh_types_scalar_TY(ty);
00580 ba = TY_mtype(ty);
00581 br = TY_mtype(cast_to_TY(t_TY(type))) ;
00582
00583 if (MTYPE_is_complex(ba)) {
00584 switch(ba) {
00585 case MTYPE_C4: intr = INTRN_F4C4ABS ; break;
00586 case MTYPE_C8: intr = INTRN_F8C8ABS ; break;
00587 case MTYPE_CQ: intr = INTRN_FQCQABS ; break;
00588
00589 }
00590 wn = cwh_intrin_build(&wn,intr,br,1);
00591 wn = cwh_expr_restore_arrayexp(wn,ae);
00592 cwh_stk_push(wn,WN_item);
00593
00594 } else {
00595 wn = cwh_wrap_cvtl(wn,br);
00596 wn = cwh_expr_restore_arrayexp(wn,ae);
00597 cwh_stk_push(wn,WN_item);
00598 simple_intrinsic(i_abs,br,1,0);
00599 }
00600 }
00601
00602
00603
00604
00605
00606 void
00607 fei_cot(TYPE type)
00608 {
00609 WN *one, *wn;
00610
00611 fei_tan(type);
00612 wn = cwh_expr_operand(NULL);
00613 one = WN_Intconst(MTYPE_I4,1);
00614 cwh_stk_push(one,WN_item);
00615 cwh_stk_push(wn,WN_item);
00616 fei_div(type);
00617 }
00618
00619 void
00620 fei_exponentiate(TYPE type)
00621 {
00622
00623 TYPE_ID bt, rt;
00624 TYPE_ID et;
00625 #ifdef KEY
00626 INTRINSIC intr = INTRN_I4EXPEXPR;
00627 #else
00628 INTRINSIC intr;
00629 #endif
00630 WN *k[2];
00631 WN *wn ;
00632 WN *base, *exp;
00633 WN *ae=NULL;
00634
00635
00636 bt = TY_mtype(cast_to_TY(t_TY(type))) ;
00637 exp = cwh_expr_operand(&ae);
00638 base = cwh_get_typed_operand(bt,&ae);
00639
00640 et = WN_rtype(exp);
00641
00642 if (et == MTYPE_I4) {
00643 switch (bt) {
00644 case MTYPE_I1:
00645 case MTYPE_I2:
00646 case MTYPE_I4:
00647 intr = INTRN_I4EXPEXPR; break;
00648 case MTYPE_I8: intr = INTRN_I8EXPEXPR; break;
00649 case MTYPE_F4: intr = INTRN_F4I4EXPEXPR; break;
00650 case MTYPE_F8: intr = INTRN_F8I4EXPEXPR; break;
00651 case MTYPE_FQ: intr = INTRN_FQI4EXPEXPR; break;
00652 case MTYPE_C4: intr = INTRN_C4I4EXPEXPR; break;
00653 case MTYPE_C8: intr = INTRN_C8I4EXPEXPR; break;
00654 case MTYPE_CQ: intr = INTRN_CQI4EXPEXPR; break;
00655 }
00656 } else if (et == MTYPE_I8) {
00657 switch (bt) {
00658 case MTYPE_I1:
00659 case MTYPE_I2:
00660 case MTYPE_I4:
00661 case MTYPE_I8:
00662 intr = INTRN_I8EXPEXPR; break;
00663 case MTYPE_F4: intr = INTRN_F4I8EXPEXPR; break;
00664 case MTYPE_F8: intr = INTRN_F8I8EXPEXPR; break;
00665 case MTYPE_FQ: intr = INTRN_FQI8EXPEXPR; break;
00666 case MTYPE_C4: intr = INTRN_C4I8EXPEXPR; break;
00667 case MTYPE_C8: intr = INTRN_C8I8EXPEXPR; break;
00668 case MTYPE_CQ: intr = INTRN_CQI8EXPEXPR; break;
00669 }
00670 } else {
00671 exp = cwh_convert_to_ty(exp,bt);
00672 switch (bt) {
00673 case MTYPE_F4: intr = INTRN_F4EXPEXPR; break;
00674 case MTYPE_F8: intr = INTRN_F8EXPEXPR; break;
00675 case MTYPE_FQ: intr = INTRN_FQEXPEXPR; break;
00676 case MTYPE_C4: intr = INTRN_C4EXPEXPR; break;
00677 case MTYPE_C8: intr = INTRN_C8EXPEXPR; break;
00678 case MTYPE_CQ: intr = INTRN_CQEXPEXPR; break;
00679 }
00680 }
00681
00682 rt = WN_rtype(base);
00683 k[0] = base;
00684 k[1] = exp ;
00685 wn = cwh_intrin_build(k,intr,rt,2);
00686
00687 wn = cwh_expr_restore_arrayexp(wn,ae);
00688 cwh_stk_push(wn,WN_item);
00689 }
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703 void
00704 fei_round(TYPE type)
00705 {
00706 TYPE_ID bt,rt ;
00707 #ifdef KEY
00708 OPCODE opc = (OPCODE) 0;
00709 INTRINSIC intr = INTRN_I4EXPEXPR;
00710 #else
00711 OPCODE opc ;
00712 INTRINSIC intr;
00713 #endif
00714 WN *k[2];
00715 WN *wn ;
00716 WN *ae=NULL;
00717
00718 rt = TY_mtype(cast_to_TY(t_TY(type)));
00719
00720 if(MTYPE_is_float(rt)) {
00721 k[0] = cwh_expr_operand(&ae);
00722 bt = WNRTY(k[0]);
00723 opc = cwh_make_typed_opcode(OPR_INTRINSIC_OP, bt, MTYPE_V);
00724 k[0] = cwh_intrin_wrap_value_parm(k[0]);
00725
00726 switch (bt) {
00727 case MTYPE_F4: intr = INTRN_F4ANINT; break;
00728 case MTYPE_F8: intr = INTRN_F8ANINT; break;
00729 case MTYPE_FQ: intr = INTRN_FQANINT; break;
00730 }
00731 } else {
00732
00733 k[0] = cwh_expr_operand(&ae);
00734 bt = WNRTY(k[0]);
00735 k[0] = cwh_intrin_wrap_value_parm(k[0]);
00736
00737 switch (rt) {
00738 case MTYPE_I1:
00739 case MTYPE_I2:
00740 case MTYPE_I4:
00741 opc = cwh_make_typed_opcode(OPR_INTRINSIC_OP, MTYPE_I4, MTYPE_V);
00742 switch (bt) {
00743 case MTYPE_F4: intr = INTRN_I4F4NINT; break;
00744 case MTYPE_F8: intr = INTRN_I4F8IDNINT; break;
00745 case MTYPE_FQ: intr = INTRN_I4FQIQNINT; break;
00746 }
00747 break;
00748
00749 case MTYPE_I8:
00750 opc = cwh_make_typed_opcode(OPR_INTRINSIC_OP, MTYPE_I8, MTYPE_V);
00751 switch (bt) {
00752 case MTYPE_F4: intr = INTRN_I8F4NINT; break;
00753 case MTYPE_F8: intr = INTRN_I8F8IDNINT; break;
00754 case MTYPE_FQ: intr = INTRN_I8FQIQNINT; break;
00755 }
00756 break;
00757 }
00758 }
00759
00760 wn = WN_Create_Intrinsic(opc,intr,1,k);
00761 if(MTYPE_is_float(rt)) {
00762 wn = cwh_convert_to_ty(wn,rt);
00763 } else {
00764 wn = cwh_wrap_cvtl(wn,rt);
00765 }
00766
00767 wn = cwh_expr_restore_arrayexp(wn,ae);
00768 cwh_stk_push_typed(wn,WN_item,Be_Type_Tbl(rt));
00769 }
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779 void
00780 fei_trunc(TYPE type)
00781 {
00782 TYPE_ID bt,rt ;
00783 INTRINSIC intr;
00784 WN *k[1];
00785 WN *wn ;
00786 WN *ae=NULL;
00787
00788 rt = TY_mtype(cast_to_TY(t_TY(type)));
00789 k[0] = cwh_expr_operand(&ae);
00790 bt = WNRTY(k[0]);
00791 k[0] = cwh_intrin_wrap_value_parm(k[0]);
00792
00793 intr = GET_ITAB_IOP(i_trunc,bt);
00794
00795 DevAssert((intr),("Unsupported intr/ty combo"));
00796
00797 wn = cwh_intrin_build(k,intr,bt,1);
00798 wn = cwh_convert_to_ty(wn,rt);
00799
00800 wn = cwh_expr_restore_arrayexp(wn,ae);
00801 cwh_stk_push(wn,WN_item);
00802 }
00803
00804 void fei_scale(TYPE type)
00805 {
00806 TYPE_ID bt ;
00807 INTRINSIC intr;
00808 WN *k[2];
00809 WN *wn ;
00810 WN *ae=NULL;
00811
00812 k[1] = cwh_get_typed_operand(MTYPE_I4,&ae);
00813 k[0] = cwh_expr_operand(&ae);
00814 bt = WN_rtype(k[0]);
00815 intr = GET_ITAB_IOP(i_scale,bt);
00816
00817 wn = cwh_intrin_build(k,intr,bt,2);
00818 wn = cwh_expr_restore_arrayexp(wn,ae);
00819 cwh_stk_push(wn,WN_item);
00820 }
00821
00822 void fei_near(TYPE type)
00823 {
00824 TYPE_ID bt;
00825 INTRINSIC intr;
00826 WN *k[2];
00827 WN *wn;
00828 WN *ae=NULL;
00829
00830 WN_DELETE_Tree(cwh_expr_operand(NULL));
00831 k[1] = cwh_expr_operand(&ae);
00832 k[0] = cwh_expr_operand(&ae);
00833 bt = WN_rtype(k[0]);
00834 #ifdef KEY
00835
00836
00837
00838
00839
00840
00841
00842 k[1] = cwh_convert_to_ty(k[1], bt);
00843 #endif
00844 intr = GET_ITAB_IOP(i_near,bt);
00845
00846 wn = cwh_intrin_build(k,intr,bt,2);
00847 wn = cwh_expr_restore_arrayexp(wn,ae);
00848 cwh_stk_push(wn,WN_item);
00849 }
00850
00851
00852 void fei_set_exponent(TYPE type)
00853 {
00854 TYPE_ID bt ;
00855 INTRINSIC intr;
00856 WN *k[2];
00857 WN *wn ;
00858 WN *ae=NULL;
00859
00860 k[1] = cwh_get_typed_operand(MTYPE_I4,&ae);
00861 k[0] = cwh_expr_operand(&ae);
00862 bt = WN_rtype(k[0]);
00863
00864 intr = GET_ITAB_IOP(i_set_exponent,bt);
00865 wn = cwh_intrin_build(k,intr,bt,2);
00866 wn = cwh_expr_restore_arrayexp(wn,ae);
00867 cwh_stk_push(wn,WN_item);
00868 }
00869
00870 void fei_exponent(TYPE type)
00871 {
00872 TYPE_ID bt,rt;
00873 INTRINSIC intr;
00874 WN *k[1];
00875 WN *wn ;
00876 WN *ae=NULL;
00877
00878 rt = TY_mtype(cast_to_TY(t_TY(type)));
00879 k[0] = cwh_expr_operand(&ae);
00880 bt = WN_rtype(k[0]);
00881
00882 intr = GET_ITAB_IOP(i_exponent,bt);
00883 wn = cwh_intrin_build(k,intr,rt,1);
00884 wn = cwh_expr_restore_arrayexp(wn,ae);
00885 cwh_stk_push(wn,WN_item);
00886 }
00887
00888
00889
00890
00891
00892 void fei_pos_diff(TYPE type)
00893 {
00894 WN *zero;
00895 fei_minus(type);
00896 zero = WN_Intconst(MTYPE_I4,0);
00897 cwh_stk_push(zero,WN_item);
00898 fei_max(2,type);
00899 }
00900
00901
00902 #ifndef KEY
00903
00904
00905
00906 void fei_sign_xfer(TYPE type)
00907 {
00908 WN *a, *aneg, *b;
00909 WN *ae=NULL;
00910
00911 b = cwh_expr_operand(&ae);
00912
00913 fei_abs(type);
00914 a = cwh_expr_operand(&ae);
00915 cwh_stk_push(WN_COPY_Tree(a),WN_item);
00916 fei_uminus(type);
00917 aneg = cwh_expr_operand(&ae);
00918
00919
00920 cwh_stk_push(b,WN_item);
00921 cwh_stk_push(WN_Zerocon(WN_rtype(b)),WN_item);
00922 fei_ge(type);
00923 b = cwh_expr_operand(&ae);
00924 cwh_stk_push(a,WN_item);
00925 cwh_stk_push(aneg,WN_item);
00926 b = cwh_expr_restore_arrayexp(b,ae);
00927 cwh_stk_push(b,WN_item);
00928 #ifdef KEY
00929 fei_select(type, 0);
00930 #else
00931 fei_select(type);
00932 #endif
00933 }
00934 #endif
00935
00936
00937
00938
00939 void fei_ieee_sign_xfer(TYPE type)
00940 {
00941 WN *a, *b;
00942 WN *ae=NULL;
00943 TYPE_ID rt,it,bt;
00944
00945 rt = TY_mtype(cast_to_TY(t_TY(type)));
00946 if (rt == MTYPE_FQ) {
00947 fei_sign_xfer(type);
00948 return;
00949 } else if (rt == MTYPE_F8) {
00950 it = MTYPE_I8;
00951 } else {
00952 it = MTYPE_I4;
00953 }
00954
00955 b = cwh_expr_operand(&ae);
00956 bt = WNRTY(b);
00957 if (bt == MTYPE_F4) {
00958 b = WN_Tas(MTYPE_I4,Be_Type_Tbl(MTYPE_I4),b);
00959 b = WN_Lshr(MTYPE_I4,b,WN_Intconst(MTYPE_I4,31));
00960 } else if (bt == MTYPE_F8) {
00961 b = WN_Tas(MTYPE_I8,Be_Type_Tbl(MTYPE_I8),b);
00962 b = WN_Lshr(MTYPE_I8,b,WN_Intconst(MTYPE_I8,63));
00963 } else {
00964
00965 b = WN_LT(bt,b,WN_Zerocon(bt));
00966 }
00967
00968
00969
00970 bt = WNRTY(b);
00971 if (MTYPE_bit_size(bt) == MTYPE_bit_size(rt)) {
00972 b = WN_Shl(bt,b,WN_Intconst(MTYPE_I4,MTYPE_bit_size(bt)-1));
00973 } else if (MTYPE_bit_size(bt) > MTYPE_bit_size(rt)) {
00974
00975 b = WN_Shl(MTYPE_I4,b,WN_Intconst(MTYPE_I4,31));
00976 } else {
00977
00978 b = WN_Shl(MTYPE_I8,b,WN_Intconst(MTYPE_I4,63));
00979 }
00980
00981
00982 fei_abs(type);
00983 a = cwh_expr_operand(&ae);
00984
00985
00986 a = WN_Tas(it,Be_Type_Tbl(it),a);
00987 a = cwh_expr_bincalc(OPR_BIOR,a,b);
00988
00989
00990 a = WN_Tas(rt,Be_Type_Tbl(rt),a);
00991
00992 a = cwh_expr_restore_arrayexp(a,ae);
00993 cwh_stk_push(a,WN_item);
00994 }
00995
00996 static void cwh_ceiling_floor(TYPE type, OPERATOR opr)
00997 {
00998
00999 TYPE_ID bt;
01000 TYPE_ID rt;
01001 OPCODE opc ;
01002 WN *k;
01003 WN *wn ;
01004 WN *ae=NULL;
01005
01006 k = cwh_expr_operand(&ae);
01007 bt = WN_rtype(k);
01008 rt = TY_mtype(cast_to_TY(t_TY(type)));
01009
01010 opc = cwh_make_typed_opcode(opr, rt, bt);
01011 wn = WN_CreateExp1 ( opc, k) ;
01012
01013 wn = cwh_expr_restore_arrayexp(wn,ae);
01014 cwh_stk_push(wn,WN_item);
01015 }
01016
01017 void fei_ceiling (TYPE type)
01018 {
01019 cwh_ceiling_floor(type, OPR_CEIL);
01020 }
01021
01022 void fei_floor (TYPE type)
01023 {
01024 cwh_ceiling_floor(type, OPR_FLOOR);
01025 }
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043 #define MAXARGS 6
01044
01045 static void
01046 cwh_do_tranformational(INTRINSIC intrn, INT numargs, TYPE rtype, BOOL is_numeric,
01047 BOOL cvt_to_rtype)
01048 {
01049 WN * args[MAXARGS];
01050 WN *wn;
01051 #ifdef KEY
01052 WN *charlen = 0;
01053 #else
01054 WN *charlen;
01055 #endif
01056 OPCODE op;
01057 INT i;
01058 BOOL is_char;
01059 #ifdef KEY
01060 TY_IDX str_ty = 0;
01061 #else
01062 TY_IDX str_ty;
01063 #endif
01064 TY_IDX p_ty;
01065 TY_IDX rty;
01066 TYPE_ID type_from_first;
01067 TYPE_ID result_type;
01068
01069 rty = cast_to_TY(t_TY(rtype));
01070 result_type = TY_mtype(rty);
01071
01072 is_char = FALSE;
01073 for (i=numargs-1; i >= 0; i--) {
01074
01075 if (cwh_stk_get_class() == STR_item) {
01076 is_char = TRUE;
01077
01078 cwh_stk_pop_STR();
01079 charlen = cwh_expr_operand(NULL);
01080 str_ty = cwh_stk_get_TY();
01081 args[i] = cwh_expr_address(f_NONE);
01082
01083 if (TY_kind(str_ty) == KIND_POINTER) {
01084 p_ty = str_ty;
01085 str_ty = TY_pointed(p_ty);
01086
01087 } else
01088 p_ty = cwh_types_make_pointer_type(str_ty, FALSE);
01089
01090 if (WN_operator(args[i]) != OPR_INTRINSIC_OP) {
01091 args[i] = WN_CreateMload(0,p_ty,args[i],WN_COPY_Tree(charlen));
01092 } else {
01093 WN_set_opcode(args[i],OPC_MINTRINSIC_OP);
01094 }
01095 args[i] = WN_CreateParm(MTYPE_M,args[i],str_ty,WN_PARM_BY_VALUE);
01096
01097 } else {
01098 args[i] = cwh_expr_operand(NULL);
01099 if (!args[i]) {
01100 args[i] = cwh_intrin_null_parm();
01101 } else {
01102 if (cvt_to_rtype) {
01103 args[i] = cwh_convert_to_ty(args[i],result_type);
01104 }
01105 args[i] = cwh_intrin_wrap_value_parm(args[i]);
01106 }
01107 }
01108 }
01109
01110 if (is_char) {
01111 type_from_first = Pointer_Mtype;
01112 op = cwh_make_typed_opcode(OPR_INTRINSIC_OP, Pointer_Mtype, MTYPE_V);
01113 } else {
01114 type_from_first = result_type;
01115 if (is_numeric) {
01116 op = OPCODE_make_op(OPR_INTRINSIC_OP, result_type, MTYPE_V);
01117 } else {
01118 op = OPCODE_make_op(OPR_INTRINSIC_OP, WNRTY(args[0]), MTYPE_V);
01119 }
01120 }
01121
01122 wn = WN_Create_Intrinsic(op,intrn,numargs,args);
01123 if (is_numeric) {
01124 wn = cwh_wrap_cvtl(wn,type_from_first);
01125 }
01126 wn = F90_Wrap_ARREXP(wn);
01127
01128 if (is_char) {
01129 cwh_stk_push_STR(charlen,wn,str_ty,WN_item);
01130 } else {
01131 cwh_stk_push_typed(wn,WN_item,rty);
01132 }
01133 return;
01134 }
01135
01136 #define do_transformational(name,intrn,numargs,is_numeric) void name(TYPE rtype) \
01137 {cwh_do_tranformational(intrn,numargs,rtype,is_numeric,FALSE);}
01138
01139 #define do_transformational_cvt(name,intrn,numargs,is_numeric) void name(TYPE rtype) \
01140 {cwh_do_tranformational(intrn,numargs,rtype,is_numeric,TRUE);}
01141
01142 do_transformational(fei_spread,INTRN_SPREAD,3,FALSE)
01143 do_transformational(fei_transpose,INTRN_TRANSPOSE,1,FALSE)
01144 do_transformational(fei_all,INTRN_ALL,2,TRUE)
01145 do_transformational(fei_any,INTRN_ANY,2,TRUE)
01146 do_transformational(fei_product,INTRN_PRODUCT,3,TRUE)
01147 do_transformational(fei_sum,INTRN_SUM,3,TRUE)
01148 do_transformational(fei_maxval,INTRN_MAXVAL,3,TRUE)
01149 do_transformational(fei_minval,INTRN_MINVAL,3,TRUE)
01150 do_transformational(fei_maxloc,INTRN_MAXLOC,2,TRUE)
01151 do_transformational(fei_minloc,INTRN_MINLOC,2,TRUE)
01152 do_transformational(fei__maxloc,INTRN_MAXLOC,3,TRUE)
01153 do_transformational(fei__minloc,INTRN_MINLOC,3,TRUE)
01154 do_transformational(fei_pack,INTRN_PACK,3,FALSE)
01155 do_transformational(fei_unpack,INTRN_UNPACK,3,FALSE)
01156 do_transformational(fei_cshift,INTRN_CSHIFT,3,FALSE)
01157 do_transformational(fei_eoshift,INTRN_EOSHIFT,4,FALSE)
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168 void
01169 fei_matmul(TYPE rtype)
01170 {
01171 WN * args[2];
01172 WN * wn;
01173 OPCODE op;
01174 INT i;
01175 TY_IDX rty;
01176 TYPE_ID result_type;
01177
01178 rty = cast_to_TY(t_TY(rtype));
01179 result_type = TY_mtype(rty);
01180
01181 for (i=1; i >= 0; i--) {
01182 args[i] = cwh_expr_operand(NULL);
01183 args[i] = cwh_convert_to_ty(args[i],result_type);
01184 args[i] = cwh_intrin_wrap_value_parm(args[i]);
01185 }
01186
01187 if (TY_is_logical(rty)) {
01188 op = OPCODE_make_op(OPR_INTRINSIC_OP, MTYPE_B, MTYPE_V);
01189 } else {
01190 op = OPCODE_make_op(OPR_INTRINSIC_OP, result_type, MTYPE_V);
01191 }
01192
01193 wn = WN_Create_Intrinsic(op,INTRN_MATMUL,2,args);
01194 if (!TY_is_logical(rty)) {
01195 wn = cwh_wrap_cvtl(wn,result_type);
01196 }
01197 wn = F90_Wrap_ARREXP(wn);
01198
01199 cwh_stk_push_typed(wn,WN_item,rty);
01200 return;
01201 }
01202
01203
01204
01205 void
01206 fei_dot_product(TYPE rtype)
01207 {
01208 WN *arg0,*arg1;
01209 WN *intr_args[3];
01210 WN *wn;
01211 OPCODE op,mpy_op;
01212 INTRINSIC intr;
01213 WN *ae=NULL;
01214 TY_IDX rty;
01215 TYPE_ID ty;
01216
01217 rty = cast_to_TY(t_TY(rtype));
01218 ty = TY_mtype(rty);
01219
01220 arg1 = cwh_expr_operand(&ae);
01221 arg0 = cwh_expr_operand(&ae);
01222 arg0 = cwh_convert_to_ty(arg0,ty);
01223 arg1 = cwh_convert_to_ty(arg1,ty);
01224
01225 op = cwh_make_typed_opcode(OPR_INTRINSIC_OP, ty, MTYPE_V);
01226 mpy_op = cwh_make_typed_opcode(OPR_MPY,ty,MTYPE_V);
01227
01228 if (MTYPE_is_complex(ty)) {
01229
01230 if (ty == MTYPE_C4) {
01231 intr = INTRN_C4CONJG;
01232 } else if (ty == MTYPE_C8) {
01233 intr = INTRN_C8CONJG;
01234 } else {
01235 intr = INTRN_CQCONJG;
01236 }
01237 arg0 = cwh_intrin_wrap_value_parm(arg0);
01238 arg0 = WN_Create_Intrinsic(op,intr,1,&arg0);
01239 }
01240
01241 arg0 = WN_CreateExp2(mpy_op,arg0,arg1);
01242 arg0 = cwh_expr_restore_arrayexp(arg0,ae);
01243 intr_args[0] = cwh_intrin_wrap_value_parm(arg0);
01244 intr_args[1] = cwh_intrin_null_parm();
01245 intr_args[2] = cwh_intrin_null_parm();
01246 wn = WN_Create_Intrinsic(op,INTRN_SUM,3,intr_args);
01247 wn = cwh_wrap_cvtl(wn,ty);
01248
01249 cwh_stk_push_typed(wn,WN_item,rty);
01250 return;
01251 }
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265 void
01266 fei_dot_product_logical(TYPE rtype)
01267 {
01268 WN *arg0,*arg1;
01269 WN *intr_args[2];
01270 WN *wn;
01271 OPCODE op ;
01272 WN *ae=NULL;
01273
01274
01275 TYPE_ID ty;
01276
01277 arg1 = cwh_expr_operand(&ae);
01278 arg0 = cwh_expr_operand(&ae);
01279 ty = cwh_get_highest_type(arg0,arg1);
01280 arg0 = cwh_convert_to_ty(arg0,ty);
01281 arg1 = cwh_convert_to_ty(arg1,ty);
01282
01283 op = cwh_make_typed_opcode(OPR_INTRINSIC_OP, ty, MTYPE_V);
01284
01285 arg0 = WN_CreateExp2(OPC_I4LAND,arg0,arg1);
01286 arg0 = cwh_expr_restore_arrayexp(arg0,ae);
01287 intr_args[0] = cwh_intrin_wrap_value_parm(arg0);
01288 intr_args[1] = cwh_intrin_null_parm();
01289 wn = WN_Create_Intrinsic(op,INTRN_ANY,2,intr_args);
01290
01291 cwh_stk_push_typed(wn,WN_item,cast_to_TY(t_TY(rtype)));
01292 return;
01293 }
01294
01295 void
01296 fei_count(TYPE type)
01297 {
01298 WN *args[3];
01299 WN *wn;
01300 OPCODE op;
01301 TYPE_ID ty;
01302 WN *ae=NULL;
01303
01304 args[1] = cwh_expr_operand(NULL);
01305 args[0] = cwh_expr_operand(&ae);
01306 if (!args[1]) {
01307 args[1] = cwh_intrin_wrap_value_parm(WN_Zerocon(MTYPE_I4));
01308 } else {
01309 args[1] = cwh_intrin_wrap_value_parm(args[1]);
01310 }
01311 args[2] = cwh_intrin_wrap_value_parm(WN_Intconst(MTYPE_I4,1));
01312
01313
01314 ty = WN_rtype(args[0]);
01315 if (ty != MTYPE_B) {
01316 op = cwh_make_typed_opcode(OPR_NE,MTYPE_I4,ty);
01317 args[0] = WN_CreateExp2(op,args[0],WN_Zerocon(ty));
01318 }
01319 args[0] = cwh_expr_restore_arrayexp(args[0],ae);
01320 args[0] = cwh_intrin_wrap_value_parm(args[0]);
01321
01322 op = cwh_make_typed_opcode(OPR_INTRINSIC_OP, Pointer_Size==8 ? MTYPE_I8 : MTYPE_I4, MTYPE_V);
01323 wn = WN_Create_Intrinsic(op,INTRN_SUM,3,args);
01324
01325 wn = F90_Wrap_ARREXP(wn);
01326 cwh_stk_push(wn,WN_item);
01327 return;
01328 }
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343 void
01344 fei_malloc (void)
01345 {
01346 WN * k[1];
01347 WN * sz = NULL ;
01348 WN * call;
01349 BOOL v = TRUE;
01350 WN * wn ;
01351 INTRINSIC intr;
01352 char preg_name[32];
01353
01354
01355 k[0] = cwh_expr_operand(NULL);
01356 intr = (Pointer_Size == 4) ? INTRN_U4I4MALLOC : INTRN_U8I8MALLOC;
01357
01358 call = cwh_intrin_call(intr, 1, k, &sz, &v, Pointer_Mtype);
01359 WN_Set_Call_Does_Mem_Alloc(call);
01360
01361
01362 wn = cwh_stmt_return_scalar(NULL, NULL, Be_Type_Tbl(Pointer_Mtype), FALSE);
01363 cwh_stk_push(wn,WN_item);
01364 sprintf(preg_name,"malloc@line_%d",USRCPOS_linenum(current_srcpos));
01365 wn = cwh_intrin_get_return_value(Pointer_Mtype,preg_name);
01366
01367
01368 cwh_stk_push(wn,WN_item);
01369 }
01370
01371 void
01372 fei_alloc (void)
01373 {
01374 WN * k[1];
01375 WN * wn ;
01376
01377 k[0] = cwh_expr_operand(NULL);
01378 if (Heap_Allocation_Threshold == -1) {
01379 wn = cwh_intrin_build(k,INTRN_F90_STACKTEMPALLOC,Pointer_Mtype,1);
01380 } else if (Heap_Allocation_Threshold == 0) {
01381 wn = cwh_intrin_build(k,INTRN_F90_HEAPTEMPALLOC,Pointer_Mtype,1);
01382 } else {
01383 wn = cwh_intrin_build(k,INTRN_F90_DYNAMICTEMPALLOC,Pointer_Mtype,1);
01384 }
01385
01386 cwh_stk_push(wn,WN_item);
01387 }
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398 void
01399 fei_mfree (void)
01400 {
01401 WN * k[1];
01402 WN * sz = NULL ;
01403 WN * call;
01404 BOOL val = TRUE;
01405 INTRINSIC intr;
01406
01407 intr = (Pointer_Size == 4) ? INTRN_U4FREE : INTRN_U8FREE;
01408
01409 k[0] = cwh_expr_operand(NULL);
01410 call = cwh_intrin_call(intr,1,k,&sz,&val,MTYPE_V);
01411 WN_Set_Call_Does_Mem_Free(call);
01412 }
01413
01414 void
01415 fei_free (void)
01416 {
01417 WN * k[1];
01418 WN * sz = NULL ;
01419 BOOL val = TRUE;
01420
01421 k[0] = cwh_expr_operand(NULL);
01422 if (Heap_Allocation_Threshold == -1) {
01423 cwh_intrin_call(INTRN_F90_STACKTEMPFREE,1,k,&sz,&val,Pointer_Mtype);
01424 } else if (Heap_Allocation_Threshold == 0) {
01425 cwh_intrin_call(INTRN_F90_HEAPTEMPFREE,1,k,&sz,&val,Pointer_Mtype);
01426 } else {
01427 cwh_intrin_call(INTRN_F90_DYNAMICTEMPFREE,1,k,&sz,&val,Pointer_Mtype);
01428 }
01429
01430 }
01431
01432
01433
01434
01435
01436
01437
01438
01439
01440
01441
01442
01443 void
01444 fei_ranf(TYPE type) {
01445 WN *wn;
01446 TYPE_ID t;
01447
01448 t = TY_mtype(cast_to_TY(t_TY(type)));
01449 if (t == MTYPE_F4) {
01450 wn = WN_Create_Intrinsic(OPC_F4INTRINSIC_OP,INTRN_F4I4RAN,0,NULL);
01451 } else {
01452 wn = WN_Create_Intrinsic(OPC_F8INTRINSIC_OP,INTRN_F8I4RAN,0,NULL);
01453 }
01454 cwh_stk_push(wn,WN_item);
01455 }
01456
01457
01458
01459
01460
01461
01462
01463
01464
01465
01466
01467
01468 void
01469 fei_ranget (TYPE type) {
01470 WN *addr;
01471 WN *call;
01472 INT64 flags = 0;
01473
01474 if (!ranget_st) {
01475 ranget_st = cwh_intrin_make_intrinsic_symbol("_RANGET",MTYPE_V);
01476 }
01477
01478 addr = cwh_expr_address(f_T_PASSED);
01479 cwh_stk_push(ranget_st,ST_item);
01480 cwh_stk_push(addr,ADDR_item);
01481 call = cwh_stmt_call_helper(1,Be_Type_Tbl(MTYPE_V),0,flags);
01482 #ifdef KEY
01483 cwh_stk_push(NULL,WN_item);
01484 #endif
01485
01486 }
01487
01488
01489
01490
01491
01492
01493
01494
01495
01496
01497
01498
01499 void
01500 fei_ranset (TYPE type) {
01501 WN *call;
01502 WN *wn;
01503 INT64 flags = 0;
01504
01505 if (!ranset_st) {
01506 ranset_st = cwh_intrin_make_intrinsic_symbol("_RANSET",MTYPE_V);
01507 }
01508
01509 wn = cwh_expr_address(f_T_PASSED);
01510 cwh_stk_push(ranset_st,ST_item);
01511 cwh_stk_push(wn,ADDR_item);
01512 call = cwh_stmt_call_helper(1,Be_Type_Tbl(MTYPE_V),0,flags);
01513
01514 cwh_stk_push(NULL,WN_item);
01515 }
01516
01517
01518 void
01519 fei_rtc (TYPE type) {
01520 WN *call;
01521 WN *wn;
01522 INT64 flags = 0;
01523
01524 if (!rtc_st) {
01525 rtc_st = cwh_intrin_make_intrinsic_symbol("_IRTC_",MTYPE_I8);
01526 }
01527
01528 cwh_stk_push(rtc_st,ST_item);
01529 call = cwh_stmt_call_helper(0,Be_Type_Tbl(MTYPE_I8),0,flags);
01530 wn = cwh_intrin_get_return_value(MTYPE_I8,"@f90rtc");
01531 wn = cwh_convert_to_ty(wn,TY_mtype(cast_to_TY(t_TY(type))));
01532 cwh_stk_push(wn,WN_item);
01533 }
01534
01535 void
01536 fei_unit(void)
01537 {
01538 WN *call;
01539 WN *addr;
01540 WN *wn;
01541 INT64 flags = 0;
01542
01543 if (!unit_st) {
01544 unit_st = cwh_intrin_make_intrinsic_symbol("_UNIT_",MTYPE_F4);
01545 }
01546
01547 addr = cwh_expr_address(f_T_PASSED);
01548 cwh_stk_push(unit_st,ST_item);
01549 cwh_stk_push(addr,ADDR_item);
01550 call = cwh_stmt_call_helper(1,Be_Type_Tbl(MTYPE_F4),0,flags);
01551
01552 wn = cwh_intrin_get_return_value (MTYPE_F4,"@f90unit");
01553 cwh_stk_push(wn,WN_item);
01554
01555 }
01556
01557
01558 void
01559 fei_length(void)
01560 {
01561 WN *call;
01562 WN *addr;
01563 WN *wn;
01564 INT64 flags = 0;
01565
01566 if (!length_st) {
01567 length_st = cwh_intrin_make_intrinsic_symbol("_LENGTH_",MTYPE_I4);
01568 }
01569
01570 addr = cwh_expr_address(f_T_PASSED);
01571 cwh_stk_push(length_st,ST_item);
01572 cwh_stk_push(addr,ADDR_item);
01573 call = cwh_stmt_call_helper(1,Be_Type_Tbl(MTYPE_I4),0,flags);
01574
01575 wn = cwh_intrin_get_return_value (MTYPE_I4,"@f90length");
01576 cwh_stk_push(wn,WN_item);
01577
01578 }
01579
01580
01581
01582 void
01583 fei_present(void)
01584 {
01585 WN *wn;
01586 WN *arg;
01587 TY_IDX ty;
01588
01589 arg = cwh_expr_address(f_NONE);
01590 wn = WN_CreateExp2(OPCODE_make_op(OPR_NE,MTYPE_I4,Pointer_Mtype),
01591 arg,
01592 WN_Intconst(Pointer_Mtype,0));
01593 cwh_stk_push_typed(wn,WN_item,logical4_ty);
01594 }
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611 void
01612 fei_ibits(TYPE type)
01613 {
01614 WN *x, *pos, *len;
01615 WN *mask;
01616 TYPE_ID ty,rty;
01617 WN *ae=NULL;
01618
01619 len = cwh_expr_operand(&ae);
01620 pos = cwh_expr_operand(&ae);
01621 x = cwh_expr_operand(&ae);
01622
01623 rty = TY_mtype(cast_to_TY(t_TY(type)));
01624 ty = Mtype_comparison(rty);
01625
01626 x = WN_Lshr(ty,x,pos);
01627
01628 mask = cwh_generate_bitmask(len,ty);
01629 x = cwh_expr_bincalc(OPR_BAND,x,mask);
01630 #ifdef KEY
01631
01632
01633
01634 ty = WN_rtype(x);
01635 if (ty != rty) {
01636 if (MTYPE_I4 == rty || MTYPE_I8 == rty) {
01637 OPCODE cvt_op = OPCODE_make_op(OPR_CVT,rty,ty);
01638 x = WN_CreateExp1(cvt_op, x);
01639 }
01640 else {
01641 x = cwh_wrap_cvtl(x, rty);
01642 }
01643 }
01644 #else
01645 x = cwh_wrap_cvtl(x,rty);
01646 #endif
01647
01648 x = cwh_expr_restore_arrayexp(x,ae);
01649 cwh_stk_push(x,WN_item);
01650 }
01651
01652
01653
01654
01655
01656
01657
01658
01659 void
01660 fei_mvbits(TYPE type)
01661 {
01662 WN *from,*frompos,*len,*to,*topos;
01663 WN *t1,*mask,*r;
01664 WN *ae=NULL;
01665
01666 TYPE_ID ty,rty;
01667
01668 topos = cwh_expr_operand(&ae);
01669 to = cwh_expr_operand(&ae);
01670 len = cwh_expr_operand(&ae);
01671 frompos = cwh_expr_operand(&ae);
01672 from = cwh_expr_operand(&ae);
01673
01674 rty = TY_mtype(cast_to_TY(t_TY(type)));
01675 ty = Mtype_comparison(rty);
01676
01677 from = WN_Lshr(ty,from,frompos);
01678 mask = cwh_generate_bitmask(len,ty);
01679 t1 = cwh_expr_bincalc(OPR_BAND,from,WN_COPY_Tree(mask));
01680 t1 = cwh_expr_bincalc(OPR_SHL,t1,WN_COPY_Tree(topos));
01681
01682 mask = WN_Shl(ty,mask,topos);
01683 mask = WN_CreateExp1(OPCODE_make_op(OPR_BNOT,ty,MTYPE_V),mask);
01684
01685 r = cwh_expr_bincalc(OPR_BAND,to,mask);
01686 r = cwh_expr_bincalc(OPR_BIOR,r,t1);
01687 r = cwh_wrap_cvtl(r,rty);
01688
01689 r = cwh_expr_restore_arrayexp(r,ae);
01690 cwh_stk_push(r,WN_item);
01691 fei_store(type);
01692 }
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705
01706
01707 static void
01708 cwh_char_intrin(INTRINSIC intr, INT numargs)
01709 {
01710 WN * args[5];
01711 INT arg_count;
01712 INT i;
01713 WN *charlen;
01714 WN *charlen1;
01715 WN *wn;
01716 OPCODE op;
01717
01718 arg_count = 5;
01719 for (i = 0; i < numargs; i++) {
01720 if (cwh_stk_get_class() == STR_item) {
01721 cwh_stk_pop_STR();
01722 charlen = cwh_expr_operand(NULL);
01723 charlen1 = WN_COPY_Tree(charlen);
01724 args[--arg_count] = cwh_intrin_wrap_value_parm(charlen);
01725 args[--arg_count] = cwh_expr_address(f_NONE);
01726 args[arg_count] = cwh_intrin_wrap_char_parm(args[arg_count],charlen1);
01727 } else {
01728 args[--arg_count] = cwh_intrin_wrap_value_parm(cwh_expr_operand(NULL));
01729 }
01730 }
01731
01732 wn = WN_Create_Intrinsic(OPC_I4INTRINSIC_OP,intr,5-arg_count,&args[arg_count]);
01733 cwh_stk_push(wn,WN_item);
01734 }
01735
01736
01737 #define do_char_intrin(name,intr,args) void name(TYPE type) {cwh_char_intrin(intr,args);}
01738 #define do_char_intrin_nt(name,intr,args) void name(void) {cwh_char_intrin(intr,args);}
01739
01740 do_char_intrin(fei_scan,INTRN_SCAN,3)
01741 do_char_intrin(fei_verify,INTRN_VERIFY,3)
01742 do_char_intrin_nt(fei_index,INTRN_F90INDEX,3)
01743 do_char_intrin_nt(fei_len_trim,INTRN_LENTRIM,1)
01744
01745
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755
01756 void
01757 fei_adjustl (TYPE type)
01758 {
01759 cwh_stmt_character_icall(INTRN_ADJUSTL);
01760 cwh_stk_push(NULL,WN_item);
01761 cwh_stk_push(NULL,WN_item);
01762 }
01763
01764 void
01765 fei_adjustr (TYPE type)
01766 {
01767 cwh_stmt_character_icall(INTRN_ADJUSTR);
01768 cwh_stk_push(NULL,WN_item);
01769 cwh_stk_push(NULL,WN_item);
01770 }
01771
01772 void
01773 fei_ieee_round(TYPE type)
01774 {
01775 fei_cvtop(type);
01776 }
01777
01778
01779 void
01780 fei_ieee_trunc(TYPE type)
01781 {
01782 TY_IDX ty;
01783 WN *ae=NULL;
01784 WN *r;
01785 TYPE_ID bt;
01786 INTRINSIC intr;
01787
01788 ty = cast_to_TY(t_TY(type));
01789 bt = TY_mtype(ty);
01790
01791
01792 r = cwh_expr_operand(&ae);
01793 r = cwh_convert_to_ty(r,MTYPE_FQ);
01794 intr = GET_ITAB_IOP(i_ieee_int,bt);
01795 r = cwh_intrin_build(&r, intr, bt, 1);
01796 r = cwh_wrap_cvtl(r,bt);
01797 r = cwh_expr_restore_arrayexp(r,ae);
01798 cwh_stk_push_typed(r,WN_item,ty);
01799 }
01800
01801
01802
01803 static void
01804 cwh_intrin_popcnt_leadz_helper(INTRINSIC i1, INTRINSIC i2, INTRINSIC i4, INTRINSIC i8,
01805 TYPE rtype, TYPE arg)
01806 {
01807 WN *wn;
01808 WN *r;
01809 TYPE_ID t,ti,rt;
01810 #ifdef KEY
01811 INTRINSIC intr = INTRN_I4EXPEXPR;
01812 #else
01813 INTRINSIC intr;
01814 #endif
01815 WN *ae=NULL;
01816
01817 t = TY_mtype(t_TY(arg));
01818 rt = TY_mtype(t_TY(rtype));
01819
01820 wn = cwh_expr_operand(&ae);
01821
01822
01823 if (!MTYPE_is_integral(t)) {
01824 if (MTYPE_size_reg(t) == 32) {
01825 ti = MTYPE_U4;
01826 } else {
01827 ti = MTYPE_U8;
01828 }
01829 wn = WN_Tas(ti,Be_Type_Tbl(t),wn);
01830 } else {
01831 ti = t;
01832 }
01833
01834
01835
01836
01837 switch (ti) {
01838 case MTYPE_U1: case MTYPE_I1: intr = i1; break;
01839 case MTYPE_U2: case MTYPE_I2: intr = i2; break;
01840 case MTYPE_U4: case MTYPE_I4: intr = i4; break;
01841 case MTYPE_U8: case MTYPE_I8: intr = i8; break;
01842 default: DevAssert(0,("Unknown type"));
01843 }
01844
01845 wn = cwh_intrin_wrap_value_parm(wn);
01846 r = WN_Create_Intrinsic(OPC_I4INTRINSIC_OP,intr,1,&wn);
01847 r = cwh_convert_to_ty(r,rt);
01848 r = cwh_expr_restore_arrayexp(r,ae);
01849 cwh_stk_push(r,WN_item);
01850 }
01851
01852
01853 void
01854 fei_popcnt (TYPE type, TYPE arg)
01855 {
01856 cwh_intrin_popcnt_leadz_helper(INTRN_I1POPCNT,INTRN_I2POPCNT,
01857 INTRN_I4POPCNT,INTRN_I8POPCNT,type,arg);
01858 }
01859
01860
01861 void
01862 fei_leadz (TYPE type, TYPE arg)
01863 {
01864 cwh_intrin_popcnt_leadz_helper(INTRN_I1LEADZ,INTRN_I2LEADZ,
01865 INTRN_I4LEADZ,INTRN_I8LEADZ,type,arg);
01866 }
01867
01868
01869 void
01870 fei_poppar (TYPE type, TYPE arg)
01871 {
01872 cwh_intrin_popcnt_leadz_helper(INTRN_I4POPPAR,INTRN_I4POPPAR,
01873 INTRN_I4POPPAR,INTRN_I8POPPAR,type,arg);
01874 }
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888
01889
01890 static void cwh_funny_fp_intrinsic(INTRINSIC intr, INT numargs, WN **args, TY_IDX ty,
01891 BOOL cvtf4, WN *ae)
01892 {
01893 INT i;
01894 WN *wn;
01895 OPCODE opc;
01896 TYPE_ID t;
01897
01898 t = TY_mtype(ty);
01899
01900
01901 for (i=0; i < numargs; i++) {
01902 if (WN_rtype(args[i]) == MTYPE_F4 && cvtf4) {
01903 args[i] = cwh_convert_to_ty(args[i],MTYPE_F8);
01904 }
01905 args[i] = cwh_intrin_wrap_value_parm(args[i]);
01906 }
01907
01908 if (t == MTYPE_F4 && cvtf4) {
01909 opc = OPC_F8INTRINSIC_OP;
01910 } else {
01911 opc = cwh_make_typed_opcode(OPR_INTRINSIC_OP, t, MTYPE_V);
01912 }
01913
01914 wn = WN_Create_Intrinsic(opc,intr,numargs,args);
01915
01916
01917 if (t == MTYPE_F4 && cvtf4) {
01918 wn = cwh_convert_to_ty(wn,MTYPE_F4);
01919 }
01920 wn = cwh_expr_restore_arrayexp(wn,ae);
01921 cwh_stk_push_typed(wn,WN_item,ty);
01922 }
01923
01924
01925 #define SELECT_INTRINSIC(t,f) ((t==MTYPE_F4) ? INTRN_F4##f : \
01926 ((t==MTYPE_F8) ? INTRN_F8##f : INTRN_FQ##f))
01927
01928 void
01929 fei_scalb(TYPE type)
01930 {
01931 WN *args[2];
01932 INTRINSIC intr;
01933 TYPE_ID t;
01934 WN *ae=NULL;
01935
01936 args[1] = cwh_get_typed_operand(MTYPE_I4,&ae);
01937 args[0] = cwh_expr_operand(&ae);
01938 t = WN_rtype(args[0]);
01939 intr = SELECT_INTRINSIC(t,SCALB);
01940 cwh_funny_fp_intrinsic(intr,2,args,Be_Type_Tbl(t),TRUE,ae);
01941 }
01942
01943 void
01944 fei_remainder(TYPE type)
01945 {
01946 WN *args[2];
01947 INTRINSIC intr;
01948 TYPE_ID t;
01949 WN *ae=NULL;
01950
01951 args[1] = cwh_expr_operand(&ae);
01952 args[0] = cwh_expr_operand(&ae);
01953 t = cwh_get_highest_type(args[0],args[1]);
01954 args[0] = cwh_convert_to_ty(args[0],t);
01955 args[1] = cwh_convert_to_ty(args[1],t);
01956
01957 intr = SELECT_INTRINSIC(t,IEEE_REMAINDER);
01958 cwh_funny_fp_intrinsic(intr,2,args,Be_Type_Tbl(t),TRUE,ae);
01959 }
01960
01961 void
01962 fei_logb(TYPE type)
01963 {
01964 WN *args[1];
01965 INTRINSIC intr;
01966 TYPE_ID t,rt,ot;
01967 WN *wn;
01968 WN *ae=NULL;
01969 WN *argeq0;
01970 INT64 mhuge;
01971
01972 rt = TY_mtype(cast_to_TY(t_TY(type)));
01973 args[0] = cwh_expr_operand(&ae);
01974 t = WN_rtype(args[0]);
01975 argeq0 = WN_EQ(t,WN_COPY_Tree(args[0]),WN_Zerocon(t));
01976 intr = SELECT_INTRINSIC(t,LOGB);
01977 cwh_funny_fp_intrinsic(intr,1,args,Be_Type_Tbl(t),TRUE,NULL);
01978 if (MTYPE_is_integral(rt)) {
01979 ot = MTYPE_I4;
01980 switch (rt) {
01981 case MTYPE_I1:
01982 mhuge = 127LL;
01983 break;
01984 case MTYPE_I2:
01985 mhuge = 32767LL;
01986 break;
01987 case MTYPE_I4:
01988 mhuge = 2147483647LL;
01989 break;
01990 case MTYPE_I8:
01991 default:
01992 mhuge = 9223372036854775807LL;
01993 ot = MTYPE_I8;
01994 break;
01995 }
01996
01997
01998
01999 wn = cwh_get_typed_operand(ot,NULL);
02000 if (rt == MTYPE_I1 || rt == MTYPE_I2) {
02001 wn = WN_CreateExp2(OPC_I4MIN,wn,WN_Intconst(MTYPE_I4,mhuge));
02002 }
02003 wn = WN_Select(ot,argeq0,WN_Intconst(ot,-mhuge),wn);
02004 wn = cwh_wrap_cvtl(wn,rt);
02005 } else {
02006 wn = cwh_get_typed_operand(rt,NULL);
02007 }
02008 wn = cwh_expr_restore_arrayexp(wn,ae);
02009 cwh_stk_push_typed(wn,WN_item,Be_Type_Tbl(rt));
02010 }
02011
02012 void
02013 fei_isfinite(TYPE type)
02014 {
02015 WN *args[1];
02016 INTRINSIC intr;
02017 TYPE_ID t;
02018 WN *ae=NULL;
02019
02020 args[0] = cwh_expr_operand(&ae);
02021 t = WN_rtype(args[0]);
02022 intr = SELECT_INTRINSIC(t,FINITE);
02023 cwh_funny_fp_intrinsic(intr,1,args,logical4_ty,TRUE,ae);
02024 }
02025
02026 void
02027 fei_isnan(TYPE type)
02028 {
02029 WN *args[1];
02030 INTRINSIC intr;
02031 TYPE_ID t;
02032 WN *ae=NULL;
02033
02034 args[0] = cwh_expr_operand(&ae);
02035 t = WN_rtype(args[0]);
02036 intr = SELECT_INTRINSIC(t,ISNAN);
02037 cwh_funny_fp_intrinsic(intr,1,args,logical4_ty,FALSE,ae);
02038 }
02039
02040 void
02041 fei_isunordered(TYPE type)
02042 {
02043 WN *args[2];
02044 INTRINSIC intr;
02045 TYPE_ID t;
02046 WN *ae=NULL;
02047
02048 args[1] = cwh_expr_operand(&ae);
02049 args[0] = cwh_expr_operand(&ae);
02050 t = WN_rtype(args[0]);
02051 intr = SELECT_INTRINSIC(t,UNORDERED);
02052 cwh_funny_fp_intrinsic(intr,2,args,logical4_ty,TRUE,ae);
02053 }
02054
02055 void
02056 fei_fpclass(TYPE type)
02057 {
02058 WN *args[1];
02059 INTRINSIC intr;
02060 TYPE_ID t;
02061 WN *ae=NULL;
02062
02063 args[0] = cwh_expr_operand(&ae);
02064 t = WN_rtype(args[0]);
02065 intr = SELECT_INTRINSIC(t,FPCLASS);
02066 cwh_funny_fp_intrinsic(intr,1,args,Be_Type_Tbl(MTYPE_I4),FALSE,ae);
02067 }
02068
02069 #define UNIMPLEMENTED(fname) void fname() {printf("%3d %s\n",__LINE__,# fname);}
02070
02071
02072
02073
02074 static void
02075 cwh_intrin_ieee_intrin_call_helper(INTRINSIC intrin, TYPE_ID type, INT nargs,
02076 BOOL issue_warning, const char * iname)
02077 {
02078 BOOL v[2];
02079 WN *args[2];
02080 WN *sz[2];
02081 INT i;
02082 WN *wn;
02083
02084 if (issue_warning && (Opt_Level != 0)) {
02085 ErrMsg(EC_IEEE_Intrinsic_Warning,iname);
02086 }
02087
02088 sz[0] = NULL;
02089 sz[1] = NULL;
02090 v[0] = TRUE;
02091 v[1] = TRUE;
02092
02093 for (i=nargs-1 ; i >= 0; i--) {
02094 args[i] = cwh_expr_operand(NULL);
02095 }
02096
02097 cwh_intrin_call(intrin, nargs, args, sz, v, type);
02098 if (type != MTYPE_V ) {
02099 wn = cwh_stmt_return_scalar(NULL, NULL, Be_Type_Tbl(type), FALSE);
02100 cwh_stk_push(wn,WN_item);
02101 }
02102 }
02103
02104 #define IEEE_INTRINCALL(name,intrin,rty,nargs,warn_msg) \
02105 extern void name (void) {cwh_intrin_ieee_intrin_call_helper(INTRN_##intrin,rty,nargs,warn_msg,#intrin); }
02106
02107 IEEE_INTRINCALL(fei_set_all_estat,SET_IEEE_EXCEPTIONS,MTYPE_V,1,TRUE);
02108 IEEE_INTRINCALL(fei_get_interupt,GET_IEEE_INTERRUPTS,MTYPE_I4,0,FALSE);
02109 IEEE_INTRINCALL(fei_get_all_estat,GET_IEEE_EXCEPTIONS,MTYPE_I4,0,TRUE);
02110 IEEE_INTRINCALL(fei_readsr,GET_IEEE_STATUS,MTYPE_I4,1,TRUE);
02111 IEEE_INTRINCALL(fei_get_rmode,GET_IEEE_ROUNDING_MODE,MTYPE_I4,0,FALSE);
02112 IEEE_INTRINCALL(fei_set_rmode,SET_IEEE_ROUNDING_MODE,MTYPE_V,1,TRUE);
02113 IEEE_INTRINCALL(fei_set_ieee_stat,SET_IEEE_STATUS,MTYPE_V,1,TRUE);
02114 IEEE_INTRINCALL(fei_set_interupt,SET_IEEE_INTERRUPTS,MTYPE_V,1,TRUE);
02115 IEEE_INTRINCALL(fei_set_estat,SET_IEEE_EXCEPTION,MTYPE_V,2,TRUE);
02116 IEEE_INTRINCALL(fei_dsbl_interupt,DISABLE_IEEE_INTERRUPT,MTYPE_V,1,TRUE);
02117 IEEE_INTRINCALL(fei_enbl_interupt,ENABLE_IEEE_INTERRUPT,MTYPE_V,1,TRUE);
02118
02119
02120
02121
02122 static void
02123 cwh_intrin_ieee_intrin_helper(INTRINSIC intrin,BOOL issue_warning,const char *iname)
02124 {
02125 WN *args;
02126 WN *sz;
02127 BOOL v;
02128
02129 WN *wn;
02130 TY_IDX ty;
02131 WN *oldblock;
02132
02133 if (issue_warning && (Opt_Level != 0)) {
02134 ErrMsg(EC_IEEE_Intrinsic_Warning,iname);
02135 }
02136
02137 oldblock = cwh_block_new_and_current();
02138
02139 args = cwh_expr_operand(NULL);
02140 sz = NULL;
02141 v = TRUE;
02142 cwh_intrin_call(intrin, 1, &args, &sz, &v, MTYPE_I4);
02143
02144
02145 wn = cwh_stmt_return_scalar(NULL, NULL, logical4_ty, FALSE);
02146 cwh_stk_push(wn,WN_item);
02147 wn = cwh_intrin_get_return_value(MTYPE_I4,"f90ieeelogval");
02148
02149
02150 oldblock = cwh_block_exchange_current(oldblock);
02151
02152
02153 wn = WN_CreateComma(OPC_I4COMMA,oldblock,wn);
02154 cwh_stk_push_typed(wn,WN_item,logical4_ty);
02155 }
02156
02157
02158 void
02159 fei_test_interupt(void)
02160 {
02161 cwh_intrin_ieee_intrin_helper(INTRN_TEST_IEEE_INTERRUPT,FALSE,NULL);
02162 }
02163
02164 void
02165 fei_test_estat(void)
02166 {
02167 cwh_intrin_ieee_intrin_helper(INTRN_TEST_IEEE_EXCEPTION,TRUE,"TEST_IEEE_EXCEPTION");
02168 }
02169
02170
02171
02172
02173
02174 void fei_omp_set_lock(void)
02175 {
02176 WN *args;
02177 WN *wn;
02178 INT64 flags = 0;
02179
02180 if (!omp_set_lock_st) {
02181 omp_set_lock_st = cwh_intrin_make_intrinsic_symbol("omp_set_lock_",MTYPE_V);
02182 }
02183 args = cwh_expr_address(f_T_PASSED);
02184 cwh_stk_push(omp_set_lock_st,ST_item);
02185 cwh_stk_push(args,WN_item);
02186 cwh_stmt_call_helper(1,Be_Type_Tbl(MTYPE_V),0,flags);
02187
02188
02189 wn = WN_CreateBarrier( FALSE, 0 );
02190 cwh_block_append(wn);
02191 }
02192
02193 void fei_omp_unset_lock(void)
02194 {
02195 WN *args;
02196 WN *wn;
02197 INT64 flags = 0;
02198
02199 if (!omp_unset_lock_st) {
02200 omp_unset_lock_st = cwh_intrin_make_intrinsic_symbol("omp_unset_lock_",MTYPE_V);
02201 }
02202
02203 wn = WN_CreateBarrier( TRUE, 0 );
02204 cwh_block_append(wn);
02205
02206 args = cwh_expr_address(f_T_PASSED);
02207 cwh_stk_push(omp_unset_lock_st,ST_item);
02208 cwh_stk_push(args,WN_item);
02209 cwh_stmt_call_helper(1,Be_Type_Tbl(MTYPE_V),0,flags);
02210
02211 }
02212
02213
02214 void fei_omp_test_lock(void)
02215 {
02216 WN *args;
02217 WN *wn;
02218 WN *rval;
02219 INT64 flags = 0;
02220
02221 if (!omp_test_lock_st) {
02222 omp_test_lock_st = cwh_intrin_make_intrinsic_symbol("omp_test_lock_",MTYPE_I4);
02223 }
02224
02225 args = cwh_expr_address(f_T_PASSED);
02226 cwh_stk_push(omp_test_lock_st,ST_item);
02227 cwh_stk_push(args,WN_item);
02228 cwh_stmt_call_helper(1,Be_Type_Tbl(MTYPE_I4),0,flags);
02229 rval = cwh_intrin_get_return_value(MTYPE_I4,"@f90testlock");
02230
02231
02232 wn = WN_CreateBarrier( FALSE, 0 );
02233 cwh_block_append(wn);
02234
02235
02236 cwh_stk_push_typed(rval,WN_item,logical4_ty);
02237 }
02238
02239
02240
02241
02242
02243
02244
02245
02246
02247
02248 static void
02249 cwh_intrin_sync_intrin(INTRINSIC i4intrin, INTRINSIC i8intrin, TYPE_ID rtype, INT num_args)
02250 {
02251 WN *args[3];
02252 BOOL v[3];
02253 WN *sz[3];
02254 INT i;
02255 ST *st;
02256 WN *wn;
02257 TYPE_ID atype;
02258 INTRINSIC intr;
02259
02260
02261 cwh_block_append(WN_CreateBarrier (TRUE, 0));
02262 atype = rtype;
02263
02264
02265 for (i=num_args-1; i >= 0; i--) {
02266 sz[i] = NULL;
02267 if (i != 0) {
02268 v[i] = TRUE;
02269 args[i] = cwh_expr_operand(NULL);
02270 } else {
02271 v[i] = FALSE;
02272 if (cwh_stk_get_class() == ST_item) {
02273 args[i] = cwh_expr_address(f_T_PASSED);
02274 } else {
02275
02276 wn = cwh_expr_operand(NULL);
02277 atype = WNRTY(wn);
02278 st = cwh_stab_temp_ST(Be_Type_Tbl(atype),"synctmp");
02279 cwh_addr_store_ST(st,0,0,wn);
02280 args[i] = cwh_addr_address_ST(st,0);
02281 cwh_expr_set_flags(st,f_T_PASSED);
02282 }
02283 }
02284 }
02285
02286
02287 if (rtype == MTYPE_V && atype != MTYPE_V) {
02288 intr = (atype == MTYPE_I8 ? i8intrin : i4intrin);
02289 } else if (rtype == MTYPE_V && atype == MTYPE_V) {
02290 intr = i4intrin;
02291 } else {
02292 intr = (rtype == MTYPE_I8 ? i8intrin : i4intrin);
02293 }
02294
02295
02296 cwh_intrin_call(intr, num_args, args, sz, v, rtype);
02297
02298 if (rtype != MTYPE_V) {
02299
02300 wn = cwh_stmt_return_scalar(NULL, NULL, Be_Type_Tbl(rtype), FALSE);
02301 cwh_stk_push(wn,WN_item);
02302 wn = cwh_intrin_get_return_value(rtype,"syncpreg");
02303 cwh_stk_push(wn,WN_item);
02304 }
02305
02306
02307 cwh_block_append(WN_CreateBarrier (FALSE, 0));
02308 }
02309
02310 #define SYNC_INTRIN(name,iname,nargs) void name (TYPE type) {\
02311 cwh_intrin_sync_intrin(INTRN_##iname##_I4,INTRN_##iname##_I8,TY_mtype(cast_to_TY(t_TY(type))),nargs);}
02312
02313
02314 SYNC_INTRIN(fei_fetch_and_add,FETCH_AND_ADD,2)
02315 SYNC_INTRIN(fei_fetch_and_and,FETCH_AND_AND,2)
02316 SYNC_INTRIN(fei_fetch_and_nand,FETCH_AND_NAND,2)
02317 SYNC_INTRIN(fei_fetch_and_or,FETCH_AND_OR,2)
02318 SYNC_INTRIN(fei_fetch_and_sub,FETCH_AND_SUB,2)
02319 SYNC_INTRIN(fei_fetch_and_xor,FETCH_AND_XOR,2)
02320 SYNC_INTRIN(fei_add_and_fetch,ADD_AND_FETCH,2)
02321 SYNC_INTRIN(fei_and_and_fetch,AND_AND_FETCH,2)
02322 SYNC_INTRIN(fei_nand_and_fetch,NAND_AND_FETCH,2)
02323 SYNC_INTRIN(fei_or_and_fetch,OR_AND_FETCH,2)
02324 SYNC_INTRIN(fei_sub_and_fetch,SUB_AND_FETCH,2)
02325 SYNC_INTRIN(fei_xor_and_fetch,XOR_AND_FETCH,2)
02326 SYNC_INTRIN(fei_compare_and_swap,COMPARE_AND_SWAP,3)
02327 SYNC_INTRIN(fei_lock_test_and_set,LOCK_TEST_AND_SET,2)
02328
02329 void
02330 fei_synchronize (void)
02331 {
02332 cwh_intrin_sync_intrin(INTRN_SYNCHRONIZE,INTRN_SYNCHRONIZE,MTYPE_V,0);
02333 }
02334
02335 void
02336 fei_lock_release(void)
02337 {
02338 cwh_intrin_sync_intrin(INTRN_LOCK_RELEASE_I4,INTRN_LOCK_RELEASE_I8,MTYPE_V,1);
02339 }
02340
02341 #ifdef KEY
02342 static void
02343 help_make_intrin_symbol(ST **symbol, const char *func_name, TYPE_ID result_type) {
02344 if (! *symbol) {
02345 *symbol = cwh_intrin_make_intrinsic_symbol(func_name,result_type);
02346 }
02347 }
02348
02349
02350
02351
02352
02353
02354
02355
02356
02357 void
02358 fei_erf (TYPE type, int complement) {
02359 WN *addr;
02360 WN *call;
02361 INT64 flags = 0;
02362
02363 const char *func_name;
02364 TYPE_ID result_type = TY_mtype(cast_to_TY(t_TY(type)));
02365 ST *symbol;
02366
02367 if (complement) {
02368 if (MTYPE_F4 == result_type) {
02369 func_name = "erfc_";
02370 symbol = erfc_st;
02371 }
02372 else {
02373 func_name = "derfc_";
02374 symbol = derfc_st;
02375 }
02376 }
02377 else {
02378 if (MTYPE_F4 == result_type) {
02379 func_name = "erf_";
02380 symbol = erf_st;
02381 }
02382 else {
02383 func_name = "derf_";
02384 symbol = derf_st;
02385 }
02386 }
02387
02388 help_make_intrin_symbol(&symbol, func_name, result_type);
02389
02390 addr = cwh_expr_address(f_T_PASSED);
02391 cwh_stk_push(symbol,ST_item);
02392 cwh_stk_push(addr,ADDR_item);
02393 call = cwh_stmt_call_helper(1,Be_Type_Tbl(result_type),0,flags);
02394 WN *wn = cwh_intrin_get_return_value (result_type,"@f90erf{c}");
02395 cwh_stk_push(wn,WN_item);
02396 }
02397 #endif
02398
02399
02400
02401
02402
02403
02404
02405
02406
02407
02408
02409
02410
02411
02412
02413
02414
02415
02416 extern WN *
02417 cwh_intrin_call(INTRINSIC intr, INT16 numargs, WN ** k, WN**sz, BOOL *v, TYPE_ID bt )
02418 {
02419 INT16 i ;
02420 OPCODE opc ;
02421 WN * wn ;
02422
02423 opc = cwh_make_typed_opcode(OPR_INTRINSIC_CALL, bt, MTYPE_V);
02424
02425 for (i = 0 ; i < numargs; i++) {
02426 if (v[i])
02427 k[i] = cwh_intrin_wrap_value_parm(k[i]);
02428 else if (sz[i] != NULL)
02429 k[i] = cwh_intrin_wrap_char_parm(k[i],sz[i]);
02430 else
02431 k[i] = cwh_intrin_wrap_ref_parm(k[i], (TY_IDX) NULL);
02432 }
02433
02434 wn = WN_Create_Intrinsic(opc,intr,numargs,k);
02435
02436 WN_Set_Call_Default_Flags(wn);
02437
02438 cwh_block_append(wn);
02439
02440 return (wn);
02441 }
02442
02443
02444
02445
02446
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
02457
02458
02459 extern WN *
02460 cwh_intrin_op(INTRINSIC intr, INT16 numargs, WN ** k, WN**sz, BOOL *v, TYPE_ID bt )
02461 {
02462 INT16 i ;
02463 OPCODE opc ;
02464 WN * wn ;
02465
02466 opc = cwh_make_typed_opcode(OPR_INTRINSIC_OP, bt, MTYPE_V);
02467
02468 for (i = 0 ; i < numargs; i++) {
02469 if (v[i])
02470 k[i] = cwh_intrin_wrap_value_parm(k[i]);
02471 else if (sz[i] != NULL)
02472 k[i] = cwh_intrin_wrap_char_parm(k[i],sz[i]);
02473 else
02474 k[i] = cwh_intrin_wrap_ref_parm(k[i], (TY_IDX) NULL);
02475 }
02476
02477 wn = WN_Create_Intrinsic(opc,intr,numargs,k);
02478
02479 return(wn);
02480 }
02481
02482
02483
02484
02485
02486
02487
02488
02489
02490
02491
02492 static WN *
02493 cwh_intrin_build(WN **k, INTRINSIC intr,TYPE_ID bt, INT numargs)
02494 {
02495 INT i;
02496 OPCODE opc;
02497 WN *wn ;
02498
02499 opc = cwh_make_typed_opcode(OPR_INTRINSIC_OP, bt, MTYPE_V);
02500
02501 for (i = 0 ; i < numargs; i++)
02502 k[i] = cwh_intrin_wrap_value_parm(k[i]);
02503
02504 wn = WN_Create_Intrinsic(opc,intr,numargs,k);
02505
02506 return wn ;
02507 }
02508
02509
02510
02511
02512
02513
02514
02515
02516
02517
02518
02519
02520
02521 extern void
02522 cwh_whirl_simplfier_control(BOOL onoff)
02523 {
02524 #if 0
02525 static INT32 onoff_count=0;
02526 static BOOL simplifier_enabled;
02527
02528 printf("onoff count = %d\n",onoff_count);
02529 if (onoff) {
02530
02531 if (onoff_count == 1) {
02532 (void) WN_Simplifier_Enable(save_wn_simplifier_enable);
02533 }
02534 if (onoff_count > 0) {
02535 onoff_count -= 1;
02536 }
02537 } else {
02538
02539 (void) WN_Simplifier_Enable(save_wn_simplifier_enable);
02540 onoff_count += 1;
02541 }
02542 #endif
02543 }