1 /* intrin.c -- Recognize references to intrinsics
2 Copyright (C) 1995-1997 Free Software Foundation, Inc.
3 Contributed by James Craig Burley (burley@gnu.ai.mit.edu).
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
34 struct _ffeintrin_name_
40 ffeintrinSpec specific
;
43 struct _ffeintrin_gen_
45 char *name
; /* Name as seen in program. */
46 ffeintrinSpec specs
[2];
49 struct _ffeintrin_spec_
51 char *name
; /* Uppercase name as seen in source code,
52 lowercase if no source name, "none" if no
53 name at all (NONE case). */
54 bool is_actualarg
; /* Ok to pass as actual arg if -pedantic. */
55 ffeintrinFamily family
;
56 ffeintrinImp implementation
;
59 struct _ffeintrin_imp_
61 char *name
; /* Name of implementation. */
62 #if FFECOM_targetCURRENT == FFECOM_targetGCC
63 ffecomGfrt gfrt_direct
; /* library routine, direct-callable form. */
64 ffecomGfrt gfrt_f2c
; /* library routine, f2c-callable form. */
65 ffecomGfrt gfrt_gnu
; /* library routine, gnu-callable form. */
66 #endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */
70 static ffebad
ffeintrin_check_ (ffeintrinImp imp
, ffebldOp op
,
71 ffebld args
, ffeinfoBasictype
*xbt
,
73 ffetargetCharacterSize
*xsz
,
77 static bool ffeintrin_check_any_ (ffebld arglist
);
78 static int ffeintrin_cmp_name_ (const void *name
, const void *intrinsic
);
80 static struct _ffeintrin_name_ ffeintrin_names_
[]
83 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) \
84 { UPPER, LOWER, MIXED, FFEINTRIN_ ## GEN, FFEINTRIN_ ## SPEC },
85 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
86 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
87 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
95 static 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 #include "intrin.def"
110 static struct _ffeintrin_imp_ ffeintrin_imps_
[]
113 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC)
114 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
115 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP)
116 #if FFECOM_targetCURRENT == FFECOM_targetGCC
117 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \
118 { NAME, FFECOM_gfrt ## GFRTDIRECT, FFECOM_gfrt ## GFRTF2C, \
119 FFECOM_gfrt ## GFRTGNU, CONTROL },
120 #elif FFECOM_targetCURRENT == FFECOM_targetFFE
121 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \
126 #include "intrin.def"
133 static struct _ffeintrin_spec_ ffeintrin_specs_
[]
136 #define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC)
137 #define DEFGEN(CODE,NAME,SPEC1,SPEC2)
138 #define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) \
139 { NAME, CALLABLE, FAMILY, IMP, },
140 #define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL)
141 #include "intrin.def"
149 ffeintrin_check_ (ffeintrinImp imp
, ffebldOp op
,
150 ffebld args
, ffeinfoBasictype
*xbt
,
151 ffeinfoKindtype
*xkt
,
152 ffetargetCharacterSize
*xsz
,
157 char *c
= ffeintrin_imps_
[imp
].control
;
158 bool subr
= (c
[0] == '-');
163 ffetargetCharacterSize sz
= FFETARGET_charactersizeNONE
;
164 ffeinfoKindtype firstarg_kt
;
166 ffeinfoBasictype col_bt
= FFEINFO_basictypeNONE
;
167 ffeinfoKindtype col_kt
= FFEINFO_kindtypeNONE
;
168 int colon
= (c
[2] == ':') ? 2 : 3;
171 /* Check procedure type (function vs. subroutine) against
174 if (op
== FFEBLD_opSUBRREF
)
177 return FFEBAD_INTRINSIC_IS_FUNC
;
179 else if (op
== FFEBLD_opFUNCREF
)
182 return FFEBAD_INTRINSIC_IS_SUBR
;
185 return FFEBAD_INTRINSIC_REF
;
187 /* Check the arglist for validity. */
190 && (ffebld_head (args
) != NULL
))
191 firstarg_kt
= ffeinfo_kindtype (ffebld_info (ffebld_head (args
)));
193 firstarg_kt
= FFEINFO_kindtype
;
195 for (argc
= &c
[colon
+ 3],
200 char optional
= '\0';
201 char required
= '\0';
207 bool lastarg_complex
= FALSE
;
209 /* We don't do anything with keywords yet. */
212 } while (*(++argc
) != '=');
218 optional
= *(argc
++);
222 required
= *(argc
++);
227 length
= *++argc
- '0';
229 length
= 10 * length
+ (*(argc
++) - '0');
236 elements
= *++argc
- '0';
238 elements
= 10 * elements
+ (*(argc
++) - '0');
241 else if (*argc
== '&')
256 /* Break out of this loop only when current arg spec completely
265 ffeinfoBasictype abt
= FFEINFO_basictypeNONE
;
266 ffeinfoKindtype akt
= FFEINFO_kindtypeNONE
;
269 || (ffebld_head (arg
) == NULL
))
271 if (required
!= '\0')
272 return FFEBAD_INTRINSIC_TOOFEW
;
273 if (optional
== '\0')
274 return FFEBAD_INTRINSIC_TOOFEW
;
276 arg
= ffebld_trail (arg
);
277 break; /* Try next argspec. */
280 a
= ffebld_head (arg
);
282 anynum
= (ffeinfo_basictype (i
) == FFEINFO_basictypeHOLLERITH
)
283 || (ffeinfo_basictype (i
) == FFEINFO_basictypeTYPELESS
);
285 /* See how well the arg matches up to the spec. */
290 okay
= (ffeinfo_basictype (i
) == FFEINFO_basictypeCHARACTER
)
292 || (ffeinfo_size (i
) == (ffetargetCharacterSize
) length
));
297 || (ffeinfo_basictype (i
) == FFEINFO_basictypeCOMPLEX
);
298 abt
= FFEINFO_basictypeCOMPLEX
;
303 || (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
);
304 abt
= FFEINFO_basictypeINTEGER
;
309 || (ffeinfo_basictype (i
) == FFEINFO_basictypeLOGICAL
);
310 abt
= FFEINFO_basictypeLOGICAL
;
315 || (ffeinfo_basictype (i
) == FFEINFO_basictypeREAL
);
316 abt
= FFEINFO_basictypeREAL
;
321 || (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
322 || (ffeinfo_basictype (i
) == FFEINFO_basictypeLOGICAL
);
327 || (ffeinfo_basictype (i
) == FFEINFO_basictypeCOMPLEX
)
328 || (ffeinfo_basictype (i
) == FFEINFO_basictypeREAL
);
333 || (ffeinfo_basictype (i
) == FFEINFO_basictypeCOMPLEX
)
334 || (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
335 || (ffeinfo_basictype (i
) == FFEINFO_basictypeREAL
);
340 || (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
341 || (ffeinfo_basictype (i
) == FFEINFO_basictypeREAL
);
345 okay
= ((ffebld_op (a
) == FFEBLD_opLABTER
)
346 || (ffebld_op (a
) == FFEBLD_opLABTOK
));
352 okay
= (((((ffeinfo_basictype (i
) == FFEINFO_basictypeNONE
)
353 && (ffeinfo_kindtype (i
) == FFEINFO_kindtypeNONE
)
354 && (ffeinfo_kind (i
) == FFEINFO_kindSUBROUTINE
))
355 || ((ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
356 && (ffeinfo_kindtype (i
) == FFEINFO_kindtypeINTEGERDEFAULT
)
357 && (ffeinfo_kind (i
) == FFEINFO_kindFUNCTION
))
358 || (ffeinfo_kind (i
) == FFEINFO_kindNONE
))
359 && ((ffeinfo_where (i
) == FFEINFO_whereDUMMY
)
360 || (ffeinfo_where (i
) == FFEINFO_whereGLOBAL
)))
361 || ((ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
362 && (ffeinfo_kind (i
) == FFEINFO_kindENTITY
)));
375 case '1': case '2': case '3': case '4': case '5':
376 case '6': case '7': case '8': case '9':
378 if ((ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
379 || (ffeinfo_basictype (i
) == FFEINFO_basictypeLOGICAL
))
382 { /* Translate to internal kinds for now! */
403 okay
&= anynum
|| (ffeinfo_kindtype (i
) == akt
);
407 okay
&= anynum
|| (ffeinfo_kindtype (i
) == firstarg_kt
);
408 akt
= (firstarg_kt
== FFEINFO_kindtype
) ? FFEINFO_kindtypeNONE
425 if (ffeinfo_rank (i
) != 0)
430 if ((ffeinfo_rank (i
) != 1)
431 || (ffebld_op (a
) != FFEBLD_opSYMTER
)
432 || ((b
= ffesymbol_arraysize (ffebld_symter (a
))) == NULL
)
433 || (ffebld_op (b
) != FFEBLD_opCONTER
)
434 || (ffeinfo_basictype (ffebld_info (b
)) != FFEINFO_basictypeINTEGER
)
435 || (ffeinfo_kindtype (ffebld_info (b
)) != FFEINFO_kindtypeINTEGERDEFAULT
)
436 || (ffebld_constant_integer1 (ffebld_conter (b
)) != elements
))
444 if ((ffeinfo_kind (i
) != FFEINFO_kindENTITY
)
445 || ((ffebld_op (a
) != FFEBLD_opSYMTER
)
446 && (ffebld_op (a
) != FFEBLD_opSUBSTR
)
447 && (ffebld_op (a
) != FFEBLD_opARRAYREF
)))
453 if ((ffeinfo_kind (i
) != FFEINFO_kindENTITY
)
454 || ((ffebld_op (a
) != FFEBLD_opSYMTER
)
455 && (ffebld_op (a
) != FFEBLD_opARRAYREF
)
456 && (ffebld_op (a
) != FFEBLD_opSUBSTR
)))
465 if (ffeinfo_kind (i
) != FFEINFO_kindENTITY
)
470 if ((optional
== '!')
476 /* If it wasn't optional, it's an error,
477 else maybe it could match a later argspec. */
478 if (optional
== '\0')
479 return FFEBAD_INTRINSIC_REF
;
480 break; /* Try next argspec. */
484 = (ffeinfo_basictype (i
) == FFEINFO_basictypeCOMPLEX
);
488 /* If we know dummy arg type, convert to that now. */
490 if ((abt
!= FFEINFO_basictypeNONE
)
491 && (akt
!= FFEINFO_kindtypeNONE
)
494 /* We have a known type, convert hollerith/typeless
497 a
= ffeexpr_convert (a
, t
, NULL
,
499 FFETARGET_charactersizeNONE
,
501 ffebld_set_head (arg
, a
);
505 arg
= ffebld_trail (arg
); /* Arg accepted, now move on. */
508 continue; /* Go ahead and try another arg. */
509 if (required
== '\0')
511 if ((required
== 'n')
512 || (required
== '+'))
517 else if (required
== 'p')
522 /* Ignore explicit trailing omitted args. */
524 while ((arg
!= NULL
) && (ffebld_head (arg
) == NULL
))
525 arg
= ffebld_trail (arg
);
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! */
607 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
;
628 arg
= (c
[colon
+ 1] == '*') ? ffebld_trail (arg
) : NULL
)
630 ffebld a
= ffebld_head (arg
);
638 anynum
= (ffeinfo_basictype (i
) == FFEINFO_basictypeHOLLERITH
)
639 || (ffeinfo_basictype (i
) == FFEINFO_basictypeTYPELESS
);
646 if ((col_bt
== FFEINFO_basictypeNONE
)
647 && (col_kt
== FFEINFO_kindtypeNONE
))
649 col_bt
= ffeinfo_basictype (i
);
650 col_kt
= ffeinfo_kindtype (i
);
654 ffeexpr_type_combine (&col_bt
, &col_kt
,
656 ffeinfo_basictype (i
),
657 ffeinfo_kindtype (i
),
659 if ((col_bt
== FFEINFO_basictypeNONE
)
660 || (col_kt
== FFEINFO_kindtypeNONE
))
661 return FFEBAD_INTRINSIC_REF
;
666 && ((col_bt
== FFEINFO_basictypeNONE
)
667 || (col_kt
== FFEINFO_kindtypeNONE
)))
669 /* No type, but have hollerith/typeless. Use type of return
670 value to determine type of COL. */
675 return FFEBAD_INTRINSIC_REF
;
680 if ((col_bt
!= FFEINFO_basictypeNONE
)
681 && (col_bt
!= FFEINFO_basictypeINTEGER
))
682 return FFEBAD_INTRINSIC_REF
;
688 col_bt
= FFEINFO_basictypeINTEGER
;
689 col_kt
= FFEINFO_kindtypeINTEGER1
;
693 if ((col_bt
!= FFEINFO_basictypeNONE
)
694 && (col_bt
!= FFEINFO_basictypeCOMPLEX
))
695 return FFEBAD_INTRINSIC_REF
;
696 col_bt
= FFEINFO_basictypeCOMPLEX
;
697 col_kt
= FFEINFO_kindtypeREAL1
;
701 if ((col_bt
!= FFEINFO_basictypeNONE
)
702 && (col_bt
!= FFEINFO_basictypeREAL
))
703 return FFEBAD_INTRINSIC_REF
;
706 col_bt
= FFEINFO_basictypeREAL
;
707 col_kt
= FFEINFO_kindtypeREAL1
;
715 okay
= (col_bt
== FFEINFO_basictypeINTEGER
)
716 || (col_bt
== FFEINFO_basictypeLOGICAL
);
722 okay
= (col_bt
== FFEINFO_basictypeCOMPLEX
)
723 || (col_bt
== FFEINFO_basictypeREAL
);
729 okay
= (col_bt
== FFEINFO_basictypeCOMPLEX
)
730 || (col_bt
== FFEINFO_basictypeINTEGER
)
731 || (col_bt
== FFEINFO_basictypeREAL
);
737 okay
= (col_bt
== FFEINFO_basictypeINTEGER
)
738 || (col_bt
== FFEINFO_basictypeREAL
)
739 || (col_bt
== FFEINFO_basictypeCOMPLEX
);
741 bt
= ((col_bt
!= FFEINFO_basictypeCOMPLEX
) ? col_bt
742 : FFEINFO_basictypeREAL
);
754 if (col_bt
== FFEINFO_basictypeCOMPLEX
)
756 if (col_kt
!= FFEINFO_kindtypeREALDEFAULT
)
757 *check_intrin
= TRUE
;
765 return FFEBAD_INTRINSIC_REF
;
768 /* Now, convert args in the arglist to the final type of the COL. */
770 for (argno
= 0, argc
= &c
[colon
+ 3],
775 char optional
= '\0';
776 char required
= '\0';
782 bool lastarg_complex
= FALSE
;
784 /* We don't do anything with keywords yet. */
787 } while (*(++argc
) != '=');
793 optional
= *(argc
++);
797 required
= *(argc
++);
802 length
= *++argc
- '0';
804 length
= 10 * length
+ (*(argc
++) - '0');
811 elements
= *++argc
- '0';
813 elements
= 10 * elements
+ (*(argc
++) - '0');
816 else if (*argc
== '&')
831 /* Break out of this loop only when current arg spec completely
840 ffeinfoBasictype abt
= FFEINFO_basictypeNONE
;
841 ffeinfoKindtype akt
= FFEINFO_kindtypeNONE
;
844 || (ffebld_head (arg
) == NULL
))
847 arg
= ffebld_trail (arg
);
848 break; /* Try next argspec. */
851 a
= ffebld_head (arg
);
853 anynum
= (ffeinfo_basictype (i
) == FFEINFO_basictypeHOLLERITH
)
854 || (ffeinfo_basictype (i
) == FFEINFO_basictypeTYPELESS
);
856 /* Determine what the default type for anynum would be. */
860 switch (c
[colon
+ 1])
864 case '0': case '1': case '2': case '3': case '4':
865 case '5': case '6': case '7': case '8': case '9':
866 if (argno
!= (c
[colon
+ 1] - '0'))
875 /* Again, match arg up to the spec. We go through all of
876 this again to properly follow the contour of optional
877 arguments. Probably this level of flexibility is not
878 needed, perhaps it's even downright naughty. */
883 okay
= (ffeinfo_basictype (i
) == FFEINFO_basictypeCHARACTER
)
885 || (ffeinfo_size (i
) == (ffetargetCharacterSize
) length
));
890 || (ffeinfo_basictype (i
) == FFEINFO_basictypeCOMPLEX
);
891 abt
= FFEINFO_basictypeCOMPLEX
;
896 || (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
);
897 abt
= FFEINFO_basictypeINTEGER
;
902 || (ffeinfo_basictype (i
) == FFEINFO_basictypeLOGICAL
);
903 abt
= FFEINFO_basictypeLOGICAL
;
908 || (ffeinfo_basictype (i
) == FFEINFO_basictypeREAL
);
909 abt
= FFEINFO_basictypeREAL
;
914 || (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
915 || (ffeinfo_basictype (i
) == FFEINFO_basictypeLOGICAL
);
920 || (ffeinfo_basictype (i
) == FFEINFO_basictypeCOMPLEX
)
921 || (ffeinfo_basictype (i
) == FFEINFO_basictypeREAL
);
926 || (ffeinfo_basictype (i
) == FFEINFO_basictypeCOMPLEX
)
927 || (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
928 || (ffeinfo_basictype (i
) == FFEINFO_basictypeREAL
);
933 || (ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
934 || (ffeinfo_basictype (i
) == FFEINFO_basictypeREAL
);
938 okay
= ((ffebld_op (a
) == FFEBLD_opLABTER
)
939 || (ffebld_op (a
) == FFEBLD_opLABTOK
));
945 okay
= (((((ffeinfo_basictype (i
) == FFEINFO_basictypeNONE
)
946 && (ffeinfo_kindtype (i
) == FFEINFO_kindtypeNONE
)
947 && (ffeinfo_kind (i
) == FFEINFO_kindSUBROUTINE
))
948 || ((ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
949 && (ffeinfo_kindtype (i
) == FFEINFO_kindtypeINTEGERDEFAULT
)
950 && (ffeinfo_kind (i
) == FFEINFO_kindFUNCTION
))
951 || (ffeinfo_kind (i
) == FFEINFO_kindNONE
))
952 && ((ffeinfo_where (i
) == FFEINFO_whereDUMMY
)
953 || (ffeinfo_where (i
) == FFEINFO_whereGLOBAL
)))
954 || ((ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
955 && (ffeinfo_kind (i
) == FFEINFO_kindENTITY
)));
968 case '1': case '2': case '3': case '4': case '5':
969 case '6': case '7': case '8': case '9':
971 if ((ffeinfo_basictype (i
) == FFEINFO_basictypeINTEGER
)
972 || (ffeinfo_basictype (i
) == FFEINFO_basictypeLOGICAL
))
975 { /* Translate to internal kinds for now! */
996 okay
&= anynum
|| (ffeinfo_kindtype (i
) == akt
);
1000 okay
&= anynum
|| (ffeinfo_kindtype (i
) == firstarg_kt
);
1001 akt
= (firstarg_kt
== FFEINFO_kindtype
) ? FFEINFO_kindtypeNONE
1018 if (ffeinfo_rank (i
) != 0)
1023 if ((ffeinfo_rank (i
) != 1)
1024 || (ffebld_op (a
) != FFEBLD_opSYMTER
)
1025 || ((b
= ffesymbol_arraysize (ffebld_symter (a
))) == NULL
)
1026 || (ffebld_op (b
) != FFEBLD_opCONTER
)
1027 || (ffeinfo_basictype (ffebld_info (b
)) != FFEINFO_basictypeINTEGER
)
1028 || (ffeinfo_kindtype (ffebld_info (b
)) != FFEINFO_kindtypeINTEGERDEFAULT
)
1029 || (ffebld_constant_integer1 (ffebld_conter (b
)) != elements
))
1037 if ((ffeinfo_kind (i
) != FFEINFO_kindENTITY
)
1038 || ((ffebld_op (a
) != FFEBLD_opSYMTER
)
1039 && (ffebld_op (a
) != FFEBLD_opSUBSTR
)
1040 && (ffebld_op (a
) != FFEBLD_opARRAYREF
)))
1046 if ((ffeinfo_kind (i
) != FFEINFO_kindENTITY
)
1047 || ((ffebld_op (a
) != FFEBLD_opSYMTER
)
1048 && (ffebld_op (a
) != FFEBLD_opARRAYREF
)
1049 && (ffebld_op (a
) != FFEBLD_opSUBSTR
)))
1058 if (ffeinfo_kind (i
) != FFEINFO_kindENTITY
)
1063 if ((optional
== '!')
1069 /* If it wasn't optional, it's an error,
1070 else maybe it could match a later argspec. */
1071 if (optional
== '\0')
1072 return FFEBAD_INTRINSIC_REF
;
1073 break; /* Try next argspec. */
1077 = (ffeinfo_basictype (i
) == FFEINFO_basictypeCOMPLEX
);
1079 if (anynum
&& commit
)
1081 /* If we know dummy arg type, convert to that now. */
1083 if (abt
== FFEINFO_basictypeNONE
)
1084 abt
= FFEINFO_basictypeINTEGER
;
1085 if (akt
== FFEINFO_kindtypeNONE
)
1086 akt
= FFEINFO_kindtypeINTEGER1
;
1088 /* We have a known type, convert hollerith/typeless to it. */
1090 a
= ffeexpr_convert (a
, t
, NULL
,
1092 FFETARGET_charactersizeNONE
,
1093 FFEEXPR_contextLET
);
1094 ffebld_set_head (arg
, a
);
1096 else if ((c
[colon
+ 1] == '*') && commit
)
1098 /* This is where we promote types to the consensus
1099 type for the COL. Maybe this is where -fpedantic
1100 should issue a warning as well. */
1102 a
= ffeexpr_convert (a
, t
, NULL
,
1105 FFEEXPR_contextLET
);
1106 ffebld_set_head (arg
, a
);
1109 arg
= ffebld_trail (arg
); /* Arg accepted, now move on. */
1111 if (optional
== '*')
1112 continue; /* Go ahead and try another arg. */
1113 if (required
== '\0')
1115 if ((required
== 'n')
1116 || (required
== '+'))
1121 else if (required
== 'p')
1133 ffeintrin_check_any_ (ffebld arglist
)
1137 for (; arglist
!= NULL
; arglist
= ffebld_trail (arglist
))
1139 item
= ffebld_head (arglist
);
1141 && (ffebld_op (item
) == FFEBLD_opANY
))
1148 /* Compare name to intrinsic's name. Uses strcmp on arguments' names. */
1151 ffeintrin_cmp_name_ (const void *name
, const void *intrinsic
)
1153 char *uc
= (char *) ((struct _ffeintrin_name_
*) intrinsic
)->name_uc
;
1154 char *lc
= (char *) ((struct _ffeintrin_name_
*) intrinsic
)->name_lc
;
1155 char *ic
= (char *) ((struct _ffeintrin_name_
*) intrinsic
)->name_ic
;
1157 return ffesrc_strcmp_2c (ffe_case_intrin (), name
, uc
, lc
, ic
);
1160 /* Return basic type of intrinsic implementation, based on its
1161 run-time implementation *only*. (This is used only when
1162 the type of an intrinsic name is needed without having a
1163 list of arguments, i.e. an interface signature, such as when
1164 passing the intrinsic itself, or really the run-time-library
1165 function, as an argument.)
1167 If there's no eligible intrinsic implementation, there must be
1168 a bug somewhere else; no such reference should have been permitted
1169 to go this far. (Well, this might be wrong.) */
1172 ffeintrin_basictype (ffeintrinSpec spec
)
1177 assert (spec
< FFEINTRIN_spec
);
1178 imp
= ffeintrin_specs_
[spec
].implementation
;
1179 assert (imp
< FFEINTRIN_imp
);
1182 gfrt
= ffeintrin_imps_
[imp
].gfrt_f2c
;
1184 gfrt
= ffeintrin_imps_
[imp
].gfrt_gnu
;
1186 assert (gfrt
!= FFECOM_gfrt
);
1188 return ffecom_gfrt_basictype (gfrt
);
1191 /* Return family to which specific intrinsic belongs. */
1194 ffeintrin_family (ffeintrinSpec spec
)
1196 if (spec
>= FFEINTRIN_spec
)
1198 return ffeintrin_specs_
[spec
].family
;
1201 /* Check and fill in info on func/subr ref node.
1203 ffebld expr; // FUNCREF or SUBRREF with no info (caller
1204 // gets it from the modified info structure).
1205 ffeinfo info; // Already filled in, will be overwritten.
1206 ffelexToken token; // Used for error message.
1207 ffeintrin_fulfill_generic (&expr, &info, token);
1209 Based on the generic id, figure out which specific procedure is meant and
1210 pick that one. Else return an error, a la _specific. */
1213 ffeintrin_fulfill_generic (ffebld
*expr
, ffeinfo
*info
, ffelexToken t
)
1218 ffeintrinSpec spec
= FFEINTRIN_specNONE
;
1219 ffeinfoBasictype bt
= FFEINFO_basictypeNONE
;
1220 ffeinfoKindtype kt
= FFEINFO_kindtypeNONE
;
1221 ffetargetCharacterSize sz
= FFETARGET_charactersizeNONE
;
1223 ffeintrinSpec tspec
;
1224 ffeintrinImp nimp
= FFEINTRIN_impNONE
;
1227 bool highly_specific
= FALSE
;
1230 op
= ffebld_op (*expr
);
1231 assert ((op
== FFEBLD_opFUNCREF
) || (op
== FFEBLD_opSUBRREF
));
1232 assert (ffebld_op (ffebld_left (*expr
)) == FFEBLD_opSYMTER
);
1234 gen
= ffebld_symter_generic (ffebld_left (*expr
));
1235 assert (gen
!= FFEINTRIN_genNONE
);
1237 imp
= FFEINTRIN_impNONE
;
1240 any
= ffeintrin_check_any_ (ffebld_right (*expr
));
1243 (((size_t) i
) < ARRAY_SIZE (ffeintrin_gens_
[gen
].specs
))
1244 && ((tspec
= ffeintrin_gens_
[gen
].specs
[i
]) != FFEINTRIN_specNONE
)
1248 ffeintrinImp timp
= ffeintrin_specs_
[tspec
].implementation
;
1249 ffeinfoBasictype tbt
;
1250 ffeinfoKindtype tkt
;
1251 ffetargetCharacterSize tsz
;
1252 ffeIntrinsicState state
1253 = ffeintrin_state_family (ffeintrin_specs_
[tspec
].family
);
1256 if (state
== FFE_intrinsicstateDELETED
)
1259 if (timp
!= FFEINTRIN_impNONE
)
1261 if (!(ffeintrin_imps_
[timp
].control
[0] == '-')
1262 != !(ffebld_op (*expr
) == FFEBLD_opSUBRREF
))
1263 continue; /* Form of reference must match form of specific. */
1266 if (state
== FFE_intrinsicstateDISABLED
)
1267 terror
= FFEBAD_INTRINSIC_DISABLED
;
1268 else if (timp
== FFEINTRIN_impNONE
)
1269 terror
= FFEBAD_INTRINSIC_UNIMPL
;
1272 terror
= ffeintrin_check_ (timp
, ffebld_op (*expr
),
1273 ffebld_right (*expr
),
1274 &tbt
, &tkt
, &tsz
, NULL
, t
, FALSE
);
1275 if (terror
== FFEBAD
)
1277 if (imp
!= FFEINTRIN_impNONE
)
1279 ffebad_start (FFEBAD_INTRINSIC_AMBIG
);
1280 ffebad_here (0, ffelex_token_where_line (t
),
1281 ffelex_token_where_column (t
));
1282 ffebad_string (ffeintrin_gens_
[gen
].name
);
1283 ffebad_string (ffeintrin_specs_
[spec
].name
);
1284 ffebad_string (ffeintrin_specs_
[tspec
].name
);
1289 if (ffebld_symter_specific (ffebld_left (*expr
))
1291 highly_specific
= TRUE
;
1300 else if (terror
!= FFEBAD
)
1301 { /* This error has precedence over others. */
1302 if ((error
== FFEBAD_INTRINSIC_DISABLED
)
1303 || (error
== FFEBAD_INTRINSIC_UNIMPL
))
1308 if (error
== FFEBAD
)
1312 if (any
|| (imp
== FFEINTRIN_impNONE
))
1316 if (error
== FFEBAD
)
1317 error
= FFEBAD_INTRINSIC_REF
;
1318 ffebad_start (error
);
1319 ffebad_here (0, ffelex_token_where_line (t
),
1320 ffelex_token_where_column (t
));
1321 ffebad_string (ffeintrin_gens_
[gen
].name
);
1325 *expr
= ffebld_new_any ();
1326 *info
= ffeinfo_new_any ();
1330 if (!highly_specific
&& (nimp
!= FFEINTRIN_impNONE
))
1332 fprintf (stderr
, "lineno=%ld, gen=%s, imp=%s, timp=%s\n",
1334 ffeintrin_gens_
[gen
].name
,
1335 ffeintrin_imps_
[imp
].name
,
1336 ffeintrin_imps_
[nimp
].name
);
1337 assert ("Ambiguous generic reference" == NULL
);
1340 error
= ffeintrin_check_ (imp
, ffebld_op (*expr
),
1341 ffebld_right (*expr
),
1342 &bt
, &kt
, &sz
, NULL
, t
, TRUE
);
1343 assert (error
== FFEBAD
);
1344 *info
= ffeinfo_new (bt
,
1348 FFEINFO_whereFLEETING
,
1350 symter
= ffebld_left (*expr
);
1351 ffebld_symter_set_specific (symter
, spec
);
1352 ffebld_symter_set_implementation (symter
, imp
);
1353 ffebld_set_info (symter
,
1357 (bt
== FFEINFO_basictypeNONE
)
1358 ? FFEINFO_kindSUBROUTINE
1359 : FFEINFO_kindFUNCTION
,
1360 FFEINFO_whereINTRINSIC
,
1363 if ((ffesymbol_attrs (ffebld_symter (symter
)) & FFESYMBOL_attrsTYPE
)
1364 && (((bt
!= ffesymbol_basictype (ffebld_symter (symter
)))
1365 || (kt
!= ffesymbol_kindtype (ffebld_symter (symter
)))
1366 || (sz
!= ffesymbol_size (ffebld_symter (symter
))))))
1368 ffebad_start (FFEBAD_INTRINSIC_TYPE
);
1369 ffebad_here (0, ffelex_token_where_line (t
),
1370 ffelex_token_where_column (t
));
1371 ffebad_string (ffeintrin_gens_
[gen
].name
);
1377 /* Check and fill in info on func/subr ref node.
1379 ffebld expr; // FUNCREF or SUBRREF with no info (caller
1380 // gets it from the modified info structure).
1381 ffeinfo info; // Already filled in, will be overwritten.
1382 bool check_intrin; // May be omitted, else set TRUE if intrinsic needs checking.
1383 ffelexToken token; // Used for error message.
1384 ffeintrin_fulfill_specific (&expr, &info, &check_intrin, token);
1386 Based on the specific id, determine whether the arg list is valid
1387 (number, type, rank, and kind of args) and fill in the info structure
1388 accordingly. Currently don't rewrite the expression, but perhaps
1389 someday do so for constant collapsing, except when an error occurs,
1390 in which case it is overwritten with ANY and info is also overwritten
1394 ffeintrin_fulfill_specific (ffebld
*expr
, ffeinfo
*info
,
1395 bool *check_intrin
, ffelexToken t
)
1402 ffeinfoBasictype bt
= FFEINFO_basictypeNONE
;
1403 ffeinfoKindtype kt
= FFEINFO_kindtypeNONE
;
1404 ffetargetCharacterSize sz
= FFETARGET_charactersizeNONE
;
1405 ffeIntrinsicState state
;
1410 op
= ffebld_op (*expr
);
1411 assert ((op
== FFEBLD_opFUNCREF
) || (op
== FFEBLD_opSUBRREF
));
1412 assert (ffebld_op (ffebld_left (*expr
)) == FFEBLD_opSYMTER
);
1414 gen
= ffebld_symter_generic (ffebld_left (*expr
));
1415 spec
= ffebld_symter_specific (ffebld_left (*expr
));
1416 assert (spec
!= FFEINTRIN_specNONE
);
1418 if (gen
!= FFEINTRIN_genNONE
)
1419 name
= ffeintrin_gens_
[gen
].name
;
1421 name
= ffeintrin_specs_
[spec
].name
;
1423 state
= ffeintrin_state_family (ffeintrin_specs_
[spec
].family
);
1425 imp
= ffeintrin_specs_
[spec
].implementation
;
1426 if (check_intrin
!= NULL
)
1427 *check_intrin
= FALSE
;
1429 any
= ffeintrin_check_any_ (ffebld_right (*expr
));
1431 if (state
== FFE_intrinsicstateDISABLED
)
1432 error
= FFEBAD_INTRINSIC_DISABLED
;
1433 else if (imp
== FFEINTRIN_impNONE
)
1434 error
= FFEBAD_INTRINSIC_UNIMPL
;
1437 error
= ffeintrin_check_ (imp
, ffebld_op (*expr
),
1438 ffebld_right (*expr
),
1439 &bt
, &kt
, &sz
, check_intrin
, t
, TRUE
);
1442 error
= FFEBAD
; /* Not really needed, but quiet -Wuninitialized. */
1444 if (any
|| (error
!= FFEBAD
))
1449 ffebad_start (error
);
1450 ffebad_here (0, ffelex_token_where_line (t
),
1451 ffelex_token_where_column (t
));
1452 ffebad_string (name
);
1456 *expr
= ffebld_new_any ();
1457 *info
= ffeinfo_new_any ();
1461 *info
= ffeinfo_new (bt
,
1465 FFEINFO_whereFLEETING
,
1467 symter
= ffebld_left (*expr
);
1468 ffebld_set_info (symter
,
1472 (bt
== FFEINFO_basictypeNONE
)
1473 ? FFEINFO_kindSUBROUTINE
1474 : FFEINFO_kindFUNCTION
,
1475 FFEINFO_whereINTRINSIC
,
1478 if ((ffesymbol_attrs (ffebld_symter (symter
)) & FFESYMBOL_attrsTYPE
)
1479 && (((bt
!= ffesymbol_basictype (ffebld_symter (symter
)))
1480 || (kt
!= ffesymbol_kindtype (ffebld_symter (symter
)))
1481 || (sz
!= ffesymbol_size (ffebld_symter (symter
))))))
1483 ffebad_start (FFEBAD_INTRINSIC_TYPE
);
1484 ffebad_here (0, ffelex_token_where_line (t
),
1485 ffelex_token_where_column (t
));
1486 ffebad_string (name
);
1492 /* Return run-time index of intrinsic implementation as direct call. */
1494 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1496 ffeintrin_gfrt_direct (ffeintrinImp imp
)
1498 assert (imp
< FFEINTRIN_imp
);
1500 return ffeintrin_imps_
[imp
].gfrt_direct
;
1504 /* Return run-time index of intrinsic implementation as actual argument. */
1506 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1508 ffeintrin_gfrt_indirect (ffeintrinImp imp
)
1510 assert (imp
< FFEINTRIN_imp
);
1512 if (! ffe_is_f2c ())
1513 return ffeintrin_imps_
[imp
].gfrt_gnu
;
1514 return ffeintrin_imps_
[imp
].gfrt_f2c
;
1527 if (!ffe_is_do_internal_checks ())
1530 assert (FFEINTRIN_gen
== ARRAY_SIZE (ffeintrin_gens_
));
1531 assert (FFEINTRIN_imp
== ARRAY_SIZE (ffeintrin_imps_
));
1532 assert (FFEINTRIN_spec
== ARRAY_SIZE (ffeintrin_specs_
));
1534 for (i
= 1; ((size_t) i
) < ARRAY_SIZE (ffeintrin_names_
); ++i
)
1535 { /* Make sure binary-searched list is in alpha
1537 if (strcmp (ffeintrin_names_
[i
- 1].name_uc
,
1538 ffeintrin_names_
[i
].name_uc
) >= 0)
1539 assert ("name list out of order" == NULL
);
1542 for (i
= 0; ((size_t) i
) < ARRAY_SIZE (ffeintrin_names_
); ++i
)
1544 assert ((ffeintrin_names_
[i
].generic
== FFEINTRIN_genNONE
)
1545 || (ffeintrin_names_
[i
].specific
== FFEINTRIN_specNONE
));
1547 p1
= ffeintrin_names_
[i
].name_uc
;
1548 p2
= ffeintrin_names_
[i
].name_lc
;
1549 p3
= ffeintrin_names_
[i
].name_ic
;
1550 for (; *p1
!= '\0' && *p2
!= '\0' && *p3
!= '\0'; ++p1
, ++p2
, ++p3
)
1552 if (!isascii (*p1
) || !isascii (*p2
) || !isascii (*p3
))
1554 if ((isdigit (*p1
) || (*p1
== '_')) && (*p1
== *p2
) && (*p1
== *p3
))
1556 if (!isupper (*p1
) || !islower (*p2
)
1557 || (*p1
!= toupper (*p2
)) || ((*p3
!= *p1
) && (*p3
!= *p2
)))
1560 assert ((*p1
== *p2
) && (*p1
== *p3
) && (*p1
== '\0'));
1563 for (i
= 0; ((size_t) i
) < ARRAY_SIZE (ffeintrin_imps_
); ++i
)
1565 char *c
= ffeintrin_imps_
[i
].control
;
1581 fprintf (stderr
, "%s: bad return-base-type\n",
1582 ffeintrin_imps_
[i
].name
);
1592 fprintf (stderr
, "%s: bad return-kind-type\n",
1593 ffeintrin_imps_
[i
].name
);
1602 fprintf (stderr
, "%s: bad return-modifier\n",
1603 ffeintrin_imps_
[i
].name
);
1608 if ((c
[colon
] != ':') || (c
[colon
+ 2] != ':'))
1610 fprintf (stderr
, "%s: bad control\n",
1611 ffeintrin_imps_
[i
].name
);
1614 if ((c
[colon
+ 1] != '-')
1615 && (c
[colon
+ 1] != '*')
1616 && ((c
[colon
+ 1] < '0')
1617 || (c
[colon
+ 1] > '9')))
1619 fprintf (stderr
, "%s: bad COL-spec\n",
1620 ffeintrin_imps_
[i
].name
);
1624 while (c
[0] != '\0')
1626 while ((c
[0] != '=')
1632 fprintf (stderr
, "%s: bad keyword\n",
1633 ffeintrin_imps_
[i
].name
);
1661 fprintf (stderr
, "%s: bad arg-type\n",
1662 ffeintrin_imps_
[i
].name
);
1667 if (((c
[4] < '0') || (c
[4] > '9'))
1669 && (++c
, (c
[4] < '0') || (c
[4] > '9')
1672 fprintf (stderr
, "%s: bad arg-len\n",
1673 ffeintrin_imps_
[i
].name
);
1680 if (((c
[4] < '0') || (c
[4] > '9'))
1682 && (++c
, (c
[4] < '0') || (c
[4] > '9')
1685 fprintf (stderr
, "%s: bad arg-rank\n",
1686 ffeintrin_imps_
[i
].name
);
1691 else if ((c
[3] == '&')
1706 fprintf (stderr
, "%s: bad arg-list\n",
1707 ffeintrin_imps_
[i
].name
);
1714 /* Determine whether intrinsic is okay as an actual argument. */
1717 ffeintrin_is_actualarg (ffeintrinSpec spec
)
1719 ffeIntrinsicState state
;
1721 if (spec
>= FFEINTRIN_spec
)
1724 state
= ffeintrin_state_family (ffeintrin_specs_
[spec
].family
);
1726 return (!ffe_is_pedantic () || ffeintrin_specs_
[spec
].is_actualarg
)
1727 #if FFECOM_targetCURRENT == FFECOM_targetGCC
1729 ? (ffeintrin_imps_
[ffeintrin_specs_
[spec
].implementation
].gfrt_f2c
1731 : (ffeintrin_imps_
[ffeintrin_specs_
[spec
].implementation
].gfrt_gnu
1734 && ((state
== FFE_intrinsicstateENABLED
)
1735 || (state
== FFE_intrinsicstateHIDDEN
));
1738 /* Determine if name is intrinsic, return info.
1740 char *name; // C-string name of possible intrinsic.
1741 ffelexToken t; // NULL if no diagnostic to be given.
1742 bool explicit; // TRUE if INTRINSIC name.
1743 ffeintrinGen gen; // (TRUE only) Generic id of intrinsic.
1744 ffeintrinSpec spec; // (TRUE only) Specific id of intrinsic.
1745 ffeintrinImp imp; // (TRUE only) Implementation id of intrinsic.
1746 if (ffeintrin_is_intrinsic (name, t, explicit,
1748 // is an intrinsic, use gen, spec, imp, and
1749 // kind accordingly. */
1752 ffeintrin_is_intrinsic (char *name
, ffelexToken t
, bool explicit,
1753 ffeintrinGen
*xgen
, ffeintrinSpec
*xspec
,
1756 struct _ffeintrin_name_
*intrinsic
;
1760 ffeIntrinsicState state
;
1761 bool disabled
= FALSE
;
1762 bool unimpl
= FALSE
;
1764 intrinsic
= bsearch (name
, &ffeintrin_names_
[0],
1765 ARRAY_SIZE (ffeintrin_names_
),
1766 sizeof (struct _ffeintrin_name_
),
1767 (void *) ffeintrin_cmp_name_
);
1769 if (intrinsic
== NULL
)
1772 gen
= intrinsic
->generic
;
1773 spec
= intrinsic
->specific
;
1774 imp
= ffeintrin_specs_
[spec
].implementation
;
1776 /* Generic is okay only if at least one of its specifics is okay. */
1778 if (gen
!= FFEINTRIN_genNONE
)
1781 ffeintrinSpec tspec
;
1784 name
= ffeintrin_gens_
[gen
].name
;
1787 (((size_t) i
) < ARRAY_SIZE (ffeintrin_gens_
[gen
].specs
))
1789 = ffeintrin_gens_
[gen
].specs
[i
]) != FFEINTRIN_specNONE
);
1792 state
= ffeintrin_state_family (ffeintrin_specs_
[tspec
].family
);
1794 if (state
== FFE_intrinsicstateDELETED
)
1797 if (state
== FFE_intrinsicstateDISABLED
)
1803 if (ffeintrin_specs_
[tspec
].implementation
== FFEINTRIN_impNONE
)
1809 if ((state
== FFE_intrinsicstateENABLED
)
1811 && (state
== FFE_intrinsicstateHIDDEN
)))
1818 gen
= FFEINTRIN_genNONE
;
1821 /* Specific is okay only if not: unimplemented, disabled, deleted, or
1822 hidden and not explicit. */
1824 if (spec
!= FFEINTRIN_specNONE
)
1826 if (gen
!= FFEINTRIN_genNONE
)
1827 name
= ffeintrin_gens_
[gen
].name
;
1829 name
= ffeintrin_specs_
[spec
].name
;
1831 if (((state
= ffeintrin_state_family (ffeintrin_specs_
[spec
].family
))
1832 == FFE_intrinsicstateDELETED
)
1834 && (state
== FFE_intrinsicstateHIDDEN
)))
1835 spec
= FFEINTRIN_specNONE
;
1836 else if (state
== FFE_intrinsicstateDISABLED
)
1839 spec
= FFEINTRIN_specNONE
;
1841 else if (imp
== FFEINTRIN_impNONE
)
1844 spec
= FFEINTRIN_specNONE
;
1848 /* If neither is okay, not an intrinsic. */
1850 if ((gen
== FFEINTRIN_genNONE
) && (spec
== FFEINTRIN_specNONE
))
1852 /* Here is where we produce a diagnostic about a reference to a
1853 disabled or unimplemented intrinsic, if the diagnostic is desired. */
1855 if ((disabled
|| unimpl
)
1858 ffebad_start (disabled
1859 ? FFEBAD_INTRINSIC_DISABLED
1860 : FFEBAD_INTRINSIC_UNIMPLW
);
1861 ffebad_here (0, ffelex_token_where_line (t
), ffelex_token_where_column (t
));
1862 ffebad_string (name
);
1869 /* Determine whether intrinsic is function or subroutine. If no specific
1870 id, scan list of possible specifics for generic to get consensus. If
1871 not unanimous, or clear from the context, return NONE. */
1873 if (spec
== FFEINTRIN_specNONE
)
1876 ffeintrinSpec tspec
;
1878 bool at_least_one_ok
= FALSE
;
1881 (((size_t) i
) < ARRAY_SIZE (ffeintrin_gens_
[gen
].specs
))
1883 = ffeintrin_gens_
[gen
].specs
[i
]) != FFEINTRIN_specNONE
);
1886 if (((state
= ffeintrin_state_family (ffeintrin_specs_
[tspec
].family
))
1887 == FFE_intrinsicstateDELETED
)
1888 || (state
== FFE_intrinsicstateDISABLED
))
1891 if ((timp
= ffeintrin_specs_
[tspec
].implementation
)
1892 == FFEINTRIN_impNONE
)
1895 at_least_one_ok
= TRUE
;
1899 if (!at_least_one_ok
)
1901 *xgen
= FFEINTRIN_genNONE
;
1902 *xspec
= FFEINTRIN_specNONE
;
1903 *ximp
= FFEINTRIN_impNONE
;
1914 /* Return TRUE if intrinsic is standard F77 (or, if -ff90, F90). */
1917 ffeintrin_is_standard (ffeintrinGen gen
, ffeintrinSpec spec
)
1919 if (spec
== FFEINTRIN_specNONE
)
1921 if (gen
== FFEINTRIN_genNONE
)
1924 spec
= ffeintrin_gens_
[gen
].specs
[0];
1925 if (spec
== FFEINTRIN_specNONE
)
1929 if ((ffeintrin_specs_
[spec
].family
== FFEINTRIN_familyF77
)
1931 && ((ffeintrin_specs_
[spec
].family
== FFEINTRIN_familyF90
)
1932 || (ffeintrin_specs_
[spec
].family
== FFEINTRIN_familyMIL
)
1933 || (ffeintrin_specs_
[spec
].family
== FFEINTRIN_familyASC
))))
1938 /* Return kind type of intrinsic implementation. See ffeintrin_basictype,
1942 ffeintrin_kindtype (ffeintrinSpec spec
)
1947 assert (spec
< FFEINTRIN_spec
);
1948 imp
= ffeintrin_specs_
[spec
].implementation
;
1949 assert (imp
< FFEINTRIN_imp
);
1952 gfrt
= ffeintrin_imps_
[imp
].gfrt_f2c
;
1954 gfrt
= ffeintrin_imps_
[imp
].gfrt_gnu
;
1956 assert (gfrt
!= FFECOM_gfrt
);
1958 return ffecom_gfrt_kindtype (gfrt
);
1961 /* Return name of generic intrinsic. */
1964 ffeintrin_name_generic (ffeintrinGen gen
)
1966 assert (gen
< FFEINTRIN_gen
);
1967 return ffeintrin_gens_
[gen
].name
;
1970 /* Return name of intrinsic implementation. */
1973 ffeintrin_name_implementation (ffeintrinImp imp
)
1975 assert (imp
< FFEINTRIN_imp
);
1976 return ffeintrin_imps_
[imp
].name
;
1979 /* Return external/internal name of specific intrinsic. */
1982 ffeintrin_name_specific (ffeintrinSpec spec
)
1984 assert (spec
< FFEINTRIN_spec
);
1985 return ffeintrin_specs_
[spec
].name
;
1988 /* Return state of family. */
1991 ffeintrin_state_family (ffeintrinFamily family
)
1993 ffeIntrinsicState state
;
1997 case FFEINTRIN_familyNONE
:
1998 return FFE_intrinsicstateDELETED
;
2000 case FFEINTRIN_familyF77
:
2001 return FFE_intrinsicstateENABLED
;
2003 case FFEINTRIN_familyASC
:
2004 state
= ffe_intrinsic_state_f2c ();
2005 state
= ffe_state_max (state
, ffe_intrinsic_state_f90 ());
2008 case FFEINTRIN_familyMIL
:
2009 state
= ffe_intrinsic_state_vxt ();
2010 state
= ffe_state_max (state
, ffe_intrinsic_state_f90 ());
2011 state
= ffe_state_max (state
, ffe_intrinsic_state_mil ());
2014 case FFEINTRIN_familyGNU
:
2015 state
= ffe_intrinsic_state_gnu ();
2018 case FFEINTRIN_familyF90
:
2019 state
= ffe_intrinsic_state_f90 ();
2022 case FFEINTRIN_familyVXT
:
2023 state
= ffe_intrinsic_state_vxt ();
2026 case FFEINTRIN_familyFVZ
:
2027 state
= ffe_intrinsic_state_f2c ();
2028 state
= ffe_state_max (state
, ffe_intrinsic_state_vxt ());
2031 case FFEINTRIN_familyF2C
:
2032 state
= ffe_intrinsic_state_f2c ();
2035 case FFEINTRIN_familyF2U
:
2036 state
= ffe_intrinsic_state_unix ();
2039 case FFEINTRIN_familyBADU77
:
2040 state
= ffe_intrinsic_state_badu77 ();
2044 assert ("bad family" == NULL
);
2045 return FFE_intrinsicstateDELETED
;