1 /* intrin.c -- Recognize references to intrinsics
2 Copyright (C) 1995, 1996, 1997, 1998, 2002 Free Software Foundation, Inc.
3 Contributed by James Craig Burley.
5 This file is part of GNU Fortran.
7 GNU Fortran is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU Fortran is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Fortran; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
33 struct _ffeintrin_name_
35 const char *const name_uc;
36 const char *const name_lc;
37 const char *const name_ic;
38 const ffeintrinGen generic;
39 const ffeintrinSpec specific;
42 struct _ffeintrin_gen_
44 const char *const name; /* Name as seen in program. */
45 const ffeintrinSpec specs[2];
48 struct _ffeintrin_spec_
50 const char *const name; /* Uppercase name as seen in source code,
51 lowercase if no source name, "none" if no
52 name at all (NONE case). */
53 const bool is_actualarg; /* Ok to pass as actual arg if -pedantic. */
54 const ffeintrinFamily family;
55 const ffeintrinImp implementation;
58 struct _ffeintrin_imp_
60 const char *const name; /* Name of implementation. */
61 const ffecomGfrt gfrt_direct;/* library routine, direct-callable form. */
62 const ffecomGfrt gfrt_f2c; /* library routine, f2c-callable form. */
63 const ffecomGfrt gfrt_gnu; /* library routine, gnu-callable form. */
64 const char *const control;
68 static ffebad ffeintrin_check_ (ffeintrinImp imp, ffebldOp op,
69 ffebld args, ffeinfoBasictype *xbt,
71 ffetargetCharacterSize *xsz,
75 static bool ffeintrin_check_any_ (ffebld arglist);
76 static int ffeintrin_cmp_name_ (const void *name, const void *intrinsic);
78 static const struct _ffeintrin_name_ ffeintrin_names_[]
81 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) \
82 { UPPER, LOWER, MIXED, FFEINTRIN_ ## GEN, FFEINTRIN_ ## SPEC },
83 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
84 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
85 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
86 #define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
95 static const struct _ffeintrin_gen_ ffeintrin_gens_[]
98 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC)
99 #define DEFGEN(CODE,NAME,SPEC1,SPEC2) \
100 { NAME, { SPEC1, SPEC2, }, },
101 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
102 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
103 #define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
104 #include "intrin.def"
112 static const struct _ffeintrin_imp_ ffeintrin_imps_[]
115 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC)
116 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
117 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
118 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \
119 { NAME, FFECOM_gfrt ## GFRTDIRECT, FFECOM_gfrt ## GFRTF2C, \
120 FFECOM_gfrt ## GFRTGNU, CONTROL, FALSE },
121 #define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD) \
122 { NAME, FFECOM_gfrt ## GFRTDIRECT, FFECOM_gfrt ## GFRTF2C, \
123 FFECOM_gfrt ## GFRTGNU, CONTROL, Y2KBAD },
124 #include "intrin.def"
132 static const struct _ffeintrin_spec_ ffeintrin_specs_[]
135 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC)
136 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
137 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) \
138 { NAME, CALLABLE, FAMILY, IMP, },
139 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
140 #define DEFIMPY(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL,Y2KBAD)
141 #include "intrin.def"
150 ffeintrin_check_ (ffeintrinImp imp, ffebldOp op,
151 ffebld args, ffeinfoBasictype *xbt,
152 ffeinfoKindtype *xkt,
153 ffetargetCharacterSize *xsz,
158 const char *c = ffeintrin_imps_[imp].control;
159 bool subr = (c[0] == '-');
164 ffetargetCharacterSize sz = FFETARGET_charactersizeNONE;
165 ffeinfoKindtype firstarg_kt;
167 ffeinfoBasictype col_bt = FFEINFO_basictypeNONE;
168 ffeinfoKindtype col_kt = FFEINFO_kindtypeNONE;
169 int colon = (c[2] == ':') ? 2 : 3;
172 /* Check procedure type (function vs. subroutine) against
175 if (op == FFEBLD_opSUBRREF)
178 return FFEBAD_INTRINSIC_IS_FUNC;
180 else if (op == FFEBLD_opFUNCREF)
183 return FFEBAD_INTRINSIC_IS_SUBR;
186 return FFEBAD_INTRINSIC_REF;
188 /* Check the arglist for validity. */
191 && (ffebld_head (args) != NULL))
192 firstarg_kt = ffeinfo_kindtype (ffebld_info (ffebld_head (args)));
194 firstarg_kt = FFEINFO_kindtype;
196 for (argc = &c[colon + 3],
201 char optional = '\0';
202 char required = '\0';
208 bool lastarg_complex = FALSE;
210 /* We don't do anything with keywords yet. */
213 } while (*(++argc) != '=');
219 optional = *(argc++);
223 required = *(argc++);
228 length = *++argc - '0';
230 length = 10 * length + (*(argc++) - '0');
237 elements = *++argc - '0';
239 elements = 10 * elements + (*(argc++) - '0');
242 else if (*argc == '&')
257 /* Break out of this loop only when current arg spec completely
266 ffeinfoBasictype abt = FFEINFO_basictypeNONE;
267 ffeinfoKindtype akt = FFEINFO_kindtypeNONE;
270 || (ffebld_head (arg) == NULL))
272 if (required != '\0')
273 return FFEBAD_INTRINSIC_TOOFEW;
274 if (optional == '\0')
275 return FFEBAD_INTRINSIC_TOOFEW;
277 arg = ffebld_trail (arg);
278 break; /* Try next argspec. */
281 a = ffebld_head (arg);
283 anynum = (ffeinfo_basictype (i) == FFEINFO_basictypeHOLLERITH)
284 || (ffeinfo_basictype (i) == FFEINFO_basictypeTYPELESS);
286 /* See how well the arg matches up to the spec. */
291 okay = (ffeinfo_basictype (i) == FFEINFO_basictypeCHARACTER)
293 || (ffeinfo_size (i) == (ffetargetCharacterSize) length));
298 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX);
299 abt = FFEINFO_basictypeCOMPLEX;
304 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER);
305 abt = FFEINFO_basictypeINTEGER;
310 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL);
311 abt = FFEINFO_basictypeLOGICAL;
316 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
317 abt = FFEINFO_basictypeREAL;
322 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
323 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL);
328 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX)
329 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
334 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX)
335 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
336 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
341 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
342 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
346 okay = ((ffebld_op (a) == FFEBLD_opLABTER)
347 || (ffebld_op (a) == FFEBLD_opLABTOK));
353 okay = (((((ffeinfo_basictype (i) == FFEINFO_basictypeNONE)
354 && (ffeinfo_kindtype (i) == FFEINFO_kindtypeNONE)
355 && (ffeinfo_kind (i) == FFEINFO_kindSUBROUTINE))
356 || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
357 && (ffeinfo_kindtype (i) == FFEINFO_kindtypeINTEGERDEFAULT)
358 && (ffeinfo_kind (i) == FFEINFO_kindFUNCTION))
359 || (ffeinfo_kind (i) == FFEINFO_kindNONE))
360 && ((ffeinfo_where (i) == FFEINFO_whereDUMMY)
361 || (ffeinfo_where (i) == FFEINFO_whereGLOBAL)))
362 || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
363 && (ffeinfo_kind (i) == FFEINFO_kindENTITY)));
376 case '1': case '2': case '3': case '4': case '5':
377 case '6': case '7': case '8': case '9':
379 if ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
380 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL))
383 { /* Translate to internal kinds for now! */
404 akt = ffecom_pointer_kind ();
408 okay &= anynum || (ffeinfo_kindtype (i) == akt);
412 okay &= anynum || (ffeinfo_kindtype (i) == firstarg_kt);
413 akt = (firstarg_kt == FFEINFO_kindtype) ? FFEINFO_kindtypeNONE
430 if (ffeinfo_rank (i) != 0)
435 if ((ffeinfo_rank (i) != 1)
436 || (ffebld_op (a) != FFEBLD_opSYMTER)
437 || ((b = ffesymbol_arraysize (ffebld_symter (a))) == NULL)
438 || (ffebld_op (b) != FFEBLD_opCONTER)
439 || (ffeinfo_basictype (ffebld_info (b)) != FFEINFO_basictypeINTEGER)
440 || (ffeinfo_kindtype (ffebld_info (b)) != FFEINFO_kindtypeINTEGERDEFAULT)
441 || (ffebld_constant_integer1 (ffebld_conter (b)) != elements))
449 if ((ffeinfo_kind (i) != FFEINFO_kindENTITY)
450 || ((ffebld_op (a) != FFEBLD_opSYMTER)
451 && (ffebld_op (a) != FFEBLD_opSUBSTR)
452 && (ffebld_op (a) != FFEBLD_opARRAYREF)))
458 if ((ffeinfo_kind (i) != FFEINFO_kindENTITY)
459 || ((ffebld_op (a) != FFEBLD_opSYMTER)
460 && (ffebld_op (a) != FFEBLD_opARRAYREF)
461 && (ffebld_op (a) != FFEBLD_opSUBSTR)))
470 if (ffeinfo_kind (i) != FFEINFO_kindENTITY)
475 if ((optional == '!')
481 /* If it wasn't optional, it's an error,
482 else maybe it could match a later argspec. */
483 if (optional == '\0')
484 return FFEBAD_INTRINSIC_REF;
485 break; /* Try next argspec. */
489 = (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX);
493 /* If we know dummy arg type, convert to that now. */
495 if ((abt != FFEINFO_basictypeNONE)
496 && (akt != FFEINFO_kindtypeNONE)
499 /* We have a known type, convert hollerith/typeless
502 a = ffeexpr_convert (a, t, NULL,
504 FFETARGET_charactersizeNONE,
506 ffebld_set_head (arg, a);
510 arg = ffebld_trail (arg); /* Arg accepted, now move on. */
513 continue; /* Go ahead and try another arg. */
514 if (required == '\0')
516 if ((required == 'n')
517 || (required == '+'))
522 else if (required == 'p')
528 return FFEBAD_INTRINSIC_TOOMANY;
530 /* Set up the initial type for the return value of the function. */
536 bt = FFEINFO_basictypeCHARACTER;
537 sz = (c[2] == '*') ? FFETARGET_charactersizeNONE : 1;
541 bt = FFEINFO_basictypeCOMPLEX;
545 bt = FFEINFO_basictypeINTEGER;
549 bt = FFEINFO_basictypeLOGICAL;
553 bt = FFEINFO_basictypeREAL;
564 bt = FFEINFO_basictypeNONE;
570 case '1': case '2': case '3': case '4': case '5':
571 case '6': case '7': case '8': case '9':
573 if ((bt == FFEINFO_basictypeINTEGER)
574 || (bt == FFEINFO_basictypeLOGICAL))
577 { /* Translate to internal kinds for now! */
598 kt = ffecom_pointer_kind ();
615 kt = FFEINFO_kindtypeNONE;
619 /* Determine collective type of COL, if there is one. */
621 if (need_col || c[colon + 1] != '-')
624 bool have_anynum = FALSE;
627 for (arg = args, arg_count=0;
629 arg = ffebld_trail (arg), arg_count++ )
631 ffebld a = ffebld_head (arg);
639 if ( c[colon+1] != '*' && (c[colon+1]-'0') != arg_count )
642 anynum = (ffeinfo_basictype (i) == FFEINFO_basictypeHOLLERITH)
643 || (ffeinfo_basictype (i) == FFEINFO_basictypeTYPELESS);
650 if ((col_bt == FFEINFO_basictypeNONE)
651 && (col_kt == FFEINFO_kindtypeNONE))
653 col_bt = ffeinfo_basictype (i);
654 col_kt = ffeinfo_kindtype (i);
658 ffeexpr_type_combine (&col_bt, &col_kt,
660 ffeinfo_basictype (i),
661 ffeinfo_kindtype (i),
663 if ((col_bt == FFEINFO_basictypeNONE)
664 || (col_kt == FFEINFO_kindtypeNONE))
665 return FFEBAD_INTRINSIC_REF;
670 && ((col_bt == FFEINFO_basictypeNONE)
671 || (col_kt == FFEINFO_kindtypeNONE)))
673 /* No type, but have hollerith/typeless. Use type of return
674 value to determine type of COL. */
679 return FFEBAD_INTRINSIC_REF;
684 if ((col_bt != FFEINFO_basictypeNONE)
685 && (col_bt != FFEINFO_basictypeINTEGER))
686 return FFEBAD_INTRINSIC_REF;
692 col_bt = FFEINFO_basictypeINTEGER;
693 col_kt = FFEINFO_kindtypeINTEGER1;
697 if ((col_bt != FFEINFO_basictypeNONE)
698 && (col_bt != FFEINFO_basictypeCOMPLEX))
699 return FFEBAD_INTRINSIC_REF;
700 col_bt = FFEINFO_basictypeCOMPLEX;
701 col_kt = FFEINFO_kindtypeREAL1;
705 if ((col_bt != FFEINFO_basictypeNONE)
706 && (col_bt != FFEINFO_basictypeREAL))
707 return FFEBAD_INTRINSIC_REF;
710 col_bt = FFEINFO_basictypeREAL;
711 col_kt = FFEINFO_kindtypeREAL1;
719 okay = (col_bt == FFEINFO_basictypeINTEGER)
720 || (col_bt == FFEINFO_basictypeLOGICAL);
726 okay = (col_bt == FFEINFO_basictypeCOMPLEX)
727 || (col_bt == FFEINFO_basictypeREAL);
733 okay = (col_bt == FFEINFO_basictypeCOMPLEX)
734 || (col_bt == FFEINFO_basictypeINTEGER)
735 || (col_bt == FFEINFO_basictypeREAL);
741 okay = (col_bt == FFEINFO_basictypeINTEGER)
742 || (col_bt == FFEINFO_basictypeREAL)
743 || (col_bt == FFEINFO_basictypeCOMPLEX);
745 bt = ((col_bt != FFEINFO_basictypeCOMPLEX) ? col_bt
746 : FFEINFO_basictypeREAL);
758 if (col_bt == FFEINFO_basictypeCOMPLEX)
760 if (col_kt != FFEINFO_kindtypeREALDEFAULT)
761 *check_intrin = TRUE;
769 return FFEBAD_INTRINSIC_REF;
772 /* Now, convert args in the arglist to the final type of the COL. */
774 for (argno = 0, argc = &c[colon + 3],
779 char optional = '\0';
780 char required = '\0';
786 bool lastarg_complex = FALSE;
788 /* We don't do anything with keywords yet. */
791 } while (*(++argc) != '=');
797 optional = *(argc++);
801 required = *(argc++);
806 length = *++argc - '0';
808 length = 10 * length + (*(argc++) - '0');
815 elements = *++argc - '0';
817 elements = 10 * elements + (*(argc++) - '0');
820 else if (*argc == '&')
835 /* Break out of this loop only when current arg spec completely
844 ffeinfoBasictype abt = FFEINFO_basictypeNONE;
845 ffeinfoKindtype akt = FFEINFO_kindtypeNONE;
848 || (ffebld_head (arg) == NULL))
851 arg = ffebld_trail (arg);
852 break; /* Try next argspec. */
855 a = ffebld_head (arg);
857 anynum = (ffeinfo_basictype (i) == FFEINFO_basictypeHOLLERITH)
858 || (ffeinfo_basictype (i) == FFEINFO_basictypeTYPELESS);
860 /* Determine what the default type for anynum would be. */
864 switch (c[colon + 1])
868 case '0': case '1': case '2': case '3': case '4':
869 case '5': case '6': case '7': case '8': case '9':
870 if (argno != (c[colon + 1] - '0'))
879 /* Again, match arg up to the spec. We go through all of
880 this again to properly follow the contour of optional
881 arguments. Probably this level of flexibility is not
882 needed, perhaps it's even downright naughty. */
887 okay = (ffeinfo_basictype (i) == FFEINFO_basictypeCHARACTER)
889 || (ffeinfo_size (i) == (ffetargetCharacterSize) length));
894 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX);
895 abt = FFEINFO_basictypeCOMPLEX;
900 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER);
901 abt = FFEINFO_basictypeINTEGER;
906 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL);
907 abt = FFEINFO_basictypeLOGICAL;
912 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
913 abt = FFEINFO_basictypeREAL;
918 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
919 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL);
924 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX)
925 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
930 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX)
931 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
932 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
937 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
938 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
942 okay = ((ffebld_op (a) == FFEBLD_opLABTER)
943 || (ffebld_op (a) == FFEBLD_opLABTOK));
949 okay = (((((ffeinfo_basictype (i) == FFEINFO_basictypeNONE)
950 && (ffeinfo_kindtype (i) == FFEINFO_kindtypeNONE)
951 && (ffeinfo_kind (i) == FFEINFO_kindSUBROUTINE))
952 || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
953 && (ffeinfo_kindtype (i) == FFEINFO_kindtypeINTEGERDEFAULT)
954 && (ffeinfo_kind (i) == FFEINFO_kindFUNCTION))
955 || (ffeinfo_kind (i) == FFEINFO_kindNONE))
956 && ((ffeinfo_where (i) == FFEINFO_whereDUMMY)
957 || (ffeinfo_where (i) == FFEINFO_whereGLOBAL)))
958 || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
959 && (ffeinfo_kind (i) == FFEINFO_kindENTITY)));
972 case '1': case '2': case '3': case '4': case '5':
973 case '6': case '7': case '8': case '9':
975 if ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
976 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL))
979 { /* Translate to internal kinds for now! */
1000 akt = ffecom_pointer_kind ();
1004 okay &= anynum || (ffeinfo_kindtype (i) == akt);
1008 okay &= anynum || (ffeinfo_kindtype (i) == firstarg_kt);
1009 akt = (firstarg_kt == FFEINFO_kindtype) ? FFEINFO_kindtypeNONE
1026 if (ffeinfo_rank (i) != 0)
1031 if ((ffeinfo_rank (i) != 1)
1032 || (ffebld_op (a) != FFEBLD_opSYMTER)
1033 || ((b = ffesymbol_arraysize (ffebld_symter (a))) == NULL)
1034 || (ffebld_op (b) != FFEBLD_opCONTER)
1035 || (ffeinfo_basictype (ffebld_info (b)) != FFEINFO_basictypeINTEGER)
1036 || (ffeinfo_kindtype (ffebld_info (b)) != FFEINFO_kindtypeINTEGERDEFAULT)
1037 || (ffebld_constant_integer1 (ffebld_conter (b)) != elements))
1045 if ((ffeinfo_kind (i) != FFEINFO_kindENTITY)
1046 || ((ffebld_op (a) != FFEBLD_opSYMTER)
1047 && (ffebld_op (a) != FFEBLD_opSUBSTR)
1048 && (ffebld_op (a) != FFEBLD_opARRAYREF)))
1054 if ((ffeinfo_kind (i) != FFEINFO_kindENTITY)
1055 || ((ffebld_op (a) != FFEBLD_opSYMTER)
1056 && (ffebld_op (a) != FFEBLD_opARRAYREF)
1057 && (ffebld_op (a) != FFEBLD_opSUBSTR)))
1066 if (ffeinfo_kind (i) != FFEINFO_kindENTITY)
1071 if ((optional == '!')
1077 /* If it wasn't optional, it's an error,
1078 else maybe it could match a later argspec. */
1079 if (optional == '\0')
1080 return FFEBAD_INTRINSIC_REF;
1081 break; /* Try next argspec. */
1085 = (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX);
1087 if (anynum && commit)
1089 /* If we know dummy arg type, convert to that now. */
1091 if (abt == FFEINFO_basictypeNONE)
1092 abt = FFEINFO_basictypeINTEGER;
1093 if (akt == FFEINFO_kindtypeNONE)
1094 akt = FFEINFO_kindtypeINTEGER1;
1096 /* We have a known type, convert hollerith/typeless to it. */
1098 a = ffeexpr_convert (a, t, NULL,
1100 FFETARGET_charactersizeNONE,
1101 FFEEXPR_contextLET);
1102 ffebld_set_head (arg, a);
1104 else if ((c[colon + 1] == '*') && commit)
1106 /* This is where we promote types to the consensus
1107 type for the COL. Maybe this is where -fpedantic
1108 should issue a warning as well. */
1110 a = ffeexpr_convert (a, t, NULL,
1113 FFEEXPR_contextLET);
1114 ffebld_set_head (arg, a);
1117 arg = ffebld_trail (arg); /* Arg accepted, now move on. */
1119 if (optional == '*')
1120 continue; /* Go ahead and try another arg. */
1121 if (required == '\0')
1123 if ((required == 'n')
1124 || (required == '+'))
1129 else if (required == 'p')
1141 ffeintrin_check_any_ (ffebld arglist)
1145 for (; arglist != NULL; arglist = ffebld_trail (arglist))
1147 item = ffebld_head (arglist);
1149 && (ffebld_op (item) == FFEBLD_opANY))
1156 /* Compare a forced-to-uppercase name with a known-upper-case name. */
1159 upcasecmp_ (const char *name, const char *ucname)
1161 for ( ; *name != 0 && *ucname != 0; name++, ucname++)
1163 int i = TOUPPER(*name) - *ucname;
1169 return *name - *ucname;
1172 /* Compare name to intrinsic's name.
1173 The intrinsics table is sorted on the upper case entries; so first
1174 compare irrespective of case on the `uc' entry. If it matches,
1175 compare according to the setting of intrinsics case comparison mode. */
1178 ffeintrin_cmp_name_ (const void *name, const void *intrinsic)
1180 const char *const uc = ((const struct _ffeintrin_name_ *) intrinsic)->name_uc;
1181 const char *const lc = ((const struct _ffeintrin_name_ *) intrinsic)->name_lc;
1182 const char *const ic = ((const struct _ffeintrin_name_ *) intrinsic)->name_ic;
1185 if ((i = upcasecmp_ (name, uc)) == 0)
1187 switch (ffe_case_intrin ())
1190 return strcmp(name, lc);
1191 case FFE_caseINITCAP:
1192 return strcmp(name, ic);
1201 /* Return basic type of intrinsic implementation, based on its
1202 run-time implementation *only*. (This is used only when
1203 the type of an intrinsic name is needed without having a
1204 list of arguments, i.e. an interface signature, such as when
1205 passing the intrinsic itself, or really the run-time-library
1206 function, as an argument.)
1208 If there's no eligible intrinsic implementation, there must be
1209 a bug somewhere else; no such reference should have been permitted
1210 to go this far. (Well, this might be wrong.) */
1213 ffeintrin_basictype (ffeintrinSpec spec)
1218 assert (spec < FFEINTRIN_spec);
1219 imp = ffeintrin_specs_[spec].implementation;
1220 assert (imp < FFEINTRIN_imp);
1223 gfrt = ffeintrin_imps_[imp].gfrt_f2c;
1225 gfrt = ffeintrin_imps_[imp].gfrt_gnu;
1227 assert (gfrt != FFECOM_gfrt);
1229 return ffecom_gfrt_basictype (gfrt);
1232 /* Return family to which specific intrinsic belongs. */
1235 ffeintrin_family (ffeintrinSpec spec)
1237 if (spec >= FFEINTRIN_spec)
1239 return ffeintrin_specs_[spec].family;
1242 /* Check and fill in info on func/subr ref node.
1244 ffebld expr; // FUNCREF or SUBRREF with no info (caller
1245 // gets it from the modified info structure).
1246 ffeinfo info; // Already filled in, will be overwritten.
1247 ffelexToken token; // Used for error message.
1248 ffeintrin_fulfill_generic (&expr, &info, token);
1250 Based on the generic id, figure out which specific procedure is meant and
1251 pick that one. Else return an error, a la _specific. */
1254 ffeintrin_fulfill_generic (ffebld *expr, ffeinfo *info, ffelexToken t)
1259 ffeintrinSpec spec = FFEINTRIN_specNONE;
1260 ffeinfoBasictype bt = FFEINFO_basictypeNONE;
1261 ffeinfoKindtype kt = FFEINFO_kindtypeNONE;
1262 ffetargetCharacterSize sz = FFETARGET_charactersizeNONE;
1264 ffeintrinSpec tspec;
1265 ffeintrinImp nimp = FFEINTRIN_impNONE;
1268 bool highly_specific = FALSE;
1271 op = ffebld_op (*expr);
1272 assert ((op == FFEBLD_opFUNCREF) || (op == FFEBLD_opSUBRREF));
1273 assert (ffebld_op (ffebld_left (*expr)) == FFEBLD_opSYMTER);
1275 gen = ffebld_symter_generic (ffebld_left (*expr));
1276 assert (gen != FFEINTRIN_genNONE);
1278 imp = FFEINTRIN_impNONE;
1281 any = ffeintrin_check_any_ (ffebld_right (*expr));
1284 (((size_t) i) < ARRAY_SIZE (ffeintrin_gens_[gen].specs))
1285 && ((tspec = ffeintrin_gens_[gen].specs[i]) != FFEINTRIN_specNONE)
1289 ffeintrinImp timp = ffeintrin_specs_[tspec].implementation;
1290 ffeinfoBasictype tbt;
1291 ffeinfoKindtype tkt;
1292 ffetargetCharacterSize tsz;
1293 ffeIntrinsicState state
1294 = ffeintrin_state_family (ffeintrin_specs_[tspec].family);
1297 if (state == FFE_intrinsicstateDELETED)
1300 if (timp != FFEINTRIN_impNONE)
1302 if (!(ffeintrin_imps_[timp].control[0] == '-')
1303 != !(ffebld_op (*expr) == FFEBLD_opSUBRREF))
1304 continue; /* Form of reference must match form of specific. */
1307 if (state == FFE_intrinsicstateDISABLED)
1308 terror = FFEBAD_INTRINSIC_DISABLED;
1309 else if (timp == FFEINTRIN_impNONE)
1310 terror = FFEBAD_INTRINSIC_UNIMPL;
1313 terror = ffeintrin_check_ (timp, ffebld_op (*expr),
1314 ffebld_right (*expr),
1315 &tbt, &tkt, &tsz, NULL, t, FALSE);
1316 if (terror == FFEBAD)
1318 if (imp != FFEINTRIN_impNONE)
1320 ffebad_start (FFEBAD_INTRINSIC_AMBIG);
1321 ffebad_here (0, ffelex_token_where_line (t),
1322 ffelex_token_where_column (t));
1323 ffebad_string (ffeintrin_gens_[gen].name);
1324 ffebad_string (ffeintrin_specs_[spec].name);
1325 ffebad_string (ffeintrin_specs_[tspec].name);
1330 if (ffebld_symter_specific (ffebld_left (*expr))
1332 highly_specific = TRUE;
1341 else if (terror != FFEBAD)
1342 { /* This error has precedence over others. */
1343 if ((error == FFEBAD_INTRINSIC_DISABLED)
1344 || (error == FFEBAD_INTRINSIC_UNIMPL))
1349 if (error == FFEBAD)
1353 if (any || (imp == FFEINTRIN_impNONE))
1357 if (error == FFEBAD)
1358 error = FFEBAD_INTRINSIC_REF;
1359 ffebad_start (error);
1360 ffebad_here (0, ffelex_token_where_line (t),
1361 ffelex_token_where_column (t));
1362 ffebad_string (ffeintrin_gens_[gen].name);
1366 *expr = ffebld_new_any ();
1367 *info = ffeinfo_new_any ();
1371 if (!highly_specific && (nimp != FFEINTRIN_impNONE))
1373 fprintf (stderr, "lineno=%ld, gen=%s, imp=%s, timp=%s\n",
1375 ffeintrin_gens_[gen].name,
1376 ffeintrin_imps_[imp].name,
1377 ffeintrin_imps_[nimp].name);
1378 assert ("Ambiguous generic reference" == NULL);
1381 error = ffeintrin_check_ (imp, ffebld_op (*expr),
1382 ffebld_right (*expr),
1383 &bt, &kt, &sz, NULL, t, TRUE);
1384 assert (error == FFEBAD);
1385 *info = ffeinfo_new (bt,
1389 FFEINFO_whereFLEETING,
1391 symter = ffebld_left (*expr);
1392 ffebld_symter_set_specific (symter, spec);
1393 ffebld_symter_set_implementation (symter, imp);
1394 ffebld_set_info (symter,
1398 (bt == FFEINFO_basictypeNONE)
1399 ? FFEINFO_kindSUBROUTINE
1400 : FFEINFO_kindFUNCTION,
1401 FFEINFO_whereINTRINSIC,
1404 if ((ffesymbol_attrs (ffebld_symter (symter)) & FFESYMBOL_attrsTYPE)
1405 && (((bt != ffesymbol_basictype (ffebld_symter (symter)))
1406 || (kt != ffesymbol_kindtype (ffebld_symter (symter)))
1407 || ((sz != FFETARGET_charactersizeNONE)
1408 && (sz != ffesymbol_size (ffebld_symter (symter)))))))
1410 ffebad_start (FFEBAD_INTRINSIC_TYPE);
1411 ffebad_here (0, ffelex_token_where_line (t),
1412 ffelex_token_where_column (t));
1413 ffebad_string (ffeintrin_gens_[gen].name);
1416 if (ffeintrin_imps_[imp].y2kbad)
1418 ffebad_start (FFEBAD_INTRINSIC_Y2KBAD);
1419 ffebad_here (0, ffelex_token_where_line (t),
1420 ffelex_token_where_column (t));
1421 ffebad_string (ffeintrin_gens_[gen].name);
1427 /* Check and fill in info on func/subr ref node.
1429 ffebld expr; // FUNCREF or SUBRREF with no info (caller
1430 // gets it from the modified info structure).
1431 ffeinfo info; // Already filled in, will be overwritten.
1432 bool check_intrin; // May be omitted, else set TRUE if intrinsic needs checking.
1433 ffelexToken token; // Used for error message.
1434 ffeintrin_fulfill_specific (&expr, &info, &check_intrin, token);
1436 Based on the specific id, determine whether the arg list is valid
1437 (number, type, rank, and kind of args) and fill in the info structure
1438 accordingly. Currently don't rewrite the expression, but perhaps
1439 someday do so for constant collapsing, except when an error occurs,
1440 in which case it is overwritten with ANY and info is also overwritten
1444 ffeintrin_fulfill_specific (ffebld *expr, ffeinfo *info,
1445 bool *check_intrin, ffelexToken t)
1452 ffeinfoBasictype bt = FFEINFO_basictypeNONE;
1453 ffeinfoKindtype kt = FFEINFO_kindtypeNONE;
1454 ffetargetCharacterSize sz = FFETARGET_charactersizeNONE;
1455 ffeIntrinsicState state;
1460 op = ffebld_op (*expr);
1461 assert ((op == FFEBLD_opFUNCREF) || (op == FFEBLD_opSUBRREF));
1462 assert (ffebld_op (ffebld_left (*expr)) == FFEBLD_opSYMTER);
1464 gen = ffebld_symter_generic (ffebld_left (*expr));
1465 spec = ffebld_symter_specific (ffebld_left (*expr));
1466 assert (spec != FFEINTRIN_specNONE);
1468 if (gen != FFEINTRIN_genNONE)
1469 name = ffeintrin_gens_[gen].name;
1471 name = ffeintrin_specs_[spec].name;
1473 state = ffeintrin_state_family (ffeintrin_specs_[spec].family);
1475 imp = ffeintrin_specs_[spec].implementation;
1476 if (check_intrin != NULL)
1477 *check_intrin = FALSE;
1479 any = ffeintrin_check_any_ (ffebld_right (*expr));
1481 if (state == FFE_intrinsicstateDISABLED)
1482 error = FFEBAD_INTRINSIC_DISABLED;
1483 else if (imp == FFEINTRIN_impNONE)
1484 error = FFEBAD_INTRINSIC_UNIMPL;
1487 error = ffeintrin_check_ (imp, ffebld_op (*expr),
1488 ffebld_right (*expr),
1489 &bt, &kt, &sz, check_intrin, t, TRUE);
1492 error = FFEBAD; /* Not really needed, but quiet -Wuninitialized. */
1494 if (any || (error != FFEBAD))
1499 ffebad_start (error);
1500 ffebad_here (0, ffelex_token_where_line (t),
1501 ffelex_token_where_column (t));
1502 ffebad_string (name);
1506 *expr = ffebld_new_any ();
1507 *info = ffeinfo_new_any ();
1511 *info = ffeinfo_new (bt,
1515 FFEINFO_whereFLEETING,
1517 symter = ffebld_left (*expr);
1518 ffebld_set_info (symter,
1522 (bt == FFEINFO_basictypeNONE)
1523 ? FFEINFO_kindSUBROUTINE
1524 : FFEINFO_kindFUNCTION,
1525 FFEINFO_whereINTRINSIC,
1528 if ((ffesymbol_attrs (ffebld_symter (symter)) & FFESYMBOL_attrsTYPE)
1529 && (((bt != ffesymbol_basictype (ffebld_symter (symter)))
1530 || (kt != ffesymbol_kindtype (ffebld_symter (symter)))
1531 || (sz != ffesymbol_size (ffebld_symter (symter))))))
1533 ffebad_start (FFEBAD_INTRINSIC_TYPE);
1534 ffebad_here (0, ffelex_token_where_line (t),
1535 ffelex_token_where_column (t));
1536 ffebad_string (name);
1539 if (ffeintrin_imps_[imp].y2kbad)
1541 ffebad_start (FFEBAD_INTRINSIC_Y2KBAD);
1542 ffebad_here (0, ffelex_token_where_line (t),
1543 ffelex_token_where_column (t));
1544 ffebad_string (name);
1550 /* Return run-time index of intrinsic implementation as direct call. */
1553 ffeintrin_gfrt_direct (ffeintrinImp imp)
1555 assert (imp < FFEINTRIN_imp);
1557 return ffeintrin_imps_[imp].gfrt_direct;
1560 /* Return run-time index of intrinsic implementation as actual argument. */
1563 ffeintrin_gfrt_indirect (ffeintrinImp imp)
1565 assert (imp < FFEINTRIN_imp);
1567 if (! ffe_is_f2c ())
1568 return ffeintrin_imps_[imp].gfrt_gnu;
1569 return ffeintrin_imps_[imp].gfrt_f2c;
1581 if (!ffe_is_do_internal_checks ())
1584 assert (FFEINTRIN_gen == ARRAY_SIZE (ffeintrin_gens_));
1585 assert (FFEINTRIN_imp == ARRAY_SIZE (ffeintrin_imps_));
1586 assert (FFEINTRIN_spec == ARRAY_SIZE (ffeintrin_specs_));
1588 for (i = 1; ((size_t) i) < ARRAY_SIZE (ffeintrin_names_); ++i)
1589 { /* Make sure binary-searched list is in alpha
1591 if (strcmp (ffeintrin_names_[i - 1].name_uc,
1592 ffeintrin_names_[i].name_uc) >= 0)
1593 assert ("name list out of order" == NULL);
1596 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffeintrin_names_); ++i)
1598 assert ((ffeintrin_names_[i].generic == FFEINTRIN_genNONE)
1599 || (ffeintrin_names_[i].specific == FFEINTRIN_specNONE));
1601 p1 = ffeintrin_names_[i].name_uc;
1602 p2 = ffeintrin_names_[i].name_lc;
1603 p3 = ffeintrin_names_[i].name_ic;
1604 for (; *p1 != '\0' && *p2 != '\0' && *p3 != '\0'; ++p1, ++p2, ++p3)
1606 if ((ISDIGIT (*p1) || (*p1 == '_')) && (*p1 == *p2) && (*p1 == *p3))
1608 if (! ISUPPER ((unsigned char)*p1) || ! ISLOWER ((unsigned char)*p2)
1609 || (*p1 != TOUPPER (*p2))
1610 || ((*p3 != *p1) && (*p3 != *p2)))
1613 assert ((*p1 == *p2) && (*p1 == *p3) && (*p1 == '\0'));
1616 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffeintrin_imps_); ++i)
1618 const char *c = ffeintrin_imps_[i].control;
1634 fprintf (stderr, "%s: bad return-base-type\n",
1635 ffeintrin_imps_[i].name);
1644 fprintf (stderr, "%s: bad return-kind-type\n",
1645 ffeintrin_imps_[i].name);
1654 fprintf (stderr, "%s: bad return-modifier\n",
1655 ffeintrin_imps_[i].name);
1660 if ((c[colon] != ':') || (c[colon + 2] != ':'))
1662 fprintf (stderr, "%s: bad control\n",
1663 ffeintrin_imps_[i].name);
1666 if ((c[colon + 1] != '-')
1667 && (c[colon + 1] != '*')
1668 && (! ISDIGIT (c[colon + 1])))
1670 fprintf (stderr, "%s: bad COL-spec\n",
1671 ffeintrin_imps_[i].name);
1675 while (c[0] != '\0')
1677 while ((c[0] != '=')
1683 fprintf (stderr, "%s: bad keyword\n",
1684 ffeintrin_imps_[i].name);
1707 fprintf (stderr, "%s: bad arg-base-type\n",
1708 ffeintrin_imps_[i].name);
1716 fprintf (stderr, "%s: bad arg-kind-type\n",
1717 ffeintrin_imps_[i].name);
1722 if ((! ISDIGIT (c[4]))
1724 && (++c, ! ISDIGIT (c[4])
1727 fprintf (stderr, "%s: bad arg-len\n",
1728 ffeintrin_imps_[i].name);
1735 if ((! ISDIGIT (c[4]))
1737 && (++c, ! ISDIGIT (c[4])
1740 fprintf (stderr, "%s: bad arg-rank\n",
1741 ffeintrin_imps_[i].name);
1746 else if ((c[3] == '&')
1761 fprintf (stderr, "%s: bad arg-list\n",
1762 ffeintrin_imps_[i].name);
1769 /* Determine whether intrinsic is okay as an actual argument. */
1772 ffeintrin_is_actualarg (ffeintrinSpec spec)
1774 ffeIntrinsicState state;
1776 if (spec >= FFEINTRIN_spec)
1779 state = ffeintrin_state_family (ffeintrin_specs_[spec].family);
1781 return (!ffe_is_pedantic () || ffeintrin_specs_[spec].is_actualarg)
1783 ? (ffeintrin_imps_[ffeintrin_specs_[spec].implementation].gfrt_f2c
1785 : (ffeintrin_imps_[ffeintrin_specs_[spec].implementation].gfrt_gnu
1787 && ((state == FFE_intrinsicstateENABLED)
1788 || (state == FFE_intrinsicstateHIDDEN));
1791 /* Determine if name is intrinsic, return info.
1793 const char *name; // C-string name of possible intrinsic.
1794 ffelexToken t; // NULL if no diagnostic to be given.
1795 bool explicit; // TRUE if INTRINSIC name.
1796 ffeintrinGen gen; // (TRUE only) Generic id of intrinsic.
1797 ffeintrinSpec spec; // (TRUE only) Specific id of intrinsic.
1798 ffeintrinImp imp; // (TRUE only) Implementation id of intrinsic.
1799 if (ffeintrin_is_intrinsic (name, t, explicit,
1801 // is an intrinsic, use gen, spec, imp, and
1802 // kind accordingly. */
1805 ffeintrin_is_intrinsic (const char *name, ffelexToken t, bool explicit,
1806 ffeintrinGen *xgen, ffeintrinSpec *xspec,
1809 struct _ffeintrin_name_ *intrinsic;
1813 ffeIntrinsicState state;
1814 bool disabled = FALSE;
1815 bool unimpl = FALSE;
1817 intrinsic = bsearch (name, &ffeintrin_names_[0],
1818 ARRAY_SIZE (ffeintrin_names_),
1819 sizeof (struct _ffeintrin_name_),
1820 (void *) ffeintrin_cmp_name_);
1822 if (intrinsic == NULL)
1825 gen = intrinsic->generic;
1826 spec = intrinsic->specific;
1827 imp = ffeintrin_specs_[spec].implementation;
1829 /* Generic is okay only if at least one of its specifics is okay. */
1831 if (gen != FFEINTRIN_genNONE)
1834 ffeintrinSpec tspec;
1837 name = ffeintrin_gens_[gen].name;
1840 (((size_t) i) < ARRAY_SIZE (ffeintrin_gens_[gen].specs))
1842 = ffeintrin_gens_[gen].specs[i]) != FFEINTRIN_specNONE);
1845 state = ffeintrin_state_family (ffeintrin_specs_[tspec].family);
1847 if (state == FFE_intrinsicstateDELETED)
1850 if (state == FFE_intrinsicstateDISABLED)
1856 if (ffeintrin_specs_[tspec].implementation == FFEINTRIN_impNONE)
1862 if ((state == FFE_intrinsicstateENABLED)
1864 && (state == FFE_intrinsicstateHIDDEN)))
1871 gen = FFEINTRIN_genNONE;
1874 /* Specific is okay only if not: unimplemented, disabled, deleted, or
1875 hidden and not explicit. */
1877 if (spec != FFEINTRIN_specNONE)
1879 if (gen != FFEINTRIN_genNONE)
1880 name = ffeintrin_gens_[gen].name;
1882 name = ffeintrin_specs_[spec].name;
1884 if (((state = ffeintrin_state_family (ffeintrin_specs_[spec].family))
1885 == FFE_intrinsicstateDELETED)
1887 && (state == FFE_intrinsicstateHIDDEN)))
1888 spec = FFEINTRIN_specNONE;
1889 else if (state == FFE_intrinsicstateDISABLED)
1892 spec = FFEINTRIN_specNONE;
1894 else if (imp == FFEINTRIN_impNONE)
1897 spec = FFEINTRIN_specNONE;
1901 /* If neither is okay, not an intrinsic. */
1903 if ((gen == FFEINTRIN_genNONE) && (spec == FFEINTRIN_specNONE))
1905 /* Here is where we produce a diagnostic about a reference to a
1906 disabled or unimplemented intrinsic, if the diagnostic is desired. */
1908 if ((disabled || unimpl)
1911 ffebad_start (disabled
1912 ? FFEBAD_INTRINSIC_DISABLED
1913 : FFEBAD_INTRINSIC_UNIMPLW);
1914 ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
1915 ffebad_string (name);
1922 /* Determine whether intrinsic is function or subroutine. If no specific
1923 id, scan list of possible specifics for generic to get consensus. If
1924 not unanimous, or clear from the context, return NONE. */
1926 if (spec == FFEINTRIN_specNONE)
1929 ffeintrinSpec tspec;
1931 bool at_least_one_ok = FALSE;
1934 (((size_t) i) < ARRAY_SIZE (ffeintrin_gens_[gen].specs))
1936 = ffeintrin_gens_[gen].specs[i]) != FFEINTRIN_specNONE);
1939 if (((state = ffeintrin_state_family (ffeintrin_specs_[tspec].family))
1940 == FFE_intrinsicstateDELETED)
1941 || (state == FFE_intrinsicstateDISABLED))
1944 if ((timp = ffeintrin_specs_[tspec].implementation)
1945 == FFEINTRIN_impNONE)
1948 at_least_one_ok = TRUE;
1952 if (!at_least_one_ok)
1954 *xgen = FFEINTRIN_genNONE;
1955 *xspec = FFEINTRIN_specNONE;
1956 *ximp = FFEINTRIN_impNONE;
1967 /* Return TRUE if intrinsic is standard F77 (or, if -ff90, F90). */
1970 ffeintrin_is_standard (ffeintrinGen gen, ffeintrinSpec spec)
1972 if (spec == FFEINTRIN_specNONE)
1974 if (gen == FFEINTRIN_genNONE)
1977 spec = ffeintrin_gens_[gen].specs[0];
1978 if (spec == FFEINTRIN_specNONE)
1982 if ((ffeintrin_specs_[spec].family == FFEINTRIN_familyF77)
1984 && ((ffeintrin_specs_[spec].family == FFEINTRIN_familyF90)
1985 || (ffeintrin_specs_[spec].family == FFEINTRIN_familyMIL)
1986 || (ffeintrin_specs_[spec].family == FFEINTRIN_familyASC))))
1991 /* Return kind type of intrinsic implementation. See ffeintrin_basictype,
1995 ffeintrin_kindtype (ffeintrinSpec spec)
2000 assert (spec < FFEINTRIN_spec);
2001 imp = ffeintrin_specs_[spec].implementation;
2002 assert (imp < FFEINTRIN_imp);
2005 gfrt = ffeintrin_imps_[imp].gfrt_f2c;
2007 gfrt = ffeintrin_imps_[imp].gfrt_gnu;
2009 assert (gfrt != FFECOM_gfrt);
2011 return ffecom_gfrt_kindtype (gfrt);
2014 /* Return name of generic intrinsic. */
2017 ffeintrin_name_generic (ffeintrinGen gen)
2019 assert (gen < FFEINTRIN_gen);
2020 return ffeintrin_gens_[gen].name;
2023 /* Return name of intrinsic implementation. */
2026 ffeintrin_name_implementation (ffeintrinImp imp)
2028 assert (imp < FFEINTRIN_imp);
2029 return ffeintrin_imps_[imp].name;
2032 /* Return external/internal name of specific intrinsic. */
2035 ffeintrin_name_specific (ffeintrinSpec spec)
2037 assert (spec < FFEINTRIN_spec);
2038 return ffeintrin_specs_[spec].name;
2041 /* Return state of family. */
2044 ffeintrin_state_family (ffeintrinFamily family)
2046 ffeIntrinsicState state;
2050 case FFEINTRIN_familyNONE:
2051 return FFE_intrinsicstateDELETED;
2053 case FFEINTRIN_familyF77:
2054 return FFE_intrinsicstateENABLED;
2056 case FFEINTRIN_familyASC:
2057 state = ffe_intrinsic_state_f2c ();
2058 state = ffe_state_max (state, ffe_intrinsic_state_f90 ());
2061 case FFEINTRIN_familyMIL:
2062 state = ffe_intrinsic_state_vxt ();
2063 state = ffe_state_max (state, ffe_intrinsic_state_f90 ());
2064 state = ffe_state_max (state, ffe_intrinsic_state_mil ());
2067 case FFEINTRIN_familyGNU:
2068 state = ffe_intrinsic_state_gnu ();
2071 case FFEINTRIN_familyF90:
2072 state = ffe_intrinsic_state_f90 ();
2075 case FFEINTRIN_familyVXT:
2076 state = ffe_intrinsic_state_vxt ();
2079 case FFEINTRIN_familyFVZ:
2080 state = ffe_intrinsic_state_f2c ();
2081 state = ffe_state_max (state, ffe_intrinsic_state_vxt ());
2084 case FFEINTRIN_familyF2C:
2085 state = ffe_intrinsic_state_f2c ();
2088 case FFEINTRIN_familyF2U:
2089 state = ffe_intrinsic_state_unix ();
2092 case FFEINTRIN_familyBADU77:
2093 state = ffe_intrinsic_state_badu77 ();
2097 assert ("bad family" == NULL);
2098 return FFE_intrinsicstateDELETED;