1 /* intrin.c -- Recognize references to intrinsics
2 Copyright (C) 1995-1998 Free Software Foundation, Inc.
3 Contributed by James Craig Burley (burley@gnu.org).
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_
39 ffeintrinSpec specific;
42 struct _ffeintrin_gen_
44 char *name; /* Name as seen in program. */
45 ffeintrinSpec specs[2];
48 struct _ffeintrin_spec_
50 char *name; /* Uppercase name as seen in source code,
51 lowercase if no source name, "none" if no
52 name at all (NONE case). */
53 bool is_actualarg; /* Ok to pass as actual arg if -pedantic. */
54 ffeintrinFamily family;
55 ffeintrinImp implementation;
58 struct _ffeintrin_imp_
60 char *name; /* Name of implementation. */
61 #if FFECOM_targetCURRENT == FFECOM_targetGCC
62 ffecomGfrt gfrt_direct; /* library routine, direct-callable form. */
63 ffecomGfrt gfrt_f2c; /* library routine, f2c-callable form. */
64 ffecomGfrt gfrt_gnu; /* library routine, gnu-callable form. */
65 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
69 static ffebad ffeintrin_check_ (ffeintrinImp imp, ffebldOp op,
70 ffebld args, ffeinfoBasictype *xbt,
72 ffetargetCharacterSize *xsz,
76 static bool ffeintrin_check_any_ (ffebld arglist);
77 static int ffeintrin_cmp_name_ (const void *name, const void *intrinsic);
79 static struct _ffeintrin_name_ ffeintrin_names_[]
82 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) \
83 { UPPER, LOWER, MIXED, FFEINTRIN_ ## GEN, FFEINTRIN_ ## SPEC },
84 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
85 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
86 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
94 static struct _ffeintrin_gen_ ffeintrin_gens_[]
97 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC)
98 #define DEFGEN(CODE,NAME,SPEC1,SPEC2) \
99 { NAME, { SPEC1, SPEC2, }, },
100 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
101 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
102 #include "intrin.def"
109 static struct _ffeintrin_imp_ ffeintrin_imps_[]
112 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC)
113 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
114 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
115 #if FFECOM_targetCURRENT == FFECOM_targetGCC
116 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \
117 { NAME, FFECOM_gfrt ## GFRTDIRECT, FFECOM_gfrt ## GFRTF2C, \
118 FFECOM_gfrt ## GFRTGNU, CONTROL },
119 #elif FFECOM_targetCURRENT == FFECOM_targetFFE
120 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \
125 #include "intrin.def"
132 static 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 #include "intrin.def"
148 ffeintrin_check_ (ffeintrinImp imp, ffebldOp op,
149 ffebld args, ffeinfoBasictype *xbt,
150 ffeinfoKindtype *xkt,
151 ffetargetCharacterSize *xsz,
156 char *c = ffeintrin_imps_[imp].control;
157 bool subr = (c[0] == '-');
162 ffetargetCharacterSize sz = FFETARGET_charactersizeNONE;
163 ffeinfoKindtype firstarg_kt;
165 ffeinfoBasictype col_bt = FFEINFO_basictypeNONE;
166 ffeinfoKindtype col_kt = FFEINFO_kindtypeNONE;
167 int colon = (c[2] == ':') ? 2 : 3;
170 /* Check procedure type (function vs. subroutine) against
173 if (op == FFEBLD_opSUBRREF)
176 return FFEBAD_INTRINSIC_IS_FUNC;
178 else if (op == FFEBLD_opFUNCREF)
181 return FFEBAD_INTRINSIC_IS_SUBR;
184 return FFEBAD_INTRINSIC_REF;
186 /* Check the arglist for validity. */
189 && (ffebld_head (args) != NULL))
190 firstarg_kt = ffeinfo_kindtype (ffebld_info (ffebld_head (args)));
192 firstarg_kt = FFEINFO_kindtype;
194 for (argc = &c[colon + 3],
199 char optional = '\0';
200 char required = '\0';
206 bool lastarg_complex = FALSE;
208 /* We don't do anything with keywords yet. */
211 } while (*(++argc) != '=');
217 optional = *(argc++);
221 required = *(argc++);
226 length = *++argc - '0';
228 length = 10 * length + (*(argc++) - '0');
235 elements = *++argc - '0';
237 elements = 10 * elements + (*(argc++) - '0');
240 else if (*argc == '&')
255 /* Break out of this loop only when current arg spec completely
264 ffeinfoBasictype abt = FFEINFO_basictypeNONE;
265 ffeinfoKindtype akt = FFEINFO_kindtypeNONE;
268 || (ffebld_head (arg) == NULL))
270 if (required != '\0')
271 return FFEBAD_INTRINSIC_TOOFEW;
272 if (optional == '\0')
273 return FFEBAD_INTRINSIC_TOOFEW;
275 arg = ffebld_trail (arg);
276 break; /* Try next argspec. */
279 a = ffebld_head (arg);
281 anynum = (ffeinfo_basictype (i) == FFEINFO_basictypeHOLLERITH)
282 || (ffeinfo_basictype (i) == FFEINFO_basictypeTYPELESS);
284 /* See how well the arg matches up to the spec. */
289 okay = (ffeinfo_basictype (i) == FFEINFO_basictypeCHARACTER)
291 || (ffeinfo_size (i) == (ffetargetCharacterSize) length));
296 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX);
297 abt = FFEINFO_basictypeCOMPLEX;
302 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER);
303 abt = FFEINFO_basictypeINTEGER;
308 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL);
309 abt = FFEINFO_basictypeLOGICAL;
314 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
315 abt = FFEINFO_basictypeREAL;
320 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
321 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL);
326 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX)
327 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
332 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX)
333 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
334 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
339 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
340 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
344 okay = ((ffebld_op (a) == FFEBLD_opLABTER)
345 || (ffebld_op (a) == FFEBLD_opLABTOK));
351 okay = (((((ffeinfo_basictype (i) == FFEINFO_basictypeNONE)
352 && (ffeinfo_kindtype (i) == FFEINFO_kindtypeNONE)
353 && (ffeinfo_kind (i) == FFEINFO_kindSUBROUTINE))
354 || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
355 && (ffeinfo_kindtype (i) == FFEINFO_kindtypeINTEGERDEFAULT)
356 && (ffeinfo_kind (i) == FFEINFO_kindFUNCTION))
357 || (ffeinfo_kind (i) == FFEINFO_kindNONE))
358 && ((ffeinfo_where (i) == FFEINFO_whereDUMMY)
359 || (ffeinfo_where (i) == FFEINFO_whereGLOBAL)))
360 || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
361 && (ffeinfo_kind (i) == FFEINFO_kindENTITY)));
374 case '1': case '2': case '3': case '4': case '5':
375 case '6': case '7': case '8': case '9':
377 if ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
378 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL))
381 { /* Translate to internal kinds for now! */
402 akt = ffecom_pointer_kind ();
406 okay &= anynum || (ffeinfo_kindtype (i) == akt);
410 okay &= anynum || (ffeinfo_kindtype (i) == firstarg_kt);
411 akt = (firstarg_kt == FFEINFO_kindtype) ? FFEINFO_kindtypeNONE
428 if (ffeinfo_rank (i) != 0)
433 if ((ffeinfo_rank (i) != 1)
434 || (ffebld_op (a) != FFEBLD_opSYMTER)
435 || ((b = ffesymbol_arraysize (ffebld_symter (a))) == NULL)
436 || (ffebld_op (b) != FFEBLD_opCONTER)
437 || (ffeinfo_basictype (ffebld_info (b)) != FFEINFO_basictypeINTEGER)
438 || (ffeinfo_kindtype (ffebld_info (b)) != FFEINFO_kindtypeINTEGERDEFAULT)
439 || (ffebld_constant_integer1 (ffebld_conter (b)) != elements))
447 if ((ffeinfo_kind (i) != FFEINFO_kindENTITY)
448 || ((ffebld_op (a) != FFEBLD_opSYMTER)
449 && (ffebld_op (a) != FFEBLD_opSUBSTR)
450 && (ffebld_op (a) != FFEBLD_opARRAYREF)))
456 if ((ffeinfo_kind (i) != FFEINFO_kindENTITY)
457 || ((ffebld_op (a) != FFEBLD_opSYMTER)
458 && (ffebld_op (a) != FFEBLD_opARRAYREF)
459 && (ffebld_op (a) != FFEBLD_opSUBSTR)))
468 if (ffeinfo_kind (i) != FFEINFO_kindENTITY)
473 if ((optional == '!')
479 /* If it wasn't optional, it's an error,
480 else maybe it could match a later argspec. */
481 if (optional == '\0')
482 return FFEBAD_INTRINSIC_REF;
483 break; /* Try next argspec. */
487 = (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX);
491 /* If we know dummy arg type, convert to that now. */
493 if ((abt != FFEINFO_basictypeNONE)
494 && (akt != FFEINFO_kindtypeNONE)
497 /* We have a known type, convert hollerith/typeless
500 a = ffeexpr_convert (a, t, NULL,
502 FFETARGET_charactersizeNONE,
504 ffebld_set_head (arg, a);
508 arg = ffebld_trail (arg); /* Arg accepted, now move on. */
511 continue; /* Go ahead and try another arg. */
512 if (required == '\0')
514 if ((required == 'n')
515 || (required == '+'))
520 else if (required == 'p')
526 return FFEBAD_INTRINSIC_TOOMANY;
528 /* Set up the initial type for the return value of the function. */
534 bt = FFEINFO_basictypeCHARACTER;
535 sz = (c[2] == '*') ? FFETARGET_charactersizeNONE : 1;
539 bt = FFEINFO_basictypeCOMPLEX;
543 bt = FFEINFO_basictypeINTEGER;
547 bt = FFEINFO_basictypeLOGICAL;
551 bt = FFEINFO_basictypeREAL;
562 bt = FFEINFO_basictypeNONE;
568 case '1': case '2': case '3': case '4': case '5':
569 case '6': case '7': case '8': case '9':
571 if ((bt == FFEINFO_basictypeINTEGER)
572 || (bt == FFEINFO_basictypeLOGICAL))
575 { /* Translate to internal kinds for now! */
596 kt = ffecom_pointer_kind ();
613 kt = FFEINFO_kindtypeNONE;
617 /* Determine collective type of COL, if there is one. */
619 if (need_col || c[colon + 1] != '-')
622 bool have_anynum = FALSE;
626 arg = (c[colon + 1] == '*') ? ffebld_trail (arg) : NULL)
628 ffebld a = ffebld_head (arg);
636 anynum = (ffeinfo_basictype (i) == FFEINFO_basictypeHOLLERITH)
637 || (ffeinfo_basictype (i) == FFEINFO_basictypeTYPELESS);
644 if ((col_bt == FFEINFO_basictypeNONE)
645 && (col_kt == FFEINFO_kindtypeNONE))
647 col_bt = ffeinfo_basictype (i);
648 col_kt = ffeinfo_kindtype (i);
652 ffeexpr_type_combine (&col_bt, &col_kt,
654 ffeinfo_basictype (i),
655 ffeinfo_kindtype (i),
657 if ((col_bt == FFEINFO_basictypeNONE)
658 || (col_kt == FFEINFO_kindtypeNONE))
659 return FFEBAD_INTRINSIC_REF;
664 && ((col_bt == FFEINFO_basictypeNONE)
665 || (col_kt == FFEINFO_kindtypeNONE)))
667 /* No type, but have hollerith/typeless. Use type of return
668 value to determine type of COL. */
673 return FFEBAD_INTRINSIC_REF;
678 if ((col_bt != FFEINFO_basictypeNONE)
679 && (col_bt != FFEINFO_basictypeINTEGER))
680 return FFEBAD_INTRINSIC_REF;
686 col_bt = FFEINFO_basictypeINTEGER;
687 col_kt = FFEINFO_kindtypeINTEGER1;
691 if ((col_bt != FFEINFO_basictypeNONE)
692 && (col_bt != FFEINFO_basictypeCOMPLEX))
693 return FFEBAD_INTRINSIC_REF;
694 col_bt = FFEINFO_basictypeCOMPLEX;
695 col_kt = FFEINFO_kindtypeREAL1;
699 if ((col_bt != FFEINFO_basictypeNONE)
700 && (col_bt != FFEINFO_basictypeREAL))
701 return FFEBAD_INTRINSIC_REF;
704 col_bt = FFEINFO_basictypeREAL;
705 col_kt = FFEINFO_kindtypeREAL1;
713 okay = (col_bt == FFEINFO_basictypeINTEGER)
714 || (col_bt == FFEINFO_basictypeLOGICAL);
720 okay = (col_bt == FFEINFO_basictypeCOMPLEX)
721 || (col_bt == FFEINFO_basictypeREAL);
727 okay = (col_bt == FFEINFO_basictypeCOMPLEX)
728 || (col_bt == FFEINFO_basictypeINTEGER)
729 || (col_bt == FFEINFO_basictypeREAL);
735 okay = (col_bt == FFEINFO_basictypeINTEGER)
736 || (col_bt == FFEINFO_basictypeREAL)
737 || (col_bt == FFEINFO_basictypeCOMPLEX);
739 bt = ((col_bt != FFEINFO_basictypeCOMPLEX) ? col_bt
740 : FFEINFO_basictypeREAL);
752 if (col_bt == FFEINFO_basictypeCOMPLEX)
754 if (col_kt != FFEINFO_kindtypeREALDEFAULT)
755 *check_intrin = TRUE;
763 return FFEBAD_INTRINSIC_REF;
766 /* Now, convert args in the arglist to the final type of the COL. */
768 for (argno = 0, argc = &c[colon + 3],
773 char optional = '\0';
774 char required = '\0';
780 bool lastarg_complex = FALSE;
782 /* We don't do anything with keywords yet. */
785 } while (*(++argc) != '=');
791 optional = *(argc++);
795 required = *(argc++);
800 length = *++argc - '0';
802 length = 10 * length + (*(argc++) - '0');
809 elements = *++argc - '0';
811 elements = 10 * elements + (*(argc++) - '0');
814 else if (*argc == '&')
829 /* Break out of this loop only when current arg spec completely
838 ffeinfoBasictype abt = FFEINFO_basictypeNONE;
839 ffeinfoKindtype akt = FFEINFO_kindtypeNONE;
842 || (ffebld_head (arg) == NULL))
845 arg = ffebld_trail (arg);
846 break; /* Try next argspec. */
849 a = ffebld_head (arg);
851 anynum = (ffeinfo_basictype (i) == FFEINFO_basictypeHOLLERITH)
852 || (ffeinfo_basictype (i) == FFEINFO_basictypeTYPELESS);
854 /* Determine what the default type for anynum would be. */
858 switch (c[colon + 1])
862 case '0': case '1': case '2': case '3': case '4':
863 case '5': case '6': case '7': case '8': case '9':
864 if (argno != (c[colon + 1] - '0'))
873 /* Again, match arg up to the spec. We go through all of
874 this again to properly follow the contour of optional
875 arguments. Probably this level of flexibility is not
876 needed, perhaps it's even downright naughty. */
881 okay = (ffeinfo_basictype (i) == FFEINFO_basictypeCHARACTER)
883 || (ffeinfo_size (i) == (ffetargetCharacterSize) length));
888 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX);
889 abt = FFEINFO_basictypeCOMPLEX;
894 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER);
895 abt = FFEINFO_basictypeINTEGER;
900 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL);
901 abt = FFEINFO_basictypeLOGICAL;
906 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
907 abt = FFEINFO_basictypeREAL;
912 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
913 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL);
918 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX)
919 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
924 || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX)
925 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
926 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
931 || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
932 || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL);
936 okay = ((ffebld_op (a) == FFEBLD_opLABTER)
937 || (ffebld_op (a) == FFEBLD_opLABTOK));
943 okay = (((((ffeinfo_basictype (i) == FFEINFO_basictypeNONE)
944 && (ffeinfo_kindtype (i) == FFEINFO_kindtypeNONE)
945 && (ffeinfo_kind (i) == FFEINFO_kindSUBROUTINE))
946 || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
947 && (ffeinfo_kindtype (i) == FFEINFO_kindtypeINTEGERDEFAULT)
948 && (ffeinfo_kind (i) == FFEINFO_kindFUNCTION))
949 || (ffeinfo_kind (i) == FFEINFO_kindNONE))
950 && ((ffeinfo_where (i) == FFEINFO_whereDUMMY)
951 || (ffeinfo_where (i) == FFEINFO_whereGLOBAL)))
952 || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
953 && (ffeinfo_kind (i) == FFEINFO_kindENTITY)));
966 case '1': case '2': case '3': case '4': case '5':
967 case '6': case '7': case '8': case '9':
969 if ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER)
970 || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL))
973 { /* Translate to internal kinds for now! */
994 akt = ffecom_pointer_kind ();
998 okay &= anynum || (ffeinfo_kindtype (i) == akt);
1002 okay &= anynum || (ffeinfo_kindtype (i) == firstarg_kt);
1003 akt = (firstarg_kt == FFEINFO_kindtype) ? FFEINFO_kindtypeNONE
1020 if (ffeinfo_rank (i) != 0)
1025 if ((ffeinfo_rank (i) != 1)
1026 || (ffebld_op (a) != FFEBLD_opSYMTER)
1027 || ((b = ffesymbol_arraysize (ffebld_symter (a))) == NULL)
1028 || (ffebld_op (b) != FFEBLD_opCONTER)
1029 || (ffeinfo_basictype (ffebld_info (b)) != FFEINFO_basictypeINTEGER)
1030 || (ffeinfo_kindtype (ffebld_info (b)) != FFEINFO_kindtypeINTEGERDEFAULT)
1031 || (ffebld_constant_integer1 (ffebld_conter (b)) != elements))
1039 if ((ffeinfo_kind (i) != FFEINFO_kindENTITY)
1040 || ((ffebld_op (a) != FFEBLD_opSYMTER)
1041 && (ffebld_op (a) != FFEBLD_opSUBSTR)
1042 && (ffebld_op (a) != FFEBLD_opARRAYREF)))
1048 if ((ffeinfo_kind (i) != FFEINFO_kindENTITY)
1049 || ((ffebld_op (a) != FFEBLD_opSYMTER)
1050 && (ffebld_op (a) != FFEBLD_opARRAYREF)
1051 && (ffebld_op (a) != FFEBLD_opSUBSTR)))
1060 if (ffeinfo_kind (i) != FFEINFO_kindENTITY)
1065 if ((optional == '!')
1071 /* If it wasn't optional, it's an error,
1072 else maybe it could match a later argspec. */
1073 if (optional == '\0')
1074 return FFEBAD_INTRINSIC_REF;
1075 break; /* Try next argspec. */
1079 = (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX);
1081 if (anynum && commit)
1083 /* If we know dummy arg type, convert to that now. */
1085 if (abt == FFEINFO_basictypeNONE)
1086 abt = FFEINFO_basictypeINTEGER;
1087 if (akt == FFEINFO_kindtypeNONE)
1088 akt = FFEINFO_kindtypeINTEGER1;
1090 /* We have a known type, convert hollerith/typeless to it. */
1092 a = ffeexpr_convert (a, t, NULL,
1094 FFETARGET_charactersizeNONE,
1095 FFEEXPR_contextLET);
1096 ffebld_set_head (arg, a);
1098 else if ((c[colon + 1] == '*') && commit)
1100 /* This is where we promote types to the consensus
1101 type for the COL. Maybe this is where -fpedantic
1102 should issue a warning as well. */
1104 a = ffeexpr_convert (a, t, NULL,
1107 FFEEXPR_contextLET);
1108 ffebld_set_head (arg, a);
1111 arg = ffebld_trail (arg); /* Arg accepted, now move on. */
1113 if (optional == '*')
1114 continue; /* Go ahead and try another arg. */
1115 if (required == '\0')
1117 if ((required == 'n')
1118 || (required == '+'))
1123 else if (required == 'p')
1135 ffeintrin_check_any_ (ffebld arglist)
1139 for (; arglist != NULL; arglist = ffebld_trail (arglist))
1141 item = ffebld_head (arglist);
1143 && (ffebld_op (item) == FFEBLD_opANY))
1150 /* Compare name to intrinsic's name. Uses strcmp on arguments' names. */
1153 ffeintrin_cmp_name_ (const void *name, const void *intrinsic)
1155 char *uc = (char *) ((struct _ffeintrin_name_ *) intrinsic)->name_uc;
1156 char *lc = (char *) ((struct _ffeintrin_name_ *) intrinsic)->name_lc;
1157 char *ic = (char *) ((struct _ffeintrin_name_ *) intrinsic)->name_ic;
1159 return ffesrc_strcmp_2c (ffe_case_intrin (), name, uc, lc, ic);
1162 /* Return basic type of intrinsic implementation, based on its
1163 run-time implementation *only*. (This is used only when
1164 the type of an intrinsic name is needed without having a
1165 list of arguments, i.e. an interface signature, such as when
1166 passing the intrinsic itself, or really the run-time-library
1167 function, as an argument.)
1169 If there's no eligible intrinsic implementation, there must be
1170 a bug somewhere else; no such reference should have been permitted
1171 to go this far. (Well, this might be wrong.) */
1174 ffeintrin_basictype (ffeintrinSpec spec)
1179 assert (spec < FFEINTRIN_spec);
1180 imp = ffeintrin_specs_[spec].implementation;
1181 assert (imp < FFEINTRIN_imp);
1184 gfrt = ffeintrin_imps_[imp].gfrt_f2c;
1186 gfrt = ffeintrin_imps_[imp].gfrt_gnu;
1188 assert (gfrt != FFECOM_gfrt);
1190 return ffecom_gfrt_basictype (gfrt);
1193 /* Return family to which specific intrinsic belongs. */
1196 ffeintrin_family (ffeintrinSpec spec)
1198 if (spec >= FFEINTRIN_spec)
1200 return ffeintrin_specs_[spec].family;
1203 /* Check and fill in info on func/subr ref node.
1205 ffebld expr; // FUNCREF or SUBRREF with no info (caller
1206 // gets it from the modified info structure).
1207 ffeinfo info; // Already filled in, will be overwritten.
1208 ffelexToken token; // Used for error message.
1209 ffeintrin_fulfill_generic (&expr, &info, token);
1211 Based on the generic id, figure out which specific procedure is meant and
1212 pick that one. Else return an error, a la _specific. */
1215 ffeintrin_fulfill_generic (ffebld *expr, ffeinfo *info, ffelexToken t)
1220 ffeintrinSpec spec = FFEINTRIN_specNONE;
1221 ffeinfoBasictype bt = FFEINFO_basictypeNONE;
1222 ffeinfoKindtype kt = FFEINFO_kindtypeNONE;
1223 ffetargetCharacterSize sz = FFETARGET_charactersizeNONE;
1225 ffeintrinSpec tspec;
1226 ffeintrinImp nimp = FFEINTRIN_impNONE;
1229 bool highly_specific = FALSE;
1232 op = ffebld_op (*expr);
1233 assert ((op == FFEBLD_opFUNCREF) || (op == FFEBLD_opSUBRREF));
1234 assert (ffebld_op (ffebld_left (*expr)) == FFEBLD_opSYMTER);
1236 gen = ffebld_symter_generic (ffebld_left (*expr));
1237 assert (gen != FFEINTRIN_genNONE);
1239 imp = FFEINTRIN_impNONE;
1242 any = ffeintrin_check_any_ (ffebld_right (*expr));
1245 (((size_t) i) < ARRAY_SIZE (ffeintrin_gens_[gen].specs))
1246 && ((tspec = ffeintrin_gens_[gen].specs[i]) != FFEINTRIN_specNONE)
1250 ffeintrinImp timp = ffeintrin_specs_[tspec].implementation;
1251 ffeinfoBasictype tbt;
1252 ffeinfoKindtype tkt;
1253 ffetargetCharacterSize tsz;
1254 ffeIntrinsicState state
1255 = ffeintrin_state_family (ffeintrin_specs_[tspec].family);
1258 if (state == FFE_intrinsicstateDELETED)
1261 if (timp != FFEINTRIN_impNONE)
1263 if (!(ffeintrin_imps_[timp].control[0] == '-')
1264 != !(ffebld_op (*expr) == FFEBLD_opSUBRREF))
1265 continue; /* Form of reference must match form of specific. */
1268 if (state == FFE_intrinsicstateDISABLED)
1269 terror = FFEBAD_INTRINSIC_DISABLED;
1270 else if (timp == FFEINTRIN_impNONE)
1271 terror = FFEBAD_INTRINSIC_UNIMPL;
1274 terror = ffeintrin_check_ (timp, ffebld_op (*expr),
1275 ffebld_right (*expr),
1276 &tbt, &tkt, &tsz, NULL, t, FALSE);
1277 if (terror == FFEBAD)
1279 if (imp != FFEINTRIN_impNONE)
1281 ffebad_start (FFEBAD_INTRINSIC_AMBIG);
1282 ffebad_here (0, ffelex_token_where_line (t),
1283 ffelex_token_where_column (t));
1284 ffebad_string (ffeintrin_gens_[gen].name);
1285 ffebad_string (ffeintrin_specs_[spec].name);
1286 ffebad_string (ffeintrin_specs_[tspec].name);
1291 if (ffebld_symter_specific (ffebld_left (*expr))
1293 highly_specific = TRUE;
1302 else if (terror != FFEBAD)
1303 { /* This error has precedence over others. */
1304 if ((error == FFEBAD_INTRINSIC_DISABLED)
1305 || (error == FFEBAD_INTRINSIC_UNIMPL))
1310 if (error == FFEBAD)
1314 if (any || (imp == FFEINTRIN_impNONE))
1318 if (error == FFEBAD)
1319 error = FFEBAD_INTRINSIC_REF;
1320 ffebad_start (error);
1321 ffebad_here (0, ffelex_token_where_line (t),
1322 ffelex_token_where_column (t));
1323 ffebad_string (ffeintrin_gens_[gen].name);
1327 *expr = ffebld_new_any ();
1328 *info = ffeinfo_new_any ();
1332 if (!highly_specific && (nimp != FFEINTRIN_impNONE))
1334 fprintf (stderr, "lineno=%ld, gen=%s, imp=%s, timp=%s\n",
1336 ffeintrin_gens_[gen].name,
1337 ffeintrin_imps_[imp].name,
1338 ffeintrin_imps_[nimp].name);
1339 assert ("Ambiguous generic reference" == NULL);
1342 error = ffeintrin_check_ (imp, ffebld_op (*expr),
1343 ffebld_right (*expr),
1344 &bt, &kt, &sz, NULL, t, TRUE);
1345 assert (error == FFEBAD);
1346 *info = ffeinfo_new (bt,
1350 FFEINFO_whereFLEETING,
1352 symter = ffebld_left (*expr);
1353 ffebld_symter_set_specific (symter, spec);
1354 ffebld_symter_set_implementation (symter, imp);
1355 ffebld_set_info (symter,
1359 (bt == FFEINFO_basictypeNONE)
1360 ? FFEINFO_kindSUBROUTINE
1361 : FFEINFO_kindFUNCTION,
1362 FFEINFO_whereINTRINSIC,
1365 if ((ffesymbol_attrs (ffebld_symter (symter)) & FFESYMBOL_attrsTYPE)
1366 && (((bt != ffesymbol_basictype (ffebld_symter (symter)))
1367 || (kt != ffesymbol_kindtype (ffebld_symter (symter)))
1368 || ((sz != FFETARGET_charactersizeNONE)
1369 && (sz != ffesymbol_size (ffebld_symter (symter)))))))
1371 ffebad_start (FFEBAD_INTRINSIC_TYPE);
1372 ffebad_here (0, ffelex_token_where_line (t),
1373 ffelex_token_where_column (t));
1374 ffebad_string (ffeintrin_gens_[gen].name);
1380 /* Check and fill in info on func/subr ref node.
1382 ffebld expr; // FUNCREF or SUBRREF with no info (caller
1383 // gets it from the modified info structure).
1384 ffeinfo info; // Already filled in, will be overwritten.
1385 bool check_intrin; // May be omitted, else set TRUE if intrinsic needs checking.
1386 ffelexToken token; // Used for error message.
1387 ffeintrin_fulfill_specific (&expr, &info, &check_intrin, token);
1389 Based on the specific id, determine whether the arg list is valid
1390 (number, type, rank, and kind of args) and fill in the info structure
1391 accordingly. Currently don't rewrite the expression, but perhaps
1392 someday do so for constant collapsing, except when an error occurs,
1393 in which case it is overwritten with ANY and info is also overwritten
1397 ffeintrin_fulfill_specific (ffebld *expr, ffeinfo *info,
1398 bool *check_intrin, ffelexToken t)
1405 ffeinfoBasictype bt = FFEINFO_basictypeNONE;
1406 ffeinfoKindtype kt = FFEINFO_kindtypeNONE;
1407 ffetargetCharacterSize sz = FFETARGET_charactersizeNONE;
1408 ffeIntrinsicState state;
1413 op = ffebld_op (*expr);
1414 assert ((op == FFEBLD_opFUNCREF) || (op == FFEBLD_opSUBRREF));
1415 assert (ffebld_op (ffebld_left (*expr)) == FFEBLD_opSYMTER);
1417 gen = ffebld_symter_generic (ffebld_left (*expr));
1418 spec = ffebld_symter_specific (ffebld_left (*expr));
1419 assert (spec != FFEINTRIN_specNONE);
1421 if (gen != FFEINTRIN_genNONE)
1422 name = ffeintrin_gens_[gen].name;
1424 name = ffeintrin_specs_[spec].name;
1426 state = ffeintrin_state_family (ffeintrin_specs_[spec].family);
1428 imp = ffeintrin_specs_[spec].implementation;
1429 if (check_intrin != NULL)
1430 *check_intrin = FALSE;
1432 any = ffeintrin_check_any_ (ffebld_right (*expr));
1434 if (state == FFE_intrinsicstateDISABLED)
1435 error = FFEBAD_INTRINSIC_DISABLED;
1436 else if (imp == FFEINTRIN_impNONE)
1437 error = FFEBAD_INTRINSIC_UNIMPL;
1440 error = ffeintrin_check_ (imp, ffebld_op (*expr),
1441 ffebld_right (*expr),
1442 &bt, &kt, &sz, check_intrin, t, TRUE);
1445 error = FFEBAD; /* Not really needed, but quiet -Wuninitialized. */
1447 if (any || (error != FFEBAD))
1452 ffebad_start (error);
1453 ffebad_here (0, ffelex_token_where_line (t),
1454 ffelex_token_where_column (t));
1455 ffebad_string (name);
1459 *expr = ffebld_new_any ();
1460 *info = ffeinfo_new_any ();
1464 *info = ffeinfo_new (bt,
1468 FFEINFO_whereFLEETING,
1470 symter = ffebld_left (*expr);
1471 ffebld_set_info (symter,
1475 (bt == FFEINFO_basictypeNONE)
1476 ? FFEINFO_kindSUBROUTINE
1477 : FFEINFO_kindFUNCTION,
1478 FFEINFO_whereINTRINSIC,
1481 if ((ffesymbol_attrs (ffebld_symter (symter)) & FFESYMBOL_attrsTYPE)
1482 && (((bt != ffesymbol_basictype (ffebld_symter (symter)))
1483 || (kt != ffesymbol_kindtype (ffebld_symter (symter)))
1484 || (sz != ffesymbol_size (ffebld_symter (symter))))))
1486 ffebad_start (FFEBAD_INTRINSIC_TYPE);
1487 ffebad_here (0, ffelex_token_where_line (t),
1488 ffelex_token_where_column (t));
1489 ffebad_string (name);
1495 /* Return run-time index of intrinsic implementation as direct call. */
1497 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1499 ffeintrin_gfrt_direct (ffeintrinImp imp)
1501 assert (imp < FFEINTRIN_imp);
1503 return ffeintrin_imps_[imp].gfrt_direct;
1507 /* Return run-time index of intrinsic implementation as actual argument. */
1509 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1511 ffeintrin_gfrt_indirect (ffeintrinImp imp)
1513 assert (imp < FFEINTRIN_imp);
1515 if (! ffe_is_f2c ())
1516 return ffeintrin_imps_[imp].gfrt_gnu;
1517 return ffeintrin_imps_[imp].gfrt_f2c;
1530 if (!ffe_is_do_internal_checks ())
1533 assert (FFEINTRIN_gen == ARRAY_SIZE (ffeintrin_gens_));
1534 assert (FFEINTRIN_imp == ARRAY_SIZE (ffeintrin_imps_));
1535 assert (FFEINTRIN_spec == ARRAY_SIZE (ffeintrin_specs_));
1537 for (i = 1; ((size_t) i) < ARRAY_SIZE (ffeintrin_names_); ++i)
1538 { /* Make sure binary-searched list is in alpha
1540 if (strcmp (ffeintrin_names_[i - 1].name_uc,
1541 ffeintrin_names_[i].name_uc) >= 0)
1542 assert ("name list out of order" == NULL);
1545 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffeintrin_names_); ++i)
1547 assert ((ffeintrin_names_[i].generic == FFEINTRIN_genNONE)
1548 || (ffeintrin_names_[i].specific == FFEINTRIN_specNONE));
1550 p1 = ffeintrin_names_[i].name_uc;
1551 p2 = ffeintrin_names_[i].name_lc;
1552 p3 = ffeintrin_names_[i].name_ic;
1553 for (; *p1 != '\0' && *p2 != '\0' && *p3 != '\0'; ++p1, ++p2, ++p3)
1555 if (! IN_CTYPE_DOMAIN (*p1)
1556 || ! IN_CTYPE_DOMAIN (*p2)
1557 || ! IN_CTYPE_DOMAIN (*p3))
1559 if ((ISDIGIT (*p1) || (*p1 == '_')) && (*p1 == *p2) && (*p1 == *p3))
1561 if (! ISUPPER (*p1) || ! ISLOWER (*p2)
1562 || (*p1 != toupper (*p2)) || ((*p3 != *p1) && (*p3 != *p2)))
1565 assert ((*p1 == *p2) && (*p1 == *p3) && (*p1 == '\0'));
1568 for (i = 0; ((size_t) i) < ARRAY_SIZE (ffeintrin_imps_); ++i)
1570 char *c = ffeintrin_imps_[i].control;
1586 fprintf (stderr, "%s: bad return-base-type\n",
1587 ffeintrin_imps_[i].name);
1596 fprintf (stderr, "%s: bad return-kind-type\n",
1597 ffeintrin_imps_[i].name);
1606 fprintf (stderr, "%s: bad return-modifier\n",
1607 ffeintrin_imps_[i].name);
1612 if ((c[colon] != ':') || (c[colon + 2] != ':'))
1614 fprintf (stderr, "%s: bad control\n",
1615 ffeintrin_imps_[i].name);
1618 if ((c[colon + 1] != '-')
1619 && (c[colon + 1] != '*')
1620 && ((c[colon + 1] < '0')
1621 || (c[colon + 1] > '9')))
1623 fprintf (stderr, "%s: bad COL-spec\n",
1624 ffeintrin_imps_[i].name);
1628 while (c[0] != '\0')
1630 while ((c[0] != '=')
1636 fprintf (stderr, "%s: bad keyword\n",
1637 ffeintrin_imps_[i].name);
1660 fprintf (stderr, "%s: bad arg-base-type\n",
1661 ffeintrin_imps_[i].name);
1669 fprintf (stderr, "%s: bad arg-kind-type\n",
1670 ffeintrin_imps_[i].name);
1675 if (((c[4] < '0') || (c[4] > '9'))
1677 && (++c, (c[4] < '0') || (c[4] > '9')
1680 fprintf (stderr, "%s: bad arg-len\n",
1681 ffeintrin_imps_[i].name);
1688 if (((c[4] < '0') || (c[4] > '9'))
1690 && (++c, (c[4] < '0') || (c[4] > '9')
1693 fprintf (stderr, "%s: bad arg-rank\n",
1694 ffeintrin_imps_[i].name);
1699 else if ((c[3] == '&')
1714 fprintf (stderr, "%s: bad arg-list\n",
1715 ffeintrin_imps_[i].name);
1722 /* Determine whether intrinsic is okay as an actual argument. */
1725 ffeintrin_is_actualarg (ffeintrinSpec spec)
1727 ffeIntrinsicState state;
1729 if (spec >= FFEINTRIN_spec)
1732 state = ffeintrin_state_family (ffeintrin_specs_[spec].family);
1734 return (!ffe_is_pedantic () || ffeintrin_specs_[spec].is_actualarg)
1735 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1737 ? (ffeintrin_imps_[ffeintrin_specs_[spec].implementation].gfrt_f2c
1739 : (ffeintrin_imps_[ffeintrin_specs_[spec].implementation].gfrt_gnu
1742 && ((state == FFE_intrinsicstateENABLED)
1743 || (state == FFE_intrinsicstateHIDDEN));
1746 /* Determine if name is intrinsic, return info.
1748 char *name; // C-string name of possible intrinsic.
1749 ffelexToken t; // NULL if no diagnostic to be given.
1750 bool explicit; // TRUE if INTRINSIC name.
1751 ffeintrinGen gen; // (TRUE only) Generic id of intrinsic.
1752 ffeintrinSpec spec; // (TRUE only) Specific id of intrinsic.
1753 ffeintrinImp imp; // (TRUE only) Implementation id of intrinsic.
1754 if (ffeintrin_is_intrinsic (name, t, explicit,
1756 // is an intrinsic, use gen, spec, imp, and
1757 // kind accordingly. */
1760 ffeintrin_is_intrinsic (char *name, ffelexToken t, bool explicit,
1761 ffeintrinGen *xgen, ffeintrinSpec *xspec,
1764 struct _ffeintrin_name_ *intrinsic;
1768 ffeIntrinsicState state;
1769 bool disabled = FALSE;
1770 bool unimpl = FALSE;
1772 intrinsic = bsearch (name, &ffeintrin_names_[0],
1773 ARRAY_SIZE (ffeintrin_names_),
1774 sizeof (struct _ffeintrin_name_),
1775 (void *) ffeintrin_cmp_name_);
1777 if (intrinsic == NULL)
1780 gen = intrinsic->generic;
1781 spec = intrinsic->specific;
1782 imp = ffeintrin_specs_[spec].implementation;
1784 /* Generic is okay only if at least one of its specifics is okay. */
1786 if (gen != FFEINTRIN_genNONE)
1789 ffeintrinSpec tspec;
1792 name = ffeintrin_gens_[gen].name;
1795 (((size_t) i) < ARRAY_SIZE (ffeintrin_gens_[gen].specs))
1797 = ffeintrin_gens_[gen].specs[i]) != FFEINTRIN_specNONE);
1800 state = ffeintrin_state_family (ffeintrin_specs_[tspec].family);
1802 if (state == FFE_intrinsicstateDELETED)
1805 if (state == FFE_intrinsicstateDISABLED)
1811 if (ffeintrin_specs_[tspec].implementation == FFEINTRIN_impNONE)
1817 if ((state == FFE_intrinsicstateENABLED)
1819 && (state == FFE_intrinsicstateHIDDEN)))
1826 gen = FFEINTRIN_genNONE;
1829 /* Specific is okay only if not: unimplemented, disabled, deleted, or
1830 hidden and not explicit. */
1832 if (spec != FFEINTRIN_specNONE)
1834 if (gen != FFEINTRIN_genNONE)
1835 name = ffeintrin_gens_[gen].name;
1837 name = ffeintrin_specs_[spec].name;
1839 if (((state = ffeintrin_state_family (ffeintrin_specs_[spec].family))
1840 == FFE_intrinsicstateDELETED)
1842 && (state == FFE_intrinsicstateHIDDEN)))
1843 spec = FFEINTRIN_specNONE;
1844 else if (state == FFE_intrinsicstateDISABLED)
1847 spec = FFEINTRIN_specNONE;
1849 else if (imp == FFEINTRIN_impNONE)
1852 spec = FFEINTRIN_specNONE;
1856 /* If neither is okay, not an intrinsic. */
1858 if ((gen == FFEINTRIN_genNONE) && (spec == FFEINTRIN_specNONE))
1860 /* Here is where we produce a diagnostic about a reference to a
1861 disabled or unimplemented intrinsic, if the diagnostic is desired. */
1863 if ((disabled || unimpl)
1866 ffebad_start (disabled
1867 ? FFEBAD_INTRINSIC_DISABLED
1868 : FFEBAD_INTRINSIC_UNIMPLW);
1869 ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t));
1870 ffebad_string (name);
1877 /* Determine whether intrinsic is function or subroutine. If no specific
1878 id, scan list of possible specifics for generic to get consensus. If
1879 not unanimous, or clear from the context, return NONE. */
1881 if (spec == FFEINTRIN_specNONE)
1884 ffeintrinSpec tspec;
1886 bool at_least_one_ok = FALSE;
1889 (((size_t) i) < ARRAY_SIZE (ffeintrin_gens_[gen].specs))
1891 = ffeintrin_gens_[gen].specs[i]) != FFEINTRIN_specNONE);
1894 if (((state = ffeintrin_state_family (ffeintrin_specs_[tspec].family))
1895 == FFE_intrinsicstateDELETED)
1896 || (state == FFE_intrinsicstateDISABLED))
1899 if ((timp = ffeintrin_specs_[tspec].implementation)
1900 == FFEINTRIN_impNONE)
1903 at_least_one_ok = TRUE;
1907 if (!at_least_one_ok)
1909 *xgen = FFEINTRIN_genNONE;
1910 *xspec = FFEINTRIN_specNONE;
1911 *ximp = FFEINTRIN_impNONE;
1922 /* Return TRUE if intrinsic is standard F77 (or, if -ff90, F90). */
1925 ffeintrin_is_standard (ffeintrinGen gen, ffeintrinSpec spec)
1927 if (spec == FFEINTRIN_specNONE)
1929 if (gen == FFEINTRIN_genNONE)
1932 spec = ffeintrin_gens_[gen].specs[0];
1933 if (spec == FFEINTRIN_specNONE)
1937 if ((ffeintrin_specs_[spec].family == FFEINTRIN_familyF77)
1939 && ((ffeintrin_specs_[spec].family == FFEINTRIN_familyF90)
1940 || (ffeintrin_specs_[spec].family == FFEINTRIN_familyMIL)
1941 || (ffeintrin_specs_[spec].family == FFEINTRIN_familyASC))))
1946 /* Return kind type of intrinsic implementation. See ffeintrin_basictype,
1950 ffeintrin_kindtype (ffeintrinSpec spec)
1955 assert (spec < FFEINTRIN_spec);
1956 imp = ffeintrin_specs_[spec].implementation;
1957 assert (imp < FFEINTRIN_imp);
1960 gfrt = ffeintrin_imps_[imp].gfrt_f2c;
1962 gfrt = ffeintrin_imps_[imp].gfrt_gnu;
1964 assert (gfrt != FFECOM_gfrt);
1966 return ffecom_gfrt_kindtype (gfrt);
1969 /* Return name of generic intrinsic. */
1972 ffeintrin_name_generic (ffeintrinGen gen)
1974 assert (gen < FFEINTRIN_gen);
1975 return ffeintrin_gens_[gen].name;
1978 /* Return name of intrinsic implementation. */
1981 ffeintrin_name_implementation (ffeintrinImp imp)
1983 assert (imp < FFEINTRIN_imp);
1984 return ffeintrin_imps_[imp].name;
1987 /* Return external/internal name of specific intrinsic. */
1990 ffeintrin_name_specific (ffeintrinSpec spec)
1992 assert (spec < FFEINTRIN_spec);
1993 return ffeintrin_specs_[spec].name;
1996 /* Return state of family. */
1999 ffeintrin_state_family (ffeintrinFamily family)
2001 ffeIntrinsicState state;
2005 case FFEINTRIN_familyNONE:
2006 return FFE_intrinsicstateDELETED;
2008 case FFEINTRIN_familyF77:
2009 return FFE_intrinsicstateENABLED;
2011 case FFEINTRIN_familyASC:
2012 state = ffe_intrinsic_state_f2c ();
2013 state = ffe_state_max (state, ffe_intrinsic_state_f90 ());
2016 case FFEINTRIN_familyMIL:
2017 state = ffe_intrinsic_state_vxt ();
2018 state = ffe_state_max (state, ffe_intrinsic_state_f90 ());
2019 state = ffe_state_max (state, ffe_intrinsic_state_mil ());
2022 case FFEINTRIN_familyGNU:
2023 state = ffe_intrinsic_state_gnu ();
2026 case FFEINTRIN_familyF90:
2027 state = ffe_intrinsic_state_f90 ();
2030 case FFEINTRIN_familyVXT:
2031 state = ffe_intrinsic_state_vxt ();
2034 case FFEINTRIN_familyFVZ:
2035 state = ffe_intrinsic_state_f2c ();
2036 state = ffe_state_max (state, ffe_intrinsic_state_vxt ());
2039 case FFEINTRIN_familyF2C:
2040 state = ffe_intrinsic_state_f2c ();
2043 case FFEINTRIN_familyF2U:
2044 state = ffe_intrinsic_state_unix ();
2047 case FFEINTRIN_familyBADU77:
2048 state = ffe_intrinsic_state_badu77 ();
2052 assert ("bad family" == NULL);
2053 return FFE_intrinsicstateDELETED;